2013-02-28 46 views
-1

几个星期的休息之后,它的时间与ANTLR再次打...ANTLR:词法投掷NoViableAltException

无论如何,我有以下词法定义令牌:

fragment EQ: '='; 
fragment NE: '<>'; 

BOOLEAN_FIELD 
    : ('ISTRAINED'|'ISCITIZEN') 
    ; 

BOOLEAN_CONSTANT 
    : ('TRUE'|'FALSE'|'Y'|'N') 
    ; 

BOOLEAN_LOGICAL 
    : BOOLEAN_FIELD (EQ|NE) (BOOLEAN_FIELD|BOOLEAN_CONSTANT) 
    ; 

不幸的是, BOOLEAN_LOGICAL标记以简单术语(如“ISTRAINED = ISTRAINED”)抛出NoViableAltException。

我知道一些响应将会是“这应该在解析器中”。它先前在解析器中,但是,我试图将一些简单的项目卸载到词法分析器中,因为我只需要“是/否,这个文本块是否有效?”

任何帮助表示赞赏。

+0

你真的使用双引号吗? '“ISTRAINED”'应该是'ISTRAINED'' – 2013-02-28 13:23:56

+0

不,这是一个“复制到SO的例子”的错误。原来使用的单引号。 – Jason 2013-02-28 14:00:17

回答

2

BOOLEAN_LOGICAL不应该是词法分析规则。词法分析规则必须(或应该)是一个单一的标记。作为词法分析规则,在BOOLEAN_FIELD(EQ|NE)之间不能有空格(您可能在搜索时跳过了空格,但这只会导致空格从解析器规则中跳过!)。

而是执行此操作:

boolean_logical 
    : BOOLEAN_FIELD (EQ|NE) (BOOLEAN_FIELD|BOOLEAN_CONSTANT) 
    ; 

这也意味着EQNE不能fragment规则了:

EQ : '='; 
NE : '<>'; 
+1

另外,'EQ'和'NE'不应该是'fragment'规则。 – 2013-02-28 14:56:08

+0

@ 280Z28,是的,当然,我错过了。谢谢。 – 2013-02-28 15:12:00

1

这看起来像它应该是一个解析器规则。但是,如果您希望将其保留为词法分析规则,则需要允许空格。

BOOLEAN_LOGICAL 
    : BOOLEAN_FIELD WS+ (EQ|NE) WS+ (BOOLEAN_FIELD|BOOLEAN_CONSTANT) 
    ; 
+0

如果Jason有'''定义了一个WS标准规则,在这个规则中'skip'这个标记(或者将标记放在'HIDDEN'信道上),使用这个'WS'规则也会导致'BOOLEAN_LOGICAL'被跳过/隐。 – 2013-02-28 16:24:36

+0

我后来想到了。不幸的是,我必须使用这么多的嵌入代码(为了抛出自定义的异常,而不是通常的NoViableAltException或MismatchedSetException,以及它们在什么情况下被抛入等)。 – Jason 2013-02-28 16:31:12