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
以便我不会出错。我可以想到递归替代方案,但我希望尽可能保持干净!
由于
答案 0 :(得分:1)
clsdata =(clsfield | clsmethod)*;
SableCC有一个类似的EBNF 语法,但不支持这种语法规则。正如您已经完成的那样,非终端替代方案clsfield
和clsmethod
需要重新投入到自己的生产中。
但我不确定这是最好的方法
如果您查看任何SableeCC example grammars,您会看到这是定义“班级成员”的标准方式。虽然您可以通过删除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
答案 1 :(得分:-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;
但我不确定这是最好的方法。我欢迎其他方法!