我在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类型。例如,如果输入为:
create a Prescription = Description: a doctor create a Prescription /* ... */
这应该是正确的。
如果输入,则为:
create a Prescription = Description: a doctor create a Rrrrescription /* ... */
那应该是错的。
答案 0 :(得分:3)
不要依赖解释器(ANTLRWorks的解释器,或Eclipse的插件之一)。解释器不考虑任何谓词。
另外,不确定您正在使用哪个目标,但是如果您使用Java({str==$useCase.text}?
比较对象的标识),请认识==
错误,请改用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问题!
请注意,在语法中填写过多的语义检查将导致难以维护混合语法规则和代码的混乱。这些检查通常在解析器创建(抽象)解析树之后执行:这意味着自由地匹配useCase
,然后在迭代解析器创建的树时验证它们。
答案 1 :(得分:0)
由于您使用的是Eclipse,我可能应该将此作为答案而不是评论发布。查看How To Configure ANTLR IDE然后Debug/Test with ANTLR IDE。如果你已经发现这些有用,请欣赏upvote。