public static bool TryParseNode(IParser parser, out TerminateReportStatement node) { node = null; bool result = false; if (parser.PeekToken(TokenKind.TerminateKeyword) && parser.PeekToken(TokenKind.ReportKeyword, 2)) { result = true; node = new TerminateReportStatement(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; parser.NextToken(); FglNameExpression rptName; if (FglNameExpression.TryParseNode(parser, out rptName)) { node.ReportName = rptName; } else { parser.ReportSyntaxError("Invalid report name found in terminate report driver."); } node.EndIndex = parser.Token.Span.End; } return(result); }
public static bool TryParseNode(Genero4glParser parser, out CloseStatement node) { node = null; bool result = false; if (parser.PeekToken(TokenKind.CloseKeyword)) { result = true; node = new CloseStatement(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; FglNameExpression cid; if (FglNameExpression.TryParseNode(parser, out cid)) { node.CursorId = cid; } else { parser.ReportSyntaxError("Invalid declared cursor id found in close statement."); } node.EndIndex = parser.Token.Span.End; } return(result); }
public static bool TryParseNode(Genero4glParser parser, out FreeStatement defNode) { defNode = null; bool result = false; if (parser.PeekToken(TokenKind.FreeKeyword)) { result = true; defNode = new FreeStatement(); parser.NextToken(); defNode.StartIndex = parser.Token.Span.Start; FglNameExpression expr; if (!FglNameExpression.TryParseNode(parser, out expr)) { parser.ReportSyntaxError("Invalid name found in free statement."); } else { defNode.Target = expr; } defNode.EndIndex = parser.Token.Span.End; } return(result); }
public static bool TryParseNode(Genero4glParser parser, out ClearStatement node) { node = null; bool result = false; if (parser.PeekToken(TokenKind.ClearKeyword)) { result = true; node = new ClearStatement(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; node.FieldList = new List <FglNameExpression>(); // get the bynamefields FglNameExpression nameExpr; while (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.FieldList.Add(nameExpr); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } if (node.FieldList.Count == 0) { parser.ReportSyntaxError("Incomplete clear statement found."); } node.EndIndex = parser.Token.Span.End; } return(result); }
public static bool TryParseNode(Genero4glParser parser, out GotoStatement node) { node = null; bool result = false; if (parser.PeekToken(TokenKind.GotoKeyword)) { result = true; node = new GotoStatement(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; // colon is optional if (parser.PeekToken(TokenKind.Colon)) { parser.NextToken(); } FglNameExpression expr; if (!FglNameExpression.TryParseNode(parser, out expr)) { parser.ReportSyntaxError("Invalid name found in goto statement."); } else { node.LabelId = expr; } node.EndIndex = parser.Token.Span.End; } return(result); }
public static bool TryParseNode(IParser parser, out FglNameExpression node, TokenKind breakToken = TokenKind.EndOfFile) { node = null; bool result = false; if (parser.PeekToken(TokenCategory.Identifier) || parser.PeekToken(TokenCategory.Keyword)) { result = true; node = new FglNameExpression(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; node._firstPiece = parser.Token.Token.Value.ToString(); StringBuilder sb = new StringBuilder(node._firstPiece); node.EndIndex = parser.Token.Span.End; while (true) { if (breakToken != TokenKind.EndOfFile && parser.PeekToken(breakToken)) { break; } MemberAccessNameExpressionPiece memberAccess; ArrayIndexFglNameExpressionPiece arrayIndex; if (MemberAccessNameExpressionPiece.TryParse(parser, out memberAccess) && memberAccess != null) { node.Children.Add(memberAccess.StartIndex, memberAccess); node.EndIndex = memberAccess.EndIndex; node.IsComplete = true; sb.Append(memberAccess.ToString()); } else if (ArrayIndexFglNameExpressionPiece.TryParse(parser, out arrayIndex, breakToken) && arrayIndex != null) { node.Children.Add(arrayIndex.StartIndex, arrayIndex); node.EndIndex = arrayIndex.EndIndex; node.IsComplete = true; sb.Append(arrayIndex.ToString()); } else if (parser.PeekToken(TokenKind.AtSymbol)) { parser.NextToken(); sb.Append("@"); if (parser.PeekToken(TokenCategory.Identifier) || parser.PeekToken(TokenCategory.Keyword)) { sb.Append(parser.NextToken().Value.ToString()); } } else { break; } } node.Name = sb.ToString(); } return(result); }
public static bool TryParseNode(Genero4glParser parser, out LocateStatement defNode) { defNode = null; bool result = false; if (parser.PeekToken(TokenKind.LocateKeyword)) { result = true; defNode = new LocateStatement(); parser.NextToken(); defNode.StartIndex = parser.Token.Span.Start; defNode.TargetVariables = new List <FglNameExpression>(); FglNameExpression name; while (FglNameExpression.TryParseNode(parser, out name)) { defNode.TargetVariables.Add(name); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } if (parser.PeekToken(TokenKind.InKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.MemoryKeyword)) { parser.NextToken(); defNode.Location = LocateLocation.Memory; } else if (parser.PeekToken(TokenKind.FileKeyword)) { parser.NextToken(); defNode.Location = LocateLocation.File; ExpressionNode filename; if (FglExpressionNode.TryGetExpressionNode(parser, out filename, Genero4glAst.ValidStatementKeywords.ToList())) { defNode.Filename = filename; } } else { parser.ReportSyntaxError("Locate statement can only specify memory or a file."); } } else { parser.ReportSyntaxError("Locate statement missing \"in\" keyword."); } defNode.EndIndex = parser.Token.Span.End; } return(result); }
public static bool TryParseNode(Genero4glParser parser, out ValidateStatement defNode) { defNode = null; bool result = false; if (parser.PeekToken(TokenKind.ValidateKeyword)) { result = true; defNode = new ValidateStatement(); parser.NextToken(); defNode.StartIndex = parser.Token.Span.Start; FglNameExpression name; while (FglNameExpression.TryParseNode(parser, out name)) { defNode.TargetVariables.Add(name); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } if (parser.PeekToken(TokenKind.LikeKeyword)) { parser.NextToken(); defNode.TableName = parser.Token.Token.Value.ToString(); parser.NextToken(); // advance to the dot if (parser.Token.Token.Kind == TokenKind.Dot) { if (parser.PeekToken(TokenKind.Multiply) || parser.PeekToken(TokenCategory.Identifier) || parser.PeekToken(TokenCategory.Keyword)) { parser.NextToken(); // advance to the column name defNode.ColumnName = parser.Token.Token.Value.ToString(); defNode.IsComplete = true; defNode.EndIndex = parser.Token.Span.End; } else { parser.ReportSyntaxError("Invalid validation form detected."); } } else { parser.ReportSyntaxError("Invalid validation form detected."); } } else { parser.ReportSyntaxError("Variables can only be validated against a database table spec."); } defNode.EndIndex = parser.Token.Span.End; } return(result); }
public static bool TryParseNode(IParser parser, out PrintxStatement node) { node = null; bool result = false; if (parser.PeekToken(TokenKind.PrintxKeyword)) { result = true; node = new PrintxStatement(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; node.Expressions = new List <ExpressionNode>(); if (parser.PeekToken(TokenKind.NameKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); FglNameExpression name; if (FglNameExpression.TryParseNode(parser, out name)) { node.Name = name; } else { parser.ReportSyntaxError("Invalid name expression found in printx statement."); } } else { parser.ReportSyntaxError("Expected '=' in printx statement."); } } ExpressionNode expr; while (FglExpressionNode.TryGetExpressionNode(parser, out expr)) { node.Expressions.Add(expr); if (parser.PeekToken(TokenKind.Comma)) { parser.NextToken(); } else { break; } } 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); }
internal static bool TryParseNode(Genero4glParser parser, out CreateSequenceStatement node) { node = null; bool result = false; if (parser.PeekToken(TokenKind.SequenceKeyword)) { result = true; node = new CreateSequenceStatement(); node.StartIndex = parser.Token.Span.Start; // want to get the start of the create token parser.NextToken(); if (parser.PeekToken(TokenKind.IfKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.NotKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.ExistsKeyword)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expecting \"exists\" keyword in create sequence statement."); } } else { parser.ReportSyntaxError("Expecting \"not\" keyword in create sequence statement."); } } FglNameExpression nameExpr; if (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.SequenceName = nameExpr; } else { parser.ReportSyntaxError("Invalid name found for create sequence statement."); } // TODO: finish getting the modifiers } return(result); }
public static bool TryParseNode(Genero4glParser parser, out LabelStatement node) { node = null; bool result = false; if (parser.PeekToken(TokenKind.LabelKeyword)) { result = true; node = new LabelStatement(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; FglNameExpression expr; if (!FglNameExpression.TryParseNode(parser, out expr, TokenKind.Colon)) { parser.ReportSyntaxError("Invalid name found in label statement."); } else { node.LabelId = expr; } if (parser.PeekToken(TokenKind.Colon)) { parser.NextToken(); } else { parser.ReportSyntaxError("Label statement requires a colon at the end."); } node.EndIndex = parser.Token.Span.End; } return(result); }
public static bool TryParseNode(Genero4glParser parser, out ConstructBlock 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.ConstructKeyword)) { result = true; node = new ConstructBlock(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; node.ColumnList = new List <FglNameExpression>(); node.FieldList = new List <FglNameExpression>(); node.Attributes = new List <ConstructAttribute>(); 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 construct statement."); } } FglNameExpression varName; if (FglNameExpression.TryParseNode(parser, out varName)) { node.Variable = varName; } else { parser.ReportSyntaxError("Invalid variable name found in construct statement."); } node.DecoratorEnd = parser.Token.Span.End; if (parser.PeekToken(TokenKind.OnKeyword)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expecting \"on\" keyword in construct statement."); } FglNameExpression colName; while (FglNameExpression.TryParseNode(parser, out colName)) { node.ColumnList.Add(colName); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } if (!node.IsImplicitMapping) { if (parser.PeekToken(TokenKind.FromKeyword)) { parser.NextToken(); // read the field list FglNameExpression nameExpr; while (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.FieldList.Add(nameExpr); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } } else { parser.ReportSyntaxError("Expected \"from\" token in construct 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 ConstructAttribute attrib; while (ConstructAttribute.TryParseNode(parser, out attrib)) { 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 construct attributes section."); } } else { parser.ReportSyntaxError("Expecting left-paren in construct 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 construct statement."); } } List <TokenKind> validExits = new List <TokenKind>(); if (validExitKeywords != null) { validExits.AddRange(validExitKeywords); } validExits.Add(TokenKind.ConstructKeyword); HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>(); if (endKeywords != null) { newEndKeywords.AddRange(endKeywords); } newEndKeywords.Add(TokenKind.ConstructKeyword); bool hasControlBlocks = false; ConstructControlBlock icb; prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); while (ConstructControlBlock.TryParseNode(parser, out icb, containingModule, 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.ConstructKeyword, 2))) { break; } } prepStatementBinders.RemoveAt(0); if (hasControlBlocks || (parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.ConstructKeyword, 2))) { if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.ConstructKeyword, 2))) { parser.ReportSyntaxError("A construct block must be terminated with \"end construct\"."); } else { parser.NextToken(); // advance to the 'end' token parser.NextToken(); // advance to the 'construct' token node.EndIndex = parser.Token.Span.End; } } } return(result); }
public static bool TryParseNode(Genero4glParser parser, out ConstructControlBlock 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 = new ConstructControlBlock(); bool result = true; node.StartIndex = parser.Token.Span.Start; node.FieldSpecList = new List <FglNameExpression>(); node.KeyNameList = new List <VirtualKey>(); switch (parser.PeekToken().Kind) { case TokenKind.Ampersand: { // handle include file PreprocessorNode preNode; PreprocessorNode.TryParseNode(parser, out preNode); node.StartIndex = -1; break; } case TokenKind.BeforeKeyword: case TokenKind.AfterKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.FieldKeyword)) { parser.NextToken(); node.Type = ConstructControlBlockType.Field; // get the list of field specs FglNameExpression fieldSpec; while (FglNameExpression.TryParseNode(parser, out fieldSpec)) { node.FieldSpecList.Add(fieldSpec); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } } else if (parser.PeekToken(TokenKind.ConstructKeyword)) { parser.NextToken(); node.Type = ConstructControlBlockType.Construct; } else { parser.ReportSyntaxError("Unexpected token found in construct control block."); result = false; } break; } case TokenKind.OnKeyword: { parser.NextToken(); switch (parser.PeekToken().Kind) { case TokenKind.IdleKeyword: parser.NextToken(); node.Type = ConstructControlBlockType.Idle; // get the idle seconds ExpressionNode idleExpr; if (FglExpressionNode.TryGetExpressionNode(parser, out idleExpr)) { node.IdleSeconds = idleExpr; } else { parser.ReportSyntaxError("Invalid idle-seconds found in construct statement."); } break; case TokenKind.ActionKeyword: parser.NextToken(); node.Type = ConstructControlBlockType.Action; // get the action name FglNameExpression actionName; if (FglNameExpression.TryParseNode(parser, out actionName)) { node.ActionName = actionName; } else { parser.ReportSyntaxError("Invalid action-name found in construct statement."); } if (parser.PeekToken(TokenKind.InfieldKeyword)) { parser.NextToken(); // get the field-spec if (FglNameExpression.TryParseNode(parser, out actionName)) { node.ActionField = actionName; } else { parser.ReportSyntaxError("Invalid field-spec found in construct statement."); } } break; case TokenKind.KeyKeyword: parser.NextToken(); node.Type = ConstructControlBlockType.Key; if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); // get the list of key names VirtualKey keyName; while (VirtualKey.TryGetKey(parser, out keyName)) { node.KeyNameList.Add(keyName); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected right-paren in construct control block."); } } else { parser.ReportSyntaxError("Expected left-paren in construct control block."); } break; default: parser.ReportSyntaxError("Unexpected token found in input control block."); //result = false; break; } break; } default: result = false; break; } if (result && node.StartIndex >= 0) { // get the dialog statements FglStatement inputStmt; prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); while (ConstructDialogStatementFactory.TryGetStatement(parser, out inputStmt, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords) && inputStmt != null) { node.Children.Add(inputStmt.StartIndex, inputStmt); } prepStatementBinders.RemoveAt(0); if (node.Type == ConstructControlBlockType.None && node.Children.Count == 0) { result = false; } } return(result); }
public static bool TryParseNode(Genero4glParser parser, out DialogControlBlock 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 = new DialogControlBlock(); node.StartIndex = parser.Token.Span.Start; node.KeyNames = new List <VirtualKey>(); bool result = true; switch (parser.PeekToken().Kind) { case TokenKind.Ampersand: { // handle include file PreprocessorNode preNode; PreprocessorNode.TryParseNode(parser, out preNode); node.StartIndex = -1; break; } case TokenKind.BeforeKeyword: case TokenKind.AfterKeyword: parser.NextToken(); if (parser.PeekToken(TokenKind.DialogKeyword)) { parser.NextToken(); node.Type = DialogControlBlockType.Dialog; } else { parser.ReportSyntaxError("Expected \"dialog\" keyword in dialog statement."); } break; case TokenKind.CommandKeyword: { parser.NextToken(); node.Type = DialogControlBlockType.Command; if (parser.PeekToken(TokenKind.KeyKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); VirtualKey vKey; while (VirtualKey.TryGetKey(parser, out vKey)) { node.KeyNames.Add(vKey); if (parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } } else { parser.ReportSyntaxError("Expecting left-paren in dialog statement."); } } ExpressionNode FglNameExpression; if (FglExpressionNode.TryGetExpressionNode(parser, out FglNameExpression)) { node.OptionName = FglNameExpression; } else { parser.ReportSyntaxError("Invalid expression found in dialog statement."); } if (!parser.PeekToken(TokenKind.HelpKeyword) && parser.PeekToken(TokenCategory.StringLiteral)) { ExpressionNode commentExpr; if (FglExpressionNode.TryGetExpressionNode(parser, out commentExpr, new List <TokenKind> { TokenKind.HelpKeyword })) { node.OptionComment = commentExpr; } else { parser.ReportSyntaxError("Invalid expression found in dialog statement."); } } if (parser.PeekToken(TokenKind.HelpKeyword)) { parser.NextToken(); ExpressionNode optionNumber; if (FglExpressionNode.TryGetExpressionNode(parser, out optionNumber)) { node.HelpNumber = optionNumber; } else { parser.ReportSyntaxError("Invalid expression found in dialog statement."); } } break; } case TokenKind.OnKeyword: { parser.NextToken(); switch (parser.PeekToken().Kind) { case TokenKind.ActionKeyword: parser.NextToken(); node.Type = DialogControlBlockType.Action; FglNameExpression nameExpr; if (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.ActionName = nameExpr; } else { parser.ReportSyntaxError("Invalid name found in dialog statement."); } break; case TokenKind.KeyKeyword: parser.NextToken(); node.Type = DialogControlBlockType.Key; if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); VirtualKey vKey; while (VirtualKey.TryGetKey(parser, out vKey)) { node.KeyNames.Add(vKey); if (parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } } else { parser.ReportSyntaxError("Expecting left-paren in dialog statement."); } break; case TokenKind.IdleKeyword: parser.NextToken(); node.Type = DialogControlBlockType.Idle; // get the idle seconds ExpressionNode idleExpr; if (FglExpressionNode.TryGetExpressionNode(parser, out idleExpr)) { node.IdleSeconds = idleExpr; } else { parser.ReportSyntaxError("Invalid idle-seconds found in dialog statement."); } break; default: parser.ReportSyntaxError("Unexpected token found in dialog control block."); break; } break; } default: break; } if (result && node.StartIndex >= 0) { // get the dialog statements FglStatement inputStmt; prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); while (DialogStatementFactory.TryGetStatement(parser, out inputStmt, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords) && inputStmt != null) { node.Children.Add(inputStmt.StartIndex, inputStmt); } prepStatementBinders.RemoveAt(0); if (node.Type == DialogControlBlockType.None && node.Children.Count == 0) { result = false; } } return(result); }
internal static void BuildDialogBlock(Genero4glParser parser, DialogBlock 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) { if (parser.PeekToken(TokenKind.AttributeKeyword) || parser.PeekToken(TokenKind.AttributesKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); // get the list of display or control attributes DialogAttribute attrib; while (DialogAttribute.TryParseNode(parser, out attrib)) { 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 dialog attributes section."); } } else { parser.ReportSyntaxError("Expecting left-paren in dialog attributes section."); } } // parse input, construct, display or SUBDIALOG bool moreBlocks = true; List <ContextStatementFactory> csfs = new List <ContextStatementFactory>(); if (contextStatementFactories != null) { csfs.AddRange(contextStatementFactories); } csfs.Add((x) => { DialogStatement testNode; DialogStatementFactory.TryGetDialogStatement(x, out testNode, true); return(testNode); }); prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); while (moreBlocks) { switch (parser.PeekToken().Kind) { case TokenKind.InputKeyword: { InputBlock inputBlock; if (InputBlock.TryParseNode(parser, out inputBlock, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, csfs, endKeywords) && inputBlock != null) { node.Children.Add(inputBlock.StartIndex, inputBlock); } else { parser.ReportSyntaxError("Invalid input block found in dialog statement."); } break; } case TokenKind.ConstructKeyword: { ConstructBlock constructBlock; if (ConstructBlock.TryParseNode(parser, out constructBlock, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, csfs, endKeywords) && constructBlock != null) { node.Children.Add(constructBlock.StartIndex, constructBlock); } else { parser.ReportSyntaxError("Invalid construct block found in dialog statement."); } break; } case TokenKind.DisplayKeyword: { DisplayBlock dispBlock; if (DisplayBlock.TryParseNode(parser, out dispBlock, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, csfs, endKeywords) && dispBlock != null) { node.Children.Add(dispBlock.StartIndex, dispBlock); } else { parser.ReportSyntaxError("Invalid display block found in dialog statement."); } break; } case TokenKind.SubdialogKeyword: { parser.NextToken(); FglNameExpression nameExpr; if (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.Subdialogs.Add(nameExpr); } else { parser.ReportSyntaxError("Invalid subdialog name found in dialog statement."); } break; } default: moreBlocks = false; break; } } prepStatementBinders.RemoveAt(0); List <TokenKind> validExits = new List <TokenKind>(); if (validExitKeywords != null) { validExits.AddRange(validExits); } validExits.Add(TokenKind.DialogKeyword); HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>(); if (endKeywords != null) { newEndKeywords.AddRange(endKeywords); } newEndKeywords.Add(TokenKind.DialogKeyword); // get the dialog control blocks prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); while (!parser.PeekToken(TokenKind.EndOfFile) && !(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.DialogKeyword, 2))) { DialogControlBlock icb; if (DialogControlBlock.TryParseNode(parser, out icb, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExits, contextStatementFactories, newEndKeywords) && icb != null) { if (icb.StartIndex < 0) { continue; } node.Children.Add(icb.StartIndex, icb); } else if (parser.PeekToken(TokenKind.EndKeyword) && endKeywords != null && endKeywords.Contains(parser.PeekToken(2).Kind)) { break; } else { parser.NextToken(); } } prepStatementBinders.RemoveAt(0); }
public static bool TryParseDefine(Genero4glParser parser, out SchemaSpecificationNode defNode) { defNode = null; bool result = false; if (parser.PeekToken(TokenKind.SchemaKeyword)) { defNode = new SchemaSpecificationNode(); parser.NextToken(); defNode.StartIndex = parser.Token.Span.Start; result = true; FglNameExpression nameExp; if (FglNameExpression.TryParseNode(parser, out nameExp)) { defNode.SchemaName = nameExp; defNode.EndIndex = parser.Token.Span.End; } else { StringExpressionNode strExp; if (StringExpressionNode.TryGetExpressionNode(parser, out strExp)) { defNode.SchemaName = nameExp; defNode.EndIndex = parser.Token.Span.End; } else { parser.ReportSyntaxError(defNode.StartIndex, parser.Token.Span.End, "Invalid token type found."); } } } else { if (parser.PeekToken(TokenKind.DescribeKeyword)) { defNode = new SchemaSpecificationNode(); defNode.StartIndex = parser.Token.Span.Start; parser.NextToken(); result = true; } if (parser.PeekToken(TokenKind.DatabaseKeyword)) { if (defNode == null) { defNode = new SchemaSpecificationNode(); defNode.StartIndex = parser.Token.Span.Start; parser.NextToken(); result = true; } parser.NextToken(); parser.NextToken(); FglNameExpression nameExp; if (FglNameExpression.TryParseNode(parser, out nameExp)) { defNode.SchemaName = nameExp; defNode.EndIndex = parser.Token.Span.End; defNode.IsComplete = true; } else { StringExpressionNode strExp; if (StringExpressionNode.TryGetExpressionNode(parser, out strExp)) { defNode.SchemaName = nameExp; defNode.EndIndex = parser.Token.Span.End; defNode.IsComplete = true; } else { parser.ReportSyntaxError(defNode.StartIndex, parser.Token.Span.End, "Invalid token type found."); } } } else if (defNode != null) { parser.ReportSyntaxError(defNode.StartIndex, parser.Token.Span.End, "Legacy schema specification is incomplete."); } } return(result); }
public static bool TryParseNode(Genero4glParser parser, out ForeachStatement 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.ForeachKeyword)) { result = true; node = new ForeachStatement(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; node.InputVars = new List <FglNameExpression>(); node.OutputVars = new List <FglNameExpression>(); FglNameExpression cid; if (FglNameExpression.TryParseNode(parser, out cid)) { node.CursorId = cid; } else { parser.ReportSyntaxError("Invalid declared cursor id found in foreach statement."); } HashSet <TokenKind> inVarMods = new HashSet <TokenKind> { TokenKind.InKeyword, TokenKind.OutKeyword, TokenKind.InOutKeyword }; if (parser.PeekToken(TokenKind.UsingKeyword)) { parser.NextToken(); FglNameExpression inVar; while (FglNameExpression.TryParseNode(parser, out inVar, TokenKind.Comma)) { node.InputVars.Add(inVar); if (inVarMods.Contains(parser.PeekToken().Kind)) { parser.NextToken(); } if (parser.PeekToken(TokenKind.Comma)) { parser.NextToken(); } else { break; } } } if (parser.PeekToken(TokenKind.IntoKeyword)) { parser.NextToken(); FglNameExpression outVar; while (FglNameExpression.TryParseNode(parser, out outVar, TokenKind.Comma)) { node.InputVars.Add(outVar); if (parser.PeekToken(TokenKind.Comma)) { parser.NextToken(); } else { break; } } } node.DecoratorEnd = parser.Token.Span.End; if (parser.PeekToken(TokenKind.WithKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.ReoptimizationKeyword)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expecting keyword \"reoptimization\" in open statement."); } } List <TokenKind> validExits = new List <TokenKind>(); if (validExitKeywords != null) { validExits.AddRange(validExitKeywords); } validExits.Add(TokenKind.ForeachKeyword); HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>(); if (endKeywords != null) { newEndKeywords.AddRange(endKeywords); } newEndKeywords.Add(TokenKind.ForeachKeyword); prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); while (!parser.PeekToken(TokenKind.EndOfFile) && !(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.ForeachKeyword, 2))) { FglStatement statement; if (parser.StatementFactory.TryParseNode(parser, out statement, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, false, validExits, contextStatementFactories, null, newEndKeywords) && statement != null) { AstNode4gl stmtNode = statement as AstNode4gl; node.Children.Add(stmtNode.StartIndex, stmtNode); if (statement is ExitStatement && (statement as ExitStatement).ExitType != TokenKind.ForeachKeyword) { if (validExitKeywords == null || !validExitKeywords.Contains((statement as ExitStatement).ExitType)) { parser.ReportSyntaxError("Invalid exit statement for for loop detected."); } } if (statement is ContinueStatement && (statement as ContinueStatement).ContinueType != TokenKind.ForeachKeyword) { if (validExitKeywords == null || !validExitKeywords.Contains((statement as ContinueStatement).ContinueType)) { parser.ReportSyntaxError("Invalid continue statement for for loop detected."); } } } else if (parser.PeekToken(TokenKind.EndKeyword) && endKeywords != null && endKeywords.Contains(parser.PeekToken(2).Kind)) { break; } else { parser.NextToken(); } } prepStatementBinders.RemoveAt(0); if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.ForeachKeyword, 2))) { parser.ReportSyntaxError("A foreach statement must be terminated with \"end foreach\"."); } else { parser.NextToken(); // advance to the 'end' token parser.NextToken(); // advance to the 'foreach' token node.EndIndex = parser.Token.Span.End; } } return(result); }
public static bool TryParseNode(Genero4glParser parser, out ExecuteStatement node) { node = null; bool result = false; if (parser.PeekToken(TokenKind.ExecuteKeyword)) { result = true; node = new ExecuteStatement(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; node.InputVars = new List <ExpressionNode>(); node.OutputVars = new List <FglNameExpression>(); if (parser.PeekToken(TokenKind.ImmediateKeyword)) { parser.NextToken(); ExpressionNode immExpr; if (FglExpressionNode.TryGetExpressionNode(parser, out immExpr, Genero4glAst.ValidStatementKeywords.ToList())) { node.ImmediateExpression = immExpr; } else { parser.ReportSyntaxError("Invalid expression found in execute immediate statement."); } } else { FglNameExpression cid; if (FglNameExpression.TryParseNode(parser, out cid)) { node.PreparedStatementId = cid; } else { parser.ReportSyntaxError("Invalid prepared statement id found in execute statement."); } HashSet <TokenKind> inVarMods = new HashSet <TokenKind> { TokenKind.InKeyword, TokenKind.OutKeyword, TokenKind.InOutKeyword }; bool hitUsing = false; if (parser.PeekToken(TokenKind.UsingKeyword)) { hitUsing = true; parser.NextToken(); ExpressionNode inVar; while (FglExpressionNode.TryGetExpressionNode(parser, out inVar)) { node.InputVars.Add(inVar); if (inVarMods.Contains(parser.PeekToken().Kind)) { parser.NextToken(); } if (parser.PeekToken(TokenKind.Comma)) { parser.NextToken(); } else { break; } } } if (parser.PeekToken(TokenKind.IntoKeyword)) { parser.NextToken(); FglNameExpression outVar; while (FglNameExpression.TryParseNode(parser, out outVar, TokenKind.Comma)) { node.InputVars.Add(outVar); if (parser.PeekToken(TokenKind.Comma)) { parser.NextToken(); } else { break; } } } if (!hitUsing && parser.PeekToken(TokenKind.UsingKeyword)) { parser.NextToken(); ExpressionNode inVar; while (FglExpressionNode.TryGetExpressionNode(parser, out inVar)) { node.InputVars.Add(inVar); if (inVarMods.Contains(parser.PeekToken().Kind)) { parser.NextToken(); } if (parser.PeekToken(TokenKind.Comma)) { parser.NextToken(); } else { break; } } } } node.EndIndex = parser.Token.Span.End; } return(result); }
public static bool TryParseNode(Genero4glParser parser, out ConstructDialogStatement node, bool returnFalseInsteadOfErrors = false) { node = new ConstructDialogStatement(); bool result = true; switch (parser.PeekToken().Kind) { case TokenKind.ContinueKeyword: case TokenKind.ExitKeyword: { if (parser.PeekToken(TokenKind.ConstructKeyword, 2)) { parser.NextToken(); node.StartIndex = parser.Token.Span.Start; parser.NextToken(); } else { result = false; } break; } case TokenKind.NextKeyword: { parser.NextToken(); node.StartIndex = parser.Token.Span.Start; if (parser.PeekToken(TokenKind.FieldKeyword)) { parser.NextToken(); switch (parser.PeekToken().Kind) { case TokenKind.NextKeyword: case TokenKind.PreviousKeyword: parser.NextToken(); break; default: { // get the field-spec FglNameExpression fieldSpec; if (FglNameExpression.TryParseNode(parser, out fieldSpec)) { node.FieldSpec = fieldSpec; } else { parser.ReportSyntaxError("Invalid field-spec found in construct statement."); } break; } } } else { if (!returnFalseInsteadOfErrors) { parser.ReportSyntaxError("Expecting \"field\" keyword in construct statement."); } else { return(false); } } break; } default: { result = false; break; } } if (result) { node.EndIndex = parser.Token.Span.End; } return(result); }
public new static bool TryParseNode(IParser parser, out RecordDefinitionNode defNode, bool isPublic = false) { defNode = null; bool result = false; if (parser.PeekToken(TokenKind.RecordKeyword)) { result = true; defNode = new RecordDefinitionNode(); defNode.StartIndex = parser.Token.Span.Start; defNode.Location = parser.TokenLocation; defNode._isPublic = isPublic; parser.NextToken(); // move past the record keyword if (parser.PeekToken(TokenKind.LikeKeyword)) { // get db info parser.NextToken(); if (!parser.PeekToken(TokenCategory.Identifier) && parser.PeekToken(TokenKind.Colon, 2)) { parser.NextToken(); // advance to the database name defNode.MimicDatabaseName = parser.Token.Token.Value.ToString(); parser.NextToken(); // advance to the colon } FglNameExpression tableName; if (FglNameExpression.TryParseNode(parser, out tableName)) { defNode.MimicTableName = tableName; if (!tableName.Name.EndsWith(".*")) { parser.ReportSyntaxError("A mimicking record must reference a table as follows: \"[tablename].*\"."); } } else { parser.ReportSyntaxError("Invalid database table name found in record definition."); } } else { AttributeSpecifier attribSpec; if (AttributeSpecifier.TryParseNode(parser, out attribSpec)) { defNode.Attribute = attribSpec; } bool advance = true; TokenWithSpan tok = default(TokenWithSpan); while (parser.PeekToken(TokenCategory.Identifier) || parser.PeekToken(TokenCategory.Keyword)) { //if (advance) //{ parser.NextToken(); tok = parser.Token; //} //else //{ // // reset // tok = parser.Token.Token; // advance = true; //} TypeReference tr; if (TypeReference.TryParseNode(parser, out tr, true)) { if (!defNode.MemberDictionary.ContainsKey(tok.Token.Value.ToString())) { defNode.MemberDictionary.Add(tok.Token.Value.ToString(), new VariableDef(tok.Token.Value.ToString(), tr, tok.Span.Start, true, defNode.Location?.FilePath)); } else { parser.ReportSyntaxError(string.Format("Record field {0} defined more than once.", tok.Token.Value.ToString()), Severity.Error); } } AttributeSpecifier.TryParseNode(parser, out attribSpec); if (parser.MaybeEat(TokenKind.Comma)) { //advance = false; continue; } else if (parser.MaybeEat(TokenKind.EndKeyword)) { if (!parser.MaybeEat(TokenKind.RecordKeyword)) { parser.ReportSyntaxError("Invalid end token in record definition"); } else { defNode.EndIndex = parser.Token.Span.End; defNode.IsComplete = true; } break; } else { parser.ReportSyntaxError("Invalid token within record definition"); break; } } } } return(result); }
public static bool TryParseNode(Genero4glParser parser, out MenuStatement node, bool returnFalseInsteadOfErrors = false) { node = new MenuStatement(); node.StartIndex = parser.Token.Span.Start; node.OptionNames = new List <ExpressionNode>(); bool result = true; switch (parser.PeekToken().Kind) { case TokenKind.ContinueKeyword: case TokenKind.ExitKeyword: { if (parser.PeekToken(TokenKind.MenuKeyword, 2)) { parser.NextToken(); node.StartIndex = parser.Token.Span.Start; parser.NextToken(); } else { result = false; } break; } case TokenKind.NextKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.OptionKeyword)) { parser.NextToken(); FglNameExpression nameExpr; if (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.OptionNames.Add(nameExpr); } else { parser.ReportSyntaxError("Invalid option name found in menu statement."); } } else { if (!returnFalseInsteadOfErrors) { parser.ReportSyntaxError("Expecting \"option\" keyword in menu statement."); } else { return(false); } } break; } case TokenKind.ShowKeyword: case TokenKind.HideKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.OptionKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.AllKeyword)) { parser.NextToken(); } else { FglNameExpression nameExpr; ExpressionNode strExpr; while (true) { if (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.OptionNames.Add(nameExpr); } else if (parser.PeekToken(TokenCategory.StringLiteral) && FglExpressionNode.TryGetExpressionNode(parser, out strExpr, new List <TokenKind> { TokenKind.Comma })) { node.OptionNames.Add(strExpr); } else { break; } if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } } } else { if (!returnFalseInsteadOfErrors) { parser.ReportSyntaxError("Expecting \"option\" keyword in menu statement."); } else { return(false); } } break; } default: { result = false; break; } } node.EndIndex = parser.Token.Span.End; return(result); }
public static bool TryParseNode(Genero4glParser parser, out DisplayBlock 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.DisplayKeyword)) { result = true; node = new DisplayBlock(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; node.Attributes = new List <DisplayAttribute>(); node.ByNameFields = new List <FglNameExpression>(); node.FieldSpecs = new List <FglNameExpression>(); node.DecoratorEnd = parser.Token.Span.End; if (parser.PeekToken(TokenKind.ByKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.NameKeyword)) { parser.NextToken(); // get the bynamefields FglNameExpression nameExpr; while (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.ByNameFields.Add(nameExpr); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } node.DecoratorEnd = parser.Token.Span.End; // get the optional attributes if (parser.PeekToken(TokenKind.AttributesKeyword) || parser.PeekToken(TokenKind.AttributeKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); DisplayAttribute attrib; while (DisplayAttribute.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 display attributes section."); } } else { parser.ReportSyntaxError("Expecting left-paren in display attributes section."); } } node.EndIndex = parser.Token.Span.End; } else { parser.ReportSyntaxError("Expected \"name\" keyword in display 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 display array statement."); } node.DecoratorEnd = parser.Token.Span.End; if (parser.PeekToken(TokenKind.ToKeyword)) { parser.NextToken(); if (FglNameExpression.TryParseNode(parser, out arrName)) { node.ScreenArrayName = arrName; } else { parser.ReportSyntaxError("Invalid array name found in display array statement."); } 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."); } } // get the optional attributes if (parser.PeekToken(TokenKind.AttributesKeyword) || parser.PeekToken(TokenKind.AttributeKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); DisplayAttribute attrib; while (DisplayAttribute.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 display attributes section."); } } else { parser.ReportSyntaxError("Expecting left-paren in display attributes section."); } } List <TokenKind> validExits = new List <TokenKind>(); if (validExitKeywords != null) { validExits.AddRange(validExitKeywords); } validExits.Add(TokenKind.DisplayKeyword); HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>(); if (endKeywords != null) { newEndKeywords.AddRange(endKeywords); } newEndKeywords.Add(TokenKind.DisplayKeyword); bool hasControlBlocks = false; DisplayControlBlock icb; prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); while (DisplayControlBlock.TryParseNode(parser, out icb, containingModule, hasControlBlocks, node.IsArray, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExits, contextStatementFactories, newEndKeywords) && icb != null) { // check for include file sign 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.DisplayKeyword, 2))) { break; } } prepStatementBinders.RemoveAt(0); if (hasControlBlocks || (parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.DisplayKeyword, 2))) { if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.DisplayKeyword, 2))) { parser.ReportSyntaxError("A display block must be terminated with \"end display\"."); } else { parser.NextToken(); // advance to the 'end' token parser.NextToken(); // advance to the 'display' token node.EndIndex = parser.Token.Span.End; } } } else { parser.ReportSyntaxError("Expected \"to\" keyword in display array statement."); } } else { // get the expression(s) ExpressionNode mainExpression = null; while (true) { ExpressionNode expr; if (!FglExpressionNode.TryGetExpressionNode(parser, out expr, new List <TokenKind> { TokenKind.ToKeyword, TokenKind.AttributeKeyword, TokenKind.AttributesKeyword })) { parser.ReportSyntaxError("Display statement must have one or more comma-separated expressions."); break; } if (mainExpression == null) { mainExpression = expr; } else { mainExpression.AppendExpression(expr); } if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } if (mainExpression != null) { node.Expression = mainExpression; } else { parser.ReportSyntaxError("Invalid expression found in display statement."); } if (parser.PeekToken(TokenKind.ToKeyword)) { parser.NextToken(); // get the field specs FglNameExpression nameExpr; while (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.FieldSpecs.Add(nameExpr); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } // get the optional attributes if (parser.PeekToken(TokenKind.AttributesKeyword) || parser.PeekToken(TokenKind.AttributeKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); DisplayAttribute attrib; while (DisplayAttribute.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 display attributes section."); } } } node.EndIndex = parser.Token.Span.End; } } return(result); }
public static bool TryParseNode(Genero4glParser parser, out MenuOption 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 = new MenuOption(); bool result = true; prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); switch (parser.PeekToken().Kind) { case TokenKind.Ampersand: { PreprocessorNode preNode; PreprocessorNode.TryParseNode(parser, out preNode); node.StartIndex = -1; break; } case TokenKind.CommandKeyword: { parser.NextToken(); node.StartIndex = parser.Token.Span.Start; bool getOptionName = false; if (parser.PeekToken(TokenKind.KeyKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); VirtualKey keyName; if (VirtualKey.TryGetKey(parser, out keyName)) { node.KeyName = keyName; } else { parser.ReportSyntaxError("Invalid key-name found in menu command option."); } if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expecting right-paren in menu command option."); } } else { parser.ReportSyntaxError("Expecting left-paren in menu command option."); } node.DecoratorEnd = parser.Token.Span.End; } else { getOptionName = true; } // at this point we need to try to get a menu-statement. If it doesn't work, we have some other stuff to gather FglStatement menuStmt = null; if (getOptionName || !MenuStatementFactory.TryGetStatement(parser, out menuStmt, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords)) { ExpressionNode optionName; if (FglExpressionNode.TryGetExpressionNode(parser, out optionName)) { node.OptionName = optionName; } else { parser.ReportSyntaxError("Invalid option-name found in menu command option."); } node.DecoratorEnd = parser.Token.Span.End; if (parser.PeekToken(TokenCategory.StringLiteral) || parser.PeekToken(TokenCategory.Identifier)) { ExpressionNode optionComment; if (FglExpressionNode.TryGetExpressionNode(parser, out optionComment)) { node.OptionComment = optionComment; } } if (parser.PeekToken(TokenKind.HelpKeyword)) { parser.NextToken(); ExpressionNode optionNumber; if (FglExpressionNode.TryGetExpressionNode(parser, out optionNumber)) { node.HelpNumber = optionNumber; } else { parser.ReportSyntaxError("Invalid help-number found in menu command option."); } } } else if (menuStmt != null) { node.Children.Add(menuStmt.StartIndex, menuStmt); } while (MenuStatementFactory.TryGetStatement(parser, out menuStmt, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords)) { if (menuStmt != null && !node.Children.ContainsKey(menuStmt.StartIndex)) { node.Children.Add(menuStmt.StartIndex, menuStmt); } } break; } case TokenKind.OnKeyword: { parser.NextToken(); node.StartIndex = parser.Token.Span.Start; if (parser.PeekToken(TokenKind.ActionKeyword)) { parser.NextToken(); FglNameExpression action; if (FglNameExpression.TryParseNode(parser, out action)) { node.ActionName = action; } else { parser.ReportSyntaxError("Invalid action-name found in menu option."); } node.DecoratorEnd = parser.Token.Span.End; FglStatement menuStmt = null; while (MenuStatementFactory.TryGetStatement(parser, out menuStmt, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords) && menuStmt != null) { node.Children.Add(menuStmt.StartIndex, menuStmt); } } else if (parser.PeekToken(TokenKind.IdleKeyword)) { parser.NextToken(); ExpressionNode idleExpr; if (FglExpressionNode.TryGetExpressionNode(parser, out idleExpr)) { node.IdleSeconds = idleExpr; } else { parser.ReportSyntaxError("Invalid idle-seconds found in menu block."); } node.DecoratorEnd = parser.Token.Span.End; FglStatement menuStmt = null; while (MenuStatementFactory.TryGetStatement(parser, out menuStmt, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords) && menuStmt != null) { node.Children.Add(menuStmt.StartIndex, menuStmt); } } else { parser.ReportSyntaxError("Expecting \"action\" or \"idle\" keyword in menu option."); } break; } default: result = false; break; } prepStatementBinders.RemoveAt(0); node.EndIndex = parser.Token.Span.End; return(result); }
protected bool BindPrepareCursorFromIdentifier(PrepareStatement prepStmt) { // If the prepare statement uses a variable from prepare from, that variable should have been encountered // prior to the prepare statement. So we'll do a binary search in the children of this function to look for // a LetStatement above the prepare statement where the prepare statement's from identifier was assigned. // If it can't be found, then we have to assume that the identifier was assigned outside of this function, // and we have no real way to determining the cursor SQL text. bool result = false; if (prepStmt.Children.Count == 1) { StringExpressionNode strExpr = prepStmt.Children[prepStmt.Children.Keys[0]] as StringExpressionNode; if (strExpr != null) { prepStmt.SetSqlStatement(strExpr.LiteralValue); } else { FglNameExpression exprNode = prepStmt.Children[prepStmt.Children.Keys[0]] as FglNameExpression; if (exprNode != null) { string ident = exprNode.Name; List <int> keys = Children.Select(x => x.Key).ToList(); int searchIndex = keys.BinarySearch(prepStmt.StartIndex); if (searchIndex < 0) { searchIndex = ~searchIndex; if (searchIndex > 0) { searchIndex--; } } LetStatement letStmt = null; while (searchIndex >= 0 && searchIndex < keys.Count) { int key = keys[searchIndex]; letStmt = Children[key] as LetStatement; if (letStmt != null) { // check for the LetStatement's identifier if (ident.Equals(letStmt.Variable.Name, StringComparison.OrdinalIgnoreCase)) { break; } else { letStmt = null; } } searchIndex--; } if (letStmt != null) { // we have a match, bind the let statement's value prepStmt.SetSqlStatement(letStmt.GetLiteralValue()); result = true; } } } } return(result); }
internal static bool TryParseNode(Genero4glParser parser, out CreateTableStatement node, IModuleResult containingModule) { node = null; bool result = false; bool temp = false; int tempIndex = -1; if (parser.PeekToken(TokenKind.TempKeyword)) { tempIndex = parser.Token.Span.Start; temp = true; parser.NextToken(); } if (parser.PeekToken(TokenKind.TableKeyword)) { result = true; node = new CreateTableStatement(); node.TempTable = temp; if (tempIndex >= 0) { node.StartIndex = tempIndex; } else { node.StartIndex = parser.Token.Span.Start; } parser.NextToken(); if (parser.PeekToken(TokenKind.IfKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.NotKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.ExistsKeyword)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expecting \"exists\" keyword in create table statement."); } } else { parser.ReportSyntaxError("Expecting \"not\" keyword in create table statement."); } } FglNameExpression nameExpr; if (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.TableName = nameExpr; } else { parser.ReportSyntaxError("Invalid name found for create table statement."); } if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); CreatedTableColumn tableCol; while (CreatedTableColumn.TryParseNode(parser, out tableCol) && tableCol != null) { node.Children.Add(tableCol.StartIndex, tableCol); if (parser.PeekToken(TokenKind.Comma)) { parser.NextToken(); } else { break; } } if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected right-paren in create table statement."); } if (parser.PeekToken(TokenKind.WithKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.NoKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.LogKeyword)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expecting \"log\" keyword in create table statement."); } } else { parser.ReportSyntaxError("Expecting \"no\" keyword in create table statement."); } } if (parser.PeekToken(TokenKind.InKeyword)) { parser.NextToken(); if (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.TablespaceName = nameExpr; } else { parser.ReportSyntaxError("Invalid name found for create table statement."); } } if (parser.PeekToken(TokenKind.ExtentKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.SizeKeyword)) { parser.NextToken(); ExpressionNode extSize; if (FglExpressionNode.TryGetExpressionNode(parser, out extSize)) { node.ExtentSize = extSize; } else { parser.ReportSyntaxError("Invalid expression found for extent size in create table statement."); } } else { parser.ReportSyntaxError("Expecting \"size\" keyword in create table statement."); } } if (parser.PeekToken(TokenKind.NextKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.SizeKeyword)) { parser.NextToken(); ExpressionNode extSize; if (FglExpressionNode.TryGetExpressionNode(parser, out extSize)) { node.NextSize = extSize; } else { parser.ReportSyntaxError("Invalid expression found for next size in create table statement."); } } else { parser.ReportSyntaxError("Expecting \"size\" keyword in create table statement."); } } if (parser.PeekToken(TokenKind.LockKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.ModeKeyword)) { parser.NextToken(); switch (parser.PeekToken().Kind) { case TokenKind.PageKeyword: parser.NextToken(); break; case TokenKind.RowKeyword: parser.NextToken(); break; default: parser.ReportSyntaxError("Expecting \"page\" or \"row\" keyword in create table statement."); break; } } else { parser.ReportSyntaxError("Expecting \"mode\" keyword in create table statement."); } } } else { parser.ReportSyntaxError("Expected left-paren in create table statement."); } containingModule.BindTableResult(node, parser); } return(result); }
public static bool TryParseNode(Genero4glParser parser, out DisplayAttribute node, bool isArray) { node = new DisplayAttribute(); 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.NormalKeyword: case TokenKind.ReverseKeyword: case TokenKind.BlinkKeyword: case TokenKind.UnderlineKeyword: case TokenKind.InvisibleKeyword: 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.HelpKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected equals token in display attribute."); } // get the help number ExpressionNode optionNumber; if (!FglExpressionNode.TryGetExpressionNode(parser, out optionNumber)) { parser.ReportSyntaxError("Invalid help-number found in display attribute."); } break; } case TokenKind.CountKeyword: { 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 display attribute."); } } else { parser.ReportSyntaxError("Expected integer expression in display array attribute."); } } else { parser.ReportSyntaxError("Attribute can only be used for an display array statement."); } 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.DetailActionKeyword: case TokenKind.DoubleClickKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.Equals)) { parser.NextToken(); FglNameExpression nameExpression; if (!FglNameExpression.TryParseNode(parser, out nameExpression)) { parser.ReportSyntaxError("Invalid action name found in input attribute."); } } else { parser.ReportSyntaxError("Expected equals token in display attribute."); } break; } case TokenKind.AccessoryTypeKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.Equals)) { var tokKind = parser.NextToken().Kind; if (tokKind != TokenKind.DetailActionKeyword || tokKind != TokenKind.DisclosureIndicatorKeyword || tokKind != TokenKind.CheckmarkKeyword) { parser.ReportSyntaxError("Invalid token found in ACCESSORYTYPE display attribute."); } } else { parser.ReportSyntaxError("Expected equals token in display attribute."); } break; } default: result = false; break; } return(result); }
public static bool TryParseNode(Genero4glParser parser, out CreatedTableColumn node) { node = new CreatedTableColumn(); node.StartIndex = parser.Token.Span.Start; node.UniqueColumns = new List <FglNameExpression>(); node.ReferencingTableColumnNames = new List <FglNameExpression>(); bool result = true; switch (parser.PeekToken().Kind) { case TokenKind.UniqueKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); FglNameExpression nameExpr; while (FglNameExpression.TryParseNode(parser, out nameExpr)) { node.UniqueColumns.Add(nameExpr); if (parser.PeekToken(TokenKind.Comma)) { parser.NextToken(); } else { break; } } if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected right-paren in create table statement."); } } else { parser.ReportSyntaxError("Expected left-paren in create table statement."); } break; } case TokenKind.PrimaryKeyword: case TokenKind.CheckKeyword: case TokenKind.ForeignKeyword: result = false; parser.ReportSyntaxError("Token not supported at this time for create table statements."); break; default: { FglNameExpression colName; if (FglNameExpression.TryParseNode(parser, out colName)) { node.ColumnName = colName; } else { parser.ReportSyntaxError("Invalid name found for table column in create table statement."); } TypeReference dataType; if (TypeReference.TryParseNode(parser, out dataType)) { // TODO: should probably ensure that only SQL compatible types are used here... node.DataType = dataType; } else { parser.ReportSyntaxError("Invalid data-type found for table column in create table statement."); } if (parser.PeekToken(TokenKind.DefaultKeyword)) { parser.NextToken(); ExpressionNode defVal; if (FglExpressionNode.TryGetExpressionNode(parser, out defVal)) { node.DefaultValue = defVal; } else { parser.ReportSyntaxError("Invalid expression found for default value in create table statement."); } } if (parser.PeekToken(TokenKind.NotKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.NullKeyword)) { parser.NextToken(); node.NotNull = true; } else { parser.ReportSyntaxError("Expecting \"null\" keyword in create table statement."); } } // TODO: do the other modifiers (primary key, unique, check, references) } break; } return(result); }
public static bool TryParseNode(Genero4glParser parser, out DisplayControlBlock node, IModuleResult containingModule, bool allowNonControlBlocks, bool isArray, 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 = new DisplayControlBlock(); bool result = true; node.KeyNameList = new List <VirtualKey>(); bool isDragAndDrop = false; switch (parser.PeekToken().Kind) { case TokenKind.Ampersand: { // handle include file PreprocessorNode preNode; PreprocessorNode.TryParseNode(parser, out preNode); node.StartIndex = -1; break; } case TokenKind.BeforeKeyword: case TokenKind.AfterKeyword: { parser.NextToken(); node.StartIndex = parser.Token.Span.Start; if (parser.PeekToken(TokenKind.DisplayKeyword)) { parser.NextToken(); node.Type = DisplayControlBlockType.Display; } else if (parser.PeekToken(TokenKind.RowKeyword)) { parser.NextToken(); node.Type = DisplayControlBlockType.Row; } else { parser.ReportSyntaxError("Unexpected keyword found in display control block."); result = false; } break; } case TokenKind.OnKeyword: { parser.NextToken(); node.StartIndex = parser.Token.Span.Start; switch (parser.PeekToken().Kind) { case TokenKind.IdleKeyword: parser.NextToken(); node.Type = DisplayControlBlockType.Idle; // get the idle seconds ExpressionNode idleExpr; if (FglExpressionNode.TryGetExpressionNode(parser, out idleExpr)) { node.IdleSeconds = idleExpr; } else { parser.ReportSyntaxError("Invalid idle-seconds found in display array statement."); } break; case TokenKind.TimerKeyword: parser.NextToken(); node.Type = DisplayControlBlockType.Timer; // get the timer seconds ExpressionNode timerExpr; if (FglExpressionNode.TryGetExpressionNode(parser, out timerExpr)) { node.TimerSeconds = timerExpr; } else { parser.ReportSyntaxError("Invalid timer-seconds found in display array statement."); } break; case TokenKind.ActionKeyword: parser.NextToken(); node.Type = DisplayControlBlockType.Action; // get the action name FglNameExpression actionName; if (FglNameExpression.TryParseNode(parser, out actionName)) { node.ActionName = actionName; } else { parser.ReportSyntaxError("Invalid action-name found in display array statement."); } GetActionAttributesDisplayArray(parser); break; case TokenKind.KeyKeyword: parser.NextToken(); node.Type = DisplayControlBlockType.Key; if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); // get the list of key names VirtualKey keyName; while (VirtualKey.TryGetKey(parser, out keyName)) { node.KeyNameList.Add(keyName); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected right-paren in display array block."); } } else { parser.ReportSyntaxError("Expected left-paren in display array block."); } break; case TokenKind.AppendKeyword: node.Type = DisplayControlBlockType.Append; parser.NextToken(); GetActionAttributesListmodTriggers(parser); break; case TokenKind.InsertKeyword: node.Type = DisplayControlBlockType.Insert; parser.NextToken(); GetActionAttributesListmodTriggers(parser); break; case TokenKind.UpdateKeyword: node.Type = DisplayControlBlockType.Update; parser.NextToken(); GetActionAttributesListmodTriggers(parser); break; case TokenKind.DeleteKeyword: node.Type = DisplayControlBlockType.Delete; parser.NextToken(); GetActionAttributesListmodTriggers(parser); break; case TokenKind.ExpandKeyword: node.Type = DisplayControlBlockType.Expand; parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); FglNameExpression rowInd; if (FglNameExpression.TryParseNode(parser, out rowInd)) { node.RowIndex = rowInd; } else { parser.ReportSyntaxError("Invalid row-index found in display array statement."); } if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected right-paren in display array statement."); } } else { parser.ReportSyntaxError("Expected left-paren in display array statement."); } break; case TokenKind.CollapseKeyword: node.Type = DisplayControlBlockType.Collapse; parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); FglNameExpression rowInd1; if (FglNameExpression.TryParseNode(parser, out rowInd1)) { node.RowIndex = rowInd1; } else { parser.ReportSyntaxError("Invalid row-index found in display array statement."); } if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected right-paren in display array statement."); } } else { parser.ReportSyntaxError("Expected left-paren in display array statement."); } break; case TokenKind.Drag_EnterKeyword: node.Type = DisplayControlBlockType.DragEnter; parser.NextToken(); isDragAndDrop = true; break; case TokenKind.Drag_FinishKeyword: case TokenKind.Drag_FinishedKeyword: node.Type = DisplayControlBlockType.DragFinish; parser.NextToken(); isDragAndDrop = true; break; case TokenKind.Drag_OverKeyword: node.Type = DisplayControlBlockType.DragOver; parser.NextToken(); isDragAndDrop = true; break; case TokenKind.Drag_StartKeyword: node.Type = DisplayControlBlockType.DragStart; parser.NextToken(); isDragAndDrop = true; break; case TokenKind.DropKeyword: node.Type = DisplayControlBlockType.Drop; parser.NextToken(); isDragAndDrop = true; break; default: parser.ReportSyntaxError("Unexpected token found in input control block."); result = false; break; } break; } default: if (!allowNonControlBlocks) { result = false; } else { node.StartIndex = parser.Token.Span.Start; } break; } if (result && node.StartIndex >= 0) { node.DecoratorEnd = parser.Token.Span.End; if (isDragAndDrop) { if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); FglNameExpression keyName; if (FglNameExpression.TryParseNode(parser, out keyName)) { node.DragAndDropObject = keyName; } else { parser.ReportSyntaxError("Invalid drag-and-drop object name found in display array statement."); } if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected right-paren in input control block."); } } else { parser.ReportSyntaxError("Expected left-paren in input control block."); } } // get the dialog statements FglStatement dispStmt; prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); while (DisplayStatementFactory.TryGetStatement(parser, out dispStmt, isArray, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, contextStatementFactories, endKeywords) && dispStmt != null) { node.Children.Add(dispStmt.StartIndex, dispStmt); node.EndIndex = dispStmt.EndIndex; } prepStatementBinders.RemoveAt(0); if (node.Type == DisplayControlBlockType.None && node.Children.Count == 0) { result = false; } } return(result); }
public static bool TryParseNode(Genero4glParser parser, out InputDialogStatement node, bool isArray, bool returnFalseInsteadOfErrors = false) { node = new InputDialogStatement(); bool result = true; switch (parser.PeekToken().Kind) { case TokenKind.AcceptKeyword: case TokenKind.ContinueKeyword: case TokenKind.ExitKeyword: { if (parser.PeekToken(TokenKind.InputKeyword, 2)) { parser.NextToken(); node.StartIndex = parser.Token.Span.Start; parser.NextToken(); } else { result = false; } break; } case TokenKind.NextKeyword: { parser.NextToken(); node.StartIndex = parser.Token.Span.Start; if (parser.PeekToken(TokenKind.FieldKeyword)) { parser.NextToken(); switch (parser.PeekToken().Kind) { case TokenKind.CurrentKeyword: case TokenKind.NextKeyword: case TokenKind.PreviousKeyword: parser.NextToken(); break; default: { // get the field-spec FglNameExpression fieldSpec; if (FglNameExpression.TryParseNode(parser, out fieldSpec)) { node.FieldSpec = fieldSpec; } else { parser.ReportSyntaxError("Invalid field-spec found in input statement."); } break; } } } else { if (!returnFalseInsteadOfErrors) { parser.ReportSyntaxError("Expecting \"field\" keyword in input statement."); } else { return(false); } } break; } case TokenKind.CancelKeyword: { if (isArray) { parser.NextToken(); node.StartIndex = parser.Token.Span.Start; if (parser.PeekToken(TokenKind.DeleteKeyword) || parser.PeekToken(TokenKind.InsertKeyword)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected \"delete\" or \"insert\" keyword in input statement."); } } else { if (!returnFalseInsteadOfErrors) { parser.ReportSyntaxError("Keyword \"cancel\" can only exist in an input array statement."); } else { return(false); } } break; } default: { result = false; break; } } if (result && node != null) { node.EndIndex = parser.Token.Span.End; } return(result); }