【发布时间】:2015-02-24 15:29:59
【问题描述】:
我的 ANTLR3 语法中有这些词法分析器规则:
INTEGER: DIGITS;
FLOAT: DIGITS? DOT_SYMBOL DIGITS ('E' (MINUS_OPERATOR | PLUS_OPERATOR)? DIGITS)?;
HEXNUMBER: '0X' HEXDIGIT+;
HEXSTRING: 'X' '\'' HEXDIGIT+ '\'';
BITNUMBER: '0B' ('0' | '1')+;
BITSTRING: 'B' '\'' ('0' | '1')+ '\'';
NCHAR_TEXT: 'N' SINGLE_QUOTED_TEXT;
IDENTIFIER: LETTER_WHEN_UNQUOTED+;
fragment LETTER_WHEN_UNQUOTED:
'0'..'9'
| 'A'..'Z' // Only upper case, as we use a case insensitive parser (insensitive only for ASCII).
| '$'
| '_'
| '\u0080'..'\uffff'
;
和
qualified_identifier:
IDENTIFIER ( options { greedy = true; }: DOT_SYMBOL IDENTIFIER)?
;
除了输入t1.1_d 等非常特殊的情况外,这几乎可以正常工作,它应该被解析为两个用点连接的标识符。发生的情况是 .1 匹配为浮点数,即使它后面跟着下划线和字母。
很清楚它的来源:LETTER_WHEN_UNQUOTED 包含数字,因此“1”既可以是整数,也可以是标识符。但规则顺序应注意将其解析为整数,正如预期的那样(通常会这样做)。
但是,我很困惑t1.1_d 输入会导致浮动规则生效,并希望有一些指针可以解决这个问题。只要我在点之后添加一个空格就可以了,但这显然不是一个真正的解决方案。
当我将 IDENTIFIER 规则移到其他规则之前时,我遇到了新的麻烦,因为那时无法再匹配其他几条规则。在 IDENTIFIER 规则之后移动 FLOAT 规则也不能解决问题(但至少不会产生新问题)。在这种情况下,我们看到了实际的问题:如果点后面直接跟一个数字,那么 FLOAT 规则总是匹配点。我该怎么做才能使它与我的情况不匹配?
【问题讨论】:
-
您能否包含完整的语法(即包含示例中引用的所有标记/片段)?此外,greedy 默认为 true,因此不需要指定它。
-
您可能会考虑重新设计:目前 1234 既是整数又是标识符。我不是说它不起作用,但它让我头疼。
标签: antlr3