Java Antlr4:如何避免过多的语义谓词?
以下是我的lexer规则的开始:Java Antlr4:如何避免过多的语义谓词?,java,antlr4,Java,Antlr4,以下是我的lexer规则的开始: F_TEXT_START : {! matchingFText}? 'f"' {matchingFText = true;} ; F_TEXT_PH_ESCAPE : {matchingFText && ! matchingFTextPh}? '{=/' ; F_TEXT_PH_START : {matchingFText && ! matchingFTextPh}? '{='
F_TEXT_START
: {! matchingFText}? 'f"' {matchingFText = true;}
;
F_TEXT_PH_ESCAPE
: {matchingFText && ! matchingFTextPh}? '{=/'
;
F_TEXT_PH_START
: {matchingFText && ! matchingFTextPh}? '{=' {matchingFTextPh = true;}
;
F_TEXT_PH_END
: {matchingFText && matchingFTextPh}? '}' {matchingFTextPh = false;}
;
F_TEXT_CHAR
: {matchingFText && ! matchingFTextPh}? (~('"' | '{')+ | '""' | '{' ~'=')
;
F_TEXT_END
: {matchingFText && ! matchingFTextPh}? '"' {matchingFText = false;}
;
IF
: {! matchingFText || matchingFTextPh}? 'if'
;
ELIF
: {! matchingFText || matchingFTextPh}? 'elif'
;
// Lots of other keywords
fragment LETTER
: ('A' .. 'Z' | 'a' .. 'z' | '_')
;
VARIABLE
: {! matchingFText || matchingFTextPh}? LETTER (LETTER | DIGIT)*
;
我所做的是将格式化文本不仅仅像普通文本标记一样放在前面,而是将其添加到解析树中,以便能够在解析时判断是否有错误(仅使用parser.start()
)。因此,格式化文本以f“
开头,以”
结尾,任何“
都必须替换为”
,并且可以包含以{=/code>开头和以}
结尾的占位符,但如果您想实际编写{
,则必须将其替换为{
。
问题是,在一个普通的格式化文本内容(不是占位符)中,lexer不仅开始处理F_text\u CHAR
,而且还处理其他lexer规则,比如变量。我所做的事情看起来相当愚蠢,我只是为每一个其他规则添加语义谓词,以避免它们在格式化文本的内容中匹配(但仍然在占位符中)
没有更好的方法吗?我会使用词法模式。要使用词法模式,您必须定义单独的词法分析器和语法分析器。下面是一个快速演示:
lexer grammar TestLexer;
F_TEXT_START
: 'f"' -> pushMode(F_TEXT)
;
VARIABLE
: LETTER (LETTER | DIGIT)*
;
F_TEXT_PH_ESCAPE
: '{=/'
;
F_TEXT_PH_END
: '}' -> popMode
;
SPACES
: [ \t\r\n]+ -> skip
;
fragment LETTER
: [a-zA-Z_]
;
fragment DIGIT
: [0-9]
;
mode F_TEXT;
F_TEXT_CHAR
: ~["{]+ | '""' | '{' ~'='
;
F_TEXT_PH_START
: '{=' -> pushMode(DEFAULT_MODE)
;
F_TEXT_END
: '"' -> popMode
;
在解析器中使用lexer,如下所示:
parser grammar TestParser;
options {
tokenVocab=TestLexer;
}
// ...
如果您现在标记化输入f“mu{=mu}”mu
,您将获得以下标记:
F_TEXT_START `f"`
F_TEXT_CHAR `mu `
F_TEXT_PH_START `{=`
VARIABLE `mu`
F_TEXT_PH_END `}`
F_TEXT_END `"`
VARIABLE `mu`
谢谢!但我不明白:你为什么不把F_TEXT\u PH_START
置于F_TEXT
模式?顺便说一句,谢谢你的GitHub repo“mu”“,它帮助很大!我认为F_TEXT_PH_START
只能出现在格式化的字符串中。如果不是这样,请相应地调整我的示例语法。是的,确实如此!而且,它可以合并成F_TEXT_CHAR
如下:F_TEXT_CHAR:~[“{]+|”“'{'~'='{='{=/'
而且,我已经在使用{
和}
在我的默认语法中(但它不能在表达式中),我在解析器中要求占位符。它的语义谓词是什么?我在阅读antlr的代码时发现语义pretate:\u modeStack.contains(1)