Я написал несколько функций и хотел разобрать с помощью Antlr4. Но для вложенной функции не будет отображаться ошибка типа данных. Итак, как я могу сгенерировать ожидаемый тип данных в сравнении с данным как исключение из самого грамматика.
Граммер: грамматика FunctionGrammer;
INT
: [0-9]+
;
ID
: [a-zA-Z_] [a-zA-Z_0-9]*
;
//expr : add;
integer : 'Functionadd(' INT ',' INT ')' | INT ;
add : 'Functionadd(' INT ',' INT ')' ;
concat : 'Functionconcat(' (integer |INT )','INT ')';
exp : 'Functionadd(' INT ',' INT ')' | 'Functionconcat(' integer ','INT ')';
Слушатель для выброса исключений:
public class VerboseListener extends BaseErrorListener {
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
List<String> stack = ((Parser)recognizer).getRuleInvocationStack();
Collections.reverse(stack);
throw new FunctionInvalidException("line "+line+":"+charPositionInLine+" at "+ offendingSymbol+": "+msg);
}
}
Ниже приведен метод проверки выражения:
public static void main(String[] args) {
try {
CodePointCharStream input = CharStreams.fromString("Functionconcat(m,1)");
FunctionGrammerLexer lexer = new FunctionGrammerLexer(input);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
FunctionGrammerParser parser = new FunctionGrammerParser(tokenStream);
parser.removeErrorListeners(); // remove ConsoleErrorListener
parser.addErrorListener(new VerboseListener()); // add ours
ParseTree tree = parser.exp();
FunctionCompilerImpl visitor = new FunctionCompilerImpl();
visitor.visit(tree);
} catch (Exception e) {
System.out.println();
System.out.println("exception--->"+e.getMessage());
}
}
}
Для ввода типа:
1) Functionconcat(Functionadd(m,2),1)
Вывод: exception--->line 1:27 at [@2,27:27='m',<6>,1:27]: mismatched input 'm' expecting INT
Но для 2) Functionconcat(a,1)
Вывод: exception--->line 1:15 at [@1,15:15='a',<6>,1:15]: no viable alternative at input 'a'
Исключение, которое я хотел, является чем-то вроде целочисленного значения, поскольку он дает на входе 1 (INT). Итак, как я могу бросить error
в VerboseListener
или exception
прямо из грамматики, когда он не соответствует, что-то вроде этого exp: 'Functionadd(' INT ',' INT ')' | 'Functionconcat(' integer|{throw new FunctionInvalidException("datatype mismatch")} ','INT ')';
.