1

我正在使用 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”已经在其中一个规则中用作终端,它不能出现在语法的其他任何地方?

如何修正这个语法?

4

2 回答 2

1

对于问题 #1:

root: a+=a* (b=b a+=a* & c=c a+=a*);

对于问题 #2,您需要这样的数据类型规则

IdOrABC: ID | 'a' | 'b' | 'c' ;

你必须在你的any规则中使用它,name=IdOrABC而不是name=ID.

于 2016-10-19T10:25:09.650 回答
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”。也许更好的策略是保持语法简单,如下所示: root: any+=any+ ;

any:
  name=ID
  '{'
    any+=any+
  '}'
;

并通过验证器强制执行特殊的 x/y/z 层次结构。

于 2016-09-09T21:18:18.257 回答