问题
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 ';'
;
规则
Declaration
和Expression
是不明确的,因为这两个规则共享完全相同的语法,并且会出现问题,因为交叉引用[Declaration]
和[UserType]
都基于终端规则ID
。因此,为上述语法生成代码将抛出ANTLR警告:
Decision can match input such as "RULE_ID '*' RULE_ID ';'"
using multiple alternatives: 1, 2
目标
我想选择的规则是能够解决交叉引用首先。
假设如下:
typedef x;
int* x;
int* b;
的AST
x*b
应该看起来像:
x = Entry -> Expression -> Primary (temp1) -> [Declaration] -> Stop!
* = Entry -> Expression -> Primary '*' -> Stop!
b = Entry -> Expression -> Primary (temp2) -> [Declaration] -> Stop!
因此
Entry -> Declaration
不应该被考虑,因为
Entry -> Expression -> [Declaration]
已经可以验证交叉引用
[Declaration]
。问题
因为我们在Xtext中没有语义谓词(或者我错了?),是否有方法验证交叉引用并基于该验证显式选择该规则?
PS:一些人可能已经知道,这个问题源于我试图用Xtext实现的C语言。
最佳答案
对于Xtext的当前版本,不支持语义谓词。
交叉引用被解析到它们的终端(在我的例子中UserRole
和Declaration
到终端ID
)。只有在链接过程中才会验证引用,在我的例子中,这已经太晚了,因为AST已经创建了。
使用上下文相关规则决策的唯一可能方法是在语法中定义一个声明语法的抽象规则在上面的例子中,规则Expression
和Declaration
将被重写为一个然后在必要的领域进行语义验证,比如内容辅助作用域的使用。
关于c - Xtext-在没有语义谓词的情况下解决歧义?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13717565/