如何最好地编写此 xtext 语法
How best to write this xtext grammar
我正在使用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"已经在其中一个规则中作为终结符,它不能出现在语法的其他任何地方?
如何修正这个语法?
对于问题#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 层次结构。
对于问题 #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
。
我正在使用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"已经在其中一个规则中作为终结符,它不能出现在语法的其他任何地方?
如何修正这个语法?
对于问题#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 层次结构。
对于问题 #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
。