2

我在 Eclipse 环境中使用 ANTLR。我想将一个属性 ( n.text) 传递给另一个规则 ( description),并在后一个规则中使用语义谓词来验证与n.text. 这是我的代码:

useCaseSpecification 
    :   n=useCase '='
        description[$n.text]
    ;

useCase
    : ucID=('UC' INTEGER)? ucName
    ;

ucName
    :   caren io
    ;

caren
    :   'create' | 'creates' | alter | read | 'erase' | 'erases' | notify
    ;

/* ..more code */

description[String str]
    :   'Description' ':' primaryActor (useCase {str==$useCase.text}?) /* more grammar */
    ;

我尝试了语义谓词表达式的许多替代方案,例如{str.equals($useCase.text)},但没有。解析器似乎没有进行验证。

当我使用示例运行解释器时,它允许 useCase 类型的每个输入。例如,如果输入是:

创建处方 =
描述:医生开处方 /* ... */

那应该是正确的。

如果输入,是:

创建处方 =
描述:一个医生创建一个Rrrrescription /* ... */

那应该是错误的。

4

2 回答 2

3

不要依赖解释器(ANTLRWorks 的解释器或 Eclipse 的插件之一)。解释器不考虑任何谓词。

此外,不确定您使用的是什么目标,但{str==$useCase.text}?如果您使用 Java,请意识到这是错误的(==比较对象的身份,equals(...)改为使用)。

例如,解析两个相同的字母可以如下完成:

grammar T;

parse
 : Letter same[$Letter.text] EOF
 ;

same [String s]
 : Letter {$Letter.text.equals(s)}?
 ;

Letter : 'a'..'z' | 'A'..'Z';

解析"AB"会导致异常:

在此处输入图像描述

而解析"AA"不会:

在此处输入图像描述

上面的树是使用 ANTLRWorks 的调试器生成的,它的工作原理就像一个魅力。请注意,调试器会忽略该language=XYZ选项:它将以 Java 作为目标语言来调试您的语法。因此,除 Java 之外的任何嵌入式代码都会导致问题!

请注意,在语法中塞入过多的这些语义检查将导致难以维护混合语法规则和代码的混乱。这些检查通常在解析器创建(抽象)解析树之后执行:这意味着自由匹配useCases,然后在遍历解析器创建的树时验证它们。

于 2012-07-23T09:31:03.693 回答
0

由于您使用的是 Eclipse,我可能应该将其发布为答案而不是评论。查看如何配置 ANTLR IDE,然后使用 ANTLR IDE 进行调试/测试。如果您已经发现这些有用,请感谢支持。

于 2012-07-31T04:40:49.827 回答