示例#1
0
 public override void Validate(LexerSpec lexerSpec)
 {
     foreach (var expression in Expressions)
     {
         expression.Validate(lexerSpec);
     }
 }
        public override RegexSpec Simplify(LexerSpec lexerSpec)
        {
            // a-b -> !(!a|b)
            var expanded = Expressions.Aggregate((exp1, exp2) => new ComplementSpec(new AlternationSpec(new[] { new ComplementSpec(exp1), exp2 })));

            return(expanded.Simplify(lexerSpec));
        }
示例#3
0
 public override void Validate(LexerSpec lexerSpec)
 {
     if (!lexerSpec.Rules.Contains(RuleName))
     {
         throw new Exception($"Reference to rule '{RuleName}' that isn't in lexer spec.");
     }
 }
示例#4
0
        public sealed override RegexSpec Simplify(LexerSpec lexerSpec)
        {
            var codePoints = InversionListCodePointSet.Empty;
            var simplified = new List <RegexSpec>();

            foreach (var exp in Expressions.Select(e => e.Simplify(lexerSpec)))
            {
                var charClass = exp.AsCharClass();
                if (charClass != null)
                {
                    // [x]|[y] -> [xy]
                    codePoints = codePoints.Union(charClass.CodePoints);
                }
                else
                {
                    simplified.Add(exp);
                }
            }
            if (!codePoints.IsEmpty())
            {
                simplified.Add(new CharClassSpec(codePoints));
            }

            //  All expressions reduced
            if (simplified.Count == 1)
            {
                return(simplified[0]);
            }

            return(Expressions.SequenceEqual(simplified) ? this : new AlternationSpec(simplified));
        }
示例#5
0
 public override void Validate(RuleSpec rule, LexerSpec lexer)
 {
     if (!lexer.Channels.Contains(Channel))
     {
         throw new Exception($"Rule '{rule.Name}' references channel not in lexer spec: '{Channel}'");
     }
 }
        public override RegexSpec Simplify(LexerSpec lexerSpec)
        {
            // a&b&c -> !(!a|!b|!c)
            var expanded = new ComplementSpec(new AlternationSpec(Expressions.Select(exp => new ComplementSpec(exp))));

            return(expanded.Simplify(lexerSpec));
        }
 public override void Validate(RuleSpec rule, LexerSpec lexer)
 {
     if (!lexer.Modes.Contains(Mode))
     {
         throw new Exception($"Rule '{rule.Name}' references mode not in lexer spec: '{Mode}'");
     }
 }
 public void Validate(LexerSpec lexer)
 {
     var modeReferenceErrors = Modes.Except(lexer.Modes).ToList();
     if(modeReferenceErrors.Any())
         throw new Exception($"Rule '{Name}' references mode(s) not in lexer spec: '{string.Join("', '", modeReferenceErrors)}'");
     ValidateCommands(lexer);
     Expression.Validate(lexer);
 }
        public RuleSpec Simplify(ISet<Mode> modesEntered, LexerSpec lexer)
        {
            var reducedModes = new HashSet<Mode>(Modes.Intersect(modesEntered));
            var simplfiedExpression = Expression.Simplify(lexer);
            if(reducedModes.Count >= Modes.Count && Expression == simplfiedExpression) return this;

            return new RuleSpec(reducedModes, Name, simplfiedExpression, Commands);
        }
        public override void Validate(RuleSpec rule, LexerSpec lexer)
        {
            if(!lexer.Rules.Contains(TokenType))
                throw new Exception($"Rule '{rule.Name}' references type not in lexer spec: '{TokenType}'");

            if(lexer.Rules[TokenType].IsFragment)
                throw new Exception($"Rule '{rule.Name}' references fragment for token type: '{TokenType}'");
        }
