生产规则上的sablecc问题形式为prod =(expr | expr')*

时间:2011-03-28 01:23:20

标签: parsing compiler-construction computer-science sablecc

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以便我不会出错。我可以想到递归替代方案,但我希望尽可能保持干净!

由于

2 个答案:

答案 0 :(得分:1)

  

clsdata =(clsfield | clsmethod)*;

SableCC有一个类似的EBNF 语法,但不支持这种语法规则。正如您已经完成的那样,非终端替代方案clsfieldclsmethod需要重新投入到自己的生产中。

  

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

如果您查看任何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;

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