匹配错误标记的 ParserRule
ParserRule matching the wrong token
我正在尝试学习一点 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
;
我希望能够解析的内容:
测试 (A10)
我得到的:
typedeclaration:1:6: mismatched input 'A10' expecting DATATYPE
不过我可以写:
测试(A 10)
为什么我要在这里放一个白色space? LPAREN DATATYPE 本身就可以工作,所以中间不需要 space。 INT RPAREN 也在工作。
为什么在 DATATYPE 和 INT 之间需要 space?我对此有点困惑。
我猜它是匹配 ID,因为它是 "longest" 匹配,但必须有某种方法可以强制在这里变得更懒惰,对吧?
您应该忽略 ID 第一个位置的 'A' 和 'N' 聊天。正如@CoronA 注意到的那样,ANTLR 会尽可能长时间地匹配令牌(ID 'A10' 的长度超过 DATATYPE_ALPHANUMERIC 'A' 的长度)。另请阅读:。尝试使用以下语法:
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]
;
我正在尝试学习一点 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
;
我希望能够解析的内容:
测试 (A10)
我得到的:
typedeclaration:1:6: mismatched input 'A10' expecting DATATYPE
不过我可以写:
测试(A 10)
为什么我要在这里放一个白色space? LPAREN DATATYPE 本身就可以工作,所以中间不需要 space。 INT RPAREN 也在工作。 为什么在 DATATYPE 和 INT 之间需要 space?我对此有点困惑。 我猜它是匹配 ID,因为它是 "longest" 匹配,但必须有某种方法可以强制在这里变得更懒惰,对吧?
您应该忽略 ID 第一个位置的 'A' 和 'N' 聊天。正如@CoronA 注意到的那样,ANTLR 会尽可能长时间地匹配令牌(ID 'A10' 的长度超过 DATATYPE_ALPHANUMERIC 'A' 的长度)。另请阅读:
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]
;