ANTLR输入'NUM'不匹配期待{....,'NUM'}

时间:2016-04-08 10:14:52

标签: java grammar antlr4

尝试解析文件时,我遇到ANTLR4的问题。它首先起作用,但在我的语法中添加以下内容后,我得到一个错误(见下文):

TYPE_NUM: 'NUM';

mismatched input 'NUM' expecting {'LOAD', '\n', 'HEAR', 'NUM', 'STRING', 'COORD', 'BOOL', 'VOID', 'LIST'}

我语言中的'NUM'关键字符合以下规则:

typePrefix: type=('NUM' | 'BOOL' | 'STRING' | 'COORD' | 'LIST');

我的所有其他类型的修正也遇到了同样的问题,但我猜这是所有这些问题的解决方案。

我试图用TYPE_NUM,TYPE_BOOL等替换typePrefix规则的所有选项,但这似乎不起作用。

修改 根据评论中的要求,我发布了我的语法部分,我使用'NUM':

prog
    :   roboDcl loads roboBodyDcl;
loads
    :   recursion=loads 'LOAD' '(' load_id=StringLit ')' '\n' 
    |   //lambda
    ;
memberDcl
    :   dcl=fieldDcl
    |   met_dcl=methodDcl
    |   '\n'
    ;
roboDcl
    :   id=Identifier':''\n'
    ;
roboBodyDcl
    :   recursion=roboBodyDcl dcl=memberDcl
    |   dcl=memberDcl   
    ;
fieldDcl
    :   t=typePrefix dcl_list=variableDclList '\n';
typePrefix
    :   type=('NUM' | 'BOOL' | 'STRING' | 'COORD' | 'LIST');
variableDclList
    :   single=variableDcl
    |   list=variableDclList ',' single=variableDcl
    ;
variableDcl
    :   var_init=variableInitializer
    |   id=Identifier '=' list_init=listInitializer
    ;
variableInitializer 
    :   expr=assignmentExpression
    ;
TYPE_NUM: 'NUM';
TYPE_STRING: 'STRING';
TYPE_COORD: 'COORD';
TYPE_BOOL: 'BOOL';
TYPE_VOID: 'VOID';
TYPE_LIST: 'LIST';

如前所述,我尝试用以下内容替换typePrefix规则:

typePrefix
    :    type=(TYPE_NUM | TYPE_BOOL | TYPE_STRING | TYPE_COORD | TYPE_LIST);

我希望这样就足够了,并提前感谢!

1 个答案:

答案 0 :(得分:0)

我发现了问题,并会尝试提供解释,以防有人在同样的情况下结束。

如上所述“最终Antlr 4参考”ANTLR通过选择首先定义的规则来解决词法分析器规则中的歧义。并声明“这意味着您的ID规则应该在所有关键字规则之后定义......”

在我的情况下,我用以下方式定义了我的语法:

fragment NameStartChar
    :       'A'..'Z' | 'a'..'z';
fragment NameChar
    :       NameStartChar
    |       Num
    |       '_'
    ;
fragment Num
    :       '0'..'9';
Identifier
    :   NameStartChar NameChar*;
TYPE_NUM: 'NUM';

最终匹配我的所有关键字'NUM','BOOL'等等。

因此,解决方案是将标识符规则定义为词法分析器规则的最后一个。下面是一个示例:

fragment NameStartChar
    :       'A'..'Z' | 'a'..'z';
fragment NameChar
    :       NameStartChar
    |       Num
    |       '_'
    ;
fragment Num
    :       '0'..'9';
TYPE_NUM: 'NUM';
//All other keyword definitions ('BOOL', 'STRING' and so alike)
Identifier
    :   NameStartChar NameChar*