/** * Traverses the tree of <code>root</code> via the depth first strategy and executes the * corresponding semantic actions. If an ambiguity node is found an {@link ParseError} is thrown. * * @param root {@link AbstractParseNode} the root of the internal parse forest <code>currentNode * </code> belongs to */ private void traverse(AbstractParseNode root) { // check if root is an ambiguity node if (root.isAmbNode()) { System.out.println("\tAn ambiguity was detected..."); throw new ParseError("An ambiguity was detected.\n" + printParseForest(root)); } // enter root stack.enterNode(getRule(root.getLabel()), root, graphBuilder); executeSemanticAction(root, stack.getCurrentElement().getRepresentedNode()); while (!stack.isEmpty()) { ((GraphBuilderBaseImpl) graphBuilder).addToSizeOfInternalParseForest(1); if (stack.getCurrentElement().haveAllChildrenBeenHandeled()) { // leave node stack.leaveNode(); // return to parent node stack.returnToNode(); if (stack.isEmpty()) { break; } executeSemanticAction(root, stack.getCurrentElement().getRepresentedNode()); } else { AbstractParseNode nextChild = stack .getCurrentElement() .getRepresentedNode() .getChildren()[stack.getCurrentElement().getNumberOfChildren()]; // check if nextChild is an ambiguity node if (nextChild.isAmbNode()) { System.out.println("\tAn ambiguity was detected..."); throw new ParseError("An ambiguity was detected.\n" + printParseForest(root)); } stack.enterNode(getRule(nextChild.getLabel()), nextChild, graphBuilder); executeSemanticAction(root, stack.getCurrentElement().getRepresentedNode()); } } }