Ejemplo n.º 1
0
        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) : LNode.List(parser.ParseStmtsGreedy()).AsLNode(S.Splice);

            AreEqual(TokenType.EOF, parser.LT0.Type(), string.Format("Parser stopped before EOF at [{0}] in {1}", parser.LT0.StartIndex, text));
            AreEqual(expected, result);
            if (sink is MessageHolder)
            {
                GreaterOrEqual(((MessageHolder)sink).List.Count, 1, "Expected an error but got none for " + text);
            }
        }
Ejemplo n.º 2
0
        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 | Mode.ExpectAndDropParserError)) == 0)
            {
                return;
            }
            var sink = (mode & Mode.ExpectAndDropParserError) != 0 ? new MessageHolder() : (IMessageSink)ConsoleMessageSink.Value;

            using (Token.SetToStringStrategy(TokenExt.ToString))             // debugging aid
            {
                // 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), "", sink);
                var            preprocessed = new EcsPreprocessor(lexer, true);
                var            treeified    = new TokensToTree(preprocessed, false);
                var            parser       = new EcsParser(treeified.Buffered(), lexer.SourceFile, sink, null);
                LNodeList      results      = exprMode ? LNode.List(parser.ExprStart(false)) : LNode.List(parser.ParseStmtsGreedy());

                // Inject comments
                var injector = new EcsTriviaInjector(preprocessed.TriviaList, preprocessed.SourceFile, (int)TokenType.Newline, "/*", "*/", "//", (mode & Mode.Expression) == 0);
                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;
                }
                if (sink is MessageHolder)
                {
                    ((MessageHolder)sink).WriteListTo(TraceMessageSink.Value);
                    GreaterOrEqual(((MessageHolder)sink).List.Count(m => m.Severity >= Severity.Error), 1,
                                   "Expected an error but got none for " + text);
                    if (expected == null)
                    {
                        return;
                    }
                }
                if (!expected.Equals(result, LNode.CompareMode.TypeMarkers))
                {
                    if ((mode & Mode.CompareAsLes) != 0)
                    {
                        using (LNode.SetPrinter(Syntax.Les.Les3LanguageService.Value))
                            AreEqual(expected.ToString(), result.ToString());
                    }
                    else
                    {
                        AreEqual(expected, result);
                    }
                    Fail("{0} has a different type marker than {1}", expected, result);
                }
            }
        }
Ejemplo n.º 3
0
        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());
            }
        }
Ejemplo n.º 4
0
        public IListSource <LNode> Parse(IListSource <Token> input, ISourceFile file, IMessageSink msgs, Symbol 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.
            bool exprMode = inputType == ParsingService.Exprs;
            char _        = '\0';

            if (inputType == ParsingService.Exprs || file.Text.TryGet(255, ref _))
            {
                EcsParser parser = _parser;
                if (parser == null)
                {
                    _parser = parser = new EcsParser(input, file, msgs);
                }
                else
                {
                    parser.ErrorSink = msgs ?? MessageSink.Current;
                    parser.Reset(input, file);
                }
                if (inputType == ParsingService.Exprs)
                {
                    return(parser.ParseExprs());
                }
                else
                {
                    return(parser.ParseStmtsGreedy());
                }
            }
            else
            {
                var parser = new EcsParser(input, file, msgs);
                return(parser.ParseStmtsLazy().Buffered());
            }
        }