如何成功测试ANTLR4语法?自定义语言算术表达式测试报错咨询
Hey there! Let's work through this step by step since you're new to ANTLR v4 and just got your grammar up and running. That "mismatched input" error is super common when starting out, so let's break down what's going on and how to fix it.
First: Check Your Grammar Definition
The most likely cause of that error is that your grammar doesn't properly define the structure of 6+9, or your entry rule isn't set up to accept the full input. Let's start with a minimal, working arithmetic grammar you can use as a reference:
grammar SimpleMath; // Entry rule: Ensures the parser reads the entire input (ends with EOF) prog: expr EOF; // Expression rules with operator precedence (mult/div before add/sub) expr: expr ('*' | '/') expr # MulDiv | expr ('+' | '-') expr # AddSub | NUMBER # Number | '(' expr ')' # ParenExpr ; // Token for numbers (supports integers and decimals) NUMBER: DIGIT+ ('.' DIGIT+)?; DIGIT: [0-9]; // Ignore whitespace (spaces, tabs, newlines) WS: [ \t\r\n]+ -> skip;
Key things to note here:
- The
progentry rule includesEOF, which tells ANTLR the input should end after the expression. Without this, ANTLR might wait for more input and throw a mismatch error when you stop typing. - The
NUMBERtoken correctly matches integers like6and9. - Operator precedence is built into the rule order (mul/div rules come first, so they're evaluated before add/sub).
Second: How to Test with ANTLR's TestRig (grun)
If you're using the built-in grun tool to test, follow these exact steps (replace SimpleMath with your grammar name):
- Compile your grammar:
antlr4 SimpleMath.g4 - Compile the generated Java files:
javac SimpleMath*.java - Run the TestRig with your entry rule:
grun SimpleMath prog -gui - Input your expression and signal end of input:
- Type
6+9and press Enter. - On Linux/macOS, press
Ctrl+D; on Windows, pressCtrl+Zto tell ANTLR you're done inputting.
- Type
This should pop up a GUI showing the parse tree for 6+9—no more mismatch errors!
If your entry rule is named something else (like expr instead of prog), adjust the command to match: grun SimpleMath expr -gui. Just remember to include EOF in your entry rule or you'll hit the same waiting-for-input issue.
Third: Alternative Test with Custom Java Code
If you prefer to test directly in Java (instead of using grun), here's a simple test class you can adapt:
import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.*; public class MathParserTest { public static void main(String[] args) { String input = "6+9"; // Set up the lexer and parser CharStream inputStream = CharStreams.fromString(input); SimpleMathLexer lexer = new SimpleMathLexer(inputStream); CommonTokenStream tokenStream = new CommonTokenStream(lexer); SimpleMathParser parser = new SimpleMathParser(tokenStream); // Add an error listener to catch issues clearly parser.addErrorListener(new BaseErrorListener() { @Override public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { throw new RuntimeException(String.format( "Syntax error at line %d, position %d: %s", line, charPositionInLine, msg )); } }); // Parse the input using your entry rule ParseTree tree = parser.prog(); // Print the parse tree for debugging System.out.println("Parse tree:"); System.out.println(tree.toStringTree(parser)); } }
Compile and run this class, and it'll directly test your expression without needing manual input termination.
Common Mistakes to Avoid
- Forgetting
EOFin the entry rule: ANTLR expects more input unless you explicitly mark the end withEOF, which leads to mismatch errors when you stop typing. - Incorrect token definitions: Double-check your
NUMBERtoken—if it only matches digits 0-8, for example,9won't be recognized. - Wrong entry rule in
grun: Make sure the rule name you pass togrunmatches the top-level rule in your grammar that should accept the full expression.
内容的提问来源于stack exchange,提问作者Dorra Ben Khalifa

