java - 如何让词法分析器解析java中的特定代码部分?

标签 java antlr antlr4

我目前正在使用antlr4创建一个编译器,它应该允许解析java代码。

我如何允许:

public void =(Integer value) => java { this.value = value; }

java { }之间的代码没有被antlr解析,但在我的解析器中应该有一个访问者。

目前我有

javaStatementBody: KWJAVA LCURLY .*? RCURLY

但这显然不起作用,.*?解析整个文件。

请不要用“使用引号”回答,这不是我的解决方案,因为我想允许 java 代码突出显示。

最佳答案

您可以创建单独的词法分析器和解析器语法,以便可以使用 lexical modes 。每当词法分析器“看到”输入 java { 时,它就会移动到 JAVA_MODE。在 Java 模式下,您可以对注释、字符串和字 rune 字进行标记。此外,在此模式下,您遇到 {,您会推送相同的 JAVA_MODE,以便词法分析器知道它嵌套了一次。当您遇到 } 时,您会从堆栈中弹出一个模式(导致返回到默认模式,或保持在 Java 模式但深度较低一层)。

快速演示:

IslandLexer.g4

lexer grammar IslandLexer;

JAVA_START
 : 'java' SPACES '{' -> pushMode(JAVA_MODE)
 ;

OTHER
 : .
 ;

fragment SPACES : [ \t\r\n]+;

mode JAVA_MODE;

  JAVA_CHAR          : '\'' ( ~[\\'\r\n] | '\\' [tbnrf'\\] ) '\'';
  JAVA_STRING        : '"' ( ~[\\"\r\n] | '\\' [tbnrf"\\] )* '"';
  JAVA_LINE_COMMENT  : '//' ~[\r\n]*;
  JAVA_BLOCK_COMMENT : '/*' .*? '*/';
  JAVA_OPEN_BRACE    : '{' -> pushMode(JAVA_MODE);
  JAVA_CLOSE_BRACE   : '}' -> popMode;
  JAVA_OTHER         : ~[{}];

IslandParser.g4

parser grammar IslandParser;

options { tokenVocab=IslandLexer; }

parse
 : unit* EOF
 ;

unit
 : base_language
 | java_janguage
 ;

base_language
 : OTHER+
 ;

java_janguage
 : JAVA_START java_atom+
 ;

java_atom
 : JAVA_CHAR
 | JAVA_STRING
 | JAVA_LINE_COMMENT
 | JAVA_BLOCK_COMMENT
 | JAVA_OPEN_BRACE
 | JAVA_CLOSE_BRACE
 | JAVA_OTHER
 ;

使用以下代码进行测试:

String source = "foo \n" +
        "\n" +
        "java { \n" +
        "  char foo() { \n" +
        "    /* a quote in a comment \\\" */ \n" +
        "    String s = \"java {...}\"; \n" +
        "    return '}'; \n" +
        "  }\n" +
        "}\n" +
        "\n" +
        "bar";

IslandLexer lexer = new IslandLexer(CharStreams.fromString(source));
IslandParser parser = new IslandParser(new CommonTokenStream(lexer));
System.out.println(parser.parse().toStringTree(parser));

这是以下解析树:

enter image description here

关于java - 如何让词法分析器解析java中的特定代码部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63260964/

相关文章:

java - 有没有办法测试方法处理并发调用的能力?

java - 如果属性中有几何图形,则 Geojson 文件无法正确导入

antlr - "fragment"在ANTLR中是什么意思?

algorithm - 说明 token 流上的最左边的推导

c# - 如果输入无效,是否可以抛出异常?

Antlr 语义谓词未能找到可行的替代方案

java - 使用数组适配器和 listView 时出现异常

java - 如何保存 fragment 娱乐

java - 命题逻辑的 BNF 语法 ANTLR

parsing - ANTLR4 谓词失败忽略以下替代方案?