org.antlr.v4.runtime.atn.Transition Java Examples

The following examples show how to use org.antlr.v4.runtime.atn.Transition. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ErrorHandler.java    From presto with Apache License 2.0 6 votes vote down vote up
private boolean isReachable(ATNState target, RuleStartState from)
{
    Deque<ATNState> activeStates = new ArrayDeque<>();
    activeStates.add(from);

    while (!activeStates.isEmpty()) {
        ATNState current = activeStates.pop();

        if (current.stateNumber == target.stateNumber) {
            return true;
        }

        for (int i = 0; i < current.getNumberOfTransitions(); i++) {
            Transition transition = current.transition(i);

            if (transition.isEpsilon()) {
                activeStates.push(transition.target);
            }
        }
    }

    return false;
}
 
Example #2
Source File: TokenSuggester.java    From antlr4-autosuggest with Apache License 2.0 6 votes vote down vote up
private void suggest(String tokenSoFar, ATNState lexerState, String remainingText) {
    logger.debug(
            "SUGGEST: tokenSoFar=" + tokenSoFar + " remainingText=" + remainingText + " lexerState=" + toString(lexerState));
    if (visitedLexerStates.contains(lexerState.stateNumber)) {
        return; // avoid infinite loop and stack overflow
    }
    visitedLexerStates.add(lexerState.stateNumber);
    try {
        Transition[] transitions = lexerState.getTransitions();
        boolean tokenNotEmpty = tokenSoFar.length() > 0;
        boolean noMoreCharactersInToken = (transitions.length == 0);
        if (tokenNotEmpty && noMoreCharactersInToken) {
            addSuggestedToken(tokenSoFar);
            return;
        }
        for (Transition trans : transitions) {
            suggestViaLexerTransition(tokenSoFar, remainingText, trans);
        }
    } finally {
        visitedLexerStates.remove(visitedLexerStates.size() - 1);
    }
}
 
Example #3
Source File: TokenSuggester.java    From antlr4-autosuggest with Apache License 2.0 6 votes vote down vote up
private void suggestViaLexerTransition(String tokenSoFar, String remainingText, Transition trans) {
    if (trans.isEpsilon()) {
        suggest(tokenSoFar, trans.target, remainingText);
    } else if (trans instanceof AtomTransition) {
        String newTokenChar = getAddedTextFor((AtomTransition) trans);
        if (remainingText.isEmpty() || remainingText.startsWith(newTokenChar)) {
            logger.debug("LEXER TOKEN: " + newTokenChar + " remaining=" + remainingText);
            suggestViaNonEpsilonLexerTransition(tokenSoFar, remainingText, newTokenChar, trans.target);
        } else {
            logger.debug("NONMATCHING LEXER TOKEN: " + newTokenChar + " remaining=" + remainingText);
        }
    } else if (trans instanceof SetTransition) {
        List<Integer> symbols = ((SetTransition) trans).label().toList();
        for (Integer symbol : symbols) {
            char[] charArr = Character.toChars(symbol);
            String charStr = new String(charArr);
            boolean shouldIgnoreCase = shouldIgnoreThisCase(charArr[0], symbols); // TODO: check for non-BMP
            if (!shouldIgnoreCase && (remainingText.isEmpty() || remainingText.startsWith(charStr))) {
                suggestViaNonEpsilonLexerTransition(tokenSoFar, remainingText, charStr, trans.target);
            }
        }
    }
}
 
Example #4
Source File: AtnFormatter.java    From antlr4-autosuggest with Apache License 2.0 6 votes vote down vote up
private void appendAtnSubtree(String indent, String transStr, ATNState state) {
    String stateRuleName = (state.ruleIndex >= 0) ? recognizer.getRuleNames()[state.ruleIndex] : "";
    String stateClassName = state.getClass().getSimpleName();
    boolean visitedAlready = visitedStates.contains(state.stateNumber);
    String visitedTag = visitedAlready ? "*" : "";
    String stateStr = stateRuleName + " " + stateClassName + " " + state + visitedTag;
    result.append(indent + transStr + stateStr).append("\n");
    if (visitedAlready) {
        return;
    }
    visitedStates.add(state.stateNumber);
    {
        for (Transition trans : state.getTransitions()) {
            String newTransStr = trans.toString();
            if (trans instanceof AtomTransition) {
                newTransStr = toString((AtomTransition) trans);
            }
            appendAtnSubtree(indent + "  ", " " + newTransStr + "-> ", trans.target);
        }
    }
}
 
Example #5
Source File: ParserWrapper.java    From antlr4-autosuggest with Apache License 2.0 5 votes vote down vote up
public String toString(Transition t) {
    String nameOrLabel = t.getClass().getSimpleName();
    if (t instanceof AtomTransition) {
        nameOrLabel += ' ' + this.lexerVocabulary.getDisplayName(((AtomTransition) t).label);
    }
    return nameOrLabel + " -> " + toString(t.target);
}
 
Example #6
Source File: AutoSuggester.java    From antlr4-autosuggest with Apache License 2.0 5 votes vote down vote up
/**
 * Recursive through the parser ATN to process all tokens. When successful (out of tokens) - collect completion
 * suggestions.
 */
private void parseAndCollectTokenSuggestions(ATNState parserState, int tokenListIndex) {
    indent = indent + "  ";
    if (didVisitParserStateOnThisTokenIndex(parserState, tokenListIndex)) {
        logger.debug(indent + "State " + parserState + " had already been visited while processing token "
                + tokenListIndex + ", backtracking to avoid infinite loop.");
        return;
    }
    Integer previousTokenListIndexForThisState = setParserStateLastVisitedOnThisTokenIndex(parserState, tokenListIndex);
    try {
        if(logger.isDebugEnabled()) {
            logger.debug(indent + "State: " + parserWrapper.toString(parserState) );
            logger.debug(indent + "State available transitions: " + parserWrapper.transitionsStr(parserState));
        }

        if (!haveMoreTokens(tokenListIndex)) { // stop condition for recursion
            suggestNextTokensForParserState(parserState);
            return;
        }
        for (Transition trans : parserState.getTransitions()) {
            if (trans.isEpsilon()) {
                handleEpsilonTransition(trans, tokenListIndex);
            } else if (trans instanceof AtomTransition) {
                handleAtomicTransition((AtomTransition) trans, tokenListIndex);
            } else {
                handleSetTransition((SetTransition)trans, tokenListIndex);
            }
        }
    } finally {
        indent = indent.substring(2);
        setParserStateLastVisitedOnThisTokenIndex(parserState, previousTokenListIndexForThisState);
    }
}
 
Example #7
Source File: AutoSuggester.java    From antlr4-autosuggest with Apache License 2.0 5 votes vote down vote up
private void fillParserTransitionLabels(ATNState parserState, Collection<Integer> result, Set<TransitionWrapper> visitedTransitions) {
    for (Transition trans : parserState.getTransitions()) {
        TransitionWrapper transWrapper = new TransitionWrapper(parserState, trans);
        if (visitedTransitions.contains(transWrapper)) {
            logger.debug(indent + "Not following visited " + transWrapper);
            continue;
        }
        if (trans.isEpsilon()) {
            try {
                visitedTransitions.add(transWrapper);
                fillParserTransitionLabels(trans.target, result, visitedTransitions);
            } finally {
                visitedTransitions.remove(transWrapper);
            }
        } else if (trans instanceof AtomTransition) {
            int label = ((AtomTransition) trans).label;
            if (label >= 1) { // EOF would be -1
                result.add(label);
            }
        } else if (trans instanceof SetTransition) {
            for (Interval interval : ((SetTransition) trans).label().getIntervals()) {
                for (int i = interval.a; i <= interval.b; ++i) {
                    result.add(i);
                }
            }
        }
    }
}
 
Example #8
Source File: TailEpsilonRemover.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@Override
public void visitState(ATNState p) {
	if (p.getStateType() == ATNState.BASIC && p.getNumberOfTransitions() == 1) {
		ATNState q = p.transition(0).target;
		if (p.transition(0) instanceof RuleTransition) {
			q = ((RuleTransition) p.transition(0)).followState;
		}
		if (q.getStateType() == ATNState.BASIC) {
			// we have p-x->q for x in {rule, action, pred, token, ...}
			// if edge out of q is single epsilon to block end
			// we can strip epsilon p-x->q-eps->r
			Transition trans = q.transition(0);
			if (q.getNumberOfTransitions() == 1 && trans instanceof EpsilonTransition) {
				ATNState r = trans.target;
				if (r instanceof BlockEndState || r instanceof PlusLoopbackState || r instanceof StarLoopbackState) {
					// skip over q
					if (p.transition(0) instanceof RuleTransition) {
						((RuleTransition) p.transition(0)).followState = r;
					} else {
						p.transition(0).target = r;
					}
					_atn.removeState(q);
				}
			}
		}
	}
}
 
Example #9
Source File: ATNVisitor.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public void visit_(ATNState s, Set<Integer> visited) {
	if ( !visited.add(s.stateNumber) ) return;
	visited.add(s.stateNumber);

	visitState(s);
	int n = s.getNumberOfTransitions();
	for (int i=0; i<n; i++) {
		Transition t = s.transition(i);
		visit_(t.target, visited);
	}
}
 
Example #10
Source File: ParserATNFactory.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public Handle elemList(List<Handle> els) {
	int n = els.size();
	for (int i = 0; i < n - 1; i++) {	// hook up elements (visit all but last)
		Handle el = els.get(i);
		// if el is of form o-x->o for x in {rule, action, pred, token, ...}
		// and not last in alt
           Transition tr = null;
           if ( el.left.getNumberOfTransitions()==1 ) tr = el.left.transition(0);
           boolean isRuleTrans = tr instanceof RuleTransition;
           if ( el.left.getStateType() == ATNState.BASIC &&
			el.right.getStateType()== ATNState.BASIC &&
			tr!=null && (isRuleTrans && ((RuleTransition)tr).followState == el.right || tr.target == el.right) )
		{
			// we can avoid epsilon edge to next el
			if ( isRuleTrans ) ((RuleTransition)tr).followState = els.get(i+1).left;
               else tr.target = els.get(i+1).left;
			atn.removeState(el.right); // we skipped over this state
		}
		else { // need epsilon if previous block's right end node is complicated
			epsilon(el.right, els.get(i+1).left);
		}
	}
	Handle first = els.get(0);
	Handle last = els.get(n -1);
	if ( first==null || last==null ) {
		g.tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "element list has first|last == null");
	}
	return new Handle(first.left, last.right);
}
 
Example #11
Source File: ParserATNFactory.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/** Add an EOF transition to any rule end ATNState that points to nothing
    *  (i.e., for all those rules not invoked by another rule).  These
    *  are start symbols then.
 *
 *  Return the number of grammar entry points; i.e., how many rules are
 *  not invoked by another rule (they can only be invoked from outside).
 *  These are the start rules.
    */
public int addEOFTransitionToStartRules() {
	int n = 0;
	ATNState eofTarget = newState(null); // one unique EOF target for all rules
	for (Rule r : g.rules.values()) {
		ATNState stop = atn.ruleToStopState[r.index];
		if ( stop.getNumberOfTransitions()>0 ) continue;
		n++;
		Transition t = new AtomTransition(eofTarget, Token.EOF);
		stop.addTransition(t);
	}
	return n;
}
 
Example #12
Source File: LeftRecursionDetector.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/** From state s, look for any transition to a rule that is currently
 *  being traced.  When tracing r, visitedPerRuleCheck has r
 *  initially.  If you reach a rule stop state, return but notify the
 *  invoking rule that the called rule is nullable. This implies that
 *  invoking rule must look at follow transition for that invoking state.
 *
 *  The visitedStates tracks visited states within a single rule so
 *  we can avoid epsilon-loop-induced infinite recursion here.  Keep
 *  filling the cycles in listOfRecursiveCycles and also, as a
 *  side-effect, set leftRecursiveRules.
 */
public boolean check(Rule enclosingRule, ATNState s, Set<ATNState> visitedStates) {
	if ( s instanceof RuleStopState) return true;
	if ( visitedStates.contains(s) ) return false;
	visitedStates.add(s);

	//System.out.println("visit "+s);
	int n = s.getNumberOfTransitions();
	boolean stateReachesStopState = false;
	for (int i=0; i<n; i++) {
		Transition t = s.transition(i);
		if ( t instanceof RuleTransition ) {
			RuleTransition rt = (RuleTransition) t;
			Rule r = g.getRule(rt.ruleIndex);
			if ( rulesVisitedPerRuleCheck.contains((RuleStartState)t.target) ) {
				addRulesToCycle(enclosingRule, r);
			}
			else {
				// must visit if not already visited; mark target, pop when done
				rulesVisitedPerRuleCheck.add((RuleStartState)t.target);
				// send new visitedStates set per rule invocation
				boolean nullable = check(r, t.target, new HashSet<ATNState>());
				// we're back from visiting that rule
				rulesVisitedPerRuleCheck.remove((RuleStartState)t.target);
				if ( nullable ) {
					stateReachesStopState |= check(enclosingRule, rt.followState, visitedStates);
				}
			}
		}
		else if ( t.isEpsilon() ) {
			stateReachesStopState |= check(enclosingRule, t.target, visitedStates);
		}
		// else ignore non-epsilon transitions
	}
	return stateReachesStopState;
}
 
Example #13
Source File: ErrorHandler.java    From presto with Apache License 2.0 4 votes vote down vote up
private Set<Integer> process(ParsingState start, int precedence)
{
    Set<Integer> result = memo.get(start);
    if (result != null) {
        return result;
    }

    ImmutableSet.Builder<Integer> endTokens = ImmutableSet.builder();

    // Simulates the ATN by consuming input tokens and walking transitions.
    // The ATN can be in multiple states (similar to an NFA)
    Deque<ParsingState> activeStates = new ArrayDeque<>();
    activeStates.add(start);

    while (!activeStates.isEmpty()) {
        ParsingState current = activeStates.pop();

        ATNState state = current.state;
        int tokenIndex = current.tokenIndex;
        boolean suppressed = current.suppressed;

        while (stream.get(tokenIndex).getChannel() == Token.HIDDEN_CHANNEL) {
            // Ignore whitespace
            tokenIndex++;
        }
        int currentToken = stream.get(tokenIndex).getType();

        if (state.getStateType() == RULE_START) {
            int rule = state.ruleIndex;

            if (specialRules.containsKey(rule)) {
                if (!suppressed) {
                    record(tokenIndex, specialRules.get(rule));
                }
                suppressed = true;
            }
            else if (ignoredRules.contains(rule)) {
                // TODO expand ignored rules like we expand special rules
                continue;
            }
        }

        if (state instanceof RuleStopState) {
            endTokens.add(tokenIndex);
            continue;
        }

        for (int i = 0; i < state.getNumberOfTransitions(); i++) {
            Transition transition = state.transition(i);

            if (transition instanceof RuleTransition) {
                RuleTransition ruleTransition = (RuleTransition) transition;
                for (int endToken : process(new ParsingState(ruleTransition.target, tokenIndex, suppressed, parser), ruleTransition.precedence)) {
                    activeStates.push(new ParsingState(ruleTransition.followState, endToken, suppressed, parser));
                }
            }
            else if (transition instanceof PrecedencePredicateTransition) {
                if (precedence < ((PrecedencePredicateTransition) transition).precedence) {
                    activeStates.push(new ParsingState(transition.target, tokenIndex, suppressed, parser));
                }
            }
            else if (transition.isEpsilon()) {
                activeStates.push(new ParsingState(transition.target, tokenIndex, suppressed, parser));
            }
            else if (transition instanceof WildcardTransition) {
                throw new UnsupportedOperationException("not yet implemented: wildcard transition");
            }
            else {
                IntervalSet labels = transition.label();

                if (transition instanceof NotSetTransition) {
                    labels = labels.complement(IntervalSet.of(Token.MIN_USER_TOKEN_TYPE, atn.maxTokenType));
                }

                // Surprisingly, TokenStream (i.e. BufferedTokenStream) may not have loaded all the tokens from the
                // underlying stream. TokenStream.get() does not force tokens to be buffered -- it just returns what's
                // in the current buffer, or fail with an IndexOutOfBoundsError. Since Antlr decided the error occurred
                // within the current set of buffered tokens, stop when we reach the end of the buffer.
                if (labels.contains(currentToken) && tokenIndex < stream.size() - 1) {
                    activeStates.push(new ParsingState(transition.target, tokenIndex + 1, false, parser));
                }
                else {
                    if (!suppressed) {
                        record(tokenIndex, getTokenNames(labels));
                    }
                }
            }
        }
    }

    result = endTokens.build();
    memo.put(start, result);
    return result;
}
 
Example #14
Source File: TransitionWrapper.java    From antlr4-autosuggest with Apache License 2.0 4 votes vote down vote up
public TransitionWrapper(ATNState source, Transition transition) {
    super();
    this.source = source;
    this.transition = transition;
}
 
Example #15
Source File: ParserWrapper.java    From antlr4-autosuggest with Apache License 2.0 4 votes vote down vote up
public String transitionsStr(ATNState state) {
    Stream<Transition> transitionsStream = Arrays.asList(state.getTransitions()).stream();
    List<String> transitionStrings = transitionsStream.map(this::toString).collect(Collectors.toList());
    return StringUtils.join(transitionStrings, ", ");
}
 
Example #16
Source File: AutoSuggester.java    From antlr4-autosuggest with Apache License 2.0 4 votes vote down vote up
private void handleEpsilonTransition(Transition trans, int tokenListIndex) {
    // Epsilon transitions don't consume a token, so don't move the index
    parseAndCollectTokenSuggestions(trans.target, tokenListIndex);
}