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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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;
 }
Exemple #7
0
        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);
        }
Exemple #8
0
        /// <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;
        }
Exemple #9
0
        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);
        }