summaryrefslogtreecommitdiff
path: root/src/traverser.cc
blob: da8c6792989f974464b1ab10a5d447a43d20ab90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include "traverser.h"
#include "visitor.h"
#include "node.h"
#include "state.h"
#include <algorithm>
#include <boost/foreach.hpp>

void Traverser::execute() 
{
	State state(NULL);
	traverse(this->root, state);
}

Response Traverser::traverse(const AbstractNode &node, const State &state)
{
	State newstate = state;
	newstate.setNumChildren(node.getChildren().size());
	
	Response response = ContinueTraversal;
	if (traversaltype == PREFIX || traversaltype == PRE_AND_POSTFIX) {
		newstate.setPrefix(true);
		newstate.setParent(state.parent());
		response = node.accept(newstate, this->visitor);
	}

	// Pruned traversals mean don't traverse children
	if (response == ContinueTraversal) {
		newstate.setParent(&node);
		BOOST_FOREACH(const AbstractNode *chnode, node.getChildren()) {
			response = this->traverse(*chnode, newstate);
			if (response == AbortTraversal) return response; // Abort immediately
		}
	}

	// Postfix is executed for all non-aborted traversals
	if (response != AbortTraversal) {
		if (traversaltype == POSTFIX || traversaltype == PRE_AND_POSTFIX) {
			newstate.setParent(state.parent());
			newstate.setPrefix(false);
			newstate.setPostfix(true);
			response = node.accept(newstate, this->visitor);
		}
	}

	if (response != AbortTraversal) response = ContinueTraversal;
	return response;
}
contact: Jan Huwald // Impressum