В Antlr как скинуть Exception из парсера - PullRequest
1 голос
/ 19 октября 2019

Я написал несколько функций и хотел разобрать с помощью 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 ')';.

...