示例#11
0
        protected override RegexSpec Simplify(LexerSpec lexerSpec, RegexSpec exp, bool changed)
        {
            // ~a -> !([^]* a [^]*)
            var anyChar       = new CharClassSpec(InversionListCodePointSet.All);
            var repetition    = new RepetitionSpec(anyChar, 0, null);
            var concatenation = new ConcatenationSpec(new[] { repetition, exp, repetition });
            var expanded      = new ComplementSpec(concatenation);

            return(expanded.Simplify(lexerSpec));
        }
        protected override RegexSpec Simplify(LexerSpec lexerSpec, RegexSpec exp, bool changed)
        {
            // x{1,1} -> x
            if (MinRepititions == 1 && MaxRepititions == 1)
            {
                return(exp);
            }

            return(changed ? new RepetitionSpec(exp, MinRepititions, MaxRepititions) : this);
        }
        public void Validate(LexerSpec lexer)
        {
            var modeReferenceErrors = Modes.Except(lexer.Modes).ToList();

            if (modeReferenceErrors.Any())
            {
                throw new Exception($"Rule '{Name}' references mode(s) not in lexer spec: '{string.Join("', '", modeReferenceErrors)}'");
            }
            ValidateCommands(lexer);
            Expression.Validate(lexer);
        }
示例#14
0
        public override void Validate(RuleSpec rule, LexerSpec lexer)
        {
            if (!lexer.Rules.Contains(TokenType))
            {
                throw new Exception($"Rule '{rule.Name}' references type not in lexer spec: '{TokenType}'");
            }

            if (lexer.Rules[TokenType].IsFragment)
            {
                throw new Exception($"Rule '{rule.Name}' references fragment for token type: '{TokenType}'");
            }
        }
        public RuleSpec Simplify(ISet <Mode> modesEntered, LexerSpec lexer)
        {
            var reducedModes        = new HashSet <Mode>(Modes.Intersect(modesEntered));
            var simplfiedExpression = Expression.Simplify(lexer);

            if (reducedModes.Count >= Modes.Count && Expression == simplfiedExpression)
            {
                return(this);
            }

            return(new RuleSpec(reducedModes, Name, simplfiedExpression, Commands));
        }
        protected override RegexSpec Simplify(LexerSpec lexerSpec, RegexSpec exp, bool changed)
        {
            // ![x] -> [^x]
            var charClass = Expression.Simplify(lexerSpec).AsCharClass();

            if (charClass != null)
            {
                return(new CharClassSpec(charClass.CodePoints.Complement()));
            }

            // !!x -> x
            var complement = exp as ComplementSpec;

            if (complement != null)
            {
                return(complement.Expression);
            }

            return(changed ? new ComplementSpec(exp) : this);
        }
 public override void Validate(LexerSpec lexerSpec)
 {
     Expression.Validate(lexerSpec);
 }
 public override void Validate(LexerSpec lexerSpec)
 {
     Expression.Validate(lexerSpec);
 }
示例#19
0
        public override RegexSpec Simplify(LexerSpec lexerSpec)
        {
            var simplified = Expressions.Select(e => e.Simplify(lexerSpec)).ToList();

            return(Expressions.SequenceEqual(simplified) ? this : new ConcatenationSpec(simplified));
        }
示例#20
0
 public virtual void Validate(RuleSpec rule, LexerSpec lexer)
 {
 }
 protected abstract RegexSpec Simplify(LexerSpec lexerSpec, RegexSpec exp, bool changed);
