示例#1
0
        /// <summary>
        /// Calculates the first sets of all grammaticals of the given <paramref name="grammar"/>.
        /// </summary>
        /// <param name="grammar">The grammaticals which are to examen, are in this grammar.</param>
        /// <param name="epsilon_grammaticals">Set of the epsilon capable grammaticals of the given 
        /// <paramref name="grammar"/>. (see <see cref="EpsilonGrammaticals"/>)</param>
        /// <returns>The first sets for all the grammaticals of the given <paramref name="grammar"/>.</returns>
        /// <exception cref="ArgumentNullException"> if any of the parameters is <c>null</c>.</exception>
        public static IDictionary<GrammaticalSymbol, ISet<TerminalSymbol>> Build(
            ExtendedGrammar grammar, ISet<GrammaticalSymbol> epsilon_grammaticals)
        {
            if( grammar == null )
                throw new ArgumentNullException("grammar");
            if( epsilon_grammaticals == null )
                throw new ArgumentNullException("epsilon_grammaticals");

            // Relation matrix
            var f_plus = new RelationMatrix(grammar.Terminals.Count + grammar.Grammaticals.Count);
            RelationMatrix.TransitiveClosure(F_Relation(grammar), f_plus);

            // Build the first_sets
            var first_sets = new Dictionary<GrammaticalSymbol, ISet<TerminalSymbol>>();
            foreach( var gr in grammar.Grammaticals )
            {
                int gr_index = grammar.GlobalIndexOf(gr);

                // Put all terminals being in relation with gr into gr's first_set
                var first_set = new HashSet<TerminalSymbol>();
                foreach( var tr in grammar.Terminals )
                    if( f_plus[gr_index, grammar.GlobalIndexOf(tr)] )
                        first_set.Add(tr);

                if( epsilon_grammaticals.Contains(gr) )
                    first_set.Add(EpsilonSymbol.Instance);

                first_sets.Add(gr, first_set);
            }

            return first_sets;
        }
示例#2
0
        static EmptyGrammar()
        {
            BaseGrammar = Grammar.EmptyGrammar;
            RestrictedGrammar = new RestrictedStartSymbolGrammar(BaseGrammar);
            ExtendedGrammar = new ExtendedGrammar(RestrictedGrammar);

            EpsilonGrammaticals = new HashSet<GrammaticalSymbol>();
            EpsilonGrammaticals.Add(BaseGrammar.StartSymbol);

            FirstSets = new Dictionary<GrammaticalSymbol, ISet<TerminalSymbol>>();
            // S: #,Eps
            FirstSets[BaseGrammar.StartSymbol] = new HashSet<TerminalSymbol>(
                new TerminalSymbol[]
                {
                    ExtendedGrammar.EndOfSourceSymbol,
                    EpsilonSymbol.Instance
                });

            FollowSets = new Dictionary<GrammaticalSymbol, ISet<TerminalSymbol>>();
            // S: -
            FollowSets[BaseGrammar.StartSymbol] = new HashSet<TerminalSymbol>();

            LR0CanonicalSets = new Syntan.SyntacticAnalysis.LR.LR0CanonicalSets();
            LR0CanonicalSets.Add(new HashSet<Syntan.SyntacticAnalysis.LR.LR0Item>(
                new Syntan.SyntacticAnalysis.LR.LR0Item[]
                {
                    new Syntan.SyntacticAnalysis.LR.LR0Item(BaseGrammar.Rules[0], 0)
                }));

            // SLR1ParserTable
            SLR1ParserTable = new Syntan.SyntacticAnalysis.LR.ParserTable(1, 1, 1);
            SLR1ParserTable.SetAction(0, 0, Syntan.SyntacticAnalysis.LR.ParserTable.Action.Accept());
        }
