Problem with sablecc on production rule of the form prod = (expr | expr')*
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;
The problem resides in
clsdata = (clsfield|clsmethod)*;
If I set clsdata
to
clsdata = clsfield*;
or to
clsdata = clsmethod*;
it works fine, though, as you can imagine, it doesn't mean the same thing as what I intended it to. I want a class to allow for both methods and fields (in no specific order!).
So my question is in how should I define clsdata
so开发者_如何学Python that I don't get errors. I can think of recursive alternatives, but I'd like to keep this as clean as possible!
Thanks
clsdata = (clsfield|clsmethod)*;
SableCC has an EBNF like syntax, but does not support this type of grammar rule. As you've already done, the non-terminal alternatives clsfield
and clsmethod
need be refractored into their own production.
yet I am not sure this is the best way to do this
If you look at any of the SableeCC example grammars you'll see that is the standard way of defining 'class members'. Although you could perhaps simplify your grammar by removing 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
This works:
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;
yet I am not sure this is the best way to do this. I welcome other approaches!
精彩评论