示例#22
0
 public virtual void Validate(LexerSpec lexerSpec)
 {
 }
        static ThrowAway()
        {
            var newline    = new AlternationSpec(new RegexSpec[] { "\r", "\n", "\u2028", "\u2029", "\u000B", "\u000C", "\u0085", "\r\n" });
            var whitespace = new AlternationSpec(new RegexSpec[] { newline, " ", "\t", "\f", "\v" });
            var digit      = Class('0', '9');
            var hexDigit   = new AlternationSpec(new[] { digit, Class('a', 'f'), Class('A', 'F') });

            var charClassChar = new CharClassSpec(new InversionListCodePointSet('\\')
                                                  .Union(new InversionListCodePointSet('-'))
                                                  .Union(new InversionListCodePointSet(']')).Complement());

            var defaultChannel    = new Channel("Default");
            var whiteSpaceChannel = new Channel("WhiteSpace");
            var initial           = new Mode("Default");
            var startCharClass    = new Mode("StartCharacterClass");
            var charClass         = new Mode("CharacterClass");

            SpecLexerSpec = new LexerSpec("SpecLexer", "Adamant.CompilerCompiler.Lex.SpecParsing", new[]
            {
                // Comments
                new RuleSpec(initial, "Comment", ("/*" + ~R("*/")) | ("//" + ~newline), Command.SetChannel(whiteSpaceChannel)),
                new RuleSpec(initial, "WhiteSpace", whitespace.RepeatAtLeast(1), Command.SetChannel(whiteSpaceChannel)),

                // Commands
                new RuleSpec(initial, "Mode", "@mode"),
                new RuleSpec(initial, "PushMode", "@pushMode"),
                new RuleSpec(initial, "PopMode", "@popMode"),
                new RuleSpec(initial, "Skip", "@skip"),
                new RuleSpec(initial, "More", "@more"),
                new RuleSpec(initial, "Type", "@type"),
                new RuleSpec(initial, "Channel", "@channel"),
                new RuleSpec(initial, "Error", "@error"),
                new RuleSpec(initial, "Capture", "@capture"),
                new RuleSpec(initial, "Decode", "@decode"),
                new RuleSpec(initial, "Text", "@text"),
                new RuleSpec(initial, "Action", "<%" + ~R("%>"), Command.Capture),

                // Keywords
                new RuleSpec(initial, "Lexer", "@lexer"),
                new RuleSpec(initial, "Namespace", "@namespace"),
                new RuleSpec(initial, "Modes", "@modes"),
                new RuleSpec(initial, "Channels", "@channels"),
                new RuleSpec(initial, "InvalidKeyword", "@" + new RuleReferenceSpec("Identifier"), Command.Capture, Command.FlagError),

                // Expression Operators
                new RuleSpec(initial, "Definition", ":"),
                new RuleSpec(initial, "Alternation", "|"),
                new RuleSpec(initial, "BeginCharClass", "[", Command.Capture, Command.PushMode(startCharClass)),
                new RuleSpec(initial, "AnyChar", "."),
                new RuleSpec(initial, "Optional", "?"),
                new RuleSpec(initial, "Complement", "!"),
                new RuleSpec(initial, "Repetition", "*"),
                new RuleSpec(initial, "Intersection", "&"),
                new RuleSpec(initial, "Subtraction", "-"),
                new RuleSpec(initial, "Upto", "~"),
                new RuleSpec(initial, "BeginGroup", "("),
                new RuleSpec(initial, "EndGroup", ")"),
                new RuleSpec(initial, "BeginningOfLine", "^"),
                new RuleSpec(initial, "EndOfLine", "$"),
                new RuleSpec(initial, "BeginQuantifier", "{"),
                new RuleSpec(initial, "EndQuantifier", "}"),
                new RuleSpec(initial, "BeginCommands", "->"),
                new RuleSpec(initial, "Terminator", ";"),
                new RuleSpec(initial, "Comma", ","),

                // Terminals
                new RuleSpec(initial, "Number", "0" | (Class('1', '9') + digit), Command.Capture),
                new RuleSpec(initial, "Identifier", (Class('a', 'z') | Class('A', 'Z')) + (Class('a', 'z') | Class('A', 'Z') | digit).Repeat(), Command.Capture),
                new RuleSpec(initial, "Literal", R("\"") + new RuleReferenceSpec("literalChar").RepeatAtLeast(1) + R("\"") | new RuleReferenceSpec("escapeChar"), Command.Capture),
                new RuleSpec(initial, "literalChar", new RuleReferenceSpec("escapeChar") | !(R("\\") | "\"")),

                new RuleSpec(initial, "Category", R("\\R") | "\\s" | "\\d"),

                // Fragments
                new RuleSpec(initial, "escapeChar",
                             R("\\t")
                             | R("\\n")
                             | R("\\r")
                             | R("\\b")
                             | R("\\f")
                             | R("\\0")
                             | R("\\a")
                             | R("\\v")
                             | R("\\\"")
                             | R("\\{")
                             | R("\\'")
                             | R("\\\\")
                             | (R("\\x") + hexDigit.Repeat(2))
                             | (R("\\u") + hexDigit.Repeat(4))
                             | (R("\\U") + hexDigit.Repeat(6))
                             | (R("\\u{") + hexDigit.Repeat(1, 6) + R("}"))),

                // Fallback
                new RuleSpec(initial, "UnexpectedCodePoint", new CharClassSpec(InversionListCodePointSet.All), Command.Capture, Command.FlagError),

                // Character Classes
                new RuleSpec(startCharClass, "NegateCharClass", "^", Command.SetMode(charClass)),
                new RuleSpec(charClass, "Char", new RuleReferenceSpec("escapeChar") | charClassChar, Command.Capture, Command.SetMode(charClass)),
                new RuleSpec(charClass, "EscapeDash", R("\\-"), Command.Text("-"), Command.SetType("Char"), Command.SetMode(charClass)),
                new RuleSpec(charClass, "EscapeRightBracket", R("\\]"), Command.Text("-"), Command.SetType("Char"), Command.SetMode(charClass)),
                new RuleSpec(charClass, "CharRange", "-", Command.SetMode(charClass)),
                new RuleSpec(charClass, "EndCharClass", "]", Command.PopMode),
            },
                                          new[] { defaultChannel, whiteSpaceChannel },
                                          defaultChannel,
                                          new[] { initial, startCharClass, charClass },
                                          initial);
        }
 public override void Validate(RuleSpec rule, LexerSpec lexer)
 {
     if(!lexer.Modes.Contains(Mode))
         throw new Exception($"Rule '{rule.Name}' references mode not in lexer spec: '{Mode}'");
 }
 public override void Validate(RuleSpec rule, LexerSpec lexer)
 {
     if(!lexer.Channels.Contains(Channel))
         throw new Exception($"Rule '{rule.Name}' references channel not in lexer spec: '{Channel}'");
 }
