I developed complex grammar using Antlr 3 using the AST tree. ANTLR generates Lexer and Parser. The problem is that when the user enters syntax that is invalid, for example, the grammar expects ';'. The user does not enter this, then in my Eclipse IDE I get the following exception:
line 1:24 mismatched input '<EOF>' expecting ';'
How can I handle this exception because I'm trying to catch this exception, but the exception is not caught. Is this an exception? I don't seem to understand why this exception is not caught. I tried to find out, however the Antlr website does not seem to be working for a long time.
I looked at the following: handling ANTLR exceptions with "$", Java, and followed this example, but when Lexer throws code by adding a RuntimeException () exception, I get unreachable code.
I'm not sure what to do.
When I try to get the number of syntax errors from the parser, it displays 0.
EDIT:
I found a solution that works by looking at: ANTLR does not throw errors on invalid input
However, when I try to get an exception message, it is null. Have I set everything up correctly? See Sample Grammar:
grammar i; options { output=AST; } @header { package com.data; } @rulecatch { catch(RecognitionException e) { throw e; } } // by having these below it makes no difference /**@parser::members { @Override public void reportError(RecognitionException e) { throw new RuntimeException("Exception : " + " " + e.getMessage()); } } @lexer::members { @Override public void reportError(RecognitionException e) { throw new RuntimeException("Exception : " + " " + e.getMessage()); } }*/
EDIT:
See what I have so far:
grammar i; options { output=AST; } @header { package com.data; } @rulecatch { // ANTLR does not generate its normal rule try/catch catch(RecognitionException e) { throw e; } } @parser::members { @Override public void displayRecognitionError(String[] tokenNames, RecognitionException e) { String hdr = getErrorHeader(e); String msg = getErrorMessage(e, tokenNames); throw new RuntimeException(hdr + ":" + msg); } } @lexer::members { @Override public void displayRecognitionError(String[] tokenNames, RecognitionException e) { String hdr = getErrorHeader(e); String msg = getErrorMessage(e, tokenNames); throw new RuntimeException(hdr + ":" + msg); } } operatorLogic : 'AND' | 'OR'; value : STRING; query : (select)*; select : 'SELECT'^ functions 'FROM table' filters?';'; operator : '=' | '!=' | '<' | '>' | '<=' | '>='; filters : 'WHERE'^ conditions; members : STRING operator value; conditions : (members (operatorLogic members)*); functions : '*'; STRING : ('a'..'z'|'A'..'Z')+; WS : (' '|'\t'|'\f'|'\n'|'\r')+ {skip();}; // handle white space between keywords public class Processor { public Processor() { } /** * This method builds the MQL Parser. * @param args the args. * @return the built IParser. */ private IParser buildMQLParser(String query) { CharStream cs = new ANTLRStringStream(query); // the input needs to be lexed ILexer lexer = new ILexer(cs); CommonTokenStream tokens = new CommonTokenStream(); IParser parser = new IParser(tokens); tokens.setTokenSource(lexer); // use the ASTTreeAdaptor so that the grammar is aware to build tree in AST format parser.setTreeAdaptor((TreeAdaptor) new ASTTreeAdaptor().getASTTreeAdaptor()); return parser; } /** * This method parses the MQL query. * @param query the query. */ public void parseMQL(String query) { IParser parser = buildMQLParser(query); CommonTree commonTree = null; try { commonTree = (CommonTree) parser.query().getTree(); } catch(Exception e) { System.out.println("Exception :" + " " + e.getMessage()); } } } public class ASTTreeAdaptor { public ASTTreeAdaptor() { } /** * This method is used to create a TreeAdaptor. * @return a treeAdaptor. */ public Object getASTTreeAdaptor() { TreeAdaptor treeAdaptor = new CommonTreeAdaptor() { public Object create(Token payload) { return new CommonTree(payload); } }; return treeAdaptor; } }
Therefore, when I enter the following: SELECT * FROM table
without ';' I get a MismatchedTokenException:
catch(Exception e) { System.out.println("Exception : " + " " e); }
When I try:
e.getMessage();
it returns null.