Search in sources :

Example 1 with RuleContext

use of org.antlr.v4.runtime.RuleContext in project kalang by kasonyang.

the class ErrorRecoverTest method testCode.

public void testCode(String code) {
    KalangParser parser = new KalangParser(TokenStreamFactory.createTokenStream(code));
    parser.setErrorHandler(new DefaultErrorStrategy() {

        @Override
        public void recover(Parser recognizer, RecognitionException e) {
            Token ot = e.getOffendingToken();
            System.out.println("offending token:" + ot.getText());
            IntervalSet exceptedTokens = e.getExpectedTokens();
            RuleContext ctx = e.getCtx();
            if (ctx != null) {
                System.out.println("context:" + ctx.getClass().getName());
            }
            System.out.println("offending state:" + e.getOffendingState());
            String excTks = exceptedTokens.toString(KalangLexer.VOCABULARY);
            System.out.println("excepted:" + excTks);
            super.recover(recognizer, e);
        }

        @Override
        public Token recoverInline(Parser recognizer) throws RecognitionException {
            System.out.println("calling recover inline");
            // IntervalSet exceptedTokens = recognizer.getExpectedTokens();
            // if(exceptedTokens.contains(KalangLexer.SEMI)){
            // Token curToken = recognizer.getCurrentToken();
            // recognizer.getTokenFactory().create(
            // new Pair(
            // curToken.getTokenSource()
            // ,
            // ), lastErrorIndex, text, lastErrorIndex, lastErrorIndex, lastErrorIndex, lastErrorIndex, lastErrorIndex);
            // }
            Token v = super.recoverInline(recognizer);
            if (v != null)
                System.out.println("inserted token:" + v.getText());
            return v;
        }
    });
    parser.compilationUnit();
}
Also used : KalangParser(kalang.antlr.KalangParser) RuleContext(org.antlr.v4.runtime.RuleContext) DefaultErrorStrategy(org.antlr.v4.runtime.DefaultErrorStrategy) IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) Token(org.antlr.v4.runtime.Token) RecognitionException(org.antlr.v4.runtime.RecognitionException) Parser(org.antlr.v4.runtime.Parser) KalangParser(kalang.antlr.KalangParser)

Example 2 with RuleContext

use of org.antlr.v4.runtime.RuleContext in project antlr4 by tunnelvisionlabs.

the class Trees method getNodeText.

public static String getNodeText(@NotNull Tree t, @Nullable List<String> ruleNames) {
    if (ruleNames != null) {
        if (t instanceof RuleNode) {
            RuleContext ruleContext = ((RuleNode) t).getRuleContext();
            int ruleIndex = ruleContext.getRuleIndex();
            String ruleName = ruleNames.get(ruleIndex);
            int altNumber = ruleContext.getAltNumber();
            if (altNumber != ATN.INVALID_ALT_NUMBER) {
                return ruleName + ":" + altNumber;
            }
            return ruleName;
        } else if (t instanceof ErrorNode) {
            return t.toString();
        } else if (t instanceof TerminalNode) {
            Token symbol = ((TerminalNode) t).getSymbol();
            if (symbol != null) {
                String s = symbol.getText();
                return s;
            }
        }
    }
    // no recog for rule names
    Object payload = t.getPayload();
    if (payload instanceof Token) {
        return ((Token) payload).getText();
    }
    return t.getPayload().toString();
}
Also used : RuleContext(org.antlr.v4.runtime.RuleContext) ParserRuleContext(org.antlr.v4.runtime.ParserRuleContext) CommonToken(org.antlr.v4.runtime.CommonToken) Token(org.antlr.v4.runtime.Token)

Example 3 with RuleContext

use of org.antlr.v4.runtime.RuleContext in project antlr4 by tunnelvisionlabs.

the class StructDecl method addDispatchMethods.

public void addDispatchMethods(Rule r) {
    dispatchMethods = new ArrayList<DispatchMethod>();
    if (!r.hasAltSpecificContexts()) {
        // no enter/exit for this ruleContext if rule has labels
        if (factory.getGrammar().tool.gen_listener) {
            dispatchMethods.add(new ListenerDispatchMethod(factory, true));
            dispatchMethods.add(new ListenerDispatchMethod(factory, false));
        }
        if (factory.getGrammar().tool.gen_visitor) {
            dispatchMethods.add(new VisitorDispatchMethod(factory));
        }
    }
}
Also used : VisitorDispatchMethod(org.antlr.v4.codegen.model.VisitorDispatchMethod) ListenerDispatchMethod(org.antlr.v4.codegen.model.ListenerDispatchMethod) ListenerDispatchMethod(org.antlr.v4.codegen.model.ListenerDispatchMethod) VisitorDispatchMethod(org.antlr.v4.codegen.model.VisitorDispatchMethod) DispatchMethod(org.antlr.v4.codegen.model.DispatchMethod)

Example 4 with RuleContext

use of org.antlr.v4.runtime.RuleContext in project antlr4 by tunnelvisionlabs.

the class DefaultErrorStrategy method getErrorRecoverySet.

/*  Compute the error recovery set for the current rule.  During
	 *  rule invocation, the parser pushes the set of tokens that can
	 *  follow that rule reference on the stack; this amounts to
	 *  computing FIRST of what follows the rule reference in the
	 *  enclosing rule. See LinearApproximator.FIRST().
	 *  This local follow set only includes tokens
	 *  from within the rule; i.e., the FIRST computation done by
	 *  ANTLR stops at the end of a rule.
	 *
	 *  EXAMPLE
	 *
	 *  When you find a "no viable alt exception", the input is not
	 *  consistent with any of the alternatives for rule r.  The best
	 *  thing to do is to consume tokens until you see something that
	 *  can legally follow a call to r *or* any rule that called r.
	 *  You don't want the exact set of viable next tokens because the
	 *  input might just be missing a token--you might consume the
	 *  rest of the input looking for one of the missing tokens.
	 *
	 *  Consider grammar:
	 *
	 *  a : '[' b ']'
	 *    | '(' b ')'
	 *    ;
	 *  b : c '^' INT ;
	 *  c : ID
	 *    | INT
	 *    ;
	 *
	 *  At each rule invocation, the set of tokens that could follow
	 *  that rule is pushed on a stack.  Here are the various
	 *  context-sensitive follow sets:
	 *
	 *  FOLLOW(b1_in_a) = FIRST(']') = ']'
	 *  FOLLOW(b2_in_a) = FIRST(')') = ')'
	 *  FOLLOW(c_in_b) = FIRST('^') = '^'
	 *
	 *  Upon erroneous input "[]", the call chain is
	 *
	 *  a -> b -> c
	 *
	 *  and, hence, the follow context stack is:
	 *
	 *  depth     follow set       start of rule execution
	 *    0         <EOF>                    a (from main())
	 *    1          ']'                     b
	 *    2          '^'                     c
	 *
	 *  Notice that ')' is not included, because b would have to have
	 *  been called from a different context in rule a for ')' to be
	 *  included.
	 *
	 *  For error recovery, we cannot consider FOLLOW(c)
	 *  (context-sensitive or otherwise).  We need the combined set of
	 *  all context-sensitive FOLLOW sets--the set of all tokens that
	 *  could follow any reference in the call chain.  We need to
	 *  resync to one of those tokens.  Note that FOLLOW(c)='^' and if
	 *  we resync'd to that token, we'd consume until EOF.  We need to
	 *  sync to context-sensitive FOLLOWs for a, b, and c: {']','^'}.
	 *  In this case, for input "[]", LA(1) is ']' and in the set, so we would
	 *  not consume anything. After printing an error, rule c would
	 *  return normally.  Rule b would not find the required '^' though.
	 *  At this point, it gets a mismatched token error and throws an
	 *  exception (since LA(1) is not in the viable following token
	 *  set).  The rule exception handler tries to recover, but finds
	 *  the same recovery set and doesn't consume anything.  Rule b
	 *  exits normally returning to rule a.  Now it finds the ']' (and
	 *  with the successful match exits errorRecovery mode).
	 *
	 *  So, you can see that the parser walks up the call chain looking
	 *  for the token that was a member of the recovery set.
	 *
	 *  Errors are not generated in errorRecovery mode.
	 *
	 *  ANTLR's error recovery mechanism is based upon original ideas:
	 *
	 *  "Algorithms + Data Structures = Programs" by Niklaus Wirth
	 *
	 *  and
	 *
	 *  "A note on error recovery in recursive descent parsers":
	 *  http://portal.acm.org/citation.cfm?id=947902.947905
	 *
	 *  Later, Josef Grosch had some good ideas:
	 *
	 *  "Efficient and Comfortable Error Recovery in Recursive Descent
	 *  Parsers":
	 *  ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip
	 *
	 *  Like Grosch I implement context-sensitive FOLLOW sets that are combined
	 *  at run-time upon error to avoid overhead during parsing.
	 */
@NotNull
protected IntervalSet getErrorRecoverySet(@NotNull Parser recognizer) {
    ATN atn = recognizer.getInterpreter().atn;
    RuleContext ctx = recognizer._ctx;
    IntervalSet recoverSet = new IntervalSet();
    while (ctx != null && ctx.invokingState >= 0) {
        // compute what follows who invoked us
        ATNState invokingState = atn.states.get(ctx.invokingState);
        RuleTransition rt = (RuleTransition) invokingState.transition(0);
        IntervalSet follow = atn.nextTokens(rt.followState);
        recoverSet.addAll(follow);
        ctx = ctx.parent;
    }
    recoverSet.remove(Token.EPSILON);
    // System.out.println("recover set "+recoverSet.toString(recognizer.getTokenNames()));
    return recoverSet;
}
Also used : IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) RuleTransition(org.antlr.v4.runtime.atn.RuleTransition) ATN(org.antlr.v4.runtime.atn.ATN) ATNState(org.antlr.v4.runtime.atn.ATNState) NotNull(org.antlr.v4.runtime.misc.NotNull)

Example 5 with RuleContext

use of org.antlr.v4.runtime.RuleContext in project antlr4 by antlr.

the class ATN method getExpectedTokens.

/**
 * Computes the set of input symbols which could follow ATN state number
 * {@code stateNumber} in the specified full {@code context}. This method
 * considers the complete parser context, but does not evaluate semantic
 * predicates (i.e. all predicates encountered during the calculation are
 * assumed true). If a path in the ATN exists from the starting state to the
 * {@link RuleStopState} of the outermost context without matching any
 * symbols, {@link Token#EOF} is added to the returned set.
 *
 * <p>If {@code context} is {@code null}, it is treated as {@link ParserRuleContext#EMPTY}.</p>
 *
 * Note that this does NOT give you the set of all tokens that could
 * appear at a given token position in the input phrase.  In other words,
 * it does not answer:
 *
 *   "Given a specific partial input phrase, return the set of all tokens
 *    that can follow the last token in the input phrase."
 *
 * The big difference is that with just the input, the parser could
 * land right in the middle of a lookahead decision. Getting
 * all *possible* tokens given a partial input stream is a separate
 * computation. See https://github.com/antlr/antlr4/issues/1428
 *
 * For this function, we are specifying an ATN state and call stack to compute
 * what token(s) can come next and specifically: outside of a lookahead decision.
 * That is what you want for error reporting and recovery upon parse error.
 *
 * @param stateNumber the ATN state number
 * @param context the full parse context
 * @return The set of potentially valid input symbols which could follow the
 * specified state in the specified context.
 * @throws IllegalArgumentException if the ATN does not contain a state with
 * number {@code stateNumber}
 */
public IntervalSet getExpectedTokens(int stateNumber, RuleContext context) {
    if (stateNumber < 0 || stateNumber >= states.size()) {
        throw new IllegalArgumentException("Invalid state number.");
    }
    RuleContext ctx = context;
    ATNState s = states.get(stateNumber);
    IntervalSet following = nextTokens(s);
    if (!following.contains(Token.EPSILON)) {
        return following;
    }
    IntervalSet expected = new IntervalSet();
    expected.addAll(following);
    expected.remove(Token.EPSILON);
    while (ctx != null && ctx.invokingState >= 0 && following.contains(Token.EPSILON)) {
        ATNState invokingState = states.get(ctx.invokingState);
        RuleTransition rt = (RuleTransition) invokingState.transition(0);
        following = nextTokens(rt.followState);
        expected.addAll(following);
        expected.remove(Token.EPSILON);
        ctx = ctx.parent;
    }
    if (following.contains(Token.EPSILON)) {
        expected.add(Token.EOF);
    }
    return expected;
}
Also used : ParserRuleContext(org.antlr.v4.runtime.ParserRuleContext) RuleContext(org.antlr.v4.runtime.RuleContext) IntervalSet(org.antlr.v4.runtime.misc.IntervalSet)

Aggregations

RuleContext (org.antlr.v4.runtime.RuleContext)10 ParserRuleContext (org.antlr.v4.runtime.ParserRuleContext)7 Parser (org.antlr.v4.runtime.Parser)6 Token (org.antlr.v4.runtime.Token)6 IntervalSet (org.antlr.v4.runtime.misc.IntervalSet)6 ParseTree (org.antlr.v4.runtime.tree.ParseTree)6 TerminalNode (org.antlr.v4.runtime.tree.TerminalNode)4 RecognitionException (org.antlr.v4.runtime.RecognitionException)3 LTLBPredicateNode (de.bmoth.parser.ast.nodes.ltl.LTLBPredicateNode)2 LTLInfixOperatorNode (de.bmoth.parser.ast.nodes.ltl.LTLInfixOperatorNode)2 LTLKeywordNode (de.bmoth.parser.ast.nodes.ltl.LTLKeywordNode)2 LTLPrefixOperatorNode (de.bmoth.parser.ast.nodes.ltl.LTLPrefixOperatorNode)2 ArrayList (java.util.ArrayList)2 KalangParser (kalang.antlr.KalangParser)2 AstBuilder (kalang.compiler.AstBuilder)2 DispatchMethod (org.antlr.v4.codegen.model.DispatchMethod)2 ListenerDispatchMethod (org.antlr.v4.codegen.model.ListenerDispatchMethod)2 VisitorDispatchMethod (org.antlr.v4.codegen.model.VisitorDispatchMethod)2 Lexer (org.antlr.v4.runtime.Lexer)2 ATN (org.antlr.v4.runtime.atn.ATN)2