public static bool TryParseNode(Genero4glParser parser, out PromptControlBlock 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 PromptControlBlock(); bool result = true; node.KeyNameList = new List <VirtualKey>(); switch (parser.PeekToken().Kind) { case TokenKind.OnKeyword: { parser.NextToken(); node.StartIndex = parser.Token.Span.Start; switch (parser.PeekToken().Kind) { case TokenKind.IdleKeyword: parser.NextToken(); node.Type = PromptControlBlockType.Idle; // get the idle seconds ExpressionNode idleExpr; if (FglExpressionNode.TryGetExpressionNode(parser, out idleExpr)) { node.IdleSeconds = idleExpr; } else { parser.ReportSyntaxError("Invalid idle-seconds found in prompt statement."); } break; case TokenKind.ActionKeyword: parser.NextToken(); node.Type = PromptControlBlockType.Action; // get the action name FglNameExpression actionName; if (FglNameExpression.TryParseNode(parser, out actionName)) { node.ActionName = actionName; } else { parser.ReportSyntaxError("Invalid action-name found in prompt statement."); } break; case TokenKind.KeyKeyword: parser.NextToken(); node.Type = PromptControlBlockType.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 prompt block."); } } else { parser.ReportSyntaxError("Expected left-paren in prompt block."); } break; default: parser.ReportSyntaxError("Unexpected token found in prompt block."); result = false; break; } break; } default: result = false; break; } if (result) { // get the dialog statements FglStatement dispStmt; prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); while (parser.StatementFactory.TryParseNode(parser, out dispStmt, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, false, validExitKeywords, contextStatementFactories, null, endKeywords) && dispStmt != null) { node.Children.Add(dispStmt.StartIndex, dispStmt); node.EndIndex = dispStmt.EndIndex; } prepStatementBinders.RemoveAt(0); if (node.Type == PromptControlBlockType.None && node.Children.Count == 0) { result = false; } } return(result); }
public static bool TryParseNode(Genero4glParser parser, out PromptStatement 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.PromptKeyword)) { result = true; node = new PromptStatement(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; node.DisplayAttributes = new List <PromptDisplayAttribute>(); node.ControlAttributes = new List <PromptControlAttribute>(); ExpressionNode question; if (FglExpressionNode.TryGetExpressionNode(parser, out question)) { node.Question = question; } else { parser.ReportSyntaxError("Invalid question expression found in prompt statement."); } // get the optional display attributes if (parser.PeekToken(TokenKind.AttributesKeyword) || parser.PeekToken(TokenKind.AttributeKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); PromptDisplayAttribute attrib; while (PromptDisplayAttribute.TryParseNode(parser, out attrib)) { node.DisplayAttributes.Add(attrib); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expecting right-paren in prompt display attributes section."); } } else { parser.ReportSyntaxError("Expecting left-paren in prompt display attributes section."); } } if (parser.PeekToken(TokenKind.ForKeyword)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected \"for\" keyword in prompt statement."); } if (parser.PeekToken(TokenKind.CharKeyword) || parser.PeekToken(TokenKind.CharacterKeyword)) { parser.NextToken(); } FglNameExpression varName; if (FglNameExpression.TryParseNode(parser, out varName)) { node.VariableName = varName; } else { parser.ReportSyntaxError("Invalid variable name found in prompt statement."); } if (parser.PeekToken(TokenKind.HelpKeyword)) { parser.NextToken(); ExpressionNode helpNumber; if (FglExpressionNode.TryGetExpressionNode(parser, out helpNumber)) { node.HelpNumber = helpNumber; } else { parser.ReportSyntaxError("Invalid help number found in prompt statement."); } } // get the optional control attributes if (parser.PeekToken(TokenKind.AttributesKeyword) || parser.PeekToken(TokenKind.AttributeKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); PromptControlAttribute attrib; while (PromptControlAttribute.TryParseNode(parser, out attrib)) { node.ControlAttributes.Add(attrib); if (!parser.PeekToken(TokenKind.Comma)) { break; } parser.NextToken(); } if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expecting right-paren in prompt control attributes section."); } } else { parser.ReportSyntaxError("Expecting left-paren in prompt control attributes section."); } } List <TokenKind> validExits = new List <TokenKind>(); if (validExitKeywords != null) { validExits.AddRange(validExitKeywords); } validExits.Add(TokenKind.PromptKeyword); HashSet <TokenKind> newEndKeywords = new HashSet <TokenKind>(); if (endKeywords != null) { newEndKeywords.AddRange(endKeywords); } newEndKeywords.Add(TokenKind.PromptKeyword); bool hasControlBlocks = false; PromptControlBlock controlBlock; prepStatementBinders.Insert(0, node.BindPrepareCursorFromIdentifier); while (PromptControlBlock.TryParseNode(parser, out controlBlock, containingModule, prepStatementBinders, returnStatementBinder, limitedScopeVariableAdder, validExitKeywords, contextStatementFactories) && controlBlock != null) { node.Children.Add(controlBlock.StartIndex, controlBlock); hasControlBlocks = true; if (parser.PeekToken(TokenKind.EndOfFile) || (parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.PromptKeyword, 2))) { break; } } prepStatementBinders.RemoveAt(0); if (hasControlBlocks) { if (!(parser.PeekToken(TokenKind.EndKeyword) && parser.PeekToken(TokenKind.PromptKeyword, 2))) { parser.ReportSyntaxError("A prompt block must be terminated with \"end prompt\"."); } else { parser.NextToken(); // advance to the 'end' token parser.NextToken(); // advance to the 'prompt' token node.EndIndex = parser.Token.Span.End; } } } return(result); }