public static bool TryParseNode(Genero4glParser parser, out IfBlockContentsNode node, IModuleResult containingModule, List <Func <PrepareStatement, bool> > prepStatementBinders, Func <ReturnStatement, ParserResult> returnStatementBinder = null, Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null, List <TokenKind> validExitKeywords = null, IEnumerable <ContextStatementFactory> contextStatementFactories = null, ExpressionParsingOptions expressionOptions = null, HashSet <TokenKind> endKeywords = null) { node = new IfBlockContentsNode(); node.StartIndex = parser.Token.Span.Start; prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); while (!parser.PeekToken(TokenKind.EndOfFile) && !parser.PeekToken(TokenKind.ElseKeyword) && !(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.IfKeyword, 2))) { FglStatement statement; if (parser.StatementFactory.TryParseNode(parser, out statement, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, false, validExitKeywords, contextStatementFactories, expressionOptions, endKeywords)) { AstNode4gl stmtNode = statement as AstNode4gl; if (stmtNode != null && !node.Children.ContainsKey(stmtNode.StartIndex)) { node.Children.Add(stmtNode.StartIndex, stmtNode); } } else if (parser.PeekToken(TokenKind.EndKeyword) && endKeywords != null && endKeywords.Contains(parser.PeekToken(2).Kind)) { break; } else { parser.NextToken(); } } prepStatementBinders.RemoveAt(0); node.EndIndex = parser.Token.Span.End; return(true); }
public static bool TryParseNode(Genero4glParser parser, out IfStatement node, IModuleResult containingModule, List <Func <PrepareStatement, bool> > prepStatementBinders, Func <ReturnStatement, ParserResult> returnStatementBinder = null, Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null, List <TokenKind> validExitKeywords = null, IEnumerable <ContextStatementFactory> contextStatementFactories = null, ExpressionParsingOptions expressionOptions = null, HashSet <TokenKind> endKeywords = null) { node = null; bool result = false; if (parser.PeekToken(TokenKind.IfKeyword)) { result = true; node = new IfStatement(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; ExpressionNode conditionExpr; if (!FglExpressionNode.TryGetExpressionNode(parser, out conditionExpr, new List <TokenKind> { TokenKind.ThenKeyword }, expressionOptions)) { parser.ReportSyntaxError("An if statement must have a condition expression."); } else { node.ConditionExpression = conditionExpr; } if (parser.PeekToken(TokenKind.ThenKeyword)) { parser.NextToken(); node.DecoratorEnd = parser.Token.Span.End; HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>(); if (endKeywords != null) { newEndKeywords.AddRange(endKeywords); } newEndKeywords.Add(TokenKind.IfKeyword); IfBlockContentsNode ifBlock; prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); if (IfBlockContentsNode.TryParseNode(parser, out ifBlock, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, expressionOptions, newEndKeywords)) { if (ifBlock != null) { node.Children.Add(ifBlock.StartIndex, ifBlock); } } if (parser.PeekToken(TokenKind.ElseKeyword)) { parser.NextToken(); ElseBlockContentsNode elseBlock; if (ElseBlockContentsNode.TryParseNode(parser, out elseBlock, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, expressionOptions, newEndKeywords)) { if (elseBlock != null) { node.Children.Add(elseBlock.StartIndex, elseBlock); // Add the span of "else" to the additional decorators node.AdditionalDecoratorRanges.Add(elseBlock.StartIndex, elseBlock.StartIndex + 4); } } } prepStatementBinders.RemoveAt(0); if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.IfKeyword, 2))) { parser.ReportSyntaxError("An if statement must be terminated with \"end if\"."); } else { parser.NextToken(); // advance to the 'end' token parser.NextToken(); // advance to the 'if' token node.EndIndex = parser.Token.Span.End; } } else { parser.ReportSyntaxError("An if statement must have a \"then\" keyword prior to containing code."); } } return(result); }