Exemplo n.º 1
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);
                VList <LNode>  results      = exprMode ? LNode.List(parser.ExprStart(false)) : LNode.List(parser.ParseStmtsGreedy());

                // 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;
                }
                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;
                    }
                }
                AreEqual(expected, result);
            }
        }
Exemplo n.º 2
0
        // This is called either at the root node, or by a macro that wants to
        // preprocess its children (see IMacroContext.PreProcess()).
        LNode PreProcess(ref VList <LNode> list, LNode single, bool asRoot, bool resetOpenNamespaces, bool areAttributesOrIsTarget)
        {
            if (single == null && list.Count == 0)
            {
                return(null);                // no-op requested
            }
            var oldS         = _s;
            var oldAncestors = _ancestorStack;
            var oldMP        = MacroProcessor._current;

            MacroProcessor._current = _parent;
            bool newScope      = false;
            int  maxExpansions = asRoot ? MaxExpansions : _s.MaxExpansions - 1;

            try {
                bool reentrant = _reentrancyCounter++ != 0;
                if (!reentrant)
                {
                    asRoot = true;
                }
                Debug.Assert(reentrant || _scopes.Count == 0);
                Debug.Assert(reentrant || _ancestorStack == null);

                if (asRoot)
                {
                    _ancestorStack = new DList <LNode>();
                }
                _s = new CurNodeState();
                if (asRoot || resetOpenNamespaces)
                {
                    var namespaces = !reentrant || resetOpenNamespaces?_parent._preOpenedNamespaces.Clone() : _curScope.OpenNamespaces.Clone();

                    var properties = asRoot ? _rootScopedProperties.Clone() : _curScope.ScopedProperties;
                    newScope  = true;
                    _curScope = new Scope(namespaces, properties, this, true);
                    _scopes.Add(_curScope);
                }
                if (single != null)
                {
                    bool _;
                    return(ApplyMacros(single, maxExpansions, areAttributesOrIsTarget, out _) ?? single);
                }
                else
                {
                    int   oldStackCount = _ancestorStack.Count;
                    LNode splice        = null;
                    if (asRoot)
                    {
                        splice = list.AsLNode(S.Splice);
                        _ancestorStack.PushLast(splice);
                    }
                    list = ApplyMacrosToList(list, maxExpansions, areAttributesOrIsTarget);
                    if (asRoot)
                    {
                        _ancestorStack.PopLast();
                    }
                    Debug.Assert(_ancestorStack.Count == oldStackCount);
                    return(splice);
                }
            } finally {
                _reentrancyCounter--;
                MacroProcessor._current = oldMP;
                _ancestorStack          = oldAncestors;
                _s = oldS;
                if (newScope)
                {
                    PopScope();
                }
            }
        }