如何允许lexer解析来自java的特定代码部分?

如何允许lexer解析来自java的特定代码部分?,java,antlr,antlr4,Java,Antlr,Antlr4,我目前正在使用antlr4创建一个编译器,它应该允许解析java代码 我如何允许: public void=(整数值)=>java{this.value=value;} antlr没有解析java{}之间的代码,但我的解析器中应该有一个访问者 目前我有 javaStatementBody: KWJAVA LCURLY .*? RCURLY 但这显然不起作用,是吗?解析整个文件 请不要回答“使用引号”,这不是我的解决方案,因为我想允许java代码突出显示。您可以创建单独的lexer和parse

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

我如何允许:

public void=(整数值)=>java{this.value=value;}
antlr没有解析java{}之间的代码,但我的解析器中应该有一个访问者

目前我有

javaStatementBody: KWJAVA LCURLY .*? RCURLY
但这显然不起作用,是吗?解析整个文件


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

您可以创建单独的lexer和parser语法,以便使用。每当lexer“看到”输入
java{
,它就会移动到
java_模式
。在java模式下,你会标记注释、字符串和字符文本。在这种模式下,你会遇到
{
,你会推同一个
java_模式
,这样lexer就会知道它嵌套了一次。当你遇到
}
,从堆栈中弹出一个模式(导致返回默认模式,或保持Java模式,但深度降低一级)

快速演示:

IslandLexer.g4
IslandParser.g4
使用以下代码对其进行测试:

String source=“foo\n”+
“\n”+
“java{\n”+
“char foo(){\n”+
“/*注释中的引用\\\”*/\n”+
“字符串s=\“java{…}\”;\n”+
“返回'}';\n”+
“}\n”+
“}\n”+
“\n”+
“酒吧”;
IslandLexer lexer=新的IslandLexer(CharStreams.fromString(source));
IslandParser parser=新的IslandParser(新的CommonTokenStream(lexer));
System.out.println(parser.parse().toString树(parser));
以下哪个是解析树:


能否导入Java语法并引用Java正文?嵌入的代码本身是否包含嵌套的
{…}
?是否包含注释(其中可能包含
{
}
)?嵌入的代码是否包含字符串和字符文本?即,这是否有效:
Java{char foo(){/*注释“*/String s=”java{…};return'}';}}}
?是的,它应该可以包含嵌套语句,比如if语句或循环。我现在有一个Lexer和一个解析器文件,但是当我用antlr java文件创建解析器时,它找不到我的令牌,我收到了许多警告:解析器中的令牌X的隐式定义。您可能没有在解析器中正确定义
tokenVocab
。仔细看看我的答案中的例子。请注意,在组合语法中(您同时定义lexer和parser规则),当该语法被称为
Foo
时,ANTLR将生成
footexer
FooParser
。在单独的lexer和语法文件中,您必须调用语法
doublexer
FooParser
。在
FooParser
中,必须定义
tokenVocab=doublexer
选项
块内(如我的示例所示)。是。问题是我的令牌文件位于错误的目录中。修好了
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         : ~[{}];
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
 ;