如何允许lexer解析来自java的特定代码部分?
我目前正在使用antlr4创建一个编译器,它应该允许解析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
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
;