示例#26
0
 public override RegexSpec Simplify(LexerSpec lexerSpec)
 {
     return(lexerSpec.Rules[RuleName].Expression.Simplify(lexerSpec));
 }
        private void ValidateCommands(LexerSpec lexer)
        {
            if (IsFragment && Commands.Any())
            {
                throw new Exception($"Rule '{Name}' is a fragment, but has commands.  This is not allowed");
            }

            if (Commands.Count(c => c == Command.Skip || c == Command.More || c is SetTypeCommand) > 1)
            {
                throw new Exception($"Rule '{Name}', only one of @skip, @more or @type command is allowed per rule");
            }

            if (Commands.Count(c => c == Command.Capture || c is DecodeCommand || c is TextCommand) > 1)
            {
                throw new Exception($"Rule '{Name}', only one of @capture, @decode or @text command is allowed per rule");
            }

            if (Commands.Contains(Command.Skip) && Commands.Contains(Command.FlagError))
            {
                throw new Exception($"Rule '{Name}', skipped rules can't be marked @error");
            }

            if (Commands.Contains(Command.Skip) && Commands.Contains(Command.Capture))
            {
                throw new Exception($"Rule '{Name}', skipped rules can't be marked @capture");
            }

            if (Commands.Contains(Command.Skip) && Commands.Any(c => c is DecodeCommand))
            {
                throw new Exception($"Rule '{Name}', skipped rules can't be marked @decode");
            }

            if (Commands.Contains(Command.Skip) && Commands.Any(c => c is DecodeCommand))
            {
                throw new Exception($"Rule '{Name}', skipped rules can't be marked @text");
            }

            if (Commands.Contains(Command.Skip) && Commands.Any(c => c is SetChannelCommand))
            {
                throw new Exception($"Rule '{Name}', skipped rules can't be marked with a @channel");
            }

            if (Commands.Contains(Command.More) && Commands.Contains(Command.FlagError))
            {
                throw new Exception($"Rule '{Name}', more rules can't be marked @error");
            }

            if (Commands.Contains(Command.More) && Commands.Any(c => c is SetChannelCommand))
            {
                throw new Exception($"Rule '{Name}', more rules can't be marked with a @channel");
            }

            if (Commands.OfType <SetChannelCommand>().Count() > 1)
            {
                throw new Exception($"Rule '{Name}', only one @channel command is allowed per rule");
            }

            if (Commands.Count(c => c == Command.FlagError) > 1)
            {
                throw new Exception($"Rule '{Name}', only one @error command is allowed per rule");
            }

            if (Commands.Reverse().Skip(1).Any(c => c is CodeActionCommand))
            {
                throw new Exception($"Rule '{Name}', there can only be one code action per rule, and it must be the last command");
            }

            foreach (var command in Commands)
            {
                command.Validate(this, lexer);
            }
        }
 public override RegexSpec Simplify(LexerSpec lexerSpec)
 {
     var simplifiedExpression = Expression.Simplify(lexerSpec);
     return Simplify(lexerSpec, simplifiedExpression, simplifiedExpression != Expression);
 }
        public override RegexSpec Simplify(LexerSpec lexerSpec)
        {
            var simplifiedExpression = Expression.Simplify(lexerSpec);

            return(Simplify(lexerSpec, simplifiedExpression, simplifiedExpression != Expression));
        }
 protected abstract RegexSpec Simplify(LexerSpec lexerSpec, RegexSpec exp, bool changed);
        private void ValidateCommands(LexerSpec lexer)
        {
            if(IsFragment && Commands.Any())
                throw new Exception($"Rule '{Name}' is a fragment, but has commands.  This is not allowed");

            if(Commands.Count(c => c == Command.Skip || c == Command.More || c is SetTypeCommand) > 1)
                throw new Exception($"Rule '{Name}', only one of @skip, @more or @type command is allowed per rule");

            if(Commands.Count(c => c == Command.Capture || c is DecodeCommand || c is TextCommand) > 1)
                throw new Exception($"Rule '{Name}', only one of @capture, @decode or @text command is allowed per rule");

            if(Commands.Contains(Command.Skip) && Commands.Contains(Command.FlagError))
                throw new Exception($"Rule '{Name}', skipped rules can't be marked @error");

            if(Commands.Contains(Command.Skip) && Commands.Contains(Command.Capture))
                throw new Exception($"Rule '{Name}', skipped rules can't be marked @capture");

            if(Commands.Contains(Command.Skip) && Commands.Any(c => c is DecodeCommand))
                throw new Exception($"Rule '{Name}', skipped rules can't be marked @decode");

            if(Commands.Contains(Command.Skip) && Commands.Any(c => c is DecodeCommand))
                throw new Exception($"Rule '{Name}', skipped rules can't be marked @text");

            if(Commands.Contains(Command.Skip) && Commands.Any(c => c is SetChannelCommand))
                throw new Exception($"Rule '{Name}', skipped rules can't be marked with a @channel");

            if(Commands.Contains(Command.More) && Commands.Contains(Command.FlagError))
                throw new Exception($"Rule '{Name}', more rules can't be marked @error");

            if(Commands.Contains(Command.More) && Commands.Any(c => c is SetChannelCommand))
                throw new Exception($"Rule '{Name}', more rules can't be marked with a @channel");

            if(Commands.OfType<SetChannelCommand>().Count() > 1)
                throw new Exception($"Rule '{Name}', only one @channel command is allowed per rule");

            if(Commands.Count(c => c == Command.FlagError) > 1)
                throw new Exception($"Rule '{Name}', only one @error command is allowed per rule");

            if(Commands.Reverse().Skip(1).Any(c => c is CodeActionCommand))
                throw new Exception($"Rule '{Name}', there can only be one code action per rule, and it must be the last command");

            foreach(var command in Commands)
                command.Validate(this, lexer);
        }
 public override void Validate(LexerSpec lexerSpec)
 {
     foreach(var expression in Expressions)
         expression.Validate(lexerSpec);
 }
示例#33
0
 public virtual RegexSpec Simplify(LexerSpec lexerSpec)
 {
     return(this);
 }