Encapsulates the results and errors from the compilation of a PEG grammar.
        public override void Run(Grammar grammar, CompileResult result)
        {
            var seenSettings = new HashSet<string>();

            foreach (var setting in grammar.Settings)
            {
                var cursor = setting.Key.Start;

                bool singleAllowed;
                if (KnownSettings.TryGetValue(setting.Key.Name, out singleAllowed))
                {
                    if (singleAllowed && !seenSettings.Add(setting.Key.Name))
                    {
                        result.AddCompilerError(cursor, () => Resources.PEG0005_ERROR_SettingAlreadySpecified, setting.Key.Name);
                    }
                }
                else
                {
                    result.AddCompilerError(cursor, () => Resources.PEG0006_WARNING_SettingUnknown, setting.Key.Name);
                }

                string pattern;
                if (ValuePatterns.TryGetValue(setting.Key.Name, out pattern))
                {
                    if (!Regex.IsMatch(setting.Value.ToString(), pattern))
                    {
                        result.AddCompilerError(cursor, () => Resources.PEG0012_ERROR_SettingValueInvalid, setting.Value, setting.Key.Name);
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Compiles a PEG grammar into a program.
        /// </summary>
        /// <param name="grammar">The grammar to compile.</param>
        /// <returns>A <see cref="CompileResult"/> containing the errors, warnings, and results of compilation.</returns>
        public static CompileResult Compile(Grammar grammar)
        {
            var result = new CompileResult(grammar);

            var passes = PassTypes.Select(t => (CompilePass)Activator.CreateInstance(t)).ToList();
            while (true)
            {
                var existingErrors = new HashSet<string>(result.Errors.Where(e => !e.IsWarning).Select(e => e.ErrorNumber));
                var pendingErrors = new HashSet<string>(passes.SelectMany(p => p.ErrorsProduced));

                var nextPasses = passes
                    .Where(p => !p.BlockedByErrors.Any(e => existingErrors.Contains(e)))
                    .Where(p => !p.BlockedByErrors.Any(e => pendingErrors.Contains(e)))
                    .ToList();

                if (nextPasses.Count == 0)
                {
                    break;
                }

                foreach (var pass in nextPasses)
                {
                    pass.Run(grammar, result);
                    passes.Remove(pass);
                }
            }

            return result;
        }
示例#3
0
 public override void Run(Grammar grammar, CompileResult result)
 {
     if (grammar.Rules.Count == 0)
     {
         var cursor = grammar.End;
         result.AddCompilerError(cursor, () => Resources.PEG0001_ERROR_NoRulesDefined);
     }
 }
        public override void Run(Grammar grammar, CompileResult result)
        {
            var types = result.ExpressionTypes;

            foreach (var rule in grammar.Rules)
            {
                if (!types.ContainsKey(rule.Expression))
                {
                    result.AddCompilerError(rule.Identifier.Start, () => Resources.PEG0019_ERROR_UnknownType, rule.Identifier.Name);
                }
            }
        }
示例#5
0
        public override void Run(Grammar grammar, CompileResult result)
        {
            if (result.Errors.Any(e => !e.IsWarning))
            {
                return;
            }

            using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
            {
                new CodeGenerator(stringWriter, result.ExpressionTypes, result.LeftRecursiveRules).WalkGrammar(grammar);
                result.Code = stringWriter.ToString();
            }
        }
        public override void Run(Grammar grammar, CompileResult result)
        {
            var knownRules = new HashSet<string>();

            foreach (var rule in grammar.Rules)
            {
                if (!knownRules.Add(rule.Identifier.Name))
                {
                    var cursor = rule.Identifier.Start;
                    result.AddCompilerError(cursor, () => Resources.PEG0002_ERROR_RuleAlreadyDefined, rule.Identifier.Name);
                }
            }
        }
 public override void Run(Grammar grammar, CompileResult result)
 {
     foreach (var rule in grammar.Rules)
     {
         foreach (var flag in rule.Flags)
         {
             if (!KnownFlags.Contains(flag.Name))
             {
                 var cursor = flag.Start;
                 result.AddCompilerError(cursor, () => Resources.PEG0013_WARNING_FlagUnknown, flag.Name);
             }
         }
     }
 }
示例#8
0
        public override void Run(Grammar grammar, CompileResult result)
        {
            foreach (var rule in result.LeftRecursiveRules)
            {
                if (!rule.Flags.Any(f => f.Name == "memoize"))
                {
                    result.AddCompilerError(rule.Identifier.Start, () => Resources.PEG0020_ERROR_UnmemoizedLeftRecursion, rule.Identifier.Name);
                }
            }

            foreach (var rule in result.MutuallyRecursiveRules)
            {
                result.AddCompilerError(rule.Identifier.Start, () => Resources.PEG0023_ERROR_AmbiguousLeftRecursionDetected, rule.Identifier.Name);
            }
        }
        public override void Run(Grammar grammar, CompileResult result)
        {
            var knownRules = new HashSet<string>(grammar.Rules.Select(r => r.Identifier.Name));

            foreach (var setting in grammar.Settings)
            {
                if (setting.Key.Name == "start")
                {
                    var name = setting.Value.ToString().Trim();
                    if (!knownRules.Contains(name))
                    {
                        result.AddCompilerError(setting.Key.Start, () => Resources.PEG0003_ERROR_RuleDoesNotExist, name);
                    }
                }
            }
        }
 public override void Run(Grammar grammar, CompileResult result)
 {
     foreach (var rule in grammar.Rules)
     {
         if (char.IsLower(rule.Identifier.Name[0]))
         {
             if (rule.Flags.Any(f => f.Name == "public"))
             {
                 result.AddCompilerError(rule.Identifier.Start, () => Resources.PEG0025_WARNING_LowercasePublicRule, rule.Identifier.Name);
             }
             else if (rule.Flags.Any(f => f.Name == "export"))
             {
                 result.AddCompilerError(rule.Identifier.Start, () => Resources.PEG0025_WARNING_LowercaseExportedRule, rule.Identifier.Name);
             }
         }
     }
 }
示例#11
0
        /// <summary>
        /// Parse and compile a PEG grammar from a string.
        /// </summary>
        /// <param name="subject">The PEG grammar to parse and compile.</param>
        /// <param name="fileName">The filename to use in errors.</param>
        /// <returns>A <see cref="CompileResult"/> containing the result of the compilation.</returns>
        public static CompileResult CompileString(string subject, string fileName = null)
        {
            Grammar grammar;
            try
            {
                grammar = new PegParser().Parse(subject ?? string.Empty, fileName);
            }
            catch (FormatException ex)
            {
                var cursor = ex.Data["cursor"] as Cursor;
                if (cursor != null && Regex.IsMatch(ex.Message, @"^PEG\d+:"))
                {
                    var parts = ex.Message.Split(new[] { ':' }, 2);
                    var result = new CompileResult(null);
                    result.Errors.Add(new CompilerError(cursor.FileName ?? string.Empty, cursor.Line, cursor.Column, parts[0], parts[1]));
                    return result;
                }

                throw;
            }

            return PegCompiler.Compile(grammar);
        }
 public CodeSyntaxTreeWalker(CompileResult result)
 {
     this.result = result;
 }
 public override void Run(Grammar grammar, CompileResult result) => new CodeSyntaxTreeWalker(result).WalkGrammar(grammar);
 public ConflictingNamesTreeWalker(CompileResult result)
 {
     this.result = result;
 }
 public override void Run(Grammar grammar, CompileResult result) => new ConflictingNamesTreeWalker(result).WalkGrammar(grammar);
 public override void Run(Grammar grammar, CompileResult result) => new CodeSyntaxTreeWalker(result).WalkGrammar(grammar);
 public override void Run(Grammar grammar, CompileResult result)
 {
     new InvalidQuantifierTreeWalker(result).WalkGrammar(grammar);
 }
 public CodeSyntaxTreeWalker(CompileResult result)
 {
     this.result = result;
 }
示例#19
0
 public UnusedRulesExpressionTreeWalker(CompileResult result)
 {
     this.result = result;
 }
 public MissingRuleExpressionTreeWalker(Grammar grammar, CompileResult result)
 {
     this.knownRules = new HashSet<string>(grammar.Rules.Select(r => r.Identifier.Name));
     this.result = result;
 }
 public override void Run(Grammar grammar, CompileResult result)
 {
     var containsAssertions = ContainsAssertionsEvaluator.Evaluate(grammar);
     var zeroWidth = ZeroWidthEvaluator.Evaluate(grammar);
     new ZeroWidthRepetitionTreeWalker(containsAssertions, zeroWidth, result).WalkGrammar(grammar);
 }
 public InvalidQuantifierTreeWalker(CompileResult result)
 {
     this.result = result;
 }
示例#23
0
 public abstract void Run(Grammar grammar, CompileResult result);
 public override void Run(Grammar grammar, CompileResult result)
 {
     new UnusedRulesExpressionTreeWalker(result).WalkGrammar(grammar);
 }
示例#25
0
 public abstract void Run(Grammar grammar, CompileResult result);
 public UnusedRulesExpressionTreeWalker(CompileResult result)
 {
     this.result = result;
 }
 public override void Run(Grammar grammar, CompileResult result) => new MissingRuleExpressionTreeWalker(result).WalkGrammar(grammar);
 public ZeroWidthRepetitionTreeWalker(Dictionary<Expression, bool> containsAssertions, Dictionary<Expression, bool> zeroWidth, CompileResult result)
 {
     this.containsAssertions = containsAssertions;
     this.result = result;
     this.zeroWidth = zeroWidth;
 }
 public MissingRuleExpressionTreeWalker(CompileResult result)
 {
     this.result = result;
 }
示例#30
0
 public override void Run(Grammar grammar, CompileResult result) => new UnusedRulesExpressionTreeWalker(result).WalkGrammar(grammar);