public static bool TryParseNode(IParser parser, out OutputToReportStatement node) { node = null; bool result = false; if (parser.PeekToken(TokenKind.OutputKeyword) && parser.PeekToken(TokenKind.ToKeyword, 2) && parser.PeekToken(TokenKind.ReportKeyword, 3)) { result = true; parser.NextToken(); node = new OutputToReportStatement(); node.StartIndex = parser.Token.Span.Start; parser.NextToken(); parser.NextToken(); FunctionCallExpressionNode reportCall; FglNameExpression dummyName; if (FunctionCallExpressionNode.TryParseExpression(parser, out reportCall, out dummyName, true)) { node.ReportCall = reportCall; } else { parser.ReportSyntaxError("Invalid report call found in output statement."); } node.EndIndex = parser.Token.Span.End; } return(result); }
public static bool TryParseNode(Genero4glParser parser, out CallStatement node) { node = null; bool result = false; if (parser.PeekToken(TokenKind.CallKeyword)) { result = true; node = new CallStatement(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; // get the function name FunctionCallExpressionNode functionCall; FglNameExpression dummy; if (!FunctionCallExpressionNode.TryParseExpression(parser, out functionCall, out dummy, true)) { parser.ReportSyntaxError("Unexpected token found in call statement, expecting name expression."); } else { node.Function = functionCall; if (parser.PeekToken(TokenKind.ReturningKeyword)) { parser.NextToken(); FglNameExpression name; // get return values while (FglNameExpression.TryParseNode(parser, out name, TokenKind.Comma)) { node.Returns.Add(name); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } if (node.Returns.Count == 0) { parser.ReportSyntaxError("One or more return variables must be specified."); } } node.EndIndex = parser.Token.Span.End; } } return(result); }
public static bool TryParseExpression(IParser parser, out FunctionCallExpressionNode node, out FglNameExpression nonFunctionCallName, bool leftParenRequired = false, ExpressionParsingOptions options = null) { if (options == null) { options = new ExpressionParsingOptions(); } node = null; nonFunctionCallName = null; bool result = false; FglNameExpression name; if (FglNameExpression.TryParseNode(parser, out name, TokenKind.LeftParenthesis)) { node = new FunctionCallExpressionNode(); node.StartIndex = name.StartIndex; node.Function = name; // get the left paren if (parser.PeekToken(TokenKind.LeftParenthesis)) { result = true; parser.NextToken(); if (!options.AllowAnythingForFunctionParams) { // Parameters can be any expression, comma seperated ExpressionNode expr; while (FglExpressionNode.TryGetExpressionNode(parser, out expr, new List <TokenKind> { TokenKind.Comma, TokenKind.RightParenthesis }, options)) { node.Parameters.Add(expr); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } // get the right paren if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); // TODO: not sure if this is needed } else { parser.ReportSyntaxError("Call statement missing right parenthesis."); } if (parser.PeekToken(TokenKind.Dot)) { parser.NextToken(); // get the dotted member access (which could end up being another function call, so this needs to allow recursion) if (parser.PeekToken(TokenKind.Multiply)) { parser.NextToken(); node.Children.Add(parser.Token.Span.Start, new TokenExpressionNode(parser.Token)); } else { FunctionCallExpressionNode funcCall; FglNameExpression nonFuncCallName; if (FunctionCallExpressionNode.TryParseExpression(parser, out funcCall, out nonFuncCallName, false, options)) { node.Children.Add(funcCall.StartIndex, funcCall); } else if (nonFuncCallName != null) { node.Children.Add(nonFuncCallName.StartIndex, nonFuncCallName); } else { parser.NextToken(); node.Children.Add(parser.Token.Span.Start, new TokenExpressionNode(parser.Token)); } } } } else { // just int rightParenLevel = 1; Token tok; bool done = false; while (true) { tok = parser.NextToken(); switch (tok.Kind) { case TokenKind.LeftParenthesis: rightParenLevel++; break; case TokenKind.RightParenthesis: rightParenLevel--; if (rightParenLevel == 0) { done = true; } break; case TokenKind.EndOfFile: done = true; break; default: node.AnythingParameters.Add(tok); break; } if (done) { break; } } } node.EndIndex = parser.Token.Span.End; } else { if (leftParenRequired) { result = true; parser.ReportSyntaxError("Call statement missing left parenthesis."); } else { nonFunctionCallName = name; node = null; } } } return(result); }
public static bool TryGetExpressionNode(IParser parser, out ExpressionNode node, List <TokenKind> breakTokens = null, ExpressionParsingOptions options = null) { if (options == null) { options = new ExpressionParsingOptions(); } node = null; bool result = false; bool start = true; bool requireExpression = false; TokenExpressionNode startingToken = null; while (true) { // First check for allowed pre-expression tokens if (_preExpressionTokens.Contains(parser.PeekToken().Kind)) { parser.NextToken(); if (node == null) { node = new TokenExpressionNode(parser.Token); } else { node.AppendExpression(new TokenExpressionNode(parser.Token)); } requireExpression = true; } if (parser.PeekToken(TokenKind.LeftParenthesis)) { ParenWrappedExpressionNode parenExpr; if (ParenWrappedExpressionNode.TryParseExpression(parser, out parenExpr, options)) { if (node == null) { node = parenExpr; } else { node.AppendExpression(parenExpr); } result = true; } else { parser.ReportSyntaxError("Paren-nested expression expected."); } } else if (parser.PeekToken(TokenKind.LeftBracket)) { BracketWrappedExpressionNode brackNode; if (BracketWrappedExpressionNode.TryParseNode(parser, out brackNode)) { if (node == null) { node = brackNode; } else { node.AppendExpression(brackNode); } result = true; } else { parser.ReportSyntaxError("Bracket-nested expression expected."); } } else if (parser.PeekToken(TokenCategory.StringLiteral) || parser.PeekToken(TokenCategory.CharacterLiteral) || parser.PeekToken(TokenCategory.IncompleteMultiLineStringLiteral)) { result = true; parser.NextToken(); if (node == null) { node = new StringExpressionNode(parser.Token); } else { node.AppendExpression(new StringExpressionNode(parser.Token)); } } else if (parser.PeekToken(TokenCategory.NumericLiteral)) { result = true; parser.NextToken(); if (node == null) { node = new TokenExpressionNode(parser.Token); } else { node.AppendExpression(new TokenExpressionNode(parser.Token)); } } else if (parser.PeekToken(TokenKind.CurrentKeyword)) { result = true; parser.NextToken(); int currentExprStart = parser.Token.Span.Start; string currentTypeConstraint; if (TypeConstraints.VerifyValidConstraint(parser, out currentTypeConstraint, TokenKind.CurrentKeyword, true)) { result = true; StringExpressionNode strExpr = new StringExpressionNode(string.Format("current {0}", currentTypeConstraint)); strExpr.StartIndex = currentExprStart; strExpr.EndIndex = parser.Token.Span.End; if (node == null) { node = strExpr; } else { node.AppendExpression(strExpr); } } else { if (node == null) { node = new TokenExpressionNode(parser.Token); } else { node.AppendExpression(new TokenExpressionNode(parser.Token)); } } } else if (parser.PeekToken(TokenKind.IntervalKeyword)) { parser.NextToken(); TokenExpressionNode intervalNode = new TokenExpressionNode(parser.Token); if (node == null) { node = intervalNode; } else { node.AppendExpression(intervalNode); } if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); while (!parser.PeekToken(TokenKind.EndOfFile)) { parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); if (parser.Token.Token.Kind == TokenKind.RightParenthesis) { break; } } string intervalString; if (TypeConstraints.VerifyValidConstraint(parser, out intervalString, TokenKind.IntervalKeyword, true)) { result = true; node.AppendExpression(new StringExpressionNode(intervalString)); } else { parser.ReportSyntaxError("Invalid interval expression found."); } } } else if (parser.PeekToken(TokenKind.SelectKeyword) && options.AllowNestedSelectStatement) { FglStatement selStmt; bool dummy; if (SqlStatementFactory.TryParseSqlStatement(parser, out selStmt, out dummy)) { result = true; if (node == null) { node = new FglStatementExpression(selStmt); } else { node.AppendExpression(new FglStatementExpression(selStmt)); } } else { parser.ReportSyntaxError("Invalid select statement found in expression."); } } else if (parser.PeekToken(TokenCategory.Identifier) || parser.PeekToken(TokenCategory.Keyword)) { bool isCustomExpression = false; if (options != null && options.AdditionalExpressionParsers != null) { ExpressionNode parsedExpr; foreach (var exprParser in options.AdditionalExpressionParsers) { if ((parsedExpr = exprParser(parser)) != null) { result = true; if (node == null) { node = parsedExpr; } else { node.AppendExpression(parsedExpr); } isCustomExpression = true; } } } if (!isCustomExpression) { FunctionCallExpressionNode funcCall; FglNameExpression nonFuncCallName; if (FunctionCallExpressionNode.TryParseExpression(parser, out funcCall, out nonFuncCallName, false, options)) { result = true; if (node == null) { node = funcCall; } else { node.AppendExpression(funcCall); } } else if (nonFuncCallName != null) { bool isDatetime = false; var dtToken = Tokens.GetToken(nonFuncCallName.Name); if (dtToken != null) { if (TypeConstraints.DateTimeQualifiers.Contains(dtToken.Kind)) { string dtString; isDatetime = true; if (TypeConstraints.VerifyValidConstraint(parser, out dtString, TokenKind.DatetimeKeyword, true, dtToken.Kind)) { result = true; var strExpr = new StringExpressionNode(dtString); if (node == null) { node = strExpr; } else { node.AppendExpression(strExpr); } } else { isDatetime = false; } } } if (!isDatetime) { // it's a name expression result = true; if (node == null) { node = nonFuncCallName; } else { node.AppendExpression(nonFuncCallName); } } } else { result = true; parser.NextToken(); if (node == null) { node = new TokenExpressionNode(parser.Token); } else { node.AppendExpression(new TokenExpressionNode(parser.Token)); } } } } else if (parser.PeekToken(TokenKind.Multiply) && options.AllowStarParam) { result = true; parser.NextToken(); if (node == null) { node = new TokenExpressionNode(parser.Token); } else { node.AppendExpression(new TokenExpressionNode(parser.Token)); } } else if (parser.PeekToken(TokenKind.QuestionMark) && options.AllowQuestionMark) { parser.NextToken(); if (node == null) { parser.ReportSyntaxError("Invalid token '?' found in expression."); } else { node.AppendExpression(new TokenExpressionNode(parser.Token)); } } else { if (requireExpression) { var tok = parser.PeekToken(); if (breakTokens != null && !breakTokens.Contains(tok.Kind)) { parser.ReportSyntaxError("Invalid token type found in expression."); } else { parser.ReportSyntaxError("Expression required."); } } break; } requireExpression = false; Token nextTok = parser.PeekToken(); bool isOperator = true; while (isOperator && !requireExpression) { if ((breakTokens == null || (breakTokens != null && !breakTokens.Contains(nextTok.Kind))) && nextTok.Kind >= TokenKind.FirstOperator && nextTok.Kind <= TokenKind.LastOperator) { parser.NextToken(); // TODO: not sure if we want to do more analysis on what operators can start an expression if (node == null) { node = new TokenExpressionNode(parser.Token); } else { node.AppendExpression(new TokenExpressionNode(parser.Token)); } switch (parser.Token.Token.Kind) { case TokenKind.LessThan: // check for '<=' or '<>' if (parser.PeekToken(TokenKind.Equals) || parser.PeekToken(TokenKind.GreaterThan)) { parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); } break; case TokenKind.GreaterThan: // check for '>=' if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); } break; case TokenKind.Exclamation: // check for '!=' if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); } else { parser.ReportSyntaxError("Invalid token '!' found in expression."); } break; case TokenKind.Equals: // check for '==' if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); } break; case TokenKind.SingleBar: // check for '||' if (parser.PeekToken(TokenKind.SingleBar)) { parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); } else { parser.ReportSyntaxError("Invalid token '|' found in expression."); } break; } requireExpression = true; } else { // check for non-symbol operators switch (nextTok.Kind) { case TokenKind.DoubleBar: case TokenKind.AsKeyword: case TokenKind.AndKeyword: case TokenKind.OrKeyword: case TokenKind.ModKeyword: case TokenKind.UsingKeyword: case TokenKind.InstanceOfKeyword: case TokenKind.UnitsKeyword: case TokenKind.LikeKeyword: case TokenKind.MatchesKeyword: case TokenKind.ThroughKeyword: case TokenKind.ThruKeyword: case TokenKind.BetweenKeyword: { // require another expression requireExpression = true; parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); } break; case TokenKind.ClippedKeyword: case TokenKind.SpacesKeyword: { parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); } break; case TokenKind.IsKeyword: { parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); if (parser.PeekToken(TokenKind.NotKeyword)) { parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); } if (parser.PeekToken(TokenKind.NullKeyword)) { parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); } else { parser.ReportSyntaxError("NULL keyword required in expression."); } } break; case TokenKind.NotKeyword: { parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); if (parser.PeekToken(TokenKind.LikeKeyword) || parser.PeekToken(TokenKind.MatchesKeyword) || parser.PeekToken(TokenKind.InKeyword)) { // require another expression requireExpression = true; parser.NextToken(); node.AppendExpression(new TokenExpressionNode(parser.Token)); } else { parser.ReportSyntaxError("LIKE or MATCHES keyword required in expression."); } } break; default: { isOperator = false; break; } } if (!isOperator) { break; } else { nextTok = parser.PeekToken(); if (nextTok.Kind == TokenKind.EndOfFile) { break; } } } } if (!requireExpression) { break; } } if (result && node != null) { node.EndIndex = parser.Token.Span.End; } return(result); }