写在之前
我们在编写语言的时候常会碰到这样一个问题:在用ID:[a-zA-z]+
这样的词法规则作为标识符
时,类似于if while
这样的关键字匹配
就会发生歧义。
前几篇博客中,我们已经介绍了如何在文法规则
中内嵌动作。这次,我们试着只在词法规则
中内嵌动作。
预期效果
i
这样的字符会被识别成标识符
,而碰到if
这样的关键字
,其词法符号类型会被转换成对应关键字类型
。
内嵌代码
我们拿一个简单的关键字识别语法文件为例。
语法文件
BEGIN、END、IF、WHILE、THEN作为我们的关键字。
grammar Keywords;
stat: BEGIN stat* END
| IF expr THEN stat
| WHILE expr stat
| ID '=' expr ';'
;
expr: INT | CHAR ;
ID
: [a-zA-Z]+
;
CHAR: '\'' . '\''
;
INT : [0-9]+ ;
WS : [ \t\n\r]+ -> skip ;
内嵌动作
我们按照逻辑顺序进行分析。
-
关键词的替换处于
词法分析阶段
,因此我们只需要在@lexer
中内嵌动作即可。首先我们将需要的包文件通过@lexer::header
引入。 -
需要注意BEGIN,END,IF,THEN,WHILE这些关键字并没有
词法规则的定义
,我们可以通过tokens
将它们放到Parser
中:tokens{ BEGIN,END,IF,THEN,WHILE}
相当于:
//KeywordsParser.java public static final int T__0=1, T__1=