我正在使用Xtext,需要就以下两个问题提出建议。
问题#1
假设我有三条规则a,b和c。并且我想允许这些规则的任何序列,除了b和c应该只出现一次。如何最好地编写这样的语法?
以下是我提出的建议:
root:
a+=a*
b=b
a+=a*
c=c
a+=a*
;
a: 'a';
b: 'b';
c: 'c';
有没有更好的方法来编写根语法? b和c仍然必须严格按顺序排列,这并不理想。
问题#2
看看这个语法:
root:
any+=any*
x=x
any+=any*
;
any:
name=ID
'{'
any+=any*
'}'
;
x:
name='x' '{' y=y '}'
;
y:
name='y' '{' z=z '}'
;
z:
name='z' '{' any+=any* '}'
;
使用这种语法我希望能够编写如下语言:
a {
b {
}
c {
y {
}
}
}
x {
y {
z {
the_end {}
}
}
}
但是,由于节点“y”出现在“c”下,我收到错误。这是为什么?是因为现在“y”已被用作其中一个规则中的终端,它在语法中的任何其他地方都不会出现?
如何解决这个语法?
答案 0 :(得分:1)
对于问题#1:
root: a+=a* (b=b a+=a* & c=c a+=a*);
对于问题#2,您需要datatype rule,如下所示:
IdOrABC: ID | 'a' | 'b' | 'c' ;
,您必须在any
规则name=IdOrABC
中使用它,而不是name=ID
。
答案 1 :(得分:0)
对于问题#1,我们可以调整语法如下:
root:
a+=a*
(
b=b a+=a* c=c
|
c=c a+=a* b=b
)
a+=a*
;
a: 'a';
b: 'b';
c: 'c';
另一方面,问题#2无法通过语法真正解决,因为解析器永远无法区分ID和特殊关键字" x"," y"或" z"。也许更好的策略是保持语法简单如下: 根: 任何+ =任何+ ;
any:
name=ID
'{'
any+=any+
'}'
;
并通过验证器强制执行特殊的x / y / z层次结构。