Exemple #1
0
        /// <summary>
        ///     Builds a parser (lexer, syntax parser and syntax tree visitor) according to a parser definition instance
        /// </summary>
        /// <typeparam name="IN"></typeparam>
        /// <param name="parserInstance">
        ///     a parser definition instance , containing
        ///     [Reduction] methods for grammar rules
        ///     <param name="parserType">
        ///         a ParserType enum value stating the analyser type (LR, LL ...) for now only LL recurive
        ///         descent parser available
        ///     </param>
        ///     <param name="rootRule">the name of the root non terminal of the grammar</param>
        ///     <returns></returns>
        public virtual BuildResult <Parser <IN, OUT> > BuildParser(object parserInstance, ParserType parserType,
                                                                   string rootRule, BuildExtension <IN> extensionBuilder = null)
        {
            Parser <IN, OUT> parser = null;
            var result = new BuildResult <Parser <IN, OUT> >();

            if (parserType == ParserType.LL_RECURSIVE_DESCENT)
            {
                var configuration = ExtractParserConfiguration(parserInstance.GetType());
                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;
                var syntaxParser = BuildSyntaxParser(configuration, parserType, rootRule);
                var visitor      = new SyntaxTreeVisitor <IN, OUT>(configuration, parserInstance);
                parser = new Parser <IN, OUT>(syntaxParser, visitor);
                var lexerResult = BuildLexer(extensionBuilder);
                parser.Lexer = lexerResult.Result;
                if (lexerResult.IsError)
                {
                    result.Errors.AddRange(lexerResult.Errors);
                    return(result);
                }
                parser.Instance      = parserInstance;
                parser.Configuration = configuration;
                result.Result        = parser;
            }
            else if (parserType == ParserType.EBNF_LL_RECURSIVE_DESCENT)
            {
                var builder = new EBNFParserBuilder <IN, OUT>();
                result = builder.BuildParser(parserInstance, ParserType.EBNF_LL_RECURSIVE_DESCENT, rootRule,
                                             extensionBuilder);
            }

            parser = result.Result;
            if (!result.IsError)
            {
                var expressionResult = parser.BuildExpressionParser(result, rootRule);
                if (expressionResult.IsError)
                {
                    result.AddErrors(expressionResult.Errors);
                }
                result.Result.Configuration = expressionResult.Result;

                result = CheckParser(result);
                if (result.IsError)
                {
                    result.Result = null;
                }
            }
            else
            {
                result.Result = null;
            }

            return(result);
        }
Exemple #2
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);
        }