/**************************************************************************************************************************** Licensed Materials - Property of IBM BI and PM: QFW © Copyright IBM Corp. 2005, 2014 US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. *****************************************************************************************************************************/ var G_KeywordsMajorLookup = ["SELECT", "SELECT DISTINCT", "WHERE", "FROM", "GROUP BY", "ORDER BY", "WITH"]; 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"]; 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"] var G_PunctuationLookup = [".", "(", ")", ",", "=", "/", "*", "{", "}", "[", "]", "|", "||"]; var G_SQLKeywordTypeMap = {"SELECT":"k", "DISTINCT":"k", "WHERE":"k", "FROM":"k", "GROUP":"k", "ORDER":"k", "BY":"k", "WITH":"k", "BETWEEN":"k", "AND":"k", "OR":"k", "NOT":"k", "LIKE":"k", "ESCAPE": "k", "FOR":"k", "AS":"k", "AT":"k", "ASC":"k", "DESC":"k", "INTERSECT":"k", "UNION":"k", "EXCEPT":"k", "JOIN":"k", "OUTER":"k", "FULL":"k", "INNER":"k", "CROSS":"k", "LEFT":"k", "RIGHT":"k", "LOCAL":"k", "WHEN":"k", "THEN":"k", "CASE":"k", "ELSE":"k", "END":"k", /*"NULL":"k",*/ "IS":"k", "IN":"k", "ON":"k", "ALL":"k", "ANY":"k", "LOCAL":"k" }; var G_MDXKeywordTypeMap = {"SELECT":"k", "WHERE":"k", "FROM":"k", "WITH":"k", "BETWEEN":"k", "AND":"k", "OR":"k", "NOT":"k", "LIKE":"k", "ESCAPE": "k", "AS":"k", "ASC":"k", "DESC":"k", /*"NULL":"k",*/ "IS":"k", "IN":"k", "ON":"k", "DIMENSION":"k", "PROPERTIES":"k" }; var G_SQLSelectBlockKeywordsObj = {"SELECT":true, "WHERE":true, "FROM":true, "GROUP":true, "ORDER":true, "WITH":true, "FILTER": true, "WINDOW": true, "QUALIFY": true, "HAVING":true, "UNION":true, "EXCEPT":true, "INTERSECT": true }; var G_MDXSelectBlockKeywordsObj = { "SELECT":true, "WHERE":true, "FROM":true, "WITH":true, "FILTER": true }; var G_SelectBlockAdditionalKeywordsObj = {"DISTINCT":true, "BY":true }; var G_SelectBlockKeywordsRe = new RegExp( /(?:SELECT)|(?:WHERE)|(?:FROM)|(?:GROUP)|(?:ORDER)|(?:WHERE)|(?:WITH)|(?:HAVING)/i ); var G_SelectBlockAdditionalKeywordsRe = new RegExp( /(?:DISTINCT)|(?:BY)/i ); /*o*/var G_TokenOperator = new RegExp( /(?:[\(\)\,\{\}\|\[\]\+\-\*\\/%\^\.:;\=<>])/ ); /*k*/var G_Keywords = new RegExp( /(?:SELECT)|(?:DISTINCT)|(?:WHERE)|(?:FROM)|(?:GROUP)|(?:BY)|(?:ORDER)|(?:WITH)|(?:HAVING)/ig ); /*d*/var G_TokenDigit = new RegExp( /(?:\d+)/ ); /*w*/var G_TokenWhitespace = new RegExp( /(?:\s+)/ ); /*o*/var G_TokenOperator = new RegExp( /(?:[\(\)\,\{\}\|\[\]\+\-\*\\/%\^\.:;\=<>])/ ); /*n*/var G_TokenName = new RegExp( /(?:\w[\w\d]*)/ ); /*s*/var G_TokenString = new RegExp( /(?:['](?:''|[^'])*['])/ ); /*q*/var G_TokenQName = new RegExp( /(?:[\"](?:\"\"|[^\"])*[\"])/ ); /*q*/var G_TokenBName = new RegExp( /(?:[\[](?:]]|[^]])*[\]])/ ); var G_TokenNameOrQName = new RegExp( /(?:\w[\w\d]*)|(?:[\"](?:\"\"|[^\"])*[\"])/ ); var G_Tokenizer = new RegExp( /(?:\d+)|(?:[\[](?:]]|[^]])*[\]])|(?:\s+)|(?:\|\|)|(?:\>\=)|(?:\<\=)|(?:\<\>)|(?:\!\=)|(?:[\(\)\,\{\}\|\[\]\+\-\*\\/%\^\.:;\=<>])|(?:\w[\w\d]*)|(?:['](?:''|[^'])*['])|(?:[\"](?:\"\"|[^\"])*[\"])|(?:.)/g ); function C_QanParser() { } C_QanParser.prototype.F_TransformToXML_OneTwoTokens = function( sText ) { this.m_docParsed = U_XML.F_LoadString( D_XmlError, "" ); this.f_breakIntoTokens( sText ); this.f_formatLexems( this.m_docParsed ); this.f_createLexems(); return this.m_docParsed; } C_QanParser.prototype.f_breakIntoTokens = function( sText ) { this.m_reTokens = sText.match(G_Tokenizer); } C_QanParser.prototype.f_createLexems = function() { var v_length = this.m_reTokens.length; this.m_aLexems = new Array( v_length ); for( var t = 0; t < v_length; ++t ) { var v_1ch = this.m_reTokens[t].charAt(0); if( v_1ch == ' ' || v_1ch == '\t' ) this.m_aLexems[t] = ' '; else if( v_1ch == '\'' ) this.m_aLexems[t] = '\''; else if( v_1ch == '"' ) this.m_aLexems[t] = '\"'; else if( v_1ch >= '0' && v_1ch <= '0' ) this.m_aLexems[t] = '1'; else if( this.m_reTokens[t].match( G_Keywords ) ) this.m_aLexems[t] = 'k'; else if( this.m_reTokens[t].match( G_TokenOperator ) ) this.m_aLexems[t] = 'k'; else this.m_aLexems[t] = 'n'; } } C_QanParser.prototype.f_formatLexems = function() { var v_docParsedRoot = this.m_docParsed.documentElement; var v_bB = false; for( var i = 0; i < this.m_reTokens.length; ++i ) { var v_nT = this.m_docParsed.createElement( (v_bB)? "b":"i" ); v_docParsedRoot.appendChild( v_nT ); v_nT.text = this.m_reTokens[i]; v_bB = !v_bB; } return this.m_docParsed; } C_QanParser.prototype.F_TransformToHTML = function( nRoot ) { if( nRoot.xml ) return nRoot.xml.replace( /\>\s([^\<])/g, "> $1" ); else return nRoot; } C_QanParser.prototype.F_TransformBlockToHTML = function( nRoot ) { if( nRoot.xml ) return nRoot.xml.replace( /\>\s/g, "> " ).replace(/(^\s+)/g, " "); else return nRoot; } C_QanParser.prototype.F_TransformToXML = function( sText, sLang ) { this.m_bIsSQL = ( !sLang || sLang == "SQL" ); this.m_sLang = ( this.m_bIsSQL )? "SQL": "MDX"; this.m_aItemEndFrase = (this.m_bIsSQL)? ["AS","qname"]: ["ON","qname","(" , "literal", ")"]; this.m_selectBlockKeywordsObj = (this.m_bIsSQL)? G_SQLSelectBlockKeywordsObj: G_MDXSelectBlockKeywordsObj; this.m_aKeywordTypeMap = (this.m_bIsSQL)? G_SQLKeywordTypeMap : G_MDXKeywordTypeMap ; this.m_docParsed = U_XML.F_LoadString( D_XmlError, '
' ); this.f_breakIntoTokens( sText ); if( !this.m_reTokens || !this.m_reTokens.length ) return; this.f_ruleTokens_toXML( this.m_docParsed.documentElement, 0 ); this.f_markSelectBlocks( this.m_docParsed.documentElement ); return this.m_docParsed; } C_QanParser.prototype.f_ruleTokens_toXML = function( nRule, iTokenStart, sClosingToken, sSelectBlock ) { var iTokenEnd = this.m_reTokens.length - 1; var iTextTokenStart = iTokenStart; var v_isBlock = (nRule.getAttribute("class") == "block"); var v_isParentSelectNest = v_isBlock && (nRule.parentNode.getAttribute("class") == "selectNest"); var i = iTokenStart; for( ; i <= iTokenEnd; ++i ) { var sToken = this.m_reTokens[i]; if( sToken == '(' && this.m_bIsSQL ) { this.f_textTokens( nRule, iTextTokenStart, i ); i = this.f_nestTokens_toXML( nRule, i ); iTextTokenStart = i + 1; } else if( sToken == "," ) { if( v_isBlock && v_isParentSelectNest && ( this.m_bIsSQL || this.f_findFrase(i-1, this.m_aItemEndFrase ) ) ) { this.f_itemBreakToken( nRule, iTextTokenStart, i, sSelectBlock, true ); iTextTokenStart = i + 1; } } else if( sToken == sClosingToken ) break; else{ var v_sTokenUC = sToken.toUpperCase(); if( this.m_selectBlockKeywordsObj[ v_sTokenUC ] ) { if( v_isBlock && v_isParentSelectNest ) this.f_itemBreakToken( nRule, iTextTokenStart, i, sSelectBlock, false ); else this.f_textTokens( nRule, iTextTokenStart, i ); if( v_isBlock ) return i; i = this.f_selectBlockTokens_toXML( nRule, i, sClosingToken ); iTextTokenStart = i + 1; } } } if( v_isBlock && v_isParentSelectNest ) this.f_itemBreakToken( nRule, iTextTokenStart, i, sSelectBlock, false ); else this.f_textTokens( nRule, iTextTokenStart, i ); return i; } C_QanParser.prototype.f_getQnameValue = function( sQname ) { if( sQname.charAt(0) != '\"' ) return sQname; sQname = sQname.substring( 1, sQname.length-1 ); return sQname.replace( /\"\"/, "\"" ); } C_QanParser.prototype.f_findFrase = function( iTextTokenEnd, aFraseTokens, aFraseTokenPos ) { var iNonEmpty = aFraseTokens.length - 1; if( aFraseTokenPos ) aFraseTokenPos.length = aFraseTokens.length; for( var i = iTextTokenEnd; i >= 0 && iNonEmpty >= 0; --i ) { var v_sTokenType = this.f_determineTokenType(i); if( !v_sTokenType ) continue; if( v_sTokenType != aFraseTokens[iNonEmpty] ) return false; if( aFraseTokenPos ) aFraseTokenPos[iNonEmpty] = i; iNonEmpty--; } return ( iNonEmpty < 0 ); } C_QanParser.prototype.f_itemBreakToken = function( nRule, iTextTokenStart, iTokenStart, sSelectBlock, bIsComma ) { var v_bParsedItems = ( sSelectBlock ); var v_nContent; var v_nItem; if( v_bParsedItems ) { v_nContent = this.m_docParsed.createElement( "div" ); v_nContent.setAttribute( "class", "itemDef" ); nRule.appendChild( v_nContent ); for( ; v_nContent.previousSibling; ) { if( v_nContent.previousSibling.attributes && v_nContent.previousSibling.getAttribute("class") != "nest" && v_nContent.previousSibling.getAttribute("class") != "aliasedSelect" && v_nContent.previousSibling.getAttribute("class") != "selectNest" ) { break; } v_nContent.insertBefore( v_nContent.previousSibling, v_nContent.firstChild ); } v_nItem = this.m_docParsed.createElement( "div" ); v_nItem.setAttribute( "class", "item" ); nRule.appendChild( v_nItem ); v_nItem.appendChild( v_nContent ); } else { v_nContent = nRule; v_nItem = nRule; } var v_aItemEndTokensPos = []; if( v_bParsedItems && this.f_findFrase( iTokenStart-1, this.m_aItemEndFrase, v_aItemEndTokensPos ) ) { var v_iItemEnd = v_aItemEndTokensPos[ v_aItemEndTokensPos.length - 1 ]; this.f_textTokens( v_nContent, iTextTokenStart, v_aItemEndTokensPos[0] ); this.f_textTokens( v_nItem, v_aItemEndTokensPos[0], v_aItemEndTokensPos[1] ); var v_nR = this.m_docParsed.createElement( "div" ); v_nR.setAttribute( "class", "alias" ); v_nR.text = this.m_reTokens.slice( v_aItemEndTokensPos[1], v_iItemEnd +1).join(""); v_nR.setAttribute("name", this.f_getQnameValue( this.m_reTokens[v_iItemEnd] ) ); v_nItem.appendChild( v_nR ); this.f_textTokens( v_nItem, v_iItemEnd + 1, iTokenStart + ((bIsComma)? 1: 0) ); } else this.f_textTokens( v_nContent, iTextTokenStart, iTokenStart + ((bIsComma)? 1: 0) ); } C_QanParser.prototype.f_titleToken = function( nRule, iTokenStart, iTokenEnd ) { var v_nT = this.m_docParsed.createElement("span"); v_nT.setAttribute( "class", "title" ); v_nT.text = this.m_reTokens.slice( iTokenStart, iTokenEnd ).join(""); nRule.appendChild( v_nT ); } C_QanParser.prototype.f_isWhiteSpaceToken = function( iToken ) { var v_aMatched = this.m_reTokens[iToken].match( G_TokenWhitespace ); return ( v_aMatched && v_aMatched[0] === this.m_reTokens[iToken] ); } C_QanParser.prototype.f_isNameToken = function( iToken ) { var v_aMatched = this.m_reTokens[iToken].match( G_TokenNameOrQName ); return ( v_aMatched && v_aMatched[0] === this.m_reTokens[iToken] ); } C_QanParser.prototype.f_selectBlockTokens_toXML = function( nRule, iTokenStart, sClosingToken ) { var v_sToken = this.m_reTokens[iTokenStart].toUpperCase(); if( v_sToken == "SELECT" || v_sToken == "WITH" ) nRule.setAttribute( "class", "selectNest" ); var v_nBlock = this.m_docParsed.createElement( "div" ); v_nBlock.setAttribute( "class", "block" ); nRule.appendChild( v_nBlock ); var iTitleTokenEnd = iTokenStart + 1; if( this.f_isWhiteSpaceToken(iTitleTokenEnd) ) { iTitleTokenEnd += 1; if( G_SelectBlockAdditionalKeywordsObj[ this.m_reTokens[iTitleTokenEnd].toUpperCase()] ) iTitleTokenEnd += 1; } this.f_titleToken( v_nBlock, iTokenStart, iTitleTokenEnd ); if( !this.m_bIsSQL && v_sToken == "WITH" ) return this.f_mdxWithBlock_toXML( v_nBlock, iTitleTokenEnd + 1 ); return this.f_ruleTokens_toXML( v_nBlock, iTitleTokenEnd, sClosingToken, v_sToken ) - 1; } C_QanParser.prototype.f_textTokens = function( nRule, iTextTokenStart, iTextTokenEnd ) { if( iTextTokenStart >= iTextTokenEnd ) return; var v_nT = this.m_docParsed.createTextNode( this.m_reTokens.slice(iTextTokenStart, iTextTokenEnd).join("") ); nRule.appendChild( v_nT ); } C_QanParser.prototype.f_textToken = function( nRule, sOpenToken ) { var v_nT = this.m_docParsed.createTextNode( sOpenToken ); nRule.appendChild( v_nT ); } C_QanParser.prototype.f_nestTokens_toXML = function( nRule, iTokenStart ) { var v_sClosingToken; var v_sOpenToken = this.m_reTokens[iTokenStart]; if( v_sOpenToken == "(" ) v_sClosingToken = ")"; else if( v_sOpenToken == "{" ) v_sClosingToken = "}"; var v_nNest = this.m_docParsed.createElement( "div" ); v_nNest.setAttribute( "class", "nest" ); nRule.appendChild( v_nNest ); this.f_textToken( v_nNest, v_sOpenToken ); var iTokenEnd = this.f_ruleTokens_toXML( v_nNest, iTokenStart + 1, v_sClosingToken ); this.f_textToken( v_nNest, this.m_reTokens[iTokenEnd] ); iTokenEnd = this.f_markSelectBlocks( v_nNest, iTokenStart, iTokenEnd ); return iTokenEnd; } C_QanParser.prototype.f_mdxObjRef_toXML = function( nRule, iTokenStart ) { var v_isName = true; var v_isRefFound = false; var v_iFirstToken, v_iLastToken; for( var i = iTokenStart; i < this.m_reTokens.length; ++i ) { var v_sTokenType = this.f_determineTokenType(i); if( !v_sTokenType ) continue; if( ( v_isName && v_sTokenType != 'bname' ) || ( !v_isName && v_sTokenType != '.' ) ) { break; } v_iLastToken = i; if( !v_iFirstToken ) v_iFirstToken = i; v_isRefFound = true; v_isName = !v_isName; } if( !v_isRefFound ) return false; this.f_textTokens( nRule, iTokenStart, v_iFirstToken ); var v_nRef = this.m_docParsed.createElement( "div" ); v_nRef.setAttribute( "class", "alias" ); nRule.appendChild( v_nRef ); this.f_textTokens( v_nRef, v_iFirstToken, v_iLastToken + 1 ); return v_iLastToken + 1; } C_QanParser.prototype.f_mdxMemberDef_toXML = function( nRule, iTokenStart, iTokenNext ) { var v_nItem = this.m_docParsed.createElement( "div" ); v_nItem.setAttribute( "class", "item" ); nRule.appendChild( v_nItem ); this.f_textTokens( v_nItem, iTokenStart, iTokenStart+1 ); var i = this.f_mdxObjRef_toXML( v_nItem, iTokenStart+1 ); this.f_textTokens( v_nItem, i, iTokenNext ); } C_QanParser.prototype.f_mdxWithBlock_toXML = function( nRule, iTokenStart ) { var i = iTokenStart; var iMemberTokenStart; for( ; i <= this.m_reTokens.length; ++i ) { var sToken = this.m_reTokens[i].toUpperCase(); if( sToken == "MEMBER" ) { if( iMemberTokenStart ) this.f_mdxMemberDef_toXML( nRule, iMemberTokenStart, i ); else this.f_textTokens( nRule, iTokenStart, i ); iMemberTokenStart = i; } if( sToken == "SELECT" ) break; } if( iMemberTokenStart ) this.f_mdxMemberDef_toXML( nRule, iMemberTokenStart, i ); return i - 1; } C_QanParser.prototype.f_markSelectBlocks = function( nSelectNest, iTokenStart, iTokenEnd ) { if( nSelectNest.getAttribute( "class" ) != "selectNest" ) return iTokenEnd; var v_sBlockTitle; var v_nlBlocks = nSelectNest.selectNodes( "div[@class='block']" ); for( var i = 0; i < v_nlBlocks.length; ++i ) { var v_nBlock = v_nlBlocks[i]; var v_aContentNodes = []; v_nBlock.setAttribute( "class", "selectBlock" ); for( var j = 0; j < v_nBlock.childNodes.length; ++j ) { var v_nBlockChild = v_nBlock.childNodes[j]; if( v_nBlockChild.attributes && v_nBlockChild.getAttribute( "class" ) == "title" ) { v_nBlockChild.setAttribute( "class", "selectTitle" ); v_sBlockTitle = v_nBlockChild.text; continue; } v_aContentNodes.push( v_nBlockChild ); } if( v_aContentNodes.length == 0 ) continue; var v_nContent = v_nBlock.appendChild( v_nBlock.ownerDocument.createElement( "div" ) ); v_nContent.setAttribute( "class", "content" ) for( var k = 0; k < v_aContentNodes.length; ++k ) v_nContent.appendChild( v_aContentNodes[k] ); } var v_nParentTitle = nSelectNest.selectSingleNode( "../span[@class='title']" ); var v_sParentTitle = (v_nParentTitle)? v_nParentTitle.text.toUpperCase(): ""; if( v_sParentTitle == "WITH" ) this.f_markWithSelectItem( nSelectNest, iTokenStart ); if( v_sParentTitle == "FROM" ) iTokenEnd = this.f_markFromSelectItem( nSelectNest, iTokenStart, iTokenEnd ); this.f_checkForTabularOperations( nSelectNest ); return iTokenEnd; } C_QanParser.prototype.f_checkForTabularOperations = function( nSelectNest ) { var v_bSelectStartPrevBlock = true; var v_bSelectStart; v_nlSelectStart = nSelectNest.selectNodes( "div/span[@class='selectTitle']" ); for( var i = 0; i < v_nlSelectStart.length; ++i ) { var v_sBlockType = v_nlSelectStart[i].text.toUpperCase(); if( v_sBlockType == 'WITH' ) v_bSelectStart = true; else if( v_sBlockType == 'SELECT' && !v_bSelectStartPrevBlock ) v_bSelectStart = true; else v_bSelectStart = false; if( v_bSelectStart && !v_bSelectStartPrevBlock ) { var v_nSelectBreak = this.m_docParsed.createElement("div"); v_nSelectBreak.setAttribute( "class", "selectBr" ); v_nSelectBreak.text = " "; var v_nSelectNest = v_nlSelectStart[i].parentNode; v_nSelectNest.parentNode.insertBefore( v_nSelectBreak, v_nSelectNest ); } v_bSelectStartPrevBlock = v_bSelectStart; } } C_QanParser.prototype.f_markWithSelectItem = function( nSelectNest, iTokenStart ) { if( nSelectNest.previousSibling.nodeType == 3 ) { var iAsToken; var i = iTokenStart - 1; for( ; i > 0 && this.f_isWhiteSpaceToken(i); --i ); if( this.m_reTokens[i].toUpperCase() == "AS" ) { iAsToken = i; for( --i; i > 0 && this.f_isWhiteSpaceToken(i); --i ); } if( this.f_isNameToken(i) ) { var v_nAliasedSelect = this.m_docParsed.createElement( "div" ); nSelectNest.parentNode.appendChild( v_nAliasedSelect ); v_nAliasedSelect.setAttribute("class", "aliasedSelect"); nSelectNest.parentNode.removeChild( nSelectNest.previousSibling ); var v_nAlias = v_nAliasedSelect.appendChild( this.m_docParsed.createElement( "span" ) ); v_nAlias.text = this.m_reTokens[i]; v_nAlias.setAttribute("class", "selectAlias"); if( iAsToken ) { var v_nAs = this.m_docParsed.createTextNode( " " + this.m_reTokens[iAsToken] + " " ); v_nAliasedSelect.appendChild( v_nAs ); } v_nAliasedSelect.appendChild( nSelectNest ); } } } C_QanParser.prototype.f_markFromSelectItem = function( nSelectNest, iTokenStart, iTokenEnd ) { var iAsToken; var i = iTokenEnd + 1; for( ; i < this.m_reTokens.length && this.f_isWhiteSpaceToken(i); ++i ); if( this.m_reTokens[i].toUpperCase() == "AS" ) { iAsToken = i; for( ++i; i < this.m_reTokens.length && this.f_isWhiteSpaceToken(i); ++i ); } if( this.f_isNameToken(i) ) { var v_nAliasedSelect = this.m_docParsed.createElement( "div" ); nSelectNest.parentNode.appendChild( v_nAliasedSelect ); v_nAliasedSelect.setAttribute("class", "aliasedSelect"); v_nAliasedSelect.appendChild( nSelectNest ); if( iAsToken ) { var v_nAs = this.m_docParsed.createTextNode( " " + this.m_reTokens[iAsToken] + " " ); v_nAliasedSelect.appendChild( v_nAs ); } var v_nAlias = v_nAliasedSelect.appendChild( this.m_docParsed.createElement( "span" ) ); v_nAlias.text = this.m_reTokens[i]; v_nAlias.setAttribute("class", "selectAlias"); return i; } return iTokenEnd; } var v_sSQLParsingRules = '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ '' + ''+ ''+ '' + ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ '' + ''+ ''+ ''+ '' + ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''; var v_sMDXParsingRules = '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ '' + ''+ ''+ '' + ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ '' + ''+ ''+ ''+ '' + ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''+ '' + ''+ ''+ ''+ ''+ ''; C_QanParser.prototype.f_getParsedTermType = function( divParsedTerm ) { if( divParsedTerm.nodeType ) return divParsedTerm.getAttribute("class"); else return divParsedTerm; } C_QanParser.prototype.f_handleEmptyToken = function( aParsedTerms ) { var sTokenType = this.f_getTokenType( this.m_iStartToken ); if( !sTokenType ) { aParsedTerms.push( this.m_docParsed.createTextNode( this.m_reTokens[ this.m_iStartToken ] ) ); ++this.m_iStartToken; return true; } return false; } C_QanParser.prototype.f_getTermPlusTokenType = function( aParsedTerms, iTermPlusToken ) { if( iTermPlusToken < aParsedTerms.length ) return this.f_getParsedTermType( aParsedTerms[iTermPlusToken] ); var sTokenType = this.f_getTokenType( iTermPlusToken - aParsedTerms.length + this.m_iStartToken ); return sTokenType; } C_QanParser.prototype.f_applyRule_Token = function( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken ) { var sTokenType = this.f_getTermPlusTokenType( aParsedTerms, iStartTermPlusToken ); if( nRuleChoice.getAttribute("type") != sTokenType ) return false; aParsedTerms.push( this.m_reTokens[iStartTermPlusToken - aParsedTerms.length + this.m_iStartToken] ); this.m_iStartToken++; return true; } C_QanParser.prototype.f_applyRule_NestedToken = function( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken ) { var sTokenType = this.f_getTermPlusTokenType( aParsedTerms, iStartTermPlusToken ); if( nRuleChoice.getAttribute("type") != sTokenType ) return false; var nRuleTerm = this.m_docParsed.createElement( "div" ); nRuleTerm.setAttribute("class", sRuleType ); var v_sPrecedence = nRuleChoice.getAttribute("precedence"); if( v_sPrecedence ) nRuleTerm.setAttribute("p", v_sPrecedence ); var v_sTag = nRuleChoice.parentNode.getAttribute("tag"); if( v_sTag ) nRuleTerm.setAttribute("tag", v_sTag ); nRuleTerm.text = this.m_reTokens[iStartTermPlusToken - aParsedTerms.length + this.m_iStartToken]; aParsedTerms.push( nRuleTerm ); this.m_iStartToken++; return true; } C_QanParser.prototype.f_applyRule_NestedRule = function( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken, aRuleStack ) { var v_sRefRuleType = nRuleChoice.getAttribute("type"); if( aRuleStack.indexOf( v_sRefRuleType ) >= 0 ) { // first rule could not be recursive as it would end up in a loop return false; } var v_nNestedRule = this.m_rules[ v_sRefRuleType ]; if( !this.f_applyRule( v_nNestedRule, aParsedTerms, iStartTermPlusToken, aRuleStack ) ) return false; var nRuleTerm = this.m_docParsed.createElement( "div" ); nRuleTerm.setAttribute("class", sRuleType ); var v_sTag = nRuleChoice.parentNode.getAttribute("tag"); if( v_sTag ) nRuleTerm.setAttribute("tag", v_sTag ); if( aParsedTerms[aParsedTerms.length-1].nodeType ) { this.f_appendRuleContent( nRuleTerm, aParsedTerms[aParsedTerms.length-1] ); // nRuleTerm.appendChild( aParsedTerms[aParsedTerms.length-1] ); var v_sPrecedence = aParsedTerms[aParsedTerms.length-1].getAttribute("p"); if( v_sPrecedence ) nRuleTerm.setAttribute( "p", v_sPrecedence ); } else nRuleTerm.appendChild( this.m_docParsed.createTextNode( aParsedTerms[aParsedTerms.length-1] ) ); aParsedTerms.pop(); aParsedTerms.push( nRuleTerm ); return true; } C_QanParser.prototype.f_appendRuleContent = function( nToTerm, nFromTerm ) { if( this.m_bRemoveNonTags && (nFromTerm.attributes && nFromTerm.getAttribute("tag") == "false" ) ) { for( ; nFromTerm.firstChild; ) nToTerm.appendChild( nFromTerm.firstChild ); } else nToTerm.appendChild( nFromTerm ); } C_QanParser.prototype.f_getTermPrecedence = function( nTerm ) { return (nTerm.nodeType)? nTerm.getAttribute("p"): null; } C_QanParser.prototype.f_applyRule_Sequence = function( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken, aRuleStack, iParentPrecedence ) { var v_nRuleSeqItem = nRuleChoice.firstChild; var v_aSeqParsedTerms = []; var v_iCurrentPrecedence; for( ; v_nRuleSeqItem; v_nRuleSeqItem = v_nRuleSeqItem.nextSibling ) { var v_iStartTerm = 0;//this.m_iStartToken; var v_aItemParsedTerms = []; var v_bRewritten = false; if( v_nRuleSeqItem == nRuleChoice.firstChild ) { v_aItemParsedTerms = aParsedTerms; v_iStartTerm = iStartTermPlusToken; } else this.f_handleEmptyToken( v_aSeqParsedTerms ); var v_iSaveStartToken = this.m_iStartToken; var v_iSaveParsedTermsLength = aParsedTerms.length; if( this.m_iStartToken < this.m_reTokens.length ) { if( v_nRuleSeqItem.nodeName == "token" ) { v_bRewritten = this.f_applyRule_Token( v_nRuleSeqItem, sRuleType, v_aItemParsedTerms, v_iStartTerm ); } else if( v_nRuleSeqItem.nodeName == "block" ) { var v_sRefRuleType = v_nRuleSeqItem.getAttribute("type"); var v_sTokenType = this.f_getTermPlusTokenType( v_aItemParsedTerms, v_iStartTerm ); if( v_sRefRuleType == v_sTokenType ) { v_aSeqParsedTerms.push( aParsedTerms[v_iStartTerm] ); continue; } if( v_nRuleSeqItem != nRuleChoice.firstChild || // first rule could not be recursive aRuleStack.indexOf( v_sRefRuleType ) < 0 ) // as it would end up in a loop { var v_nRule = this.m_rules[v_sRefRuleType]; // For the non-first element the rule stack should be re-initialized: // no chance for looping with the rules up the stack. var aChildRuleStack = (v_nRuleSeqItem == nRuleChoice.firstChild)? aRuleStack: []; v_bRewritten = this.f_applyRule( v_nRule, v_aItemParsedTerms, v_iStartTerm, aChildRuleStack, v_iCurrentPrecedence ); } } } if( !v_bRewritten ) { if( v_nRuleSeqItem.getAttribute("optional") != "true" ) return false; this.m_iStartToken = v_iSaveStartToken; v_aItemParsedTerms.length = v_iSaveParsedTermsLength; } else { for( var i = 0; i < v_aItemParsedTerms.length; ++i ) { v_iCurrentPrecedence = this.f_getTermPrecedence(v_aItemParsedTerms[i]); if( iParentPrecedence && v_iCurrentPrecedence >= iParentPrecedence ) { return false; } v_aSeqParsedTerms.push( v_aItemParsedTerms[i] ); } } } this.f_handleEmptyToken( v_aSeqParsedTerms ); var nRuleTerm = this.m_docParsed.createElement( "div" ); nRuleTerm.setAttribute("class", sRuleType ); var v_sTag = nRuleChoice.parentNode.getAttribute("tag"); if( v_sTag ) nRuleTerm.setAttribute("tag", v_sTag ); for( var i=0; i < v_aSeqParsedTerms.length; ++i ) { if( v_aSeqParsedTerms[i].nodeType ) { this.f_appendRuleContent( nRuleTerm, v_aSeqParsedTerms[i] ); // nRuleTerm.appendChild( v_aSeqParsedTerms[i] ); } else nRuleTerm.appendChild( this.m_docParsed.createTextNode( v_aSeqParsedTerms[i] ) ); } aParsedTerms.F_Clear(); aParsedTerms.push(nRuleTerm); return true; } C_QanParser.prototype.f_applyRule = function( nRule, aParsedTerms, iStartTermPlusToken, aRuleStack, iParentPrecedence ) { if( C_QanParser.prototype.m_bLog ) this.f_logBefore_applyRule( nRule, aParsedTerms, iStartTermPlusToken, aRuleStack, iParentPrecedence ); var sRuleType = nRule.getAttribute("type"); // TODO: distingush from names aRuleStack.push( sRuleType ); var iTermPlusToken = iStartTermPlusToken; var v_bReduced = false; var nRuleChoice = nRule.firstChild; for( ; nRuleChoice; ) { var v_iSaveStartToken = this.m_iStartToken; var v_iSaveParsedTermsLength = aParsedTerms.length; var v_bRewritten = false; if( nRuleChoice.nodeName == "token" ) { if( iStartTermPlusToken < aParsedTerms.length ) { nRuleChoice = nRuleChoice.nextSibling continue; // optimization; } v_bRewritten = this.f_applyRule_NestedToken( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken ); } else if( nRuleChoice.nodeName == "block" ) v_bRewritten = this.f_applyRule_NestedRule( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken, aRuleStack ); else if( nRuleChoice.nodeName == "sequence" ) v_bRewritten = this.f_applyRule_Sequence( nRuleChoice, sRuleType, aParsedTerms, iStartTermPlusToken, aRuleStack, iParentPrecedence ); if( v_bRewritten ) { nRuleChoice = nRule.firstChild; v_bReduced = true; } else { nRuleChoice = nRuleChoice.nextSibling; this.m_iStartToken = v_iSaveStartToken; aParsedTerms.length = v_iSaveParsedTermsLength; this.m_iMisses++; } } aRuleStack.pop(); if( C_QanParser.prototype.m_bLog ) this.f_logAfter_applyRule( v_bReduced ); return v_bReduced; } C_QanParser.prototype.f_logBefore_applyRule = function( nRule, aParsedTerms, iStartTermPlusToken, aRuleStack, iParentPrecedence ) { var v_sToken = this.f_getTermPlusTokenType( aParsedTerms, iStartTermPlusToken ); var v_nRuleLog = this.m_logDoc.createElement( "rule" ); this.m_nCurRuleLog.appendChild( v_nRuleLog ); this.m_nCurRuleLog = v_nRuleLog; v_nRuleLog.setAttribute( "name", nRule.getAttribute("type") ); //v_nRuleLog.setAttribute( "def", nRule.xml.replace(/(?:type=)|(?:[\>\<\"])/g,"") ); v_nRuleLog.setAttribute( "token", v_sToken ); } C_QanParser.prototype.f_logAfter_applyRule = function( v_bReduced ) { this.m_nCurRuleLog.setAttribute( "res", (v_bReduced)? "reduced": "rejected" ); this.m_nCurRuleLog = this.m_nCurRuleLog.parentNode; } C_QanParser.prototype.f_getTokenType = function(iToken) { return this.m_reTokenTypes[iToken]; } C_QanParser.prototype.f_initTokenTypes = function() { this.m_reTokenTypes = []; this.m_reTokenTypes.length = this.m_reTokens.length; for( var i = this.m_reTokens.length - 1; i >= 0; --i ) this.m_reTokenTypes[i] = this.f_determineTokenType(i); } C_QanParser.prototype.f_determineTokenType = function(iToken) { if( iToken >= this.m_reTokens.length ) return null; var v_1ch = this.m_reTokens[iToken].charAt(0); if( v_1ch == ' ' || v_1ch == '\t' || v_1ch == '\n' || v_1ch == '\r' ) return null; else if( v_1ch == '\'' ) return 'literal'; else if( v_1ch == '[' ) return 'bname'; else if( v_1ch == '"' ) return 'qname'; else if( v_1ch >= '0' && v_1ch <= '9' ) return 'literal'; else if( v_1ch >= '!' && v_1ch < '0' || v_1ch > '9' && v_1ch < 'A' || v_1ch > 'Z' && v_1ch < 'a' || v_1ch > 'z' && v_1ch <= '~' ) { return this.m_reTokens[iToken]; } else if( this.m_aKeywordTypeMap[this.m_reTokens[iToken].toUpperCase()] ) return this.m_reTokens[iToken].toUpperCase(); else return 'qname'; } C_QanParser.prototype.f_init = function() { if( !C_QanParser.prototype.m_bRulesInitilized ) { C_QanParser.prototype.m_bRulesInitilized = []; C_QanParser.prototype.m_allRules = []; } if( !C_QanParser.prototype.m_bRulesInitilized[this.m_sLang] ) { C_QanParser.prototype.m_docRules = U_XML.F_LoadString( D_XmlError, (this.m_bIsSQL)? v_sSQLParsingRules: v_sMDXParsingRules ); var v_nLang = this.m_docRules.documentElement; C_QanParser.prototype.m_allRules[this.m_sLang] = []; var v_aRules = C_QanParser.prototype.m_allRules[this.m_sLang]; var v_nRule = v_nLang.firstChild; for( ; v_nRule; v_nRule = v_nRule.nextSibling ) v_aRules[v_nRule.getAttribute("type")] = v_nRule; C_QanParser.prototype.m_nRootRule = v_aRules[v_nLang.getAttribute("rootRule")]; C_QanParser.prototype.m_bRulesInitilized[this.m_sLang] = true; } this.m_rules = C_QanParser.prototype.m_allRules[this.m_sLang]; return C_QanParser.prototype.m_nRootRule[this.m_sLang]; } C_QanParser.prototype.F_TransformExprToXML = function( sText ) { return this.F_TransformBlockToXML( sText, "expr" ); } C_QanParser.prototype.m_bLog = false; C_QanParser.prototype.F_TransformBlockToXML = function( sText, sRootRule, sLang ) { if( C_QanParser.prototype.m_bLog ) { this.m_logDoc = U_XML.F_LoadString( D_XmlError, '' ); this.m_nCurRuleLog = this.m_logDoc.documentElement; } this.m_bIsSQL = ( !sLang || sLang == "SQL" ); this.m_sLang = ( this.m_bIsSQL )? "SQL": "MDX"; this.m_aKeywordTypeMap = (this.m_bIsSQL)? G_SQLKeywordTypeMap : G_MDXKeywordTypeMap ; this.m_bRemoveNonTags = true; this.f_init(); this.m_iMisses = 0; this.f_breakIntoTokens( sText ); this.f_initTokenTypes(); this.m_docParsed = U_XML.F_LoadString( D_XmlError, '
' ); var v_aParsedTerms = []; this.m_iStartToken = 0; var aRuleStack = []; if( !this.f_applyRule( this.m_rules[sRootRule], v_aParsedTerms, 0, aRuleStack ) ) return sText; if( this.m_iStartToken < this.m_reTokens.length - 1 ) return sText; if( v_aParsedTerms.length == 1 ) return v_aParsedTerms[0]; else return sText; }