public override object VisitTerminal(ITerminalNode node)
        {
            if (_withLogging)
            {
                _tabs = _tabs + "\t";
                PLogger.Info($"{_tabs}{PascalTokenTypes.Convert(node.Symbol.Type)}");
                _tabs = _tabs.Substring(0, _tabs.Length - 1);
            }

            //Restore whitespaces that ANTLR does not produce
            if (node.Symbol.TokenIndex != -1)
            {
                var toLoop = node.Symbol.TokenIndex - (_prev?.Symbol.TokenIndex ?? -1) - 1;
                while (toLoop > 0)
                {
                    if (!_psiBuilder.Eof())
                    {
                        _psiBuilder.AdvanceLexer();
                    }
                    toLoop--;
                }
            }

            if (!_psiBuilder.Eof())
            {
                _psiBuilder.AdvanceLexer();
            }

            _prev = node;

            return(null);
        }
        public override object VisitTerminal(ITerminalNode node)
        {
            if (node.Symbol.TokenIndex != -1)
            {
                var counter = 0;

                while (counter < node.Symbol.TokenIndex - (previousGoodToken?.Symbol.TokenIndex ?? -1) - 1)
                {
                    if (!_psiBuilder.Eof())
                    {
                        _psiBuilder.AdvanceLexer();
                    }

                    counter++;
                }
            }

            if (!_psiBuilder.Eof())
            {
                _psiBuilder.AdvanceLexer();
            }

            previousGoodToken = node;

            return(null);
        }
예제 #3
0
        private bool ParseSeq(PsiBuilder builder)
        {
            var start = builder.Mark();

            if (!ParseStmt(builder))
            {
                builder.Drop(start);
                return(false);
            }

            if (builder.Eof() || builder.GetTokenType() == SpringTokenType.RFBRACKET)
            {
                builder.Drop(start);
                return(true);
            }

            if (!ParseSeq(builder))
            {
                builder.Drop(start);
                return(false);
            }

            builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.SEQ, null);
            return(true);
        }
예제 #4
0
        public IFile ParseFile()
        {
            using (var lifetimeDefinition = Lifetime.Define())
            {
                var builder    = new PsiBuilder(_lexer, GherkinNodeTypes.FILE, null, lifetimeDefinition.Lifetime);
                var fileMarker = builder.Mark();

                while (!builder.Eof())
                {
                    var tokenType = builder.GetTokenType();

                    if (tokenType == GherkinTokenTypes.FEATURE_KEYWORD)
                    {
                        ParseFeature(builder);
                    }
                    else if (tokenType == GherkinTokenTypes.TAG)
                    {
                        ParseTags(builder);
                    }
                    else if (tokenType == GherkinTokenTypes.COMMENT)
                    {
                        ParseComments(builder);
                    }
                    else
                    {
                        builder.AdvanceLexer();
                    }
                }

                builder.Done(fileMarker, GherkinNodeTypes.FILE, new GherkinFile.FileMetadata(_sourceFile?.Name, _lang));
                var resultTree = (GherkinFile)builder.BuildTree();

                return(resultTree);
            }
        }
예제 #5
0
        private void ParseBlock(PsiBuilder builder)
        {
            while (!builder.Eof())
            {
                var tt = builder.GetTokenType();
                if (tt == SpringTokenType.LeftBrace)
                {
                    var start = builder.Mark();
                    builder.AdvanceLexer();
                    ParseBlock(builder);

                    if (builder.GetTokenType() != SpringTokenType.RightBrace)
                    {
                        builder.Error("Expected '}'");
                    }
                    else
                    {
                        builder.AdvanceLexer();
                    }

                    builder.Done(start, SpringCompositeNodeType.BLOCK, null);
                }
                else if (tt == SpringTokenType.RightBrace)
                {
                    return;
                }
                else
                {
                    builder.AdvanceLexer();
                }
            }
        }
예제 #6
0
        public void ParseFile()
        {
            var mark = MarkNoSkipWhitespace();

            ParseJsonValue();
            SkipWhitespaces();

            if (!myBuilder.Eof())
            {
                var errorMark = MarkNoSkipWhitespace();
                while (!myBuilder.Eof())
                {
                    Advance();
                }

                myBuilder.Error(errorMark, GetExpectedMessage("EOF"));
            }

            Done(mark, ElementType.JSON_NEW_FILE);
        }
예제 #7
0
        private void ParseDefines(PsiBuilder builder)
        {
            SkipWhitespace(builder);
            while (!builder.Eof())
            {
                var tt = builder.GetTokenType();
                if (tt == SpringTokenType.LPAREN)
                {
                    var start = builder.Mark();
                    AdvanceSkippingWhitespace(builder);
                    if (builder.GetTokenType() == SpringTokenType.DEFINE)
                    {
                        AdvanceSkippingWhitespace(builder);
                        ParseIdentDecl(builder);
                        SkipWhitespace(builder);
                        ParseExpr(builder);
                        SkipWhitespace(builder);
                    }
                    else
                    {
                        builder.Error("Expected definition!");
                    }

                    /*
                     * if (builder.GetTokenType() == SpringTokenType.RPAREN)
                     *  builder.AdvanceLexer();
                     * else
                     *  builder.Error("Expected ')' to close definition!");
                     *
                     * builder.Done(start, SpringCompositeNodeType.DEFINE, null);
                     */

                    SkipWhitespace(builder);
                    if (builder.GetTokenType() == SpringTokenType.RPAREN)
                    {
                        builder.AdvanceLexer();
                        builder.Done(start, SpringCompositeNodeType.DEFINE, null);
                    }
                    else
                    {
                        builder.Error(start, "Expected ')' to close definition!");
                    }
                }
                else
                {
                    var tokenType = builder.GetTokenType();
                    var mark      = builder.Mark();
                    builder.AdvanceLexer();
                    builder.Error(mark, "Expected '(', but got: " + tokenType.TokenRepresentation);
                }

                SkipWhitespace(builder);
            }
        }
예제 #8
0
        // Left mark on ')'
        private void ParseSpaceSeparatedList(PsiBuilder builder, Predicate <PsiBuilder> elementParser)
        {
            var mark = builder.Mark();

            while (builder.GetTokenType() != SpringTokenType.RPAREN && !builder.Eof())
            {
                if (!elementParser(builder) && !builder.Eof())
                {
                    builder.AdvanceLexer();
                }

                SkipWhitespace(builder);
            }

            if (builder.GetTokenType() != SpringTokenType.RPAREN)
            {
                builder.Error("Expect ')' in list!");
            }

            builder.Done(mark, SpringCompositeNodeType.LIST, null);
        }
예제 #9
0
        private static void ParsePystring(PsiBuilder builder)
        {
            if (!builder.Eof())
            {
                var marker = builder.Mark();
                builder.AdvanceLexer();
                while (!builder.Eof() && builder.GetTokenType() != GherkinTokenTypes.PYSTRING)
                {
                    if (!ParseStepParameter(builder))
                    {
                        builder.AdvanceLexer();
                    }
                }

                if (!builder.Eof())
                {
                    builder.AdvanceLexer();
                }

                builder.Done(marker, GherkinNodeTypes.PYSTRING, null);
            }
        }
예제 #10
0
        private void ParseFeature(PsiBuilder builder)
        {
            var featureMarker = builder.Mark();

            Assertion.Assert(builder.GetTokenType() == GherkinTokenTypes.FEATURE_KEYWORD,
                             "_builder.GetTokenType() == GherkinTokenTypes.FEATURE_KEYWORD");

            int? descMarker   = null;
            bool wasLineBreak = false;

            do
            {
                builder.AdvanceLexer();

                var tokenType = builder.GetTokenType();
                if (tokenType == GherkinTokenTypes.TEXT && descMarker == null)
                {
                    if (wasLineBreak)
                    {
                        descMarker = builder.Mark();
                    }
                }

                if (GherkinTokenTypes.SCENARIOS_KEYWORDS[tokenType] ||
                    tokenType == GherkinTokenTypes.RULE_KEYWORD ||
                    tokenType == GherkinTokenTypes.BACKGROUND_KEYWORD ||
                    tokenType == GherkinTokenTypes.TAG)
                {
                    if (descMarker != null)
                    {
                        builder.DoneBeforeWhitespaces(descMarker.Value, GherkinNodeTypes.FEATURE_HEADER, null);
                        descMarker = null;
                    }

                    ParseFeatureElements(builder);
                }

                wasLineBreak = IsLineBreak(builder);
                if (wasLineBreak)
                {
                    SkipGroupedWhiteSpaces(builder);
                }
            } while (builder.GetTokenType() != GherkinTokenTypes.FEATURE_KEYWORD && !builder.Eof());

            if (descMarker != null)
            {
                builder.DoneBeforeWhitespaces(descMarker.Value, GherkinNodeTypes.FEATURE_HEADER, null);
            }

            builder.DoneBeforeWhitespaces(featureMarker, GherkinNodeTypes.FEATURE, null);
        }
예제 #11
0
        public void ParseAll()
        {
            SkipNonsemanticalTokens();

            if (!ParseBlock())
            {
                builder.Error("A block expected");
                return;
            }

            if (!builder.Eof())
            {
                builder.Error("Semantical tokens after the program end!");
            }
        }
예제 #12
0
        private static void ParseFeatureElements(PsiBuilder builder)
        {
            int?ruleMarker = null;

            while (builder.GetTokenType() != GherkinTokenTypes.FEATURE_KEYWORD && !builder.Eof())
            {
                if (builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE)
                {
                    builder.AdvanceLexer();
                    continue;
                }

                ruleMarker = ParseRule(builder, ruleMarker);
                ParseScenario(builder);
            }

            if (ruleMarker.HasValue)
            {
                builder.Done(ruleMarker.Value, GherkinNodeTypes.RULE, null);
            }
        }
예제 #13
0
        public IFile ParseFile()
        {
            using (var def = Lifetime.Define())
            {
                var builder  = new PsiBuilder(myLexer, SpringFileNodeType.Instance, new TokenFactory(), def.Lifetime);
                var fileMark = builder.Mark();

                // ParseBlock(builder);
                // ParseExpression(builder);
                ParseCompoundStmt(builder);

                builder.Done(fileMark, SpringFileNodeType.Instance, null);

                if (!builder.Eof())
                {
                    builder.Error("Unexpected token");
                }

                var file = (IFile)builder.BuildTree();
                return(file);
            }
        }