示例#3
0
        private static IEnumerable<TerminalSymbol> BuildInput( ExtendedGrammar grammar, string input )
        {
            if( grammar == null )
                throw new ArgumentNullException("grammar");

            if( string.IsNullOrEmpty(input) )
            {
                return new TerminalSymbol[] { grammar.EndOfSourceSymbol };
            }

            if( input.EndsWith(grammar.EndOfSourceSymbol.Name) )
                input = input.Substring(0, input.Length - grammar.EndOfSourceSymbol.Name.Length);

            var name_to_tr = new Dictionary<string, TerminalSymbol>(grammar.Terminals.Count - 1);
            var regex_pattern = new StringBuilder();
            for( int i = 0; i < grammar.Terminals.Count - 1; ++i )
            {
                var tr = grammar.Terminals[i];

                name_to_tr[tr.Name] = tr;
                if( i > 0 )
                    regex_pattern.Append("|");
                regex_pattern.Append(System.Text.RegularExpressions.Regex.Escape(tr.Name));
            }

            string regex_pattern_str = regex_pattern.ToString();
            if( string.IsNullOrEmpty(regex_pattern_str) )
            {
                if( !string.IsNullOrEmpty(input) )
                    throw new ArgumentException("Hibás elem az input 0. helyén.");

                return new TerminalSymbol[] { grammar.EndOfSourceSymbol };
            }

            var regex = new System.Text.RegularExpressions.Regex(regex_pattern.ToString(),
                System.Text.RegularExpressions.RegexOptions.Singleline);

            var symnol_list = new List<TerminalSymbol>();
            int last_index = 0;
            foreach( System.Text.RegularExpressions.Match match in regex.Matches(input) )
            {
                if( !match.Success )
                    throw new ArgumentException("Nem tudtam feldolgozni az inputot!");

                // Check if there is an unmatched part
                if( match.Index > last_index )
                    throw new ArgumentException(string.Format("Hibás elem az inputban a {0}. helyen.", last_index));

                symnol_list.Add(name_to_tr[match.Value]);
                last_index += match.Length;
            }

            if( last_index < input.Length )
                throw new ArgumentException(string.Format("Hibás elem az inputban a {0}. helyen.", last_index));

            symnol_list.Add(grammar.EndOfSourceSymbol);
            return symnol_list;
        }
示例#4
0
        public void BuildWithValidData( ExtendedGrammar grammar, 
            ISet<GrammaticalSymbol> epsilon_grammaticals,
            IDictionary<GrammaticalSymbol, ISet<TerminalSymbol>> follow_sets)
        {
            var fs = FollowSets.Build(grammar, epsilon_grammaticals);

            foreach( var gr in grammar.Grammaticals )
                Assert.True(fs[gr].SetEquals(follow_sets[gr]));
        }
示例#5
0
        public void CreateWithValidGrammar( RestrictedStartSymbolGrammar restricted_grammar )
        {
            var eg = new ExtendedGrammar(restricted_grammar);

            Assert.NotNull(eg);
            Assert.Equal(restricted_grammar, eg.RestrictedGrammar);
            Assert.Equal(restricted_grammar.Terminals.Count + 1, eg.Terminals.Count);
            Assert.NotNull(eg.EndOfSourceSymbol);
            Assert.Equal(eg.EndOfSourceSymbol, eg.Terminals[eg.Terminals.Count - 1]);
            Assert.Equal(restricted_grammar.StartRule.RightHandSide.Count + 1, eg.StartRule.RightHandSide.Count);
            Assert.Equal(eg.EndOfSourceSymbol, eg.StartRule.RightHandSide[eg.StartRule.RightHandSide.Count - 1]);
        }
示例#6
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);
        }
示例#7
0
        /// <summary>
        /// Calculates the follow sets of all grammaticals of the given <paramref name="grammar"/>.
        /// </summary>
        /// <param name="grammar">The grammaticals which are to examen, are in this grammar.</param>
        /// <param name="epsilon_grammaticals">Set of the epsilon capable grammaticals of the given 
        /// <paramref name="grammar"/>. (see <see cref="EpsilonGrammaticals"/>)</param>
        /// <returns>The first sets for all the grammaticals of the given <paramref name="grammar"/>.</returns>
        /// <exception cref="ArgumentNullException"> if any of the parameters is <c>null</c>.</exception>
        public static IDictionary<GrammaticalSymbol, ISet<TerminalSymbol>> Build( 
            ExtendedGrammar grammar, ISet<GrammaticalSymbol> epsilon_grammaticals)
        {
            if( grammar == null )
                throw new ArgumentNullException("grammar");
            if( epsilon_grammaticals == null )
                throw new ArgumentNullException("epsilon_grammaticals");

            int symbol_count = grammar.Terminals.Count + grammar.Grammaticals.Count;

            var f_star = new RelationMatrix(symbol_count);
            RelationMatrix.TransitiveClosure(FirstSets.F_Relation(grammar), f_star);
            RelationMatrix.ReflexiveClosure(f_star);

            var l_star = new RelationMatrix(symbol_count);
            RelationMatrix.TransitiveClosure(L_Relations(grammar, epsilon_grammaticals), l_star);
            RelationMatrix.ReflexiveClosure(l_star);

            var b = B_Relation(grammar, epsilon_grammaticals);

            var tmp = new RelationMatrix(symbol_count);
            var lbf = new RelationMatrix(symbol_count);
            RelationMatrix.WharshallAlg(l_star, b, tmp);
            RelationMatrix.WharshallAlg(tmp, f_star, lbf);

            // Build the follow_sets
            var follow_sets = new Dictionary<GrammaticalSymbol, ISet<TerminalSymbol>>();
            foreach( var gr in grammar.Grammaticals )
            {
                int gr_index = grammar.GlobalIndexOf(gr);

                // Put all terminals being in relation with gr into gr's follow_set
                var follow_set = new HashSet<TerminalSymbol>();
                foreach( var tr in grammar.Terminals )
                    if( lbf[gr_index, grammar.GlobalIndexOf(tr)] )
                        follow_set.Add(tr);

                follow_sets.Add(gr, follow_set);
            }

            return follow_sets;
        }
示例#8
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]];
        }
示例#9
0
        private void Grammar_MenuItem_Click( object sender, EventArgs e )
        {
            if( this.parser.IsParsing )
                return; //TODO: ask user?

            using( var dlg = new GrammarForm() )
            {
                dlg.Text = "Nyelvtan szerkesztő";
                dlg.Grammar = this.ext_grammar != null ? this.ext_grammar.RestrictedGrammar.BaseGrammar : null;

                if( dlg.ShowDialog(this) == System.Windows.Forms.DialogResult.OK )
                {
                    try
                    {
                        var grammar = dlg.Grammar;
                        var rst_grammar = new RestrictedStartSymbolGrammar(grammar);
                        this.ext_grammar = new ExtendedGrammar(rst_grammar);
                        this.canonical_sets = SyntacticAnalysis.LR.LR0CanonicalSets.Build(rst_grammar);
                        this.epsilon_grammaticals = EpsilonGrammaticals.Build(grammar);
                        this.follow_sets = FollowSets.Build(this.ext_grammar, this.epsilon_grammaticals);
                        this.parser_table = SyntacticAnalysis.LR.SLR1ParserTableBuilder.Build(
                            this.ext_grammar, this.canonical_sets, this.follow_sets);
                    }
                    catch( Exception ex )
                    {
                        MessageBox.Show(this,
                            ex.Message, "A Nyelvtant nem tudom használni",
                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

                        this.ext_grammar = null;
                        this.canonical_sets = null;
                        this.epsilon_grammaticals = null;
                        this.follow_sets = null;
                        this.parser_table = null;
                    }

                    // Update controls
                    if( this.ext_grammar != null )
                    {
                        this.ParserStart_ToolButton.Enabled = true;

                        this.ParserView.ClearInputHistory();

                        this.ParserTable.SetTable(this.ext_grammar, this.parser_table);

                        this.DfsmView.SetCanonicalSets(this.ext_grammar.RestrictedGrammar.BaseGrammar, this.canonical_sets);
                        this.DfsmView.Invalidate();

                        this.SyntacticTreeView.ClearNodes();
                    }
                    else
                    {
                        this.ParserStart_ToolButton.Enabled = false;
                    }
                }
            }
        }
示例#10
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);
        }