Пример #1
0
 public void Test_GrammarBuilder_That_LexerRule_With_Two_Calls_To_Range_Terminal_Method_Creates_One_LexerRule()
 {
     var grammarBuilder = new GrammarBuilder("A")
         .Production("A", r => r
             .Rule("B")
             .Rule("C"))
         .LexerRule("M", new CharacterClassTerminal(
             new RangeTerminal('a', 'z'),
             new RangeTerminal('A', 'Z')));
     var grammar = grammarBuilder.ToGrammar();
     Assert.AreEqual(1, grammar.LexerRules.Count);
 }
Пример #2
0
        public void Test_GrammarBuilder_That_Production_With_No_RHS_Adds_Empty_Production_To_List()
        {
            var grammarBuilder = new GrammarBuilder("A")
                .Production("A", r=>r.Lambda());

            var grammar = grammarBuilder.ToGrammar();
            Assert.IsNotNull(grammar);
            Assert.AreEqual(1, grammar.Productions.Count);

            var production = grammar.Productions[0];
            Assert.IsNotNull(production);

            Assert.AreEqual(0, production.RightHandSide.Count);
        }
Пример #3
0
        public void Test_GrammarBuilder_That_Production_With_Character_RHS_Adds_Terminal()
        {
            var grammarBuilder = new GrammarBuilder("A")
                .Production("A", r => r.Rule('a'));

            var grammar = grammarBuilder.ToGrammar();
            Assert.IsNotNull(grammar);
            Assert.AreEqual(1, grammar.Productions.Count);

            var production = grammar.Productions[0];
            Assert.AreEqual(1, production.RightHandSide.Count);

            var symbol = production.RightHandSide[0];
            Assert.IsNotNull(symbol);
            Assert.AreEqual(SymbolType.LexerRule, symbol.SymbolType);
        }
Пример #4
0
 public void Test_Grammar_That_RulesFor_Returns_Rules_When_Production_Matches()
 {
     var B = new NonTerminal("B");
     var A = new NonTerminal("A");
     var S = new NonTerminal("S");
     var grammarBuilder = new GrammarBuilder("S")
         .Production("S", r => r
             .Rule("A")
             .Rule("B"))
         .Production("A", r => r
             .Rule('a'))
         .Production("B", r => r
             .Rule('b'));
     var grammar = grammarBuilder.ToGrammar();
     var rules = grammar.RulesFor(A).ToList();
     Assert.AreEqual(1, rules.Count);
     Assert.AreEqual("A", rules[0].LeftHandSide.Value);
 }
Пример #5
0
 public void Test_GrammarBuilder_That_Production_With_Two_Calls_To_RuleBuilder_Rule_Method_Creates_Two_Productions()
 {
     var grammarBuilder = new GrammarBuilder("A")
         .Production("A", r=>r
             .Rule("B")
             .Rule("C"));
     var grammar = grammarBuilder.ToGrammar();
     Assert.AreEqual(2, grammar.Productions.Count);
 }
