ANTLR4用于Java的。如何在词法分析中显示错误

huangapple go评论76阅读模式
英文:

ANTLR4 for Java. How to display errors in lexical analysis

问题

如何在词法分析期间显示错误列表(如果有错误)。
我尝试了以下方法,但是我的输出是 [org.antlr.v4.runtime.ConsoleErrorListener@1026c84c]。

我编写的代码:

    private static String errorsOutput(String code) {
        Java8Lexer lexer = new Java8Lexer(new ANTLRInputStream(code));

        CommonTokenStream tokens = new CommonTokenStream(lexer);
        Java8Parser parser = new Java8Parser(tokens);

        return "" + lexer.getErrorListeners();
    }

主类:

    String code = "public class Main {public static void main(String[] args) {System.out.println(\"Hello, world\")}}";
    System.out.println(errorsOutput(code));

在这个例子中没有显示出错的标志 [;],我需要程序显示这个错误。
英文:

How can you display a list of errors (if any) during lexical analysis.
I tried the following method, but my output is [org.antlr.v4.runtime.ConsoleErrorListener@1026c84c].

The code I wrote:

private static String errorsOutput(String code) {
    Java8Lexer lexer = new Java8Lexer(new ANTLRInputStream(code));

    CommonTokenStream tokens = new CommonTokenStream(lexer);
    Java8Parser parser = new Java8Parser(tokens);

    return ""+lexer.getErrorListeners();
}

Main class:

String code = "public class Main {public static void main(String[] args) {System.out.println("Hello, world")}}";
System.out.println( errorsOutput(code) );

There is no sign in this example
[;] and I need the program to display this error

答案1

得分: 1

你所描述的并不是词法分析,而是语法分析。

以下是如何添加自定义错误监听器并收集消息的方法:

String source = "public class Main {\n" +
        "    public static void main(String[] args) {\n" +
        "        System.out.println(\"Hello, world\")\n" +
        "    }\n" +
        "}";

Java8Lexer lexer = new Java8Lexer(CharStreams.fromString(source));
Java8Parser parser = new Java8Parser(new CommonTokenStream(lexer));

parser.removeErrorListeners();

final List<String> errorMessages = new ArrayList<>();

parser.addErrorListener(new BaseErrorListener(){
    @Override
    public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
        errorMessages.add(msg);
    }
});

parser.compilationUnit();

System.out.println("errorMessages: " + errorMessages);

请注意,上面的代码段会显示消息 mismatched input '(' expecting '.',因为在这个位置:

System.out.println(
//                ^
//                |
//                '-- 这里

它无法匹配 println 语句,因为缺少了 ;,所以它会尝试匹配另一个 . 来完成一个 methodInvocation,但也会失败。这只是语法的结构,除了重写大部分语法,没有太多可以做的。

如果你解析这段代码:

String source = "public class Main {\n" +
        "    public static void main(String[] args) {\n" +
        "        foo()\n" +
        "    }\n" +
        "}";

那么你会得到消息:missing ';' at '}'

英文:

What you're describing is not lexical analysis, but syntactic analysis.

This is how you add a custom error listener and collect messages:

String source = &quot;public class Main {\n&quot; +
        &quot;    public static void main(String[] args) {\n&quot; +
        &quot;        System.out.println(\&quot;Hello, world\&quot;)\n&quot; +
        &quot;    }\n&quot; +
        &quot;}&quot;;

Java8Lexer lexer = new Java8Lexer(CharStreams.fromString(source));
Java8Parser parser = new Java8Parser(new CommonTokenStream(lexer));

parser.removeErrorListeners();

final List&lt;String&gt; errorMessages = new ArrayList&lt;&gt;();

parser.addErrorListener(new BaseErrorListener(){
    @Override
    public void syntaxError(Recognizer&lt;?, ?&gt; recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
        errorMessages.add(msg);
    }
});

parser.compilationUnit();

System.out.println(&quot;errorMessages: &quot; + errorMessages);

Note that the snippet above will display the message mismatched input &#39;(&#39; expecting &#39;.&#39; because at this location:

System.out.println(
//                ^
//                |
//                &#39;-- here

it cannot match a println statement because of the missing ; so it then tries to match another . to complete a methodInvocation, which also fails. That is just how the grammar is structured, not much to do about that (besides rewriting large parts of it).

If you parse this:

String source = &quot;public class Main {\n&quot; +
        &quot;    public static void main(String[] args) {\n&quot; +
        &quot;        foo()\n&quot; +
        &quot;    }\n&quot; +
        &quot;}&quot;;

then you do get the message: missing &#39;;&#39; at &#39;}&#39;

huangapple
  • 本文由 发表于 2020年10月27日 04:08:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/64544255.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定