【发布时间】:2016-08-13 09:37:16
【问题描述】:
我正在尝试学习一点 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: 不匹配的输入 'A10' 需要 DATATYPE
但是我可以写:
测试(A 10)
为什么我需要在这里放一个空格? LPAREN DATATYPE 本身是有效的,所以中间不需要空格。 INT RPAREN 也在工作。 为什么 DATATYPE 和 INT 之间需要一个空格?我对此有点困惑。 我猜它是匹配 ID,因为它是“最长”匹配,但这里必须有一些方法可以强制变得更懒,对吧?
【问题讨论】:
-
因为
A10是 ID 的有效令牌。你想匹配第一个变体还是两者都匹配? ANTLR 总是尽可能长时间地匹配标记(并且在解析之前创建标记)。 -
@CoronA 我想匹配第一个变体,中间没有空格。
-
我可以想到以下解决方案:显式包含空格(而不是跳过),使 ID 不以
A或N开头,或者接受括号内的任何 ID 并过滤掉语义上的错误分析。有偏好吗?