0

我的词法分析器中有两种标记类型,定义如下:

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'

并且解析器无法识别超过四位数的数字。如何解决词汇歧义?

4

1 回答 1

2

在我看来,由于Linear 近似前瞻,您会遇到虚假警告。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' )
     ;

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

于 2009-01-12T11:51:11.163 回答