如何在ANTLR4中的某些时候将关键字解析为普通词

时间:2016-08-03 23:57:42

标签: antlr4

我的语言中包含hello等关键字,这些关键字只是某些类型句子中的关键字。在其他类型的句子中,例如,这些单词应该被匹配为ID。这是讲述故事的超简单语法:

grammar Hello;

file : ( sentence )* ;
sentence : 'hello' ID PERIOD
         | INT ID PERIOD;

ID  : [a-z]+ ;
INT : [0-9]+ ;
WS  : [ \t\r\n]+ -> skip ;
PERIOD : '.' ;

我希望这些句子有效:

hello fred.
31 cheeseburgers.
6 hello.

但是最后一句话在这个语法中没有用。单词hellohello类型的标记,而不是ID类型的标记。看起来lexer抓住所有的hellos并将它们变成这种类型的标记。

这是一种疯狂的方式来解释我想要的东西:

sentence : 'hello' ID PERIOD
         | INT crazyID PERIOD;

crazyID : ID | 'hello' ;

但是用我的真实语言,有很多像hello要处理的关键字,所以,是的,这种方式看起来很疯狂。

是否有合理,紧凑,与目标语言无关的方式来处理这个问题?

1 个答案:

答案 0 :(得分:2)

处理关键字的标准方法:

file     : ( sentence )* EOF ;
sentence : key=( KEYWORD | INT ) id=( KEYWORD | ID ) PERIOD ;

KEYWORD : 'hello' | 'goodbye' ; // list others as alts
PERIOD  : '.' ;
ID      : [a-z]+ ;
INT     : [0-9]+ ;
WS      : [ \t\r\n]+ -> skip ;

基于KEYWORD规则之前列出的ID规则,解决了KEYWORDID规则之间看似模棱两可的问题。

在解析器SentenceContext中,将生成TerminalNode变量keyid,并且在解析时,将有效地保存匹配的标记,从而可以轻松识别位置。