如何解决ANTLR 2中数字和日期之间的词汇歧义?

时间:2009-01-12 11:07:28

标签: antlr

我的词法分析器中有两个令牌类型,如下所示:

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'

并且解析器无法识别其中包含四位以上数字的数字。如何解决词汇歧义?

1 个答案:

答案 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' )
     ;

我认为它更具可读性,因为你不重复月/日部分。为了便于阅读,我首先将可选部分放在首位,但我理解在这些情况下应该避免从可选部分开始,因为它会使解析更难。