public void CreateWithNoStartRules() { var terminals = new TerminalSymbol[] { new TerminalSymbol("a"), new TerminalSymbol("b"), }; var grammaticals = new GrammaticalSymbol[] { new GrammaticalSymbol("S"), new GrammaticalSymbol("A"), }; var rules = new Rule[] { new Rule(grammaticals[1], new Symbol[]{ terminals[0] }), new Rule(grammaticals[1], new Symbol[]{ terminals[1] }), }; var gr = new RestrictedStartSymbolGrammar(new Grammar(terminals, grammaticals, rules, 0)); Assert.Equal(2, gr.Grammaticals.Count); Assert.Equal(3, gr.Rules.Count); Assert.Equal(gr.StartSymbol, gr.StartRule.LeftHandSide); Assert.True(gr.StartRule.IsEpsilonRule); }
public void CreateWithMultipleStartRules() { var terminals = new TerminalSymbol[] { new TerminalSymbol("a"), new TerminalSymbol("b"), }; var grammaticals = new GrammaticalSymbol[] { new GrammaticalSymbol("S"), }; var rules = new Rule[] { new Rule(grammaticals[0], new Symbol[]{ terminals[0] }), new Rule(grammaticals[0], new Symbol[]{ terminals[1] }), }; var gr = new RestrictedStartSymbolGrammar(new Grammar(terminals, grammaticals, rules, 0)); Assert.Equal(2, gr.Grammaticals.Count); Assert.Equal(3, gr.Rules.Count); Assert.Equal(1, gr.Rules.Count(r => r.LeftHandSide == gr.StartSymbol)); Assert.True(gr.Rules.FirstOrDefault(r => r.RightHandSide.IndexOf(gr.StartSymbol) != -1) == null); }
static Grammar1() { var terminals = new TerminalSymbol[] { new TerminalSymbol("a"), }; var grammaticals = new GrammaticalSymbol[] { new GrammaticalSymbol("S"), }; var rules = new Rule[] { // S->aS new Rule( grammaticals[0], new Symbol[] { terminals[0], grammaticals[0], }), // S-> new Rule( grammaticals[0], new Symbol[0]), }; BaseGrammar = new Grammar(terminals, grammaticals, rules, 0); RestrictedGrammar = new RestrictedStartSymbolGrammar(BaseGrammar); ExtendedGrammar = new ExtendedGrammar(RestrictedGrammar); EpsilonGrammaticals = new HashSet<GrammaticalSymbol>(RestrictedGrammar.Grammaticals); FirstSets = new Dictionary<GrammaticalSymbol, ISet<TerminalSymbol>>(); // S': a,Eps FirstSets[ExtendedGrammar.StartSymbol] = new HashSet<TerminalSymbol>(BaseGrammar.Terminals); FirstSets[ExtendedGrammar.StartSymbol].Add(EpsilonSymbol.Instance); // S: a,Eps FirstSets[BaseGrammar.StartSymbol] = new HashSet<TerminalSymbol>(BaseGrammar.Terminals); FirstSets[BaseGrammar.StartSymbol].Add(EpsilonSymbol.Instance); FollowSets = new Dictionary<GrammaticalSymbol, ISet<TerminalSymbol>>(); // S': FollowSets[ExtendedGrammar.Grammaticals[0]] = new HashSet<TerminalSymbol>(); // S: # FollowSets[ExtendedGrammar.Grammaticals[1]] = new HashSet<TerminalSymbol>(); FollowSets[ExtendedGrammar.Grammaticals[1]].Add(ExtendedGrammar.EndOfSourceSymbol); }
public void CreateWithForeignTerminalInRule() { var foreign_symbol = new TerminalSymbol("TestTerminal"); var bad_rule = new Rule( Fixtures.EmptyGrammar.BaseGrammar.Grammaticals[0], new Symbol[] { foreign_symbol }); var ex = Assert.Throws<ForeignSymbolInRuleException>( () => new Grammar( Fixtures.EmptyGrammar.BaseGrammar.Terminals, Fixtures.EmptyGrammar.BaseGrammar.Grammaticals, new Rule[] { Fixtures.EmptyGrammar.BaseGrammar.Rules[0], bad_rule, }, 0) ); Assert.Equal(bad_rule, ex.Rule); Assert.Equal(foreign_symbol, ex.Symbol); }
static Grammar3() { var terminals = new TerminalSymbol[] { new TerminalSymbol("a"), new TerminalSymbol("b"), }; var grammaticals = new GrammaticalSymbol[] { new GrammaticalSymbol("S"), new GrammaticalSymbol("A"), new GrammaticalSymbol("B"), }; var rules = new Rule[] { // S->AB new Rule( grammaticals[0], new Symbol[] { grammaticals[1], grammaticals[2], }), // S->aSbS new Rule( grammaticals[1], new Symbol[] { terminals[0], grammaticals[0], terminals[1], grammaticals[0], }), // A-> new Rule( grammaticals[1], new Symbol[0]), // B-> new Rule( grammaticals[2], new Symbol[0]), }; BaseGrammar = new Grammar(terminals, grammaticals, rules, 0); RestrictedGrammar = new RestrictedStartSymbolGrammar(BaseGrammar); ExtendedGrammar = new ExtendedGrammar(RestrictedGrammar); EpsilonGrammaticals = new HashSet<GrammaticalSymbol>(ExtendedGrammar.Grammaticals); FollowSets = new Dictionary<GrammaticalSymbol, ISet<TerminalSymbol>>(); // S': - FollowSets[ExtendedGrammar.StartSymbol] = new HashSet<TerminalSymbol>(); // S: b,# FollowSets[ExtendedGrammar.Grammaticals[1]] = new HashSet<TerminalSymbol>( new TerminalSymbol[]{ ExtendedGrammar.Terminals[1], ExtendedGrammar.EndOfSourceSymbol, }); // A: b,# FollowSets[ExtendedGrammar.Grammaticals[2]] = FollowSets[ExtendedGrammar.Grammaticals[1]]; // B: b,# FollowSets[ExtendedGrammar.Grammaticals[3]] = FollowSets[ExtendedGrammar.Grammaticals[1]]; }
public ForeignSymbolInRuleException( Rule rule, Symbol symbol ) { this.Rule = rule; this.Symbol = symbol; }
static Grammar2() { var terminals = new TerminalSymbol[] { new TerminalSymbol("+"), new TerminalSymbol("*"), new TerminalSymbol("("), new TerminalSymbol(")"), new TerminalSymbol("i"), }; var grammaticals = new GrammaticalSymbol[] { new GrammaticalSymbol("S"), new GrammaticalSymbol("E"), new GrammaticalSymbol("E'"), new GrammaticalSymbol("T"), new GrammaticalSymbol("T'"), new GrammaticalSymbol("F"), }; var rules = new Rule[] { // S->E new Rule( grammaticals[0], new Symbol[] { grammaticals[1], }), // E->TE' new Rule( grammaticals[1], new Symbol[] { grammaticals[3], grammaticals[2], }), // E'->+TE' new Rule( grammaticals[2], new Symbol[] { terminals[0], grammaticals[3], grammaticals[2], }), // E'-> new Rule( grammaticals[2], new Symbol[] { }), // T->FT' new Rule( grammaticals[3], new Symbol[] { grammaticals[5], grammaticals[4], }), // T'->*FT' new Rule( grammaticals[4], new Symbol[] { terminals[1], grammaticals[5], grammaticals[4], }), // T'-> new Rule( grammaticals[4], new Symbol[] { }), // F->(E) new Rule( grammaticals[5], new Symbol[] { terminals[2], grammaticals[1], terminals[3], }), // F->i new Rule( grammaticals[5], new Symbol[] { terminals[4], }), }; BaseGrammar = new Grammar(terminals, grammaticals, rules, 0); RestrictedGrammar = new RestrictedStartSymbolGrammar(BaseGrammar); ExtendedGrammar = new ExtendedGrammar(RestrictedGrammar); EpsilonGrammaticals = new HashSet<GrammaticalSymbol>( new GrammaticalSymbol[] { grammaticals[2], grammaticals[4] }); FirstSets = new Dictionary<GrammaticalSymbol, ISet<TerminalSymbol>>(); // S: (,i FirstSets[BaseGrammar.Grammaticals[0]] = new HashSet<TerminalSymbol>(new TerminalSymbol[] { BaseGrammar.Terminals[2], BaseGrammar.Terminals[4], }); // E: (,i FirstSets[BaseGrammar.Grammaticals[1]] = new HashSet<TerminalSymbol>(new TerminalSymbol[] { BaseGrammar.Terminals[2], BaseGrammar.Terminals[4], }); // E': +,Eps FirstSets[BaseGrammar.Grammaticals[2]] = new HashSet<TerminalSymbol>(new TerminalSymbol[] { BaseGrammar.Terminals[0], EpsilonSymbol.Instance, }); // T: (,i FirstSets[BaseGrammar.Grammaticals[3]] = new HashSet<TerminalSymbol>(new TerminalSymbol[] { BaseGrammar.Terminals[2], BaseGrammar.Terminals[4], }); // T': *,Eps FirstSets[BaseGrammar.Grammaticals[4]] = new HashSet<TerminalSymbol>(new TerminalSymbol[] { BaseGrammar.Terminals[1], EpsilonSymbol.Instance, }); // F: (,i FirstSets[BaseGrammar.Grammaticals[5]] = new HashSet<TerminalSymbol>(new TerminalSymbol[] { BaseGrammar.Terminals[2], BaseGrammar.Terminals[4], }); FollowSets = new Dictionary<GrammaticalSymbol, ISet<TerminalSymbol>>(); // S: FollowSets[ExtendedGrammar.Grammaticals[0]] = new HashSet<TerminalSymbol>(); // E: ),EoS FollowSets[ExtendedGrammar.Grammaticals[1]] = new HashSet<TerminalSymbol>(new TerminalSymbol[] { ExtendedGrammar.Terminals[3], ExtendedGrammar.Terminals[5], }); // E': ),EoS FollowSets[ExtendedGrammar.Grammaticals[2]] = new HashSet<TerminalSymbol>(new TerminalSymbol[] { ExtendedGrammar.Terminals[3], ExtendedGrammar.Terminals[5], }); // T: +,),EoS FollowSets[ExtendedGrammar.Grammaticals[3]] = new HashSet<TerminalSymbol>(new TerminalSymbol[] { ExtendedGrammar.Terminals[0], ExtendedGrammar.Terminals[3], ExtendedGrammar.Terminals[5], }); // T': +,),EoS FollowSets[ExtendedGrammar.Grammaticals[4]] = new HashSet<TerminalSymbol>(new TerminalSymbol[] { ExtendedGrammar.Terminals[0], ExtendedGrammar.Terminals[3], ExtendedGrammar.Terminals[5], }); // F: +,*,),EoS FollowSets[ExtendedGrammar.Grammaticals[5]] = new HashSet<TerminalSymbol>(new TerminalSymbol[] { ExtendedGrammar.Terminals[0], ExtendedGrammar.Terminals[1], ExtendedGrammar.Terminals[3], ExtendedGrammar.Terminals[5], }); //TODO: Use real fixture!! LR0CanonicalSets = LR0CanonicalSets.Build(RestrictedGrammar); //TODO: Use real fixtures!! SLR1ParserTable = SLR1ParserTableBuilder.Build(ExtendedGrammar, LR0CanonicalSets, FollowSets); }
/// <summary> /// Tells if this rule is considered equal to another one. /// </summary> /// <param name="other">The other rule to compare to.</param> /// <returns><c>true</c> if they are equal, <c>false</c> otherwise.</returns> public bool Equals( Rule other ) { if( other == null || !this.lhs.Equals(other.lhs) || this.rhs.Count != other.rhs.Count ) return false; for( int i = 0; i < this.rhs.Count; ++i ) if( !this.rhs[i].Equals(other.rhs[i]) ) return false; return true; }
private void Initialize() { this.eos = new EndOfSourceSymbol(); var terminals = new List<TerminalSymbol>(this.base_gr.Terminals); terminals.Add(this.eos); this.terminals = terminals.AsReadOnly(); var start_rule_rhs = new List<Symbol>(this.base_gr.StartRule.RightHandSide.Count + 1); start_rule_rhs.AddRange(this.base_gr.StartRule.RightHandSide); start_rule_rhs.Add(this.eos); var rules = new List<Rule>(this.base_gr.Rules); rules[0] = new Rule(this.base_gr.StartSymbol, start_rule_rhs); this.rules = rules.AsReadOnly(); }
private void Initialize() { var old_start_sym = this.base_gr.StartSymbol; var rules = new List<Rule>(this.base_gr.Rules.Count + 1); rules.AddRange(this.base_gr.Rules); var start_rules = rules.FindAll(r => r.LeftHandSide == old_start_sym); if( rules.Find(r => r.RightHandSide.Contains(old_start_sym)) != null || start_rules.Count > 1 ) { // New start symbol, and new start rule string new_start_sym_name = "S'"; while( this.base_gr.Grammaticals.FirstOrDefault(gr => gr.Name == new_start_sym_name) != null ) new_start_sym_name += "'"; var new_start_sym = new GrammaticalSymbol(new_start_sym_name); var grammaticals = new List<GrammaticalSymbol>(this.base_gr.Grammaticals.Count + 1); grammaticals.Add(new_start_sym); grammaticals.AddRange(this.base_gr.Grammaticals); this.grammaticals = grammaticals.AsReadOnly(); var new_start_rule = new Rule(new_start_sym, new Symbol[] { old_start_sym }); rules.Insert(0, new_start_rule); this.rules = rules.AsReadOnly(); } else { if( this.base_gr.IndexOf(old_start_sym) != 0 ) { int old_ind = this.base_gr.IndexOf(old_start_sym); var grammaticals = new List<GrammaticalSymbol>(this.base_gr.Grammaticals); grammaticals.RemoveAt(old_ind); grammaticals.Insert(0, old_start_sym); this.grammaticals = grammaticals.AsReadOnly(); } else { this.grammaticals = this.base_gr.Grammaticals; } if( start_rules.Count == 0 ) { // New epsilon start rule. var new_start_rule = new Rule(old_start_sym, new Symbol[0]); rules.Insert(0, new_start_rule); this.rules = rules.AsReadOnly(); } else if( rules[0] != start_rules[0] ) { // Reorder to be the first rule. var old_start_rule = start_rules[0]; rules.Remove(old_start_rule); rules.Insert(0, old_start_rule); this.rules = rules.AsReadOnly(); } else { // Rules are fine. this.rules = this.base_gr.Rules; } } }
public void CreateWithStartRuleNotTheFirst() { var terminals = new TerminalSymbol[] { new TerminalSymbol("a"), new TerminalSymbol("b"), }; var grammaticals = new GrammaticalSymbol[] { new GrammaticalSymbol("S"), new GrammaticalSymbol("A"), }; var rules = new Rule[] { new Rule(grammaticals[1], new Symbol[]{ terminals[0] }), new Rule(grammaticals[0], new Symbol[]{ terminals[1] }), }; var gr = new RestrictedStartSymbolGrammar(new Grammar(terminals, grammaticals, rules, 0)); Assert.Equal(2, gr.Grammaticals.Count); Assert.Equal(2, gr.Rules.Count); Assert.Equal(rules[1], gr.StartRule); }