/****************************************************************************************************************************
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;
}