antlr4 - 使用令牌时解析器无法正常工作

时间:2017-01-08 15:14:10

标签: parsing antlr4 abstract-syntax-tree

我创建了一个非常简单的语法来显示我遇到的问题:

grammar Expr;
test: funcDecl;
//-----------------------------------------------------------------------
funcDecl:    funcHead ';';
funcHead:    type '*'? IDENTIFIER '(' formParList? ')';
formParList: ( 'void' |
               type '*'? IDENTIFIER ('[' ']')?
               (',' type '*'? IDENTIFIER ('[' ']')?)*
             );
type:        'void' | 'bool' | 'int';

// ----------------------------------------------------------------------
Whitespace:     [ \t]+ -> skip;
LineComment:    '//' ~[\r\n]* -> skip;
NEWLINE :       ('\r' '\n'? | '\n') -> skip;

IDENTIFIER:     CHARACTER (CHARACTER | DIGIT)*;

fragment
CHARACTER: [a-zA-Z_];
fragment
DIGIT:     [0-9];

上面的语法使用以下示例代码生成以下AST:

void Sieve(int n); // declaration

AST

type更改为令牌(将type更改为TYPE)后,这就是语法的样子:

...
funcHead:    TYPE '*'? IDENTIFIER '(' formParList? ')';
...
TYPE:        'void' | 'bool' | 'int';
...

执行此操作后,我收到以下错误:

line 1:0 mismatched input 'void' expecting TYPE

为什么?只要我为该类型使用令牌,解析器就会抛出此错误。但IDENTIFIER令牌无论如何......

1 个答案:

答案 0 :(得分:0)

您是否已将formParList更改为不包含'void'。解析器部分中使用的每个Literal都成为隐式Lexer令牌,优先于明确定义的令牌。

如果你在这个位置需要空虚,你可以这样做:

funcHead:    type '*'? IDENTIFIER '(' formParList? ')';
formParList: ( VOID |
           type '*'? IDENTIFIER ('[' ']')?
           (',' type '*'? IDENTIFIER ('[' ']')?)*
         );
type:        TYPE | VOID;

...

TYPE:        'bool' | 'int';
VOID:        'void';

...

或者您为每个类型分配了自己的Lexer令牌,然后类型的解析器规则如下:type: VOID | BOOL | INT。如果你以后必须解释AST,这可能会更方便。