C_QanParser.js 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647
  1. /****************************************************************************************************************************
  2. Licensed Materials - Property of IBM
  3. BI and PM: QFW
  4. © Copyright IBM Corp. 2005, 2014
  5. US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  6. *****************************************************************************************************************************/
  7. var G_KeywordsMajorLookup = ["SELECT", "SELECT DISTINCT", "WHERE", "FROM", "GROUP BY", "ORDER BY", "WITH"];
  8. var G_KeywordMinorLookup = ["for", "as", "at", "and", "asc", "desc", "intersect", "union", "except", "join", "outer", "full", "local", "between", "when", "then", "case", "else", "end", "null", "is", "left", "in", "on"];
  9. var G_KeywordFunctLookup = ["XMAX","XSUM","XAVG","XCOUNT","XFIRST","XMOVINGAVG","XMOVINGSUM","XLAST","XNTILE","XPERC","XRANK","XRATIO","XSTDDEV","XSTDDEV_POP","XTERTILE","XVARIANCE","XVARIANCE_POP", "RSUM", "SUM", "MIN", "MAX", "SUBSTR", "NULLIF", "TO_CHAR", "TO_DATE", "ADD_MONTHS"]
  10. var G_PunctuationLookup = [".", "(", ")", ",", "=", "/", "*", "{", "}", "[", "]", "|", "||"];
  11. var G_SQLKeywordTypeMap =
  12. {"SELECT":"k", "DISTINCT":"k", "WHERE":"k", "FROM":"k", "GROUP":"k", "ORDER":"k", "BY":"k", "WITH":"k",
  13. "BETWEEN":"k", "AND":"k", "OR":"k", "NOT":"k", "LIKE":"k", "ESCAPE": "k",
  14. "FOR":"k", "AS":"k", "AT":"k", "ASC":"k", "DESC":"k",
  15. "INTERSECT":"k", "UNION":"k", "EXCEPT":"k",
  16. "JOIN":"k", "OUTER":"k", "FULL":"k", "INNER":"k", "CROSS":"k", "LEFT":"k", "RIGHT":"k",
  17. "LOCAL":"k", "WHEN":"k", "THEN":"k", "CASE":"k", "ELSE":"k", "END":"k",
  18. /*"NULL":"k",*/ "IS":"k", "IN":"k", "ON":"k", "ALL":"k", "ANY":"k", "LOCAL":"k"
  19. };
  20. var G_MDXKeywordTypeMap =
  21. {"SELECT":"k", "WHERE":"k", "FROM":"k", "WITH":"k",
  22. "BETWEEN":"k", "AND":"k", "OR":"k", "NOT":"k", "LIKE":"k", "ESCAPE": "k",
  23. "AS":"k", "ASC":"k", "DESC":"k",
  24. /*"NULL":"k",*/ "IS":"k", "IN":"k", "ON":"k", "DIMENSION":"k", "PROPERTIES":"k"
  25. };
  26. var G_SQLSelectBlockKeywordsObj =
  27. {"SELECT":true, "WHERE":true, "FROM":true, "GROUP":true,
  28. "ORDER":true, "WITH":true, "FILTER": true, "WINDOW": true, "QUALIFY": true,
  29. "HAVING":true, "UNION":true, "EXCEPT":true, "INTERSECT": true };
  30. var G_MDXSelectBlockKeywordsObj =
  31. { "SELECT":true, "WHERE":true, "FROM":true, "WITH":true, "FILTER": true };
  32. var G_SelectBlockAdditionalKeywordsObj =
  33. {"DISTINCT":true, "BY":true };
  34. var G_SelectBlockKeywordsRe = new RegExp( /(?:SELECT)|(?:WHERE)|(?:FROM)|(?:GROUP)|(?:ORDER)|(?:WHERE)|(?:WITH)|(?:HAVING)/i );
  35. var G_SelectBlockAdditionalKeywordsRe = new RegExp( /(?:DISTINCT)|(?:BY)/i );
  36. /*o*/var G_TokenOperator = new RegExp( /(?:[\(\)\,\{\}\|\[\]\+\-\*\\/%\^\.:;\=<>])/ );
  37. /*k*/var G_Keywords = new RegExp( /(?:SELECT)|(?:DISTINCT)|(?:WHERE)|(?:FROM)|(?:GROUP)|(?:BY)|(?:ORDER)|(?:WITH)|(?:HAVING)/ig );
  38. /*d*/var G_TokenDigit = new RegExp( /(?:\d+)/ );
  39. /*w*/var G_TokenWhitespace = new RegExp( /(?:\s+)/ );
  40. /*o*/var G_TokenOperator = new RegExp( /(?:[\(\)\,\{\}\|\[\]\+\-\*\\/%\^\.:;\=<>])/ );
  41. /*n*/var G_TokenName = new RegExp( /(?:\w[\w\d]*)/ );
  42. /*s*/var G_TokenString = new RegExp( /(?:['](?:''|[^'])*['])/ );
  43. /*q*/var G_TokenQName = new RegExp( /(?:[\"](?:\"\"|[^\"])*[\"])/ );
  44. /*q*/var G_TokenBName = new RegExp( /(?:[\[](?:]]|[^]])*[\]])/ );
  45. var G_TokenNameOrQName = new RegExp( /(?:\w[\w\d]*)|(?:[\"](?:\"\"|[^\"])*[\"])/ );
  46. var G_Tokenizer = new RegExp( /(?:\d+)|(?:[\[](?:]]|[^]])*[\]])|(?:\s+)|(?:\|\|)|(?:\>\=)|(?:\<\=)|(?:\<\>)|(?:\!\=)|(?:[\(\)\,\{\}\|\[\]\+\-\*\\/%\^\.:;\=<>])|(?:\w[\w\d]*)|(?:['](?:''|[^'])*['])|(?:[\"](?:\"\"|[^\"])*[\"])|(?:.)/g );
  47. function C_QanParser()
  48. {
  49. }
  50. C_QanParser.prototype.F_TransformToXML_OneTwoTokens = function( sText )
  51. {
  52. this.m_docParsed = U_XML.F_LoadString( D_XmlError, "<sql></sql>" );
  53. this.f_breakIntoTokens( sText );
  54. this.f_formatLexems( this.m_docParsed );
  55. this.f_createLexems();
  56. return this.m_docParsed;
  57. }
  58. C_QanParser.prototype.f_breakIntoTokens = function( sText )
  59. {
  60. this.m_reTokens = sText.match(G_Tokenizer);
  61. }
  62. C_QanParser.prototype.f_createLexems = function()
  63. {
  64. var v_length = this.m_reTokens.length;
  65. this.m_aLexems = new Array( v_length );
  66. for( var t = 0; t < v_length; ++t )
  67. {
  68. var v_1ch = this.m_reTokens[t].charAt(0);
  69. if( v_1ch == ' ' || v_1ch == '\t' )
  70. this.m_aLexems[t] = ' ';
  71. else if( v_1ch == '\'' )
  72. this.m_aLexems[t] = '\'';
  73. else if( v_1ch == '"' )
  74. this.m_aLexems[t] = '\"';
  75. else if( v_1ch >= '0' && v_1ch <= '0' )
  76. this.m_aLexems[t] = '1';
  77. else
  78. if( this.m_reTokens[t].match( G_Keywords ) )
  79. this.m_aLexems[t] = 'k';
  80. else
  81. if( this.m_reTokens[t].match( G_TokenOperator ) )
  82. this.m_aLexems[t] = 'k';
  83. else
  84. this.m_aLexems[t] = 'n';
  85. }
  86. }
  87. C_QanParser.prototype.f_formatLexems = function()
  88. {
  89. var v_docParsedRoot = this.m_docParsed.documentElement;
  90. var v_bB = false;
  91. for( var i = 0; i < this.m_reTokens.length; ++i )
  92. {
  93. var v_nT = this.m_docParsed.createElement( (v_bB)? "b":"i" );
  94. v_docParsedRoot.appendChild( v_nT );
  95. v_nT.text = this.m_reTokens[i];
  96. v_bB = !v_bB;
  97. }
  98. return this.m_docParsed;
  99. }
  100. C_QanParser.prototype.F_TransformToHTML = function( nRoot )
  101. {
  102. if( nRoot.xml )
  103. return nRoot.xml.replace( /\>\s([^\<])/g, ">&nbsp;$1" );
  104. else
  105. return nRoot;
  106. }
  107. C_QanParser.prototype.F_TransformBlockToHTML = function( nRoot )
  108. {
  109. if( nRoot.xml )
  110. return nRoot.xml.replace( /\>\s/g, ">&nbsp;" ).replace(/(^\s+)/g, "&nbsp;");
  111. else
  112. return nRoot;
  113. }
  114. C_QanParser.prototype.F_TransformToXML = function( sText, sLang )
  115. {
  116. this.m_bIsSQL = ( !sLang || sLang == "SQL" );
  117. this.m_sLang = ( this.m_bIsSQL )? "SQL": "MDX";
  118. this.m_aItemEndFrase = (this.m_bIsSQL)? ["AS","qname"]: ["ON","qname","(" , "literal", ")"];
  119. this.m_selectBlockKeywordsObj = (this.m_bIsSQL)? G_SQLSelectBlockKeywordsObj: G_MDXSelectBlockKeywordsObj;
  120. this.m_aKeywordTypeMap = (this.m_bIsSQL)? G_SQLKeywordTypeMap : G_MDXKeywordTypeMap ;
  121. this.m_docParsed = U_XML.F_LoadString( D_XmlError, '<div class="selectNest" ></div>' );
  122. this.f_breakIntoTokens( sText );
  123. if( !this.m_reTokens || !this.m_reTokens.length )
  124. return;
  125. this.f_ruleTokens_toXML( this.m_docParsed.documentElement, 0 );
  126. this.f_markSelectBlocks( this.m_docParsed.documentElement );
  127. return this.m_docParsed;
  128. }
  129. C_QanParser.prototype.f_ruleTokens_toXML = function( nRule, iTokenStart, sClosingToken, sSelectBlock )
  130. {
  131. var iTokenEnd = this.m_reTokens.length - 1;
  132. var iTextTokenStart = iTokenStart;
  133. var v_isBlock = (nRule.getAttribute("class") == "block");
  134. var v_isParentSelectNest = v_isBlock && (nRule.parentNode.getAttribute("class") == "selectNest");
  135. var i = iTokenStart;
  136. for( ; i <= iTokenEnd; ++i )
  137. {
  138. var sToken = this.m_reTokens[i];
  139. if( sToken == '(' && this.m_bIsSQL )
  140. {
  141. this.f_textTokens( nRule, iTextTokenStart, i );
  142. i = this.f_nestTokens_toXML( nRule, i );
  143. iTextTokenStart = i + 1;
  144. }
  145. else if( sToken == "," )
  146. {
  147. if( v_isBlock && v_isParentSelectNest &&
  148. ( this.m_bIsSQL || this.f_findFrase(i-1, this.m_aItemEndFrase ) ) )
  149. {
  150. this.f_itemBreakToken( nRule, iTextTokenStart, i, sSelectBlock, true );
  151. iTextTokenStart = i + 1;
  152. }
  153. }
  154. else if( sToken == sClosingToken )
  155. break;
  156. else{
  157. var v_sTokenUC = sToken.toUpperCase();
  158. if( this.m_selectBlockKeywordsObj[ v_sTokenUC ] )
  159. {
  160. if( v_isBlock && v_isParentSelectNest )
  161. this.f_itemBreakToken( nRule, iTextTokenStart, i, sSelectBlock, false );
  162. else
  163. this.f_textTokens( nRule, iTextTokenStart, i );
  164. if( v_isBlock )
  165. return i;
  166. i = this.f_selectBlockTokens_toXML( nRule, i, sClosingToken );
  167. iTextTokenStart = i + 1;
  168. }
  169. }
  170. }
  171. if( v_isBlock && v_isParentSelectNest )
  172. this.f_itemBreakToken( nRule, iTextTokenStart, i, sSelectBlock, false );
  173. else
  174. this.f_textTokens( nRule, iTextTokenStart, i );
  175. return i;
  176. }
  177. C_QanParser.prototype.f_getQnameValue = function( sQname )
  178. {
  179. if( sQname.charAt(0) != '\"' )
  180. return sQname;
  181. sQname = sQname.substring( 1, sQname.length-1 );
  182. return sQname.replace( /\"\"/, "\"" );
  183. }
  184. C_QanParser.prototype.f_findFrase = function( iTextTokenEnd, aFraseTokens, aFraseTokenPos )
  185. {
  186. var iNonEmpty = aFraseTokens.length - 1;
  187. if( aFraseTokenPos )
  188. aFraseTokenPos.length = aFraseTokens.length;
  189. for( var i = iTextTokenEnd; i >= 0 && iNonEmpty >= 0; --i )
  190. {
  191. var v_sTokenType = this.f_determineTokenType(i);
  192. if( !v_sTokenType )
  193. continue;
  194. if( v_sTokenType != aFraseTokens[iNonEmpty] )
  195. return false;
  196. if( aFraseTokenPos )
  197. aFraseTokenPos[iNonEmpty] = i;
  198. iNonEmpty--;
  199. }
  200. return ( iNonEmpty < 0 );
  201. }
  202. C_QanParser.prototype.f_itemBreakToken = function( nRule, iTextTokenStart, iTokenStart, sSelectBlock, bIsComma )
  203. {
  204. var v_bParsedItems = ( sSelectBlock );
  205. var v_nContent;
  206. var v_nItem;
  207. if( v_bParsedItems )
  208. {
  209. v_nContent = this.m_docParsed.createElement( "div" );
  210. v_nContent.setAttribute( "class", "itemDef" );
  211. nRule.appendChild( v_nContent );
  212. for( ; v_nContent.previousSibling; )
  213. {
  214. if( v_nContent.previousSibling.attributes &&
  215. v_nContent.previousSibling.getAttribute("class") != "nest" &&
  216. v_nContent.previousSibling.getAttribute("class") != "aliasedSelect" &&
  217. v_nContent.previousSibling.getAttribute("class") != "selectNest" )
  218. {
  219. break;
  220. }
  221. v_nContent.insertBefore( v_nContent.previousSibling, v_nContent.firstChild );
  222. }
  223. v_nItem = this.m_docParsed.createElement( "div" );
  224. v_nItem.setAttribute( "class", "item" );
  225. nRule.appendChild( v_nItem );
  226. v_nItem.appendChild( v_nContent );
  227. }
  228. else
  229. {
  230. v_nContent = nRule;
  231. v_nItem = nRule;
  232. }
  233. var v_aItemEndTokensPos = [];
  234. if( v_bParsedItems &&
  235. this.f_findFrase( iTokenStart-1, this.m_aItemEndFrase, v_aItemEndTokensPos ) )
  236. {
  237. var v_iItemEnd = v_aItemEndTokensPos[ v_aItemEndTokensPos.length - 1 ];
  238. this.f_textTokens( v_nContent, iTextTokenStart, v_aItemEndTokensPos[0] );
  239. this.f_textTokens( v_nItem, v_aItemEndTokensPos[0], v_aItemEndTokensPos[1] );
  240. var v_nR = this.m_docParsed.createElement( "div" );
  241. v_nR.setAttribute( "class", "alias" );
  242. v_nR.text = this.m_reTokens.slice( v_aItemEndTokensPos[1], v_iItemEnd +1).join("");
  243. v_nR.setAttribute("name", this.f_getQnameValue( this.m_reTokens[v_iItemEnd] ) );
  244. v_nItem.appendChild( v_nR );
  245. this.f_textTokens( v_nItem, v_iItemEnd + 1, iTokenStart + ((bIsComma)? 1: 0) );
  246. }
  247. else
  248. this.f_textTokens( v_nContent, iTextTokenStart, iTokenStart + ((bIsComma)? 1: 0) );
  249. }
  250. C_QanParser.prototype.f_titleToken = function( nRule, iTokenStart, iTokenEnd )
  251. {
  252. var v_nT = this.m_docParsed.createElement("span");
  253. v_nT.setAttribute( "class", "title" );
  254. v_nT.text = this.m_reTokens.slice( iTokenStart, iTokenEnd ).join("");
  255. nRule.appendChild( v_nT );
  256. }
  257. C_QanParser.prototype.f_isWhiteSpaceToken = function( iToken )
  258. {
  259. var v_aMatched = this.m_reTokens[iToken].match( G_TokenWhitespace );
  260. return ( v_aMatched && v_aMatched[0] === this.m_reTokens[iToken] );
  261. }
  262. C_QanParser.prototype.f_isNameToken = function( iToken )
  263. {
  264. var v_aMatched = this.m_reTokens[iToken].match( G_TokenNameOrQName );
  265. return ( v_aMatched && v_aMatched[0] === this.m_reTokens[iToken] );
  266. }
  267. C_QanParser.prototype.f_selectBlockTokens_toXML = function( nRule, iTokenStart, sClosingToken )
  268. {
  269. var v_sToken = this.m_reTokens[iTokenStart].toUpperCase();
  270. if( v_sToken == "SELECT" || v_sToken == "WITH" )
  271. nRule.setAttribute( "class", "selectNest" );
  272. var v_nBlock = this.m_docParsed.createElement( "div" );
  273. v_nBlock.setAttribute( "class", "block" );
  274. nRule.appendChild( v_nBlock );
  275. var iTitleTokenEnd = iTokenStart + 1;
  276. if( this.f_isWhiteSpaceToken(iTitleTokenEnd) )
  277. {
  278. iTitleTokenEnd += 1;
  279. if( G_SelectBlockAdditionalKeywordsObj[ this.m_reTokens[iTitleTokenEnd].toUpperCase()] )
  280. iTitleTokenEnd += 1;
  281. }
  282. this.f_titleToken( v_nBlock, iTokenStart, iTitleTokenEnd );
  283. if( !this.m_bIsSQL && v_sToken == "WITH" )
  284. return this.f_mdxWithBlock_toXML( v_nBlock, iTitleTokenEnd + 1 );
  285. return this.f_ruleTokens_toXML( v_nBlock, iTitleTokenEnd, sClosingToken, v_sToken ) - 1;
  286. }
  287. C_QanParser.prototype.f_textTokens = function( nRule, iTextTokenStart, iTextTokenEnd )
  288. {
  289. if( iTextTokenStart >= iTextTokenEnd )
  290. return;
  291. var v_nT = this.m_docParsed.createTextNode(
  292. this.m_reTokens.slice(iTextTokenStart, iTextTokenEnd).join("") );
  293. nRule.appendChild( v_nT );
  294. }
  295. C_QanParser.prototype.f_textToken = function( nRule, sOpenToken )
  296. {
  297. var v_nT = this.m_docParsed.createTextNode( sOpenToken );
  298. nRule.appendChild( v_nT );
  299. }
  300. C_QanParser.prototype.f_nestTokens_toXML = function( nRule, iTokenStart )
  301. {
  302. var v_sClosingToken;
  303. var v_sOpenToken = this.m_reTokens[iTokenStart];
  304. if( v_sOpenToken == "(" )
  305. v_sClosingToken = ")";
  306. else if( v_sOpenToken == "{" )
  307. v_sClosingToken = "}";
  308. var v_nNest = this.m_docParsed.createElement( "div" );
  309. v_nNest.setAttribute( "class", "nest" );
  310. nRule.appendChild( v_nNest );
  311. this.f_textToken( v_nNest, v_sOpenToken );
  312. var iTokenEnd = this.f_ruleTokens_toXML( v_nNest, iTokenStart + 1, v_sClosingToken );
  313. this.f_textToken( v_nNest, this.m_reTokens[iTokenEnd] );
  314. iTokenEnd = this.f_markSelectBlocks( v_nNest, iTokenStart, iTokenEnd );
  315. return iTokenEnd;
  316. }
  317. C_QanParser.prototype.f_mdxObjRef_toXML = function( nRule, iTokenStart )
  318. {
  319. var v_isName = true;
  320. var v_isRefFound = false;
  321. var v_iFirstToken, v_iLastToken;
  322. for( var i = iTokenStart; i < this.m_reTokens.length; ++i )
  323. {
  324. var v_sTokenType = this.f_determineTokenType(i);
  325. if( !v_sTokenType )
  326. continue;
  327. if( ( v_isName && v_sTokenType != 'bname' ) ||
  328. ( !v_isName && v_sTokenType != '.' ) )
  329. {
  330. break;
  331. }
  332. v_iLastToken = i;
  333. if( !v_iFirstToken )
  334. v_iFirstToken = i;
  335. v_isRefFound = true;
  336. v_isName = !v_isName;
  337. }
  338. if( !v_isRefFound )
  339. return false;
  340. this.f_textTokens( nRule, iTokenStart, v_iFirstToken );
  341. var v_nRef = this.m_docParsed.createElement( "div" );
  342. v_nRef.setAttribute( "class", "alias" );
  343. nRule.appendChild( v_nRef );
  344. this.f_textTokens( v_nRef, v_iFirstToken, v_iLastToken + 1 );
  345. return v_iLastToken + 1;
  346. }
  347. C_QanParser.prototype.f_mdxMemberDef_toXML = function( nRule, iTokenStart, iTokenNext )
  348. {
  349. var v_nItem = this.m_docParsed.createElement( "div" );
  350. v_nItem.setAttribute( "class", "item" );
  351. nRule.appendChild( v_nItem );
  352. this.f_textTokens( v_nItem, iTokenStart, iTokenStart+1 );
  353. var i = this.f_mdxObjRef_toXML( v_nItem, iTokenStart+1 );
  354. this.f_textTokens( v_nItem, i, iTokenNext );
  355. }
  356. C_QanParser.prototype.f_mdxWithBlock_toXML = function( nRule, iTokenStart )
  357. {
  358. var i = iTokenStart;
  359. var iMemberTokenStart;
  360. for( ; i <= this.m_reTokens.length; ++i )
  361. {
  362. var sToken = this.m_reTokens[i].toUpperCase();
  363. if( sToken == "MEMBER" )
  364. {
  365. if( iMemberTokenStart )
  366. this.f_mdxMemberDef_toXML( nRule, iMemberTokenStart, i );
  367. else
  368. this.f_textTokens( nRule, iTokenStart, i );
  369. iMemberTokenStart = i;
  370. }
  371. if( sToken == "SELECT" )
  372. break;
  373. }
  374. if( iMemberTokenStart )
  375. this.f_mdxMemberDef_toXML( nRule, iMemberTokenStart, i );
  376. return i - 1;
  377. }
  378. C_QanParser.prototype.f_markSelectBlocks = function( nSelectNest, iTokenStart, iTokenEnd )
  379. {
  380. if( nSelectNest.getAttribute( "class" ) != "selectNest" )
  381. return iTokenEnd;
  382. var v_sBlockTitle;
  383. var v_nlBlocks = nSelectNest.selectNodes( "div[@class='block']" );
  384. for( var i = 0; i < v_nlBlocks.length; ++i )
  385. {
  386. var v_nBlock = v_nlBlocks[i];
  387. var v_aContentNodes = [];
  388. v_nBlock.setAttribute( "class", "selectBlock" );
  389. for( var j = 0; j < v_nBlock.childNodes.length; ++j )
  390. {
  391. var v_nBlockChild = v_nBlock.childNodes[j];
  392. if( v_nBlockChild.attributes &&
  393. v_nBlockChild.getAttribute( "class" ) == "title" )
  394. {
  395. v_nBlockChild.setAttribute( "class", "selectTitle" );
  396. v_sBlockTitle = v_nBlockChild.text;
  397. continue;
  398. }
  399. v_aContentNodes.push( v_nBlockChild );
  400. }
  401. if( v_aContentNodes.length == 0 )
  402. continue;
  403. var v_nContent = v_nBlock.appendChild( v_nBlock.ownerDocument.createElement( "div" ) );
  404. v_nContent.setAttribute( "class", "content" )
  405. for( var k = 0; k < v_aContentNodes.length; ++k )
  406. v_nContent.appendChild( v_aContentNodes[k] );
  407. }
  408. var v_nParentTitle = nSelectNest.selectSingleNode( "../span[@class='title']" );
  409. var v_sParentTitle = (v_nParentTitle)? v_nParentTitle.text.toUpperCase(): "";
  410. if( v_sParentTitle == "WITH" )
  411. this.f_markWithSelectItem( nSelectNest, iTokenStart );
  412. if( v_sParentTitle == "FROM" )
  413. iTokenEnd = this.f_markFromSelectItem( nSelectNest, iTokenStart, iTokenEnd );
  414. this.f_checkForTabularOperations( nSelectNest );
  415. return iTokenEnd;
  416. }
  417. C_QanParser.prototype.f_checkForTabularOperations = function( nSelectNest )
  418. {
  419. var v_bSelectStartPrevBlock = true;
  420. var v_bSelectStart;
  421. v_nlSelectStart = nSelectNest.selectNodes( "div/span[@class='selectTitle']" );
  422. for( var i = 0; i < v_nlSelectStart.length; ++i )
  423. {
  424. var v_sBlockType = v_nlSelectStart[i].text.toUpperCase();
  425. if( v_sBlockType == 'WITH' )
  426. v_bSelectStart = true;
  427. else
  428. if( v_sBlockType == 'SELECT' && !v_bSelectStartPrevBlock )
  429. v_bSelectStart = true;
  430. else
  431. v_bSelectStart = false;
  432. if( v_bSelectStart && !v_bSelectStartPrevBlock )
  433. {
  434. var v_nSelectBreak = this.m_docParsed.createElement("div");
  435. v_nSelectBreak.setAttribute( "class", "selectBr" );
  436. v_nSelectBreak.text = " ";
  437. var v_nSelectNest = v_nlSelectStart[i].parentNode;
  438. v_nSelectNest.parentNode.insertBefore( v_nSelectBreak, v_nSelectNest );
  439. }
  440. v_bSelectStartPrevBlock = v_bSelectStart;
  441. }
  442. }
  443. C_QanParser.prototype.f_markWithSelectItem = function( nSelectNest, iTokenStart )
  444. {
  445. if( nSelectNest.previousSibling.nodeType == 3 )
  446. {
  447. var iAsToken;
  448. var i = iTokenStart - 1;
  449. for( ; i > 0 && this.f_isWhiteSpaceToken(i); --i );
  450. if( this.m_reTokens[i].toUpperCase() == "AS" )
  451. {
  452. iAsToken = i;
  453. for( --i; i > 0 && this.f_isWhiteSpaceToken(i); --i );
  454. }
  455. if( this.f_isNameToken(i) )
  456. {
  457. var v_nAliasedSelect = this.m_docParsed.createElement( "div" );
  458. nSelectNest.parentNode.appendChild( v_nAliasedSelect );
  459. v_nAliasedSelect.setAttribute("class", "aliasedSelect");
  460. nSelectNest.parentNode.removeChild( nSelectNest.previousSibling );
  461. var v_nAlias = v_nAliasedSelect.appendChild( this.m_docParsed.createElement( "span" ) );
  462. v_nAlias.text = this.m_reTokens[i];
  463. v_nAlias.setAttribute("class", "selectAlias");
  464. if( iAsToken )
  465. {
  466. var v_nAs = this.m_docParsed.createTextNode( " " + this.m_reTokens[iAsToken] + " " );
  467. v_nAliasedSelect.appendChild( v_nAs );
  468. }
  469. v_nAliasedSelect.appendChild( nSelectNest );
  470. }
  471. }
  472. }
  473. C_QanParser.prototype.f_markFromSelectItem = function( nSelectNest, iTokenStart, iTokenEnd )
  474. {
  475. var iAsToken;
  476. var i = iTokenEnd + 1;
  477. for( ; i < this.m_reTokens.length && this.f_isWhiteSpaceToken(i); ++i );
  478. if( this.m_reTokens[i].toUpperCase() == "AS" )
  479. {
  480. iAsToken = i;
  481. for( ++i; i < this.m_reTokens.length && this.f_isWhiteSpaceToken(i); ++i );
  482. }
  483. if( this.f_isNameToken(i) )
  484. {
  485. var v_nAliasedSelect = this.m_docParsed.createElement( "div" );
  486. nSelectNest.parentNode.appendChild( v_nAliasedSelect );
  487. v_nAliasedSelect.setAttribute("class", "aliasedSelect");
  488. v_nAliasedSelect.appendChild( nSelectNest );
  489. if( iAsToken )
  490. {
  491. var v_nAs = this.m_docParsed.createTextNode( " " + this.m_reTokens[iAsToken] + " " );
  492. v_nAliasedSelect.appendChild( v_nAs );
  493. }
  494. var v_nAlias = v_nAliasedSelect.appendChild( this.m_docParsed.createElement( "span" ) );
  495. v_nAlias.text = this.m_reTokens[i];
  496. v_nAlias.setAttribute("class", "selectAlias");
  497. return i;
  498. }
  499. return iTokenEnd;
  500. }
  501. var v_sSQLParsingRules =
  502. '<language name="Expression" rootRule="expr">' +
  503. '<rule type="fromItemExpr">'+
  504. '<sequence>'+
  505. '<block type="fromItem"/>'+
  506. '<token type="," optional="true"/>'+
  507. '</sequence>'+
  508. '</rule>'+
  509. '<rule type="itemExpr">'+
  510. '<sequence>'+
  511. '<block type="expr"/>'+
  512. '<token type="," optional="true"/>'+
  513. '</sequence>'+
  514. '</rule>'+
  515. '<rule type="fromList">'+
  516. '<sequence>'+
  517. '<block type="fromItem"/>'+
  518. '<token type=","/>'+
  519. '<block type="fromList"/>'+
  520. '</sequence>'+
  521. '<block type="fromItem"/>'+
  522. '</rule>'+
  523. '<rule type="fromItem">'+
  524. '<block type="tRef"/>'+
  525. '<block type="join"/>'+
  526. '</rule>'+
  527. '<rule type="tRef">'+
  528. '<sequence>'+
  529. '<block type="qnames"/>'+
  530. '<block type="tAlias" optional="true"/>'+
  531. '</sequence>'+
  532. '</rule>'+
  533. '<rule type="tAlias">'+
  534. '<token type="qname"/>'+
  535. '</rule>'+
  536. '<rule type="join">'+
  537. '<sequence>'+
  538. '<block type="fromItem"/>'+
  539. '<block type="joinTypeOn"/>'+
  540. '<block type="fromItem"/>'+
  541. '<block type="joinOn"/>'+
  542. '</sequence>'+
  543. '<sequence>'+
  544. '<block type="fromItem"/>'+
  545. '<block type="joinType"/>'+
  546. '<block type="fromItem"/>'+
  547. '</sequence>'+
  548. '</rule>'+
  549. '<rule type="joinOn">'+
  550. '<sequence>'+
  551. '<token type="ON"/>'+
  552. '<block type="expr"/>'+
  553. '</sequence>'+
  554. '</rule>'+
  555. '<rule type="joinTypeOn">'+
  556. '<sequence>'+
  557. '<token type="INNER"/>'+
  558. '<token type="JOIN"/>'+
  559. '</sequence>'+
  560. '<sequence>'+
  561. '<token type="LEFT"/>'+
  562. '<token type="OUTER"/>'+
  563. '<token type="JOIN"/>'+
  564. '</sequence>'+
  565. '<sequence>'+
  566. '<token type="RIGHT"/>'+
  567. '<token type="OUTER"/>'+
  568. '<token type="JOIN"/>'+
  569. '</sequence>'+
  570. '<sequence>'+
  571. '<token type="FULL"/>'+
  572. '<token type="OUTER"/>'+
  573. '<token type="JOIN"/>'+
  574. '</sequence>'+
  575. '</rule>'+
  576. '<rule type="joinType">'+
  577. '<sequence>'+
  578. '<token type="CROSS"/>'+
  579. '<token type="JOIN"/>'+
  580. '</sequence>'+
  581. '<sequence>'+
  582. '<token type="NATURAL"/>'+
  583. '<token type="JOIN"/>'+
  584. '</sequence>'+
  585. '</rule>'+
  586. '<rule type="expr">'+
  587. '<token type="literal"/>'+
  588. '<block type="func"/>'+
  589. '<block type="qnames"/>'+
  590. '<token type="qname"/>'+
  591. '<sequence>'+
  592. '<block type="unaryOp"/>'+
  593. '<block type="expr"/>'+
  594. '</sequence>'+
  595. '<sequence>'+
  596. '<token type="("/>'+
  597. '<block type="paramList"/>'+
  598. '<token type=")"/>'+
  599. '</sequence>'+
  600. '<sequence>'+
  601. '<block type="expr"/>'+
  602. '<block type="binaryOp"/>'+
  603. '<block type="expr"/>'+
  604. '</sequence>'+
  605. '<sequence>'+
  606. '<block type="expr"/>'+
  607. '<token type="NOT" optional="true"/>'+
  608. '<block type="betweenOp"/>'+
  609. '<block type="expr"/>'+
  610. '<token type="AND"/>'+
  611. '<block type="expr"/>'+
  612. '</sequence>'+
  613. '<sequence>'+
  614. '<block type="expr"/>'+
  615. '<block type="likeOp"/>'+
  616. '<block type="expr"/>'+
  617. '<block type="escape" optional="true"/>'+
  618. '</sequence>'+
  619. '<block type="case"/>'+
  620. '</rule>' +
  621. '<rule type="escape">'+
  622. '<sequence>'+
  623. '<token type="ESCAPE"/>'+
  624. '<block type="expr"/>'+
  625. '</sequence>'+
  626. '</rule>' +
  627. '<rule type="likeOp">'+
  628. '<token type="LIKE" precedence="40"/>'+
  629. '</rule>' +
  630. '<rule type="betweenOp">'+
  631. '<token type="BETWEEN" precedence="40"/>'+
  632. '</rule>' +
  633. '<rule type="unaryOp">'+
  634. '<token type="+" precendence="10"/>'+
  635. '<token type="-" precendence="10"/>'+
  636. '<token type="NOT" precendence="50"/>'+
  637. '</rule>' +
  638. '<rule type="binaryOp">'+
  639. '<token type="*" precedence="20"/>'+
  640. '<token type="/" precedence="20"/>'+
  641. '<token type="%" precedence="20"/>'+
  642. '<token type="^" precedence="20"/>'+
  643. '<token type="+" precedence="30"/>'+
  644. '<token type="-" precedence="30"/>'+
  645. '<token type="||" precedence="30"/>'+
  646. '<token type="&gt;" precedence="40"/>'+
  647. '<token type="&gt;=" precedence="40"/>'+
  648. '<token type="&lt;" precedence="40"/>'+
  649. '<token type="&lt;=" precedence="40"/>'+
  650. '<token type="=" precedence="40"/>'+
  651. '<token type="!=" precedence="40"/>'+
  652. '<token type="IS" precedence="40"/>'+
  653. '<token type="IN" precedence="40"/>'+
  654. '<token type="AND" precedence="60"/>'+
  655. '<token type="OR" precedence="70"/>'+
  656. '</rule>' +
  657. '<rule type="qnames" tag="false">'+
  658. '<sequence>'+
  659. '<token type="qname" optional="true"/>'+
  660. '<token type="."/>'+
  661. '<block type="qnames"/>'+
  662. '</sequence>'+
  663. '<token type="qname"/>'+
  664. '</rule>' +
  665. '<rule type="func">'+
  666. '<sequence>'+
  667. '<block type="fTitle"/>'+
  668. '<token type="("/>'+
  669. '<block type="fMod" optional="true"/>'+
  670. '<block type="funcParams" optional="true"/>'+
  671. '<block type="fPost" optional="true"/>'+
  672. '<token type=")"/>'+
  673. '</sequence>'+
  674. '</rule>' +
  675. '<rule type="fTitle">'+
  676. '<token type="qname"/>'+
  677. '</rule>' +
  678. '<rule type="fMod" tag="false">'+
  679. '<token type="DISTINCT"/>'+
  680. '<token type="ALL"/>'+
  681. '</rule>' +
  682. '<rule type="fPost" tag="false">'+
  683. '<token type="LOCAL"/>'+
  684. '</rule>' +
  685. '<rule type="funcParams" tag="false">'+
  686. '<sequence>'+
  687. '<block type="paramList"/>'+
  688. '<block type="paramBlocks" optional="true"/>'+
  689. '</sequence>'+
  690. '</rule>' +
  691. '<rule type="paramBlocks" tag="false">'+
  692. '<sequence>'+
  693. '<block type="paramBlock"/>'+
  694. '<block type="paramBlocks"/>'+
  695. '</sequence>'+
  696. '<block type="paramBlock"/>'+
  697. '</rule>' +
  698. '<rule type="paramBlock">'+
  699. '<sequence>'+
  700. '<block type="paramBlockId"/>'+
  701. '<block type="paramList"/>'+
  702. '</sequence>'+
  703. '<sequence>'+
  704. '<block type="orderBlockId"/>'+
  705. '<block type="orderList"/>'+
  706. '</sequence>'+
  707. '</rule>' +
  708. '<rule type="orderBlockId">'+
  709. '<sequence>'+
  710. '<token type="ORDER"/>'+
  711. '<token type="BY"/>'+
  712. '</sequence>'+
  713. '</rule>' +
  714. '<rule type="paramBlockId">'+
  715. '<token type="FOR"/>'+
  716. '<token type="AT"/>'+
  717. '<token type="AS"/>'+
  718. '<token type="FROM"/>'+
  719. '</rule>' +
  720. '<rule type="paramList" tag="false">'+
  721. '<sequence>'+
  722. '<block type="listItem1"/>'+
  723. '<block type="paramList"/>'+
  724. '</sequence>'+
  725. '<block type="listItem2"/>'+
  726. '</rule>' +
  727. '<rule type="listItem1">'+
  728. '<sequence>'+
  729. '<block type="expr"/>'+
  730. '<token type=","/>'+
  731. '</sequence>'+
  732. '</rule>' +
  733. '<rule type="listItem2">'+
  734. '<sequence>'+
  735. '<block type="expr"/>'+
  736. '</sequence>'+
  737. '</rule>' +
  738. '<rule type="orderList" tag="false">'+
  739. '<sequence>'+
  740. '<block type="orderItem1"/>'+
  741. '<block type="orderList"/>'+
  742. '</sequence>'+
  743. '<sequence>'+
  744. '<block type="orderItem"/>'+
  745. '</sequence>'+
  746. '</rule>' +
  747. '<rule type="orderItem1">'+
  748. '<sequence>'+
  749. '<block type="expr"/>'+
  750. '<block type="sortDir" optional="true"/>'+
  751. '<token type=","/>'+
  752. '</sequence>'+
  753. '</rule>' +
  754. '<rule type="orderItem">'+
  755. '<sequence>'+
  756. '<block type="expr"/>'+
  757. '<block type="sortDir" optional="true"/>'+
  758. '</sequence>'+
  759. '</rule>' +
  760. '<rule type="sortDir" tag="false">'+
  761. '<token type="ASC"/>'+
  762. '<token type="DESC"/>'+
  763. '</rule>'+
  764. '<rule type="case">'+
  765. '<sequence>'+
  766. '<block type="caseOp"/>'+
  767. '<block type="switch" optional="true"/>'+
  768. '<block type="wtList"/>'+
  769. '<block type="else" optional="true"/>'+
  770. '<token type="END"/>'+
  771. '</sequence>'+
  772. '</rule>' +
  773. '<rule type="switch">'+
  774. '<sequence>'+
  775. '<block type="expr"/>'+
  776. '</sequence>'+
  777. '</rule>'+
  778. '<rule type="caseOp">'+
  779. '<token type="CASE"/>'+
  780. '</rule>'+
  781. '<rule type="wtList" tag="false">'+
  782. '<sequence>'+
  783. '<block type="whenThen"/>'+
  784. '<block type="wtList"/>'+
  785. '</sequence>'+
  786. '<block type="whenThen"/>'+
  787. '</rule>' +
  788. '<rule type="whenThen">'+
  789. '<sequence>'+
  790. '<block type="when"/>'+
  791. '<block type="then"/>'+
  792. '</sequence>'+
  793. '</rule>' +
  794. '<rule type="when">'+
  795. '<sequence>'+
  796. '<token type="WHEN"/>'+
  797. '<block type="expr"/>'+
  798. '</sequence>'+
  799. '</rule>' +
  800. '<rule type="then">'+
  801. '<sequence>'+
  802. '<token type="THEN"/>'+
  803. '<block type="expr"/>'+
  804. '</sequence>'+
  805. '</rule>' +
  806. '<rule type="else">'+
  807. '<sequence>'+
  808. '<token type="ELSE"/>'+
  809. '<block type="expr"/>'+
  810. '</sequence>'+
  811. '</rule>' +
  812. '</language>';
  813. var v_sMDXParsingRules =
  814. '<language name="Expression" rootRule="expr">' +
  815. '<rule type="axisDef">'+
  816. '<sequence>'+
  817. '<block type="expr"/>'+
  818. '<block type="dimProps" optional="true"/>'+
  819. '</sequence>'+
  820. '</rule>'+
  821. '<rule type="dimPropTitle">'+
  822. '<sequence>'+
  823. '<token type="DIMENSION"/>'+
  824. '<token type="PROPERTIES"/>'+
  825. '</sequence>'+
  826. '</rule>'+
  827. '<rule type="dimProps">'+
  828. '<sequence>'+
  829. '<block type="dimPropTitle"/>'+
  830. '<block type="paramList"/>'+
  831. '</sequence>'+
  832. '</rule>'+
  833. '<rule type="expr">'+
  834. '<token type="literal"/>'+
  835. '<block type="func"/>'+
  836. '<block type="bnames"/>'+
  837. '<token type="bname"/>'+
  838. '<token type="qname"/>'+
  839. '<sequence>'+
  840. '<block type="unaryOp"/>'+
  841. '<block type="expr"/>'+
  842. '</sequence>'+
  843. '<sequence>'+
  844. '<token type="("/>'+
  845. '<block type="paramList"/>'+
  846. '<token type=")"/>'+
  847. '</sequence>'+
  848. '<sequence>'+
  849. '<token type="{"/>'+
  850. '<block type="paramList"/>'+
  851. '<token type="}"/>'+
  852. '</sequence>'+
  853. '<sequence>'+
  854. '<block type="expr"/>'+
  855. '<block type="binaryOp"/>'+
  856. '<block type="expr"/>'+
  857. '</sequence>'+
  858. '<sequence>'+
  859. '<block type="expr"/>'+
  860. '<token type="NOT" optional="true"/>'+
  861. '<block type="betweenOp"/>'+
  862. '<block type="expr"/>'+
  863. '<token type="AND"/>'+
  864. '<block type="expr"/>'+
  865. '</sequence>'+
  866. '<sequence>'+
  867. '<block type="expr"/>'+
  868. '<block type="likeOp"/>'+
  869. '<block type="expr"/>'+
  870. '<block type="escape" optional="true"/>'+
  871. '</sequence>'+
  872. '</rule>' +
  873. '<rule type="escape">'+
  874. '<sequence>'+
  875. '<token type="ESCAPE"/>'+
  876. '<block type="expr"/>'+
  877. '</sequence>'+
  878. '</rule>' +
  879. '<rule type="likeOp">'+
  880. '<token type="LIKE" precedence="40"/>'+
  881. '</rule>' +
  882. '<rule type="betweenOp">'+
  883. '<token type="BETWEEN" precedence="40"/>'+
  884. '</rule>' +
  885. '<rule type="unaryOp">'+
  886. '<token type="+" precendence="10"/>'+
  887. '<token type="-" precendence="10"/>'+
  888. '<token type="NOT" precendence="50"/>'+
  889. '</rule>' +
  890. '<rule type="binaryOp">'+
  891. '<token type="*" precedence="20"/>'+
  892. '<token type="/" precedence="20"/>'+
  893. '<token type="%" precedence="20"/>'+
  894. '<token type="^" precedence="20"/>'+
  895. '<token type="+" precedence="30"/>'+
  896. '<token type="-" precedence="30"/>'+
  897. '<token type="||" precedence="30"/>'+
  898. '<token type="&gt;" precedence="40"/>'+
  899. '<token type="&gt;=" precedence="40"/>'+
  900. '<token type="&lt;" precedence="40"/>'+
  901. '<token type="&lt;=" precedence="40"/>'+
  902. '<token type="=" precedence="40"/>'+
  903. '<token type="!=" precedence="40"/>'+
  904. '<token type="IS" precedence="40"/>'+
  905. '<token type="IN" precedence="40"/>'+
  906. '<token type="AND" precedence="60"/>'+
  907. '<token type="OR" precedence="70"/>'+
  908. '</rule>' +
  909. '<rule type="qnames" tag="false">'+
  910. '<sequence>'+
  911. '<token type="qname" optional="true"/>'+
  912. '<token type="."/>'+
  913. '<block type="qnames"/>'+
  914. '</sequence>'+
  915. '<token type="qname"/>'+
  916. '</rule>' +
  917. '<rule type="bnames" tag="false">'+
  918. '<sequence>'+
  919. '<block type="qbname" optional="true"/>'+
  920. '<token type="."/>'+
  921. '<block type="bnames"/>'+
  922. '</sequence>'+
  923. '<block type="qbname"/>'+
  924. '</rule>' +
  925. '<rule type="qbname" tag="false">'+
  926. '<token type="bname"/>'+
  927. '<token type="qname"/>'+
  928. '</rule>' +
  929. '<rule type="propList" tag="false">'+
  930. '<sequence>'+
  931. '<block type="prop" />'+
  932. '<token type=","/>'+
  933. '<block type="propList"/>'+
  934. '</sequence>'+
  935. '<block type="prop"/>'+
  936. '</rule>' +
  937. '<rule type="prop">'+
  938. '<token type="qname"/>'+
  939. '</rule>' +
  940. '<rule type="func">'+
  941. '<sequence>'+
  942. '<block type="fTitle"/>'+
  943. '<token type="("/>'+
  944. '<block type="fMod" optional="true"/>'+
  945. '<block type="funcParams" optional="true"/>'+
  946. '<block type="fPost" optional="true"/>'+
  947. '<token type=")"/>'+
  948. '</sequence>'+
  949. '</rule>' +
  950. '<rule type="fTitle">'+
  951. '<token type="qname"/>'+
  952. '</rule>' +
  953. '<rule type="fMod" tag="false">'+
  954. '<token type="DISTINCT"/>'+
  955. '<token type="ALL"/>'+
  956. '</rule>' +
  957. '<rule type="fPost" tag="false">'+
  958. '<token type="LOCAL"/>'+
  959. '</rule>' +
  960. '<rule type="funcParams" tag="false">'+
  961. '<sequence>'+
  962. '<block type="paramList"/>'+
  963. '<block type="paramBlocks" optional="true"/>'+
  964. '</sequence>'+
  965. '</rule>' +
  966. '<rule type="paramBlocks" tag="false">'+
  967. '<sequence>'+
  968. '<block type="paramBlock"/>'+
  969. '<block type="paramBlocks"/>'+
  970. '</sequence>'+
  971. '<block type="paramBlock"/>'+
  972. '</rule>' +
  973. '<rule type="paramBlock">'+
  974. '<sequence>'+
  975. '<block type="paramBlockId"/>'+
  976. '<block type="paramList"/>'+
  977. '</sequence>'+
  978. '<sequence>'+
  979. '<block type="orderBlockId"/>'+
  980. '<block type="orderList"/>'+
  981. '</sequence>'+
  982. '</rule>' +
  983. '<rule type="orderBlockId">'+
  984. '<sequence>'+
  985. '<token type="ORDER"/>'+
  986. '<token type="BY"/>'+
  987. '</sequence>'+
  988. '</rule>' +
  989. '<rule type="paramBlockId">'+
  990. '<token type="FOR"/>'+
  991. '<token type="AT"/>'+
  992. '<token type="AS"/>'+
  993. '<token type="FROM"/>'+
  994. '</rule>' +
  995. '<rule type="paramList" tag="false">'+
  996. '<sequence>'+
  997. '<block type="listItem1"/>'+
  998. '<block type="paramList"/>'+
  999. '</sequence>'+
  1000. '<block type="listItem2"/>'+
  1001. '</rule>' +
  1002. '<rule type="listItem1">'+
  1003. '<sequence>'+
  1004. '<block type="expr"/>'+
  1005. '<token type=","/>'+
  1006. '</sequence>'+
  1007. '</rule>' +
  1008. '<rule type="listItem2">'+
  1009. '<sequence>'+
  1010. '<block type="expr"/>'+
  1011. '</sequence>'+
  1012. '</rule>' +
  1013. '<rule type="orderList" tag="false">'+
  1014. '<sequence>'+
  1015. '<block type="orderItem1"/>'+
  1016. '<block type="orderList"/>'+
  1017. '</sequence>'+
  1018. '<sequence>'+
  1019. '<block type="orderItem"/>'+
  1020. '</sequence>'+
  1021. '</rule>' +
  1022. '<rule type="orderItem1">'+
  1023. '<sequence>'+
  1024. '<block type="expr"/>'+
  1025. '<block type="sortDir" optional="true"/>'+
  1026. '<token type=","/>'+
  1027. '</sequence>'+
  1028. '</rule>' +
  1029. '<rule type="orderItem">'+
  1030. '<sequence>'+
  1031. '<block type="expr"/>'+
  1032. '<block type="sortDir" optional="true"/>'+
  1033. '</sequence>'+
  1034. '</rule>' +
  1035. '<rule type="sortDir" tag="false">'+
  1036. '<token type="ASC"/>'+
  1037. '<token type="DESC"/>'+
  1038. '</rule>'+
  1039. '</language>';
  1040. C_QanParser.prototype.f_getParsedTermType = function( divParsedTerm )
  1041. {
  1042. if( divParsedTerm.nodeType )
  1043. return divParsedTerm.getAttribute("class");
  1044. else
  1045. return divParsedTerm;
  1046. }
  1047. C_QanParser.prototype.f_handleEmptyToken = function( aParsedTerms )
  1048. {
  1049. var sTokenType = this.f_getTokenType( this.m_iStartToken );
  1050. if( !sTokenType )
  1051. {
  1052. aParsedTerms.push(
  1053. this.m_docParsed.createTextNode( this.m_reTokens[ this.m_iStartToken ] ) );
  1054. ++this.m_iStartToken;
  1055. return true;
  1056. }
  1057. return false;
  1058. }
  1059. C_QanParser.prototype.f_getTermPlusTokenType = function( aParsedTerms, iTermPlusToken )
  1060. {
  1061. if( iTermPlusToken < aParsedTerms.length )
  1062. return this.f_getParsedTermType( aParsedTerms[iTermPlusToken] );
  1063. var sTokenType = this.f_getTokenType( iTermPlusToken - aParsedTerms.length + this.m_iStartToken );
  1064. return sTokenType;
  1065. }
  1066. C_QanParser.prototype.f_applyRule_Token = function( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken )
  1067. {
  1068. var sTokenType = this.f_getTermPlusTokenType( aParsedTerms, iStartTermPlusToken );
  1069. if( nRuleChoice.getAttribute("type") != sTokenType )
  1070. return false;
  1071. aParsedTerms.push( this.m_reTokens[iStartTermPlusToken - aParsedTerms.length + this.m_iStartToken] );
  1072. this.m_iStartToken++;
  1073. return true;
  1074. }
  1075. C_QanParser.prototype.f_applyRule_NestedToken = function( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken )
  1076. {
  1077. var sTokenType = this.f_getTermPlusTokenType( aParsedTerms, iStartTermPlusToken );
  1078. if( nRuleChoice.getAttribute("type") != sTokenType )
  1079. return false;
  1080. var nRuleTerm = this.m_docParsed.createElement( "div" );
  1081. nRuleTerm.setAttribute("class", sRuleType );
  1082. var v_sPrecedence = nRuleChoice.getAttribute("precedence");
  1083. if( v_sPrecedence )
  1084. nRuleTerm.setAttribute("p", v_sPrecedence );
  1085. var v_sTag = nRuleChoice.parentNode.getAttribute("tag");
  1086. if( v_sTag )
  1087. nRuleTerm.setAttribute("tag", v_sTag );
  1088. nRuleTerm.text = this.m_reTokens[iStartTermPlusToken - aParsedTerms.length + this.m_iStartToken];
  1089. aParsedTerms.push( nRuleTerm );
  1090. this.m_iStartToken++;
  1091. return true;
  1092. }
  1093. C_QanParser.prototype.f_applyRule_NestedRule = function( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken, aRuleStack )
  1094. {
  1095. var v_sRefRuleType = nRuleChoice.getAttribute("type");
  1096. if( aRuleStack.indexOf( v_sRefRuleType ) >= 0 )
  1097. { // first rule could not be recursive as it would end up in a loop
  1098. return false;
  1099. }
  1100. var v_nNestedRule = this.m_rules[ v_sRefRuleType ];
  1101. if( !this.f_applyRule( v_nNestedRule, aParsedTerms, iStartTermPlusToken, aRuleStack ) )
  1102. return false;
  1103. var nRuleTerm = this.m_docParsed.createElement( "div" );
  1104. nRuleTerm.setAttribute("class", sRuleType );
  1105. var v_sTag = nRuleChoice.parentNode.getAttribute("tag");
  1106. if( v_sTag )
  1107. nRuleTerm.setAttribute("tag", v_sTag );
  1108. if( aParsedTerms[aParsedTerms.length-1].nodeType )
  1109. {
  1110. this.f_appendRuleContent( nRuleTerm, aParsedTerms[aParsedTerms.length-1] );
  1111. // nRuleTerm.appendChild( aParsedTerms[aParsedTerms.length-1] );
  1112. var v_sPrecedence = aParsedTerms[aParsedTerms.length-1].getAttribute("p");
  1113. if( v_sPrecedence )
  1114. nRuleTerm.setAttribute( "p", v_sPrecedence );
  1115. }
  1116. else
  1117. nRuleTerm.appendChild(
  1118. this.m_docParsed.createTextNode( aParsedTerms[aParsedTerms.length-1] ) );
  1119. aParsedTerms.pop();
  1120. aParsedTerms.push( nRuleTerm );
  1121. return true;
  1122. }
  1123. C_QanParser.prototype.f_appendRuleContent = function( nToTerm, nFromTerm )
  1124. {
  1125. if( this.m_bRemoveNonTags &&
  1126. (nFromTerm.attributes && nFromTerm.getAttribute("tag") == "false" ) )
  1127. {
  1128. for( ; nFromTerm.firstChild; )
  1129. nToTerm.appendChild( nFromTerm.firstChild );
  1130. }
  1131. else
  1132. nToTerm.appendChild( nFromTerm );
  1133. }
  1134. C_QanParser.prototype.f_getTermPrecedence = function( nTerm )
  1135. {
  1136. return (nTerm.nodeType)? nTerm.getAttribute("p"): null;
  1137. }
  1138. C_QanParser.prototype.f_applyRule_Sequence = function( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken, aRuleStack, iParentPrecedence )
  1139. {
  1140. var v_nRuleSeqItem = nRuleChoice.firstChild;
  1141. var v_aSeqParsedTerms = [];
  1142. var v_iCurrentPrecedence;
  1143. for( ; v_nRuleSeqItem; v_nRuleSeqItem = v_nRuleSeqItem.nextSibling )
  1144. {
  1145. var v_iStartTerm = 0;//this.m_iStartToken;
  1146. var v_aItemParsedTerms = [];
  1147. var v_bRewritten = false;
  1148. if( v_nRuleSeqItem == nRuleChoice.firstChild )
  1149. {
  1150. v_aItemParsedTerms = aParsedTerms;
  1151. v_iStartTerm = iStartTermPlusToken;
  1152. }
  1153. else
  1154. this.f_handleEmptyToken( v_aSeqParsedTerms );
  1155. var v_iSaveStartToken = this.m_iStartToken;
  1156. var v_iSaveParsedTermsLength = aParsedTerms.length;
  1157. if( this.m_iStartToken < this.m_reTokens.length )
  1158. {
  1159. if( v_nRuleSeqItem.nodeName == "token" )
  1160. {
  1161. v_bRewritten = this.f_applyRule_Token( v_nRuleSeqItem, sRuleType, v_aItemParsedTerms, v_iStartTerm );
  1162. }
  1163. else
  1164. if( v_nRuleSeqItem.nodeName == "block" )
  1165. {
  1166. var v_sRefRuleType = v_nRuleSeqItem.getAttribute("type");
  1167. var v_sTokenType = this.f_getTermPlusTokenType( v_aItemParsedTerms, v_iStartTerm );
  1168. if( v_sRefRuleType == v_sTokenType )
  1169. {
  1170. v_aSeqParsedTerms.push( aParsedTerms[v_iStartTerm] );
  1171. continue;
  1172. }
  1173. if( v_nRuleSeqItem != nRuleChoice.firstChild || // first rule could not be recursive
  1174. aRuleStack.indexOf( v_sRefRuleType ) < 0 ) // as it would end up in a loop
  1175. {
  1176. var v_nRule = this.m_rules[v_sRefRuleType];
  1177. // For the non-first element the rule stack should be re-initialized:
  1178. // no chance for looping with the rules up the stack.
  1179. var aChildRuleStack = (v_nRuleSeqItem == nRuleChoice.firstChild)? aRuleStack: [];
  1180. v_bRewritten = this.f_applyRule( v_nRule, v_aItemParsedTerms, v_iStartTerm, aChildRuleStack, v_iCurrentPrecedence );
  1181. }
  1182. }
  1183. }
  1184. if( !v_bRewritten )
  1185. {
  1186. if( v_nRuleSeqItem.getAttribute("optional") != "true" )
  1187. return false;
  1188. this.m_iStartToken = v_iSaveStartToken;
  1189. v_aItemParsedTerms.length = v_iSaveParsedTermsLength;
  1190. }
  1191. else
  1192. {
  1193. for( var i = 0; i < v_aItemParsedTerms.length; ++i )
  1194. {
  1195. v_iCurrentPrecedence = this.f_getTermPrecedence(v_aItemParsedTerms[i]);
  1196. if( iParentPrecedence && v_iCurrentPrecedence >= iParentPrecedence )
  1197. {
  1198. return false;
  1199. }
  1200. v_aSeqParsedTerms.push( v_aItemParsedTerms[i] );
  1201. }
  1202. }
  1203. }
  1204. this.f_handleEmptyToken( v_aSeqParsedTerms );
  1205. var nRuleTerm = this.m_docParsed.createElement( "div" );
  1206. nRuleTerm.setAttribute("class", sRuleType );
  1207. var v_sTag = nRuleChoice.parentNode.getAttribute("tag");
  1208. if( v_sTag )
  1209. nRuleTerm.setAttribute("tag", v_sTag );
  1210. for( var i=0; i < v_aSeqParsedTerms.length; ++i )
  1211. {
  1212. if( v_aSeqParsedTerms[i].nodeType )
  1213. {
  1214. this.f_appendRuleContent( nRuleTerm, v_aSeqParsedTerms[i] );
  1215. // nRuleTerm.appendChild( v_aSeqParsedTerms[i] );
  1216. }
  1217. else
  1218. nRuleTerm.appendChild( this.m_docParsed.createTextNode( v_aSeqParsedTerms[i] ) );
  1219. }
  1220. aParsedTerms.F_Clear();
  1221. aParsedTerms.push(nRuleTerm);
  1222. return true;
  1223. }
  1224. C_QanParser.prototype.f_applyRule = function( nRule, aParsedTerms, iStartTermPlusToken, aRuleStack, iParentPrecedence )
  1225. {
  1226. if( C_QanParser.prototype.m_bLog )
  1227. this.f_logBefore_applyRule( nRule, aParsedTerms, iStartTermPlusToken, aRuleStack, iParentPrecedence );
  1228. var sRuleType = nRule.getAttribute("type"); // TODO: distingush from names
  1229. aRuleStack.push( sRuleType );
  1230. var iTermPlusToken = iStartTermPlusToken;
  1231. var v_bReduced = false;
  1232. var nRuleChoice = nRule.firstChild;
  1233. for( ; nRuleChoice; )
  1234. {
  1235. var v_iSaveStartToken = this.m_iStartToken;
  1236. var v_iSaveParsedTermsLength = aParsedTerms.length;
  1237. var v_bRewritten = false;
  1238. if( nRuleChoice.nodeName == "token" )
  1239. {
  1240. if( iStartTermPlusToken < aParsedTerms.length )
  1241. {
  1242. nRuleChoice = nRuleChoice.nextSibling
  1243. continue; // optimization;
  1244. }
  1245. v_bRewritten = this.f_applyRule_NestedToken( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken );
  1246. }
  1247. else
  1248. if( nRuleChoice.nodeName == "block" )
  1249. v_bRewritten = this.f_applyRule_NestedRule( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken, aRuleStack );
  1250. else
  1251. if( nRuleChoice.nodeName == "sequence" )
  1252. v_bRewritten = this.f_applyRule_Sequence( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken, aRuleStack, iParentPrecedence );
  1253. if( v_bRewritten )
  1254. {
  1255. nRuleChoice = nRule.firstChild;
  1256. v_bReduced = true;
  1257. }
  1258. else
  1259. {
  1260. nRuleChoice = nRuleChoice.nextSibling;
  1261. this.m_iStartToken = v_iSaveStartToken;
  1262. aParsedTerms.length = v_iSaveParsedTermsLength;
  1263. this.m_iMisses++;
  1264. }
  1265. }
  1266. aRuleStack.pop();
  1267. if( C_QanParser.prototype.m_bLog )
  1268. this.f_logAfter_applyRule( v_bReduced );
  1269. return v_bReduced;
  1270. }
  1271. C_QanParser.prototype.f_logBefore_applyRule = function( nRule, aParsedTerms, iStartTermPlusToken, aRuleStack, iParentPrecedence )
  1272. {
  1273. var v_sToken = this.f_getTermPlusTokenType( aParsedTerms, iStartTermPlusToken );
  1274. var v_nRuleLog = this.m_logDoc.createElement( "rule" );
  1275. this.m_nCurRuleLog.appendChild( v_nRuleLog );
  1276. this.m_nCurRuleLog = v_nRuleLog;
  1277. v_nRuleLog.setAttribute( "name", nRule.getAttribute("type") );
  1278. //v_nRuleLog.setAttribute( "def", nRule.xml.replace(/(?:type=)|(?:[\>\<\"])/g,"") );
  1279. v_nRuleLog.setAttribute( "token", v_sToken );
  1280. }
  1281. C_QanParser.prototype.f_logAfter_applyRule = function( v_bReduced )
  1282. {
  1283. this.m_nCurRuleLog.setAttribute( "res", (v_bReduced)? "reduced": "rejected" );
  1284. this.m_nCurRuleLog = this.m_nCurRuleLog.parentNode;
  1285. }
  1286. C_QanParser.prototype.f_getTokenType = function(iToken)
  1287. {
  1288. return this.m_reTokenTypes[iToken];
  1289. }
  1290. C_QanParser.prototype.f_initTokenTypes = function()
  1291. {
  1292. this.m_reTokenTypes = [];
  1293. this.m_reTokenTypes.length = this.m_reTokens.length;
  1294. for( var i = this.m_reTokens.length - 1; i >= 0; --i )
  1295. this.m_reTokenTypes[i] = this.f_determineTokenType(i);
  1296. }
  1297. C_QanParser.prototype.f_determineTokenType = function(iToken)
  1298. {
  1299. if( iToken >= this.m_reTokens.length )
  1300. return null;
  1301. var v_1ch = this.m_reTokens[iToken].charAt(0);
  1302. if( v_1ch == ' ' || v_1ch == '\t' || v_1ch == '\n' || v_1ch == '\r' )
  1303. return null;
  1304. else if( v_1ch == '\'' )
  1305. return 'literal';
  1306. else if( v_1ch == '[' )
  1307. return 'bname';
  1308. else if( v_1ch == '"' )
  1309. return 'qname';
  1310. else if( v_1ch >= '0' && v_1ch <= '9' )
  1311. return 'literal';
  1312. else
  1313. if( v_1ch >= '!' && v_1ch < '0' ||
  1314. v_1ch > '9' && v_1ch < 'A' ||
  1315. v_1ch > 'Z' && v_1ch < 'a' ||
  1316. v_1ch > 'z' && v_1ch <= '~' )
  1317. {
  1318. return this.m_reTokens[iToken];
  1319. }
  1320. else
  1321. if( this.m_aKeywordTypeMap[this.m_reTokens[iToken].toUpperCase()] )
  1322. return this.m_reTokens[iToken].toUpperCase();
  1323. else
  1324. return 'qname';
  1325. }
  1326. C_QanParser.prototype.f_init = function()
  1327. {
  1328. if( !C_QanParser.prototype.m_bRulesInitilized )
  1329. {
  1330. C_QanParser.prototype.m_bRulesInitilized = [];
  1331. C_QanParser.prototype.m_allRules = [];
  1332. }
  1333. if( !C_QanParser.prototype.m_bRulesInitilized[this.m_sLang] )
  1334. {
  1335. C_QanParser.prototype.m_docRules =
  1336. U_XML.F_LoadString( D_XmlError, (this.m_bIsSQL)? v_sSQLParsingRules: v_sMDXParsingRules );
  1337. var v_nLang = this.m_docRules.documentElement;
  1338. C_QanParser.prototype.m_allRules[this.m_sLang] = [];
  1339. var v_aRules = C_QanParser.prototype.m_allRules[this.m_sLang];
  1340. var v_nRule = v_nLang.firstChild;
  1341. for( ; v_nRule; v_nRule = v_nRule.nextSibling )
  1342. v_aRules[v_nRule.getAttribute("type")] = v_nRule;
  1343. C_QanParser.prototype.m_nRootRule = v_aRules[v_nLang.getAttribute("rootRule")];
  1344. C_QanParser.prototype.m_bRulesInitilized[this.m_sLang] = true;
  1345. }
  1346. this.m_rules = C_QanParser.prototype.m_allRules[this.m_sLang];
  1347. return C_QanParser.prototype.m_nRootRule[this.m_sLang];
  1348. }
  1349. C_QanParser.prototype.F_TransformExprToXML = function( sText )
  1350. {
  1351. return this.F_TransformBlockToXML( sText, "expr" );
  1352. }
  1353. C_QanParser.prototype.m_bLog = false;
  1354. C_QanParser.prototype.F_TransformBlockToXML = function( sText, sRootRule, sLang )
  1355. {
  1356. if( C_QanParser.prototype.m_bLog )
  1357. {
  1358. this.m_logDoc = U_XML.F_LoadString( D_XmlError, '<log ></log>' );
  1359. this.m_nCurRuleLog = this.m_logDoc.documentElement;
  1360. }
  1361. this.m_bIsSQL = ( !sLang || sLang == "SQL" );
  1362. this.m_sLang = ( this.m_bIsSQL )? "SQL": "MDX";
  1363. this.m_aKeywordTypeMap = (this.m_bIsSQL)? G_SQLKeywordTypeMap : G_MDXKeywordTypeMap ;
  1364. this.m_bRemoveNonTags = true;
  1365. this.f_init();
  1366. this.m_iMisses = 0;
  1367. this.f_breakIntoTokens( sText );
  1368. this.f_initTokenTypes();
  1369. this.m_docParsed = U_XML.F_LoadString( D_XmlError, '<div class="expr" ></div>' );
  1370. var v_aParsedTerms = [];
  1371. this.m_iStartToken = 0;
  1372. var aRuleStack = [];
  1373. if( !this.f_applyRule( this.m_rules[sRootRule], v_aParsedTerms, 0, aRuleStack ) )
  1374. return sText;
  1375. if( this.m_iStartToken < this.m_reTokens.length - 1 )
  1376. return sText;
  1377. if( v_aParsedTerms.length == 1 )
  1378. return v_aParsedTerms[0];
  1379. else
  1380. return sText;
  1381. }