public static bool TryParseNode(Genero4glParser parser, out InputAttribute node, bool isArray) { node = new InputAttribute(); node.StartIndex = parser.Token.Span.Start; bool result = true; switch (parser.PeekToken().Kind) { case TokenKind.BlackKeyword: case TokenKind.BlueKeyword: case TokenKind.CyanKeyword: case TokenKind.GreenKeyword: case TokenKind.MagentaKeyword: case TokenKind.RedKeyword: case TokenKind.WhiteKeyword: case TokenKind.YellowKeyword: case TokenKind.BoldKeyword: case TokenKind.DimKeyword: case TokenKind.InvisibleKeyword: case TokenKind.NormalKeyword: case TokenKind.ReverseKeyword: case TokenKind.BlinkKeyword: case TokenKind.UnderlineKeyword: parser.NextToken(); break; case TokenKind.AcceptKeyword: case TokenKind.CancelKeyword: case TokenKind.UnbufferedKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); ExpressionNode boolExpr; if (!FglExpressionNode.TryGetExpressionNode(parser, out boolExpr, new List <TokenKind> { TokenKind.Comma, TokenKind.RightParenthesis })) { parser.ReportSyntaxError("Invalid boolean expression found in input attribute."); } } break; } case TokenKind.CountKeyword: case TokenKind.MaxCountKeyword: { if (isArray) { parser.NextToken(); if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); ExpressionNode boolExpr; if (!FglExpressionNode.TryGetExpressionNode(parser, out boolExpr, new List <TokenKind> { TokenKind.Comma, TokenKind.RightParenthesis })) { parser.ReportSyntaxError("Invalid expression found in input attribute."); } } else { parser.ReportSyntaxError("Expected integer expression in input array attribute."); } } else { parser.ReportSyntaxError("Attribute can only be used for an input array statement."); } break; } case TokenKind.WithoutKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.DefaultsKeyword)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected \"defaults\" keyword in input attribute."); } if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); ExpressionNode boolExpr; if (!FglExpressionNode.TryGetExpressionNode(parser, out boolExpr, new List <TokenKind> { TokenKind.Comma, TokenKind.RightParenthesis })) { parser.ReportSyntaxError("Invalid boolean expression found in input attribute."); } } break; } case TokenKind.HelpKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected equals token in input attribute."); } // get the help number ExpressionNode optionNumber; if (!FglExpressionNode.TryGetExpressionNode(parser, out optionNumber)) { parser.ReportSyntaxError("Invalid help-number found in input attribute."); } break; } case TokenKind.NameKeyword: { if (!isArray) { parser.NextToken(); if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected equals token in input attribute."); } // get the help number ExpressionNode optionNumber; if (!FglExpressionNode.TryGetExpressionNode(parser, out optionNumber)) { parser.ReportSyntaxError("Invalid dialog name found in input attribute."); } } else { parser.ReportSyntaxError("The name attribute can only be used for an input statement (not an input array statement)."); } break; } case TokenKind.FieldKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.OrderKeyword)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected \"order\" keyword in input attribute."); } if (parser.PeekToken(TokenKind.FormKeyword)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected \"form\" keyword in input attribute."); } break; } case TokenKind.AppendKeyword: case TokenKind.DeleteKeyword: case TokenKind.InsertKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.RowKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); ExpressionNode boolExpr; if (!FglExpressionNode.TryGetExpressionNode(parser, out boolExpr, new List <TokenKind> { TokenKind.Comma, TokenKind.RightParenthesis })) { parser.ReportSyntaxError("Invalid boolean expression found in input array attribute."); } } } else { parser.ReportSyntaxError("Expected \"row\" keyword in input array attribute."); } break; } case TokenKind.KeepKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.CurrentKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.RowKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); ExpressionNode boolExpr; if (!FglExpressionNode.TryGetExpressionNode(parser, out boolExpr, new List <TokenKind> { TokenKind.Comma, TokenKind.RightParenthesis })) { parser.ReportSyntaxError("Invalid boolean expression found in input array attribute."); } } } else { parser.ReportSyntaxError("Expected \"row\" keyword in input array attribute."); } } else { parser.ReportSyntaxError("Expected \"current\" keyword in input array attribute."); } break; } case TokenKind.AutoKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.AppendKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); ExpressionNode boolExpr; if (!FglExpressionNode.TryGetExpressionNode(parser, out boolExpr, new List <TokenKind> { TokenKind.Comma, TokenKind.RightParenthesis })) { parser.ReportSyntaxError("Invalid boolean expression found in input array attribute."); } } } else { parser.ReportSyntaxError("Expected \"append\" keyword in input array attribute."); } break; } default: result = false; break; } if (result && node != null) { node.EndIndex = parser.Token.Span.End; } return(result); }
public static bool TryParseNode(Genero4glParser parser, out InputBlock 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, HashSet <TokenKind> endKeywords = null) { node = null; bool result = false; if (parser.PeekToken(TokenKind.InputKeyword)) { result = true; node = new InputBlock(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; node.VariableList = new List <FglNameExpression>(); node.FieldList = new List <FglNameExpression>(); node.Attributes = new List <InputAttribute>(); if (parser.PeekToken(TokenKind.ByKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.NameKeyword)) { parser.NextToken(); // Implicit field mapping node.IsImplicitMapping = true; } else { parser.ReportSyntaxError("Expected \"name\" token in input statement."); } } else if (parser.PeekToken(TokenKind.ArrayKeyword)) { parser.NextToken(); node.IsArray = true; FglNameExpression arrName; if (FglNameExpression.TryParseNode(parser, out arrName)) { node.ArrayName = arrName; } else { parser.ReportSyntaxError("Invalid array name found in input statement."); } } node.DecoratorEnd = parser.Token.Span.End; FglNameExpression nameExpr; if (!node.IsArray) { // read the variable list while (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.VariableList.Add(nameExpr); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } } if (parser.PeekToken(TokenKind.WithoutKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.DefaultsKeyword)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected \"defaults\" token in input statement."); } } if (!node.IsImplicitMapping || node.IsArray) { if (parser.PeekToken(TokenKind.FromKeyword)) { parser.NextToken(); // read the field list while (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.FieldList.Add(nameExpr); if (node.IsArray || !parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } } else { parser.ReportSyntaxError("Expected \"from\" token in input statement."); } } if (parser.PeekToken(TokenKind.AttributesKeyword) || parser.PeekToken(TokenKind.AttributeKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); // get the list of display or control attributes InputAttribute attrib; while (InputAttribute.TryParseNode(parser, out attrib, node.IsArray)) { node.Attributes.Add(attrib); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expecting right-paren in input attributes section."); } } else { parser.ReportSyntaxError("Expecting left-paren in input attributes section."); } } if (parser.PeekToken(TokenKind.HelpKeyword)) { parser.NextToken(); // get the help number ExpressionNode optionNumber; if (FglExpressionNode.TryGetExpressionNode(parser, out optionNumber)) { node.HelpNumber = optionNumber; } else { parser.ReportSyntaxError("Invalid help-number found in input statement."); } } List <TokenKind> validExits = new List <TokenKind>(); if (validExitKeywords != null) { validExits.AddRange(validExits); } validExits.Add(TokenKind.InputKeyword); HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>(); if (endKeywords != null) { newEndKeywords.AddRange(endKeywords); } newEndKeywords.Add(TokenKind.InputKeyword); bool hasControlBlocks = false; InputControlBlock icb; prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); while (InputControlBlock.TryParseNode(parser, out icb, containingModule, hasControlBlocks, node.IsArray, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExits, contextStatementFactories, newEndKeywords) && icb != null) { if (icb.StartIndex < 0) { continue; } node.Children.Add(icb.StartIndex, icb); hasControlBlocks = true; if (parser.PeekToken(TokenKind.EndOfFile) || (parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.InputKeyword, 2))) { break; } } prepStatementBinders.RemoveAt(0); if (hasControlBlocks || (parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.InputKeyword, 2))) { if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.InputKeyword, 2))) { parser.ReportSyntaxError("A input block must be terminated with \"end input\"."); } else { parser.NextToken(); // advance to the 'end' token parser.NextToken(); // advance to the 'input' token node.EndIndex = parser.Token.Span.End; } } } return(result); }