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); }
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); }
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); }
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); }
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); }
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(); }