Пример #1
0
func TestWalk(t *testing.T) {
	g := ast.Grammar([]*ast.Production{
		{
			Name: &ast.Name{Name: "E"},
			Expr: ast.Alternative([]ast.Expression{
				ast.Sequence([]ast.Expression{
					&ast.Name{Name: "T"},
					&ast.Terminal{Terminal: "+"},
					&ast.Name{Name: "T"},
				}),
				&ast.Name{Name: "T"},
				&ast.Epsilon{Epsilon: "e"},
			}),
		},
		{
			Name: &ast.Name{Name: "T"},
			Expr: ast.Alternative([]ast.Expression{
				ast.Sequence([]ast.Expression{
					&ast.Terminal{Terminal: "("},
					&ast.Name{Name: "T"},
					&ast.Terminal{Terminal: ")"},
				}),
				&ast.Name{Name: "T"},
			}),
		},
	})

	order := []string{
		"ast.Grammar",
		"*ast.Production",
		"*ast.Name",
		"ast.Alternative",
		"ast.Sequence",
		"*ast.Name",
		"*ast.Terminal",
		"*ast.Name",
		"*ast.Name",
		"*ast.Epsilon",
		"*ast.Production",
		"*ast.Name",
		"ast.Alternative",
		"ast.Sequence",
		"*ast.Terminal",
		"*ast.Name",
		"*ast.Terminal",
		"*ast.Name",
	}

	i := 0
	ast.Walk(func(n ast.Node) bool {
		if n == nil {
			return false
		}
		if typ := reflect.TypeOf(n).String(); order[i] != typ {
			t.Errorf("got %q want %q", typ, order[i])
		}
		i++
		return true
	}, g)
}
Пример #2
0
// check checks whether all productions
// used are defined.
func (p *parser) check() {
	prods := make(map[string]bool)
	for _, p := range p.grammar {
		prods[p.Name.Name] = true
	}

	ast.Walk(func(n ast.Node) bool {
		if n, ok := n.(*ast.Name); ok {
			if _, ok := prods[n.Name]; !ok {
				p.errs = append(p.errs, fmt.Errorf("%v undefined %q", n.Pos(), n.Name))
			}
		}
		return true
	}, p.grammar)
}