Пример #6
0
        static RegexGrammar()
        {
            /*  Regex                      ->   Expression |
             *                                  '^' Expression |
             *                                  Expression '$' |
             *                                  '^' Expression '$'
             *
             *  Expresion                  ->   Term |
             *                                  Term '|' Expression
             *                                  λ
             *
             *  Term                       ->   Factor |
             *                                  Factor Term
             *
             *  Factor                     ->   Atom |
             *                                  Atom Iterator
             *
             *  Atom                       ->   . |
             *                                  Character |
             *                                  '(' Expression ')' |
             *                                  Set
             *
             *  Set                        ->   PositiveSet |
             *                                  NegativeSet
             *
             *  PositiveSet                ->   '[' CharacterClass ']'
             *
             *  NegativeSet                ->   '[^' CharacterClass ']'
             *
             *  CharacterClass             ->   CharacterRange |
             *                                  CharacterRange CharacterClass
             *
             *  CharacterRange             ->   CharacterClassCharacter |
             *                                  CharacterClassCharacter '-' CharacterClassCharacter
             *
             *  Character                  ->   NotMetaCharacter
             *                                  '\' AnyCharacter
             *                                  EscapeSequence
             *
             *  CharacterClassCharacter    ->   NotCloseBracketCharacter |
             *                                  '\' AnyCharacter
             */
            const string Regex = "Regex";
            const string Expression = "Expression";
            const string Term = "Term";
            const string Factor = "Factor";
            const string Atom = "Atom";
            const string Iterator = "Iterator";
            const string Set = "Set";
            const string PositiveSet = "PositiveSet";
            const string NegativeSet = "NegativeSet";
            const string CharacterClass = "CharacterClass";
            const string Character = "Character";
            const string CharacterRange = "CharacterRange";
            const string CharacterClassCharacter = "CharacterClassCharacter";
            const string NotCloseBracket = "NotCloseBracket";
            const string NotMetaCharacter = "NotMetaCharacter";

            var caret = new TerminalLexerRule('^');
            var dollar = new TerminalLexerRule('$');
            var pipe = new TerminalLexerRule('|');
            var dot = new TerminalLexerRule('.');
            var openParen = new TerminalLexerRule('(');
            var closeParen = new TerminalLexerRule(')');
            var star = new TerminalLexerRule('*');
            var plus = new TerminalLexerRule('+');
            var question = new TerminalLexerRule('?');
            var openBracket = new TerminalLexerRule('[');
            var closeBracket = new TerminalLexerRule(']');
            var notCloseBracket = new TerminalLexerRule(new NegationTerminal(new Terminal(']')), new TokenType("!]"));
            var dash = new TerminalLexerRule('-');
            var backslash = new TerminalLexerRule('\\');
            var notMeta = new TerminalLexerRule(
                new NegationTerminal(
                    new SetTerminal('.', '^', '$', '(', ')', '[', ']', '+', '*', '?', '\\')),
                new TokenType("not-meta"));
            var any = new TerminalLexerRule(new AnyTerminal(), new TokenType("any"));

            var grammarBuilder = new GrammarBuilder(Regex)
                .Production(Regex, r => r
                    .Rule(Expression)
                    .Rule(caret, Expression)
                    .Rule(Expression, dollar)
                    .Rule(caret, Expression, dollar))
                .Production(Expression, r => r
                    .Rule(Term)
                    .Rule(Term, pipe, Expression)
                    .Lambda())
                .Production(Term, r => r
                    .Rule(Factor)
                    .Rule(Factor, Term))
                .Production(Factor, r => r
                    .Rule(Atom)
                    .Rule(Atom, Iterator))
                .Production(Atom, r => r
                    .Rule(dot)
                    .Rule(Character)
                    .Rule(openParen, Expression, closeParen)
                    .Rule(Set))
                .Production(Iterator, r => r
                    .Rule(star)
                    .Rule(plus)
                    .Rule(question))
                .Production(Set, r => r
                    .Rule(PositiveSet)
                    .Rule(NegativeSet))
                .Production(PositiveSet, r => r
                    .Rule(openBracket, CharacterClass, closeBracket))
                .Production(NegativeSet, r => r
                    .Rule(openBracket, caret, CharacterClass, closeBracket))
                .Production(CharacterClass, r => r
                    .Rule(CharacterRange)
                    .Rule(CharacterRange, CharacterClass))
                .Production(CharacterRange, r => r
                    .Rule(CharacterClassCharacter)
                    .Rule(CharacterClassCharacter, dash, CharacterClassCharacter))
                .Production(Character, r => r
                    .Rule(NotMetaCharacter)
                    .Rule(backslash, any))
                .Production(CharacterClassCharacter, r => r
                    .Rule(NotCloseBracket)
                    .Rule(backslash, any))
                .Production(NotMetaCharacter, r => r
                    .Rule(notMeta))
                .Production(NotCloseBracket, r => r
                    .Rule(notCloseBracket))
                .LexerRule(caret)
                .LexerRule(dollar)
                .LexerRule(pipe)
                .LexerRule(dot)
                .LexerRule(openParen)
                .LexerRule(closeParen)
                .LexerRule(star)
                .LexerRule(plus)
                .LexerRule(question)
                .LexerRule(openBracket)
                .LexerRule(closeBracket)
                .LexerRule(notCloseBracket)
                .LexerRule(dash)
                .LexerRule(backslash)
                .LexerRule(notMeta)
                .LexerRule(any);
            _regexGrammar = grammarBuilder.ToGrammar();
        }