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