/** * In dot mode a graphical representation of the internal parse forest <code>root</code> is * created and the path to the created file is returned. Otherwise a {@link String} representation * is returned.<br> * In verbose mode all used rules are printed. Otherwise only the rules defined in the grammar are * printed.<br> * In each case ambiguity nodes and <code>nodeWithException</code> are highlighted. * * @param root {@link AbstractParseNode} which is the root of the internal parse forest * @param nodeWithException {@link AbstractParseNode} which caused an exception an will be * highlighted in the output * @return {@link String} message as a result of the printing process */ private String printParseForest(AbstractParseNode root, AbstractParseNode nodeWithException) { ParseForest2Output printer = graphBuilder.isDotMode() ? new ParseForest2Dot(this, graphBuilder.getDotOutputFormat()) : new ParseForest2String(this); return printer.convertParseForest( root, graphBuilder.isVerboseMode(), graphBuilder.isVerboseMode() ? nodeWithException : stack.getCurrentElement().getParentApplicationOfDefinedRule().getRepresentedNode()); }
/** * Executes the semantic actions which can be identified by: * * <ul> * <li>the number of the currently executed rule * <li>the rule defined in an EDL grammar which was lastly applied before the currently applied * rule * <li>the current position in the rule (<code>position</code>) * </ul> * * If an {@link Exception} occurs during the execution of the semantic actions and the debug mode * is activated then the internal parse forest is printed and the application of rule which caused * the {@link Exception} is highlighted. * * @param root {@link AbstractParseNode} which is the root of the internal parse forest * @param currentNode {@link AbstractParseNode} the currently traversed node */ private void executeSemanticAction(AbstractParseNode root, AbstractParseNode currentNode) { try { StackElement currentElement = stack.getCurrentElement(); if (currentElement.getAppliedRule() != null && currentElement.getAppliedRule().canHaveSemanticAciton()) { // if the current element recognizes an input character no // semantic actions can be defined for that node graphBuilder.execute(stack); } } catch (Throwable e) { if (graphBuilder.isDebugMode()) { System.err.println("\tAn error occured: " + e.toString()); System.err.println(printParseForest(root, currentNode)); } if (e instanceof RuntimeException) { throw (RuntimeException) e; } else { throw new RuntimeException(e); } } }
/** * 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()); } } }