Пример #1
0
// Answer returns the filtered trace by performing a depth-first traversal on
// the graph. The traversal goes from source to sink, where a sink is one of the
// exits events of the top-level query.
func (t *truth) Answer() (result []*topdown.Event) {

	byQuery := t.byQuery[t.source.event.QueryID]
	var sink *node
	for _, node := range byQuery {
		if node.event.Op == topdown.ExitOp {
			sink = node
			break
		}
	}

	if sink == nil {
		return nil
	}

	traversal := newTruthTraversal(t)
	nodes := util.DFS(traversal, t.source, sink)

	for _, n := range nodes {
		node := n.(*node)
		result = append(result, node.event)
	}

	return result
}
Пример #2
0
// checkRecursion ensures that there are no recursive rule definitions, i.e., there are
// no cycles in the RuleGraph.
func (c *Compiler) checkRecursion() {
	for r := range c.RuleGraph {
		t := &ruleGraphTraveral{
			graph:   c.RuleGraph,
			visited: map[*Rule]struct{}{},
		}
		if p := util.DFS(t, r, r); len(p) > 0 {
			n := []string{}
			for _, x := range p {
				n = append(n, string(x.(*Rule).Name))
			}
			c.err(NewError(RecursionErr, r.Location, "%v: recursive reference: %v (recursion is not allowed)", r.Name, strings.Join(n, " -> ")))
		}
	}
}