如何强制ANTLR解析所有输入CharStream

我正在使用ANTLR4来解析语法文件。 当我使用BaseErrorListener来检测错误时,我遇到了问题。 当遇到非法输入字符串时,ANTLR会自动匹配相应的分支,然后忽略后续的字符 ,即使它包含错误。 我想检测那个错误。 这是我的g4文件和java文件。
TransitionLexer是我的lexer文件, TransitionCondition是我的解析器文件。 ErrorDialogListener.java是我的errorListener和Test.java id主java文件。

TransitionLexer.g4

lexer grammar TransitionLexer; BOOLEAN: 'true' | 'false'; IF: 'if'; THEN: 'then'; ELSE: 'else'; NAME: (ALPHA | CHINESE | '_')(ALPHA | CHINESE | '_'|DIGIT)*; ALPHA: [a-zA-Z]; CHINESE: [\u4e00-\u9fa5]; NUMBER: INT | REAL; INT: DIGIT+ |'(-'DIGIT+')'; REAL: DIGIT+ ('.' DIGIT+)? | '(-' DIGIT+ ('.' DIGIT+)? ')'; fragment DIGIT: [0-9]; OPCOMPARE: '='|'>='|''|'skip; SL_COMMENT: '/*' .*? '*/' ->skip; 

TransitionCondition.g4

 grammar TransitionCondition; import TransitionLexer; condition : stat+; stat : expr; expr: expr (('and' | 'or') expr)+ | '(' expr ')' | '(' var OPCOMPARE value ')' | booleanExpr | BOOLEAN ; var: localStates | globalStates | connector ; localStates: NAME; globalStates: 'Top' ('.' brick)+ '.' NAME; connector: brick '.' NAME; value: userdefinedValue | basicValue; userdefinedValue: NAME; basicValue: basicValue op=('*'|'/') basicValue | basicValue op=('+' | '-') basicValue | basicValue ('and' | 'or') basicValue | NUMBER | BOOLEAN | '(' basicValue ')' ; booleanExpr: booleanExpr OPCOMPARE booleanExpr | '(' booleanExpr ')' | NUMBER (OPCOMPARE|'*'| '/'|'+'|'-') NUMBER ; brick: NAME; 

ErrorDialogListener.java

 package errorprocess; import java.awt.Color; import java.awt.Container; import java.util.Collections; import java.util.List; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.Parser; import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.Recognizer; import org.antlr.v4.runtime.atn.ATNConfigSet; import org.antlr.v4.runtime.dfa.DFA; public class ErrorDialogListener extends BaseErrorListener { @Override public void reportContextSensitivity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, ATNConfigSet configs) { System.out.println(dfa.toLexerString()); System.out.println(dfa.getStates()); super.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs); } @Override public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { List stack = ((Parser)recognizer).getRuleInvocationStack(); Collections.reverse(stack); StringBuilder buf = new StringBuilder(); buf.append("rule stack: "+stack+" "); buf.append("line "+line+":"+charPositionInLine+" at "+ offendingSymbol+": "+msg); JDialog dialog = new JDialog(); Container contentPane = dialog.getContentPane(); contentPane.add(new JLabel(buf.toString())); contentPane.setBackground(Color.white); dialog.setTitle("Syntax error"); dialog.pack(); dialog.setLocationRelativeTo(null); dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); dialog.setVisible(true); } } 

Test.java

 package errorprocess; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.atn.PredictionMode; import antlr4.my.transition.TransitionConditionLexer; import antlr4.my.transition.TransitionConditionParser; public class Test { public static void main(String[] args) throws IOException { InputStream in = new FileInputStream("G:\\AltaRica\\ANTLR4\\test\\condition\\t.expr"); ANTLRInputStream input = new ANTLRInputStream(in); TransitionConditionLexer lexer = new TransitionConditionLexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); TransitionConditionParser parser = new TransitionConditionParser(tokens); parser.removeErrorListeners(); parser.addErrorListener(new ErrorDialogListener()); // parser.addErrorListener(new DiagnosticErrorListener()); // parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION); // parser.getInterpreter().setPredictionMode(PredictionMode.LL); parser.condition(); } } 

主要问题

当我的输入是(Top.b2.states = nominal)和(b1.i1 =错误)和(states> = 5.5)时 ,解析器工作正常。
但是当我的输入是(Top.b2.states = nominal)aaa(b1.i1 =错误)和(状态> = 5.5)时 ,解析器只解析(Top.b2.states = nominal)并忽略aaa之后的单词不正确的语法文件。
我想原因是解析器遵循我在TransitionCondition.g4中的第一个规则的第二个分支,即expr:’(’expr’)’ ,并且只是忽略其他分支。 那么如何强制ANTLR识别所有输入或如何强制ANTLR只选择第一个分支( expr:expr((’和’|’或’)expr)+ )在这种情况下?

我试过的。

我试图使用DiagnosticErrorListener或覆盖reportContextSensitivity()但似乎没有用。

您的主要规则需要以EOF令牌结束 – 一个ANTLR提供的特殊令牌,匹配输入的结尾。

如果令牌不存在,ANTLR将只解析它可以匹配的任何内容,然后停止。 通过将EOF放在输入规则的末尾,您告诉ANTLR它解析的任何内容必须在输入结束时结束。