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 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
于 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 に答える