func TestNNF(t *testing.T) { // Build a simple BNF aGrammar description aGrammar. gb := parser.OpenGrammarBuilder() gb.Name("a4"). Terminals("a"). Nonterminals("S", "A", "E"). Rule().Lhs("`*").Rhs("S", "`."). Rule().Lhs("S").Rhs("A", "A", "A", "A"). Rule().Lhs("A").Rhs("a"). Rule().Lhs("A").Rhs("E"). Rule().Lhs("E").Rhs("`e") g, err := gb.Build() if err != nil { t.Error(err) return } var aGrammar parser.Grammar var rTransform parser.SyntaxTreeTransform nnf, err := IsNihilisticNormalForm(g) if err != nil { t.Error() return } if !nnf { fmt.Println("Grammar is not NNF, transforming.") aGrammar, rTransform, err = GetNihilisticAugmentGrammar(g) if err != nil { t.Error(err) return } } else { t.Error("Grammar returned NNF.") return } fmt.Println("Name: " + aGrammar.Name()) terms := make([]string, aGrammar.NumTerminals()) for i, t := range aGrammar.Terminals() { terms[i] = t.String() } nterms := make([]string, aGrammar.NumNonterminals()) for i, t := range aGrammar.Nonterminals() { nterms[i] = t.String() } fmt.Println("Terminals: " + strings.Join(terms, ", ")) fmt.Println("Nonterminals: " + strings.Join(nterms, ", ")) fmt.Println("Productions:") for _, p := range aGrammar.Productions() { fmt.Println(" " + p.String()) } rTransform = rTransform }
func (ni *NameIndex) Initialize(g parser.Grammar) error { ni.nonterminalsByName = make(map[string]parser.GrammarParticle) ni.terminalsByName = make(map[string]parser.GrammarParticle) for i := 0; i < g.NumNonterminals(); i++ { nt := g.Nonterminal(i) ni.nonterminalsByName[nt.Name()] = nt } for i := 0; i < g.NumTerminals(); i++ { t := g.Terminal(i) ni.terminalsByName[t.Name()] = t } ni.lhsNames = make(map[string][]parser.Production) ni.rhsNames = make(map[string][]parser.Production) for _, p := range g.Productions() { var rhs, lhs []byte for i := 0; i < p.LhsLen(); i++ { lhs = append(lhs, p.Lhs(i).Name()...) if i < p.LhsLen()-1 { lhs = append(lhs, "|"...) } } if _, has := ni.lhsNames[string(lhs)]; !has { ni.lhsNames[string(lhs)] = []parser.Production{} } ni.lhsNames[string(lhs)] = append(ni.lhsNames[string(lhs)], p) for i := 0; i < p.RhsLen(); i++ { rhs = append(rhs, p.Rhs(i).Name()...) if i < p.RhsLen()-1 { rhs = append(rhs, "|"...) } } if _, has := ni.rhsNames[string(rhs)]; !has { ni.rhsNames[string(rhs)] = []parser.Production{} } ni.rhsNames[string(rhs)] = append(ni.rhsNames[string(rhs)], p) } return nil }