Search in sources :

Example 1 with FAState

use of org.antlr.works.visualization.fa.FAState in project antlrworks by antlr.

the class GFactory method buildGraphGroup.

private GGraphGroup buildGraphGroup(Grammar grammar, GrammarError error) {
    // Create one GGraph for each error rules
    List<GGraph> graphs = new ArrayList<GGraph>();
    FAFactory factory = new FAFactory(grammar);
    for (String rule : error.rules) {
        NFAState startState = grammar.getRuleStartState(rule);
        FAState state = factory.buildNFA(startState, optimize);
        GGraph graph = renderer.render(state);
        graph.setName(rule);
        graphs.add(graph);
    }
    // Add only graphs that are referenced by at least one error path.
    // For example, the statement rule of the java.g grammar produces
    // states that do not exist in the graph (they are after the accepted state
    // and are ignored by the FAFactory)
    GGraphGroup gg = new GGraphGroup();
    for (GGraph graph : graphs) {
        if (graph.containsAtLeastOneState(error.states))
            gg.add(graph);
    }
    // Attach all error paths to the GGraphGroup
    for (int i = 0; i < error.paths.size(); i++) {
        List states = error.paths.get(i);
        Boolean disabled = error.pathsDisabled.get(i);
        try {
            gg.addPath(states, disabled, factory.getSkippedStatesMap());
        } catch (Exception e) {
            if (console == null)
                e.printStackTrace();
            else
                console.println(e);
        }
    }
    // Attach all unreacheable alts to the GGraphGroup
    for (Object[] unreachableAlt : error.unreachableAlts) {
        gg.addUnreachableAlt((NFAState) unreachableAlt[0], (Integer) unreachableAlt[1]);
    }
    if (error.paths.size() > 0)
        gg.getPathGroup().setPathVisible(0, true);
    return gg;
}
Also used : GGraph(org.antlr.works.visualization.graphics.graph.GGraph) ArrayList(java.util.ArrayList) FAFactory(org.antlr.works.visualization.fa.FAFactory) NFAState(org.antlr.analysis.NFAState) FAState(org.antlr.works.visualization.fa.FAState) NFAState(org.antlr.analysis.NFAState) List(java.util.List) ArrayList(java.util.ArrayList) GGraphGroup(org.antlr.works.visualization.graphics.graph.GGraphGroup)

Example 2 with FAState

use of org.antlr.works.visualization.fa.FAState in project antlrworks by antlr.

the class GFactory method buildGraphsForRule.

public GGraph buildGraphsForRule(ANTLRGrammarEngine antlrEngineGrammar, String rule) throws Exception {
    NFAState startState = antlrEngineGrammar.getRuleStartState(rule);
    if (startState == null)
        return null;
    FAState state = new FAFactory(antlrEngineGrammar.getGrammarForRule(rule)).buildNFA(startState, optimize);
    GGraph graph = renderer.render(state);
    graph.setName(rule);
    return graph;
}
Also used : FAState(org.antlr.works.visualization.fa.FAState) NFAState(org.antlr.analysis.NFAState) GGraph(org.antlr.works.visualization.graphics.graph.GGraph) FAFactory(org.antlr.works.visualization.fa.FAFactory) NFAState(org.antlr.analysis.NFAState)

Example 3 with FAState

use of org.antlr.works.visualization.fa.FAState in project antlrworks by antlr.

the class GRenderer method recursiveRenderPositionAlternative.

public FAState recursiveRenderPositionAlternative(FAState state, GPoint basePoint) {
    FAState alternativeEndState = alternativeEndState(state);
    // This point is used to position each transition
    GPoint point = new GPoint(basePoint);
    point.addX(GContext.NODE_WIDTH + GContext.EPSILON_WIDTH);
    GDimension firstAlternativeDimension = null;
    for (int t = 0; t < state.getNumberOfTransitions(); t++) {
        FATransition transition = state.transition(t);
        GLink link = getNode(state).getLink(transition);
        if (t == 0) {
            // We remember here the size of the first transition because if we find later
            // a "loop" transition, we will have to offset this "loop" by the size of the first
            // transition (because the "loop" is always drawed above the first transition).
            firstAlternativeDimension = link.branchDim;
        }
        if (t > 0 && !transition.loop) {
            // Offset the current point for each transition (except for a "loop" because it is
            // displayed above the first transition)
            point.addY(GContext.LINE_SPACE);
            point.addY(link.branchDim.up);
        }
        if (transition.target == alternativeEndState) {
            // The transition is simply a single transition (epsilon normally).
            if (transition.loop) {
                // If this is a "loop", draw it above the first transition
                GPoint vp = new GPoint(basePoint);
                vp.subY(firstAlternativeDimension.up);
                vp.subY(link.branchDim.down);
                // The "virtual position" is used by the link to know where to display itself
                // when it has to "curve" (because both start and end point are on the same y-axis value)
                getNode(state).getLink(transition).setVirtualPosition(vp);
            } else {
                getNode(state).getLink(transition).setVirtualPosition(point);
                point.addY(link.branchDim.down);
            }
        } else {
            // The transition is more than a single transition, continue recursively...
            recursiveRenderPositionNode(transition.target, alternativeEndState, new GPoint(point));
            point.addY(link.branchDim.down);
        }
    }
    return alternativeEndState;
}
Also used : FAState(org.antlr.works.visualization.fa.FAState) FATransition(org.antlr.works.visualization.fa.FATransition) GDimension(org.antlr.works.visualization.graphics.primitive.GDimension) GPoint(org.antlr.works.visualization.graphics.primitive.GPoint) GLink(org.antlr.works.visualization.graphics.shape.GLink) GPoint(org.antlr.works.visualization.graphics.primitive.GPoint)

Example 4 with FAState

use of org.antlr.works.visualization.fa.FAState in project antlrworks by antlr.

the class GRenderer method alternativeEndState.

public FAState alternativeEndState(FAState alt) {
    int counter = alt.getNumberOfTransitions() - 1;
    FAState state = alt;
    while (true) {
        FATransition transition = state.getFirstTransition();
        if (transition == null)
            break;
        state = transition.target;
        // Note: a state can be both an end-of-alternative and an alternative itself ;-)
        if (analysis.numberOfIncomingTransition(state) > 1) {
            counter -= analysis.numberOfIncomingTransition(state) - 1;
            if (counter <= 0)
                break;
        }
        if (state.isAlternative()) {
            counter += state.getNumberOfTransitions() - 1;
        }
    }
    return state;
}
Also used : FAState(org.antlr.works.visualization.fa.FAState) FATransition(org.antlr.works.visualization.fa.FATransition) GPoint(org.antlr.works.visualization.graphics.primitive.GPoint)

Example 5 with FAState

use of org.antlr.works.visualization.fa.FAState in project antlrworks by antlr.

the class GGraphGroup method addPath.

public void addPath(List path, boolean disabled, Map<Integer, FAState> skippedStates) {
    List<GPathElement> elements = new ArrayList<GPathElement>();
    /** path contains a list of NFAState states (from ANTLR): they represent
         * all the states along the path. The graphical representation of the NFA/SD
         * does not necessarily contains all the states of the path because the representation
         * can be simplified to remove all unecessary states.
         * The problem here is to use the information stored in the transition of the
         * graphical representation to figure out exactly which graphical node corresponds
         * to the path.
         */
    NFAState state;
    GNode node;
    NFAState nextState = null;
    GNode nextNode = null;
    for (pathIndex = 0; getPathIndex() < path.size(); pathIndex = getPathIndex() + 1) {
        if (getPathIndex() == 0) {
            nextState = (NFAState) path.get(getPathIndex());
            nextNode = findNodeForStateNumber(nextState.stateNumber);
            if (nextNode == null) {
                // A path can start from anywhere in the graph. It might happen
                // that the starting state of the path has been skipped by
                // the optimization in FAFactory. We use the skippedStates mapping
                // to find out what is the parent state of the skipped state.
                FAState parentState = skippedStates.get(nextState.stateNumber);
                if (parentState == null) {
                    System.err.println("[GGraphGroup] Starting path state " + nextState.stateNumber + "[" + nextState.enclosingRule.name + "] cannot be found in the graph");
                    return;
                } else {
                    nextNode = findNodeForStateNumber(parentState.stateNumber);
                }
            }
            continue;
        } else {
            state = nextState;
            node = nextNode;
        }
        nextState = (NFAState) path.get(getPathIndex());
        nextNode = findNodeForStateNumber(nextState.stateNumber);
        GNode externalNode = null;
        if (nextNode == null) {
            // The state has probably been skipped during the graphical rendering.
            // Find the next non-skipped state.
            FATransition t = getNodeTransitionToNextNonSkippedState(node, path);
            if (t == null) {
                // No transition found. Look in the skipped states mapping because
                // it might be possible that the next state is in another rule but
                // cannot be found because it has been skipped.
                FAState parentState = skippedStates.get(nextState.stateNumber);
                if (parentState == null) {
                    //  OK. The node really does not exist. Continue by skipping it.
                    nextNode = node;
                    continue;
                } else {
                    nextNode = findNodeForStateNumber(parentState.stateNumber);
                }
            } else {
                // is incrementing it
                if (getPathIndex() >= path.size()) {
                    nextNode = findNodeForStateNumber(t.target.stateNumber);
                } else {
                    nextState = (NFAState) path.get(getPathIndex());
                    if (t.target.stateNumber == nextState.stateNumber) {
                        nextNode = findNodeForStateNumber(t.target.stateNumber);
                    } else {
                        // The only case that the target state of the transition if not
                        // the next state of the path is when the next state of the path
                        // is in another rule. In this case, the target state of the transition
                        // will contain a negative state number indicating an external rule reference:
                        // this external rule reference is added by AW during rendering and is not
                        // part of any ANTLR NFA.
                        // This node is the node representing the external rule reference
                        // before jumping outside of the rule
                        externalNode = findNodeForStateNumber(t.target.stateNumber);
                        // This node is the first node in the other rule
                        nextNode = findNodeForStateNumber(nextState.stateNumber);
                    }
                }
            }
        }
        if (state == null || node == null || nextNode == null)
            continue;
        if (state.enclosingRule.name.equals(nextState.enclosingRule.name))
            addNextElementInSameRule(elements, node, nextNode);
        else
            addNextElementInOtherRule(elements, node, externalNode, nextNode, nextState);
    }
    if (nextNode != null)
        elements.add(GPathElement.createElement(nextNode));
    getPathGroup().addPath(new GPath(elements, disabled));
}
Also used : FAState(org.antlr.works.visualization.fa.FAState) NFAState(org.antlr.analysis.NFAState) FATransition(org.antlr.works.visualization.fa.FATransition) GPath(org.antlr.works.visualization.graphics.path.GPath) GNode(org.antlr.works.visualization.graphics.shape.GNode) ArrayList(java.util.ArrayList) GPathElement(org.antlr.works.visualization.graphics.path.GPathElement) NFAState(org.antlr.analysis.NFAState)

Aggregations

FAState (org.antlr.works.visualization.fa.FAState)6 FATransition (org.antlr.works.visualization.fa.FATransition)4 NFAState (org.antlr.analysis.NFAState)3 GPoint (org.antlr.works.visualization.graphics.primitive.GPoint)3 ArrayList (java.util.ArrayList)2 FAFactory (org.antlr.works.visualization.fa.FAFactory)2 GGraph (org.antlr.works.visualization.graphics.graph.GGraph)2 GDimension (org.antlr.works.visualization.graphics.primitive.GDimension)2 GLink (org.antlr.works.visualization.graphics.shape.GLink)2 GNode (org.antlr.works.visualization.graphics.shape.GNode)2 List (java.util.List)1 GGraphGroup (org.antlr.works.visualization.graphics.graph.GGraphGroup)1 GPath (org.antlr.works.visualization.graphics.path.GPath)1 GPathElement (org.antlr.works.visualization.graphics.path.GPathElement)1