Exemplo n.º 1
0
        public override BuildResult <Parser <IN, OUT> > BuildParser(object parserInstance, ParserType parserType,
                                                                    string rootRule, BuildExtension <IN> extensionBuilder = null)
        {
            var ruleparser = new RuleParser <IN>();
            var builder    = new ParserBuilder <EbnfTokenGeneric, GrammarNode <IN> >();

            var grammarParser = builder.BuildParser(ruleparser, ParserType.LL_RECURSIVE_DESCENT, "rule").Result;


            var result = new BuildResult <Parser <IN, OUT> >();

            ParserConfiguration <IN, OUT> configuration = null;

            try
            {
                configuration = ExtractEbnfParserConfiguration(parserInstance.GetType(), grammarParser);
                LeftRecursionChecker <IN, OUT> recursionChecker = new LeftRecursionChecker <IN, OUT>();
                var(foundRecursion, recursions) = LeftRecursionChecker <IN, OUT> .CheckLeftRecursion(configuration);

                if (foundRecursion)
                {
                    var recs = string.Join("\n", recursions.Select(x => string.Join(" > ", x)));
                    result.AddError(new ParserInitializationError(ErrorLevel.FATAL, $"left recursion detected : {recs}", ErrorCodes.PARSER_LEFT_RECURSIVE));
                    return(result);
                }

                configuration.StartingRule = rootRule;
            }
            catch (Exception e)
            {
                result.AddError(new ParserInitializationError(ErrorLevel.ERROR, e.Message, ErrorCodes.PARSER_UNKNOWN_ERROR));
                return(result);
            }

            var syntaxParser = BuildSyntaxParser(configuration, parserType, rootRule);

            SyntaxTreeVisitor <IN, OUT> visitor = null;

            if (parserType == ParserType.LL_RECURSIVE_DESCENT)
            {
                new SyntaxTreeVisitor <IN, OUT>(configuration, parserInstance);
            }
            else if (parserType == ParserType.EBNF_LL_RECURSIVE_DESCENT)
            {
                visitor = new EBNFSyntaxTreeVisitor <IN, OUT>(configuration, parserInstance);
            }
            var parser = new Parser <IN, OUT>(syntaxParser, visitor);

            parser.Configuration = configuration;
            var lexerResult = BuildLexer(extensionBuilder);

            if (lexerResult.IsError)
            {
                foreach (var lexerResultError in lexerResult.Errors)
                {
                    result.AddError(lexerResultError);
                }
                return(result);
            }
            else
            {
                parser.Lexer = lexerResult.Result;
            }
            parser.Instance = parserInstance;
            result.Result   = parser;
            return(result);
        }