1
Productions
    program = cls*;
    cls = clsdef name openbrace clsdata closingbrace;
    clsdata = (clsfield|clsmethod)*;
    clsfield = [variabletype]:name [variablename]:name semi;
    clsmethod = [returntype]:name [methodname]:name openmethodbrace closingmethodbrace openbrace closingbrace;

问题出在

clsdata = (clsfield|clsmethod)*;

如果我设置clsdata

clsdata = clsfield*;

或者

clsdata = clsmethod*;

它工作得很好,但是,正如你可以想象的那样,它的含义与我的意图不同。我想要一个类同时允许方法和字段(没有特定的顺序!)。

所以我的问题是我应该如何定义clsdata以免出错。我可以想到递归替代方案,但我想尽可能保持干净!

谢谢

4

2 回答 2

1

clsdata = (clsfield|clsmethod)*;

SableCC 有类似 EBNF语法,但不支持这种类型的语法规则。正如您已经完成的那样,非终端替代品clsfield需要clsmethod重新转换到它们自己的生产中。

但我不确定这是最好的方法

如果您查看任何SableeCC 示例语法,您会发现这是定义“类成员”的标准方法。尽管您可以通过删除来简化语法clsmembers

Productions
    program = cls*;
    cls = clsdef name openbrace clsmember* closingbrace;
    clsmember = {clsfield} clsfield | {clsmethod} clsmethod;
    clsfield = [variabletype]:name [variablename]:name semi;
    clsmethod = [returntype]:name [methodname]:name openmethodbrace closingmethodbrace openbrace closingbrace
于 2011-03-28T12:55:46.907 回答
-1

这有效:

Productions
    program = cls*;
    cls = clsdef name openbrace clsmembers closingbrace;
    clsmembers = clsmember*;
    clsmember = {clsfield} clsfield | {clsmethod} clsmethod;
    clsfield = [variabletype]:name [variablename]:name semi;
    clsmethod = [returntype]:name [methodname]:name openmethodbrace closingmethodbrace openbrace closingbrace;

但我不确定这是最好的方法。我欢迎其他方法!

于 2011-03-28T01:51:39.863 回答