Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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
}