2

Problem

Entry
    : temp += (Expression | Declaration | UserType)*
;

Declaration
    : Type '*' name=ID ';'
;

Expression
    : temp1 = Primary ('*' temp2 += Primary)* ';'
;

Primary
    : temp1 = INT
    | temp2 = [Declaration]
;

Type
    : temp1 = SimpleType
    | temp2 = [UserType]
;

SimpleType
    : 'int' | 'long'
;

UserType
    : 'typedef' name=ID ';'
;

Rules Declaration and Expression are ambiguous due to the fact that both rules share the exact same syntax and problems occur because both cross references [Declaration] as well as [UserType] are based on the terminal rule ID.

Therefore generating code for the grammar above will throw the ANTLR warning:

Decision can match input such as "RULE_ID '*' RULE_ID ';'"
using multiple alternatives: 1, 2

Goal

I would like the rule to be chosen which was able to resolve the cross reference first.

Assume the following:

typedef x;

int* x;
int* b;

The AST for

x*b

should look something like:

x = Entry -> Expression -> Primary (temp1) -> [Declaration] -> Stop!
* = Entry -> Expression -> Primary '*' -> Stop!
b = Entry -> Expression -> Primary (temp2) -> [Declaration] -> Stop!

Therefore

Entry -> Declaration

should never be considered, since

Entry -> Expression -> [Declaration]

could already validate the cross reference [Declaration].

Question

Because we do not have semantic predicates in Xtext (or am I wrong?), is there a way to validate a cross reference and explicitly choose that rule based on that validation?

PS: As a few might already know, this problem stems from the C language which I am trying to implement with Xtext.

4

1 回答 1

0

关于当前版本的 Xtext,不支持语义谓词。

交叉引用被解析到它们的终端(在我的例子中UserRoleDeclaration终端ID)。并且仅在链接过程中验证引用,在我的情况下为时已晚,因为 AST 已经创建。

使用上下文相关规则决策的唯一可能方法是在说明语法的语法中实际定义一个抽象规则。在上面的示例中,规则ExpressionDeclaration将被重写为一个。然后在必要的领域进行语义验证,例如使用范围界定的内容辅助。

于 2012-12-12T05:44:24.003 回答