gpt4 book ai didi

java - 如何检测用户是否输入了不符合我的ANTLR语法规则的字符串?

转载 作者:行者123 更新时间:2023-12-03 08:45:29 25 4
gpt4 key购买 nike

我正在制作一个计算机代数系统,它将采用代数表达式并将其简化或区分。

如下面的代码所示,用户输入已被接受,但是如果它是不符合我的语法规则的字符串,则错误,
第1:6行出现不匹配的输入'',期望{'(',INT,VAR},并且程序继续运行。

如何捕获错误并停止程序运行?预先感谢您的任何帮助。

Controller 类:

    public static void main(String[] args) throws IOException {
String userInput = "x*x*x+";
getAST(userInput);

}

public static AST getAST(String userInput) {
ParseTree tree = null;
ExpressionLexer lexer = null;
ANTLRInputStream input = new ANTLRInputStream(userInput);
try {
lexer = new ExpressionLexer(input);
}catch(Exception e) {
System.out.println("Incorrect grammar");
}
System.out.println("Lexer created");

CommonTokenStream tokens = new CommonTokenStream(lexer);
System.out.println("Tokens created");
ExpressionParser parser = new ExpressionParser(tokens);
System.out.println("Tokens parsed");


tree = parser.expr();

System.out.println("Tree created");
System.out.println(tree.toStringTree(parser)); // print LISP-style tree
Trees.inspect(tree, parser);

ParseTreeWalker walker = new ParseTreeWalker();
ExpressionListener listener = new buildAST();
walker.walk(listener, tree);

listener.printAST();
listener.extractExpression();

return new AST();
}
}

我的语法:
grammar Expression;

@header {
package exprs;

}
@members {
// This method makes the parser stop running if it encounters
// invalid input and throw a RuntimeException.
public void reportErrorsAsExceptions() {
//removeErrorListeners();

addErrorListener(new ExceptionThrowingErrorListener());
}

private static class ExceptionThrowingErrorListener extends BaseErrorListener {
@Override
public void syntaxError(Recognizer<?, ?> recognizer,
Object offendingSymbol, int line, int charPositionInLine,
String msg, RecognitionException e) {
throw new RuntimeException(msg);
}
}
}
@rulecatch {
// ANTLR does not generate its normal rule try/catch
catch(RecognitionException e) {
throw e;
}
}

expr : left=expr op=('*'|'/'|'^') right=expr
| left=expr op=('+'|'-') right=expr
| '(' expr ')'
| atom
;

atom : INT|VAR;
INT : ('0'..'9')+ ;
VAR : ('a' .. 'z') | ('A' .. 'Z') | '_';

WS : [ \t\r\n]+ -> skip ;

最佳答案

ANTLR4的典型解析运行包括两个阶段:

  • 使用SLL预测模式运行的“快速处理”,可根据发现的第一个语法错误提供帮助。
  • 使用LL预测模式的常规运行,尝试从解析器错误中恢复。仅在第一步出错时才需要执行此第二步。

  • 第一步是一个宽松的解析运行,它不能解决某些歧义,因此可以报告一个实际上不存在的错误(在LL模式下解决时)。但是第一步要更快,并且为语法正确的输入提供更快的结果。此(JS)代码显示了设置:
        this.parser.removeErrorListeners();
    this.parser.addErrorListener(this.errorListener);

    this.parser.errorHandler = new BailErrorStrategy();
    this.parser.interpreter.setPredictionMode(PredictionMode.SLL);

    try {
    this.tree = this.parser.grammarSpec();
    } catch (e) {
    if (e instanceof ParseCancellationException) {
    this.tokenStream.seek(0);
    this.parser.reset();
    this.parser.errorHandler = new DefaultErrorStrategy();
    this.parser.interpreter.setPredictionMode(PredictionMode.LL);
    this.tree = this.parser.grammarSpec();
    } else {
    throw e;
    }
    }

    为了避免在第一步中尝试解决语法错误,还必须设置 BailErrorStrategy。如果发生语法错误,此策略只会抛出 ParseCancellationException(类似于您在代码中所做的操作)。您可以在catch子句中添加您自己的处理,以询问用户正确的输入并重新旋转解析步骤。

    关于java - 如何检测用户是否输入了不符合我的ANTLR语法规则的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55746530/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com