最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

exception - Java Antlr4 ParseCancellationException Ignored (Solved-ish) - Stack Overflow

programmeradmin1浏览0评论

Solution: This is a workaround, but if you store a boolean 'cancel' field within your listener class, and, at the top of any exit methods, check this value and throw an exception if True, this successfully throws the ParseCancellationException.

Note that this must be done individually for each exit listener; exitEveryRule always executes after each rule.

I believe that the reason this works and other approaches do not is due to Antlr4's error recovery attempts; upon encountering an error it attempts to rerun the visitor method multiple times, even if you have set a BailErrorStrategy or other custom strategy.

Thank you for everyone's help, I will attach my solution as a comment below this post.


I'm working on a mini compiler project, and I was attempting to throw a ParseCancellationException in a parseListener class or similar exception to halt parsing upon encountering a fatal error, however this simply gets ignored during execution.

I was wondering if anyone knew a way to successfully halt parsing upon throwing an exception.

I have verified through debugging that the exception is in fact thrown, though it seems to be ignored. I have also attempted throwing RuntimeExceptions instead, to no avail.

My program uses a stack to store results of expressions, and for some reason EmptyStackExceptions seem to successfully halt parsing.

Here is the code of my method I am experiencing issues with:

 @Override
    public void exitAddExpr(BasicLangParser.AddExprContext ctx) {
        Util.Value left = stack.pop();
        Util.Value right = stack.pop();

        if (left.datatype==right.datatype) {
            String result = switch (left.datatype) {
                case INT, FLOAT -> String.valueOf((Double)left.getValue() + (Double)right.getValue());
                case STRING, CHAR -> (String)left.getValue() + (String)right.getValue();
                default -> throw new ParseCancellationException("Addition Error - Invalid Datatype ("+left.datatype.toString()+","+right.datatype.toString()+")");
            };
            stack.push(Util.Value.newValue(result));
        } else {
            throw new ParseCancellationException("Addition Error - Mismatched Datatypes ("+left.datatype.toString()+","+right.datatype.toString()+")");
        }

        super.exitAddExpr(ctx);
    }

Because this code does in fact throw an exception, the 12th line stack.push() does not run, and so later in my program I encounter the aforementioned empty stack exception.

Edit: I am not currently attempting to catch the ParseCancellationException within my code for now; I simply caught this exception using Intellij's debugger and enabling exception breakpoints.

I'm working on a single threaded application, so the exception is definitely not thrown on the UI thread.

I have not blocked exception propagation within my code, though I am unaware as to whether Antlr4 does this, hence my question.

The only other exception is a caught exception where I attempt to parse a String as a double in order to determine whether it is numeric.

Solution: This is a workaround, but if you store a boolean 'cancel' field within your listener class, and, at the top of any exit methods, check this value and throw an exception if True, this successfully throws the ParseCancellationException.

Note that this must be done individually for each exit listener; exitEveryRule always executes after each rule.

I believe that the reason this works and other approaches do not is due to Antlr4's error recovery attempts; upon encountering an error it attempts to rerun the visitor method multiple times, even if you have set a BailErrorStrategy or other custom strategy.

Thank you for everyone's help, I will attach my solution as a comment below this post.


I'm working on a mini compiler project, and I was attempting to throw a ParseCancellationException in a parseListener class or similar exception to halt parsing upon encountering a fatal error, however this simply gets ignored during execution.

I was wondering if anyone knew a way to successfully halt parsing upon throwing an exception.

I have verified through debugging that the exception is in fact thrown, though it seems to be ignored. I have also attempted throwing RuntimeExceptions instead, to no avail.

My program uses a stack to store results of expressions, and for some reason EmptyStackExceptions seem to successfully halt parsing.

Here is the code of my method I am experiencing issues with:

 @Override
    public void exitAddExpr(BasicLangParser.AddExprContext ctx) {
        Util.Value left = stack.pop();
        Util.Value right = stack.pop();

        if (left.datatype==right.datatype) {
            String result = switch (left.datatype) {
                case INT, FLOAT -> String.valueOf((Double)left.getValue() + (Double)right.getValue());
                case STRING, CHAR -> (String)left.getValue() + (String)right.getValue();
                default -> throw new ParseCancellationException("Addition Error - Invalid Datatype ("+left.datatype.toString()+","+right.datatype.toString()+")");
            };
            stack.push(Util.Value.newValue(result));
        } else {
            throw new ParseCancellationException("Addition Error - Mismatched Datatypes ("+left.datatype.toString()+","+right.datatype.toString()+")");
        }

        super.exitAddExpr(ctx);
    }

Because this code does in fact throw an exception, the 12th line stack.push() does not run, and so later in my program I encounter the aforementioned empty stack exception.

Edit: I am not currently attempting to catch the ParseCancellationException within my code for now; I simply caught this exception using Intellij's debugger and enabling exception breakpoints.

I'm working on a single threaded application, so the exception is definitely not thrown on the UI thread.

I have not blocked exception propagation within my code, though I am unaware as to whether Antlr4 does this, hence my question.

The only other exception is a caught exception where I attempt to parse a String as a double in order to determine whether it is numeric.

Share Improve this question edited Feb 16 at 17:51 Willo678 asked Feb 16 at 5:45 Willo678Willo678 77 bronze badges New contributor Willo678 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 3
  • The exception is being caught higher up the stack. Find the catch by stepping through after your exception in debug mode. Once you have than you may have more to work with. – John Williams Commented Feb 16 at 13:10
  • According to the Antlr4 documentation, this error should not be caught by the library I am using, and should instead propagate up to my own code. My question is regarding the unintended behaviour of the exception. – Willo678 Commented Feb 16 at 16:15
  • So, lets find out where it's getting caught and take it from there. – John Williams Commented Feb 16 at 16:21
Add a comment  | 

1 Answer 1

Reset to default -1

This is a workaround, but if you store a boolean 'cancel' field within your listener class, and, at the top of any exit methods, check this value and throw an exception if True, this successfully throws the ParseCancellationException.

Note that this must be done individually for each exit listener; exitEveryRule always executes after each rule, which will not meet needs if an overridden method would throw its own exception.

I believe that the reason this works and other approaches do not is due to Antlr4's error recovery attempts; upon encountering an error it attempts to rerun the visitor method multiple times, even if you have set a BailErrorStrategy or other custom strategy.

The solution is as follows:

private boolean stopping = false;

private void attemptStop() {
     stopping = true;
}

private void quitIfStopping() {
     if (stopping) {throw new ParseCancellationException();}
}


@Override
public void exitAddExpr(BasicLangParser.AddExprContext ctx) {
    quitIfStopping();


    if (condition) {
        String result = "example result";
        stack.push(Util.Value.newValue(result));
    } else {
        attemptStop();
    }

    super.exitAddExpr(ctx);
}

`

发布评论

评论列表(0)

  1. 暂无评论