ParserRule匹配错误的令牌

时间:2016-08-13 09:37:16

标签: antlr antlr4

我正在尝试学习一点ANTLR4并为某些4GL语言定义语法。

这就是我所拥有的:

compileUnit
:
    typedeclaration EOF
;

typedeclaration
:
    ID LPAREN DATATYPE INT RPAREN
;

DATATYPE
:
    DATATYPE_ALPHANUMERIC
    | DATATYPE_NUMERIC
;

DATATYPE_ALPHANUMERIC
:
    'A'
;

DATATYPE_NUMERIC
:
    'N'
;

fragment
DIGIT
:
    [0-9]
;

fragment
LETTER
:
    [a-zA-Z]
;

INT
:
    DIGIT+
;

ID
:
    LETTER
    (
        LETTER
        | DIGIT
    )*
;

LPAREN
:
    '('
;

RPAREN
:
    ')'
;

WS
:
    [ \t\f]+ -> skip
;

我希望能够解析的内容:

TEST(A10)

我得到了什么:

  

typedeclaration:1:6:不匹配的输入'A10'期待DATATYPE

但我能够写下:

TEST(A 10)

为什么我需要在这里放一个空格? LPAREN DATATYPE本身正在工作,因此不需要在它们之间留出空间。 INT RPAREN也在工作。 为什么DATATYPE和INT之间需要一个空间?我对那个有点困惑。 我猜它是匹配的ID,因为它是“最长的”匹配,但是必须有一些方法可以让这里更加懒散,对吗?

1 个答案:

答案 0 :(得分:1)

你应该在ID的第一个位置忽略'A'和'N'聊天。由于@CoronA注意到ANTLR尽可能地匹配令牌(ID'A10'的长度超过DATATYPE_ALPHANUMERIC'A'的长度)。另请阅读:Priority rules。尝试使用以下语法:

grammar expr;

compileUnit
    : typedeclaration EOF
    ;

typedeclaration
    : ID LPAREN datatype INT RPAREN
    ;

datatype
    : DATATYPE_ALPHANUMERIC
    | DATATYPE_NUMERIC
    ;

DATATYPE_ALPHANUMERIC
    : 'A'
    ;

DATATYPE_NUMERIC
    : 'N'
    ;

INT
    : DIGIT+
    ;

ID
    : [b-mo-zB-MO-Z] (LETTER | DIGIT)*
;

LPAREN
    : '('
    ;

RPAREN
    : ')'
    ;

WS
    : [ \t\f]+ -> skip
    ;

fragment
DIGIT
    : [0-9]
    ;

fragment
LETTER
    : [a-zA-Z]
    ;

此外,您可以使用以下语法而不受ID限制。数据类型将比字母更早识别。它也不清楚:

grammar expr;

compileUnit
    : typedeclaration EOF
    ;

typedeclaration
    : id LPAREN datatype DIGIT+ RPAREN
    ;

id
    : (datatype | LETTER) (datatype | LETTER | DIGIT)*
    ;

datatype
    : DATATYPE_ALPHANUMERIC
    | DATATYPE_NUMERIC
    ;

DATATYPE_ALPHANUMERIC: 'A';
DATATYPE_NUMERIC:      'N';
// List with another Data types.
LETTER:                [a-zA-Z];

LPAREN
    : '('
    ;

RPAREN
    : ')'
    ;

WS
    : [ \t\f]+ -> skip
    ;

DIGIT
    : [0-9]
    ;