只需要在正确的位置识别关键字

时间:2014-06-25 12:40:32

标签: parsing antlr antlr4

我是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在只有定义/引入的位置强制执行令牌识别?

谢谢!

2 个答案:

答案 0 :(得分:2)

你所拥有的本质上是湖语语法,与岛语法相反。湖语语法是一种你大多数都有结构化文本,然后是你不关心的东西的湖泊语法。一般来说,关键是有一些词汇Sentinel,表示“输入非结构化文本区域”,然后“重新输入结构化文本区域”。在你的情况下,它似乎是(...)。 ANTLR具有词法模式的概念,这是你想要处理具有不同词汇结构的区域。当你看到'('你要将模式切换到某个自由格式区域时。当你在该区域看到')'时,你想要切换回默认模式。无论如何"mode"是你的关键词。

答案 1 :(得分:0)

我的关键字有类似问题,有时只是标识符。我是这样做的:

 OnlySometimesAKeyword : 'value' ;

 identifier 
     :   Identifier // defined as usual
     |   maybeKeywords
     ;

 maybeKeywords
     :   OnlySometimesAKeyword 
     // ...
     ;

在您的解析器规则中,只需使用identifier代替Identifier,您也可以匹配“可能的关键字”。这当然也会在它们将成为关键字的地方匹配它们,但如果需要,您可以在解析器中进行检查。