我是Antlr的新手并且正在解析,所以这对我来说是一次学习练习。
我正在尝试解析某些位置允许自由格式文本的语言。因此,自由格式文本可以是任何单词或单词,包括语言中的关键字 - 它们在语言中的位置将它们定义为关键字或自由文本。
在以下示例中," JOB"的第一个实例是一个关键字;第二个" JOB"是自由形式的文本:
JOB=(JOB)
我尝试了以下语法,避免在词法规则中定义语言的关键字。
grammar Test;
test1 : 'JOB' EQ OPAREN (utext) CPAREN ;
utext : UNQUOTEDTEXT ;
COMMA : ',' ;
OPAREN : '(' ;
CPAREN : ')' ;
EQ : '=' ;
UNQUOTEDTEXT : ~[a-z,()\'\" \r\n\t]*? ;
SPC : [ \t]+ -> skip ;
我希望通过在解析器规则中定义关键字字符串文字,如上所述,它们只应用于定义它们的位置。情况似乎并非如此。在测试" test1"规则(使用IDEA中的Antlr4插件),并使用上面显示的上述示例短语 - " JOB =(JOB)" (没有引号) - 作为输入,我收到以下错误消息:
line 1:5 mismatched input 'JOB' expecting UNQUOTEDTEXT
因此,在为' JOB'创建隐式令牌之后,看起来Antlr也在解析器语法的其他点中使用该令牌,即每当它看到' JOB'串。为了测试这个,我添加了另一个解析器规则:
test2 : 'DATA' EQ OPAREN (utext) CPAREN ;
并使用" DATA =(JOB)"
进行测试我收到以下错误(与以前类似):
line 1:6 mismatched input 'JOB' expecting UNQUOTEDTEXT
有没有办法让Antlr在只有定义/引入的位置强制执行令牌识别?
谢谢!
答案 0 :(得分:2)
你所拥有的本质上是湖语语法,与岛语法相反。湖语语法是一种你大多数都有结构化文本,然后是你不关心的东西的湖泊语法。一般来说,关键是有一些词汇Sentinel,表示“输入非结构化文本区域”,然后“重新输入结构化文本区域”。在你的情况下,它似乎是(...)。 ANTLR具有词法模式的概念,这是你想要处理具有不同词汇结构的区域。当你看到'('你要将模式切换到某个自由格式区域时。当你在该区域看到')'时,你想要切换回默认模式。无论如何"mode"是你的关键词。
答案 1 :(得分:0)
我的关键字有类似问题,有时只是标识符。我是这样做的:
OnlySometimesAKeyword : 'value' ;
identifier
: Identifier // defined as usual
| maybeKeywords
;
maybeKeywords
: OnlySometimesAKeyword
// ...
;
在您的解析器规则中,只需使用identifier
代替Identifier
,您也可以匹配“可能的关键字”。这当然也会在它们将成为关键字的地方匹配它们,但如果需要,您可以在解析器中进行检查。