Parsing sablecc在prod=(expr | expr';)形式的产生式规则上存在问题*

Parsing sablecc在prod=(expr | expr';)形式的产生式规则上存在问题*,parsing,compiler-construction,computer-science,sablecc,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 openmetho

问题在于

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
设置为

clsdata = (clsfield|clsmethod)*;

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

所以我的问题是我应该如何定义
clsdata
,这样我就不会出错。我可以想到递归的替代方案,但我希望尽可能保持干净

谢谢

这很有效:

clsdata = clsmethod*;
但我不确定这是最好的方法。我欢迎其他方法

clsdata=(clsfield | clsmethod)*

SableCC具有类似于EBNF的语法,但不支持这种语法规则。正如您所做的,非终端替代方案
clsfield
clsmethod
需要折射到它们自己的产品中

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

如果您查看其中任何一个,您将看到这是定义“类成员”的标准方法。尽管您可以通过删除
clsmembers
简化语法:

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;
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;
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