我的词法分析器中有两个令牌类型,如下所示:
NUMBERVALUE
: ( '0' .. '9' )+ ( '.' ( '0' .. '9' )+ )?
;
DATEVALUE
: ( '0' .. '9' ) ( '0' .. '9' ) ( '0' .. '9' ) ( '0' .. '9' ) '-'
( '0' .. '9' ) ( '0' .. '9' ) '-'
( '0' .. '9' ) ( '0' .. '9' )
| ( '0' .. '9' ) ( '0' .. '9' ) '-'
( '0' .. '9' ) ( '0' .. '9' ) '-'
( '0' .. '9' ) ( '0' .. '9' )
;
我原以为,因为日期必须在前五个字符中包含一个连字符,所以在词法分析器选项中设置k = 5就足以让词法分析器始终分开。但是,当我运行antlr时,我收到了这个警告:
warning:lexical nondeterminism between rules NUMBERVALUE and DATEVALUE upon
k==1:'0'..'9'
k==2:'0'..'9'
k==3:'0'..'9'
k==4:'0'..'9'
k==5:'0'..'9'
并且解析器无法识别其中包含四位以上数字的数字。如何解决词汇歧义?
答案 0 :(得分:2)
在我看来,由于Linear approximate lookahead而发生虚假警告。 DATEVALUE的第1个,第2个,第3个,第4个和第5个字符都可以是数字,而不是所有数字。
我试图摆脱2/4位数年份替代品。对于初学者,您不想对Y2.1K错误负责;其次,它为您节省了另一种DATEVALUE语法。 我尝试的另一个解决方案是使用不同的分组:
DATEVALUE
: ( '0' .. '9' ) ( '0' .. '9' ) (( '0' .. '9' ) ( '0' .. '9' ))? '-'
( '0' .. '9' ) ( '0' .. '9' ) '-'
( '0' .. '9' ) ( '0' .. '9' )
;
我认为它更具可读性,因为你不重复月/日部分。为了便于阅读,我首先将可选部分放在首位,但我理解在这些情况下应该避免从可选部分开始,因为它会使解析更难。