protected override void Stmt(string text, LNode expected, Action<EcsPrinterOptions> configure = null, Mode mode = Mode.Both) { bool exprMode = (mode & Mode.Expression) != 0; if ((mode & Mode.ParserTest) == 0) return; var sink = (mode & Mode.ExpectAndDropParserError) != 0 ? new MessageHolder() : (IMessageSink)ConsoleMessageSink.Value; // This is the easy way: //LNode result = EcsLanguageService.Value.ParseSingle(text, sink, exprMode ? ParsingMode.Expressions : ParsingMode.Statements, preserveComments: true); // But to make debugging easier, I'll do it the long way: ILexer<Token> lexer = EcsLanguageService.Value.Tokenize(new UString(text), "", ConsoleMessageSink.Value); var preprocessed = new EcsPreprocessor(lexer, true); var treeified = new TokensToTree(preprocessed, false); var parser = new EcsParser(treeified.Buffered(), lexer.SourceFile, sink); VList<LNode> results = exprMode ? LNode.List(parser.ExprStart(false)) : LNode.List(parser.ParseStmtsGreedy()); //if (!preprocessed.TriviaList.IsEmpty) { // Inject comments var injector = new EcsTriviaInjector(preprocessed.TriviaList, preprocessed.SourceFile, (int)TokenType.Newline, "/*", "*"+"/", "//"); results = LNode.List(injector.Run(results.GetEnumerator()).ToList()); } LNode result = results.AsLNode(S.Splice); AreEqual(TokenType.EOF, parser.LT0.Type(), string.Format("Parser stopped before EOF at [{0}] in {1}", parser.LT0.StartIndex, text)); if ((mode & Mode.IgnoreTrivia) != 0) result = result.ReplaceRecursive(n => n.IsTrivia ? Maybe<LNode>.NoValue : n, LNode.ReplaceOpt.ProcessAttrs).Value; AreEqual(expected, result); if (sink is MessageHolder) GreaterOrEqual(((MessageHolder)sink).List.Count, 1, "Expected an error but got none for "+text); }
private LNode ParseExpr(IListSource <Token> tree) { if (_parser == null) { _parser = new EcsParser(tree, SourceFile, ErrorSink); } else { _parser.Reset(tree, SourceFile); } LNode expr = _parser.ExprStart(false); return(expr); }
protected override void Stmt(string text, LNode expected, Action<EcsNodePrinter> configure = null, Mode mode = Mode.Both) { bool exprMode = (mode & Mode.Expression) != 0; if ((mode & Mode.ParserTest) == 0) return; // This is the easy way: //LNode result = EcsLanguageService.Value.ParseSingle(text, MessageSink.Console, exprMode ? ParsingService.Exprs : ParsingService.Stmts); // But to make debugging easier, I'll do it the long way: ILexer<Token> lexer = EcsLanguageService.Value.Tokenize(new UString(text), "", MessageSink.Console); var preprocessed = new EcsPreprocessor(lexer); var treeified = new TokensToTree(preprocessed, false); var sink = (mode & Mode.ExpectAndDropParserError) != 0 ? new MessageHolder() : (IMessageSink)MessageSink.Console; var parser = new EcsParser(treeified.Buffered(), lexer.SourceFile, sink); LNode result = exprMode ? parser.ExprStart(false) : parser.Stmt(); AreEqual(TokenType.EOF, parser.LT0.Type()); AreEqual(expected, result); if (sink is MessageHolder) GreaterOrEqual(((MessageHolder)sink).List.Count, 1); }
public IListSource<LNode> Parse(IListSource<Token> input, ISourceFile file, IMessageSink msgs, ParsingMode inputType = null) { // For efficiency we'd prefer to re-use our _parser object, but // when parsing lazily, we can't re-use it because another parsing // operation could start before this one is finished. To force // greedy parsing, we can call ParseStmtsGreedy(), but the caller may // prefer lazy parsing, especially if the input is large. As a // compromise I'll check if the source file is larger than a // certain arbitrary size. Also, ParseExprs() is always greedy // so we can always re-use _parser in that case. char _ = '\0'; if (file.Text.TryGet(255, ref _) || inputType == ParsingMode.FormalArguments || inputType == ParsingMode.Types || inputType == ParsingMode.Expressions) { EcsParser parser = _parser; if (parser == null) _parser = parser = new EcsParser(input, file, msgs); else { parser.ErrorSink = msgs ?? MessageSink.Default; parser.Reset(input, file); } if (inputType == ParsingMode.Expressions) return parser.ParseExprs(false, allowUnassignedVarDecl: false); else if (inputType == ParsingMode.FormalArguments) return parser.ParseExprs(false, allowUnassignedVarDecl: true); else if (inputType == ParsingMode.Types) return LNode.List(parser.DataType()); else return parser.ParseStmtsGreedy(); } else { var parser = new EcsParser(input, file, msgs); return parser.ParseStmtsLazy().Buffered(); } }