14

GNU Bison 2.4.2 を使用して、取り組んでいる新しい言語の文法を書いていますが、質問があります。ルールを指定するときは、次のように言いましょう。

statement : T_CLASS T_IDENT  '{' T_CLASS_MEMBERS '}' {
           // create a node for the statement ...
}

たとえば、ルールにバリエーションがある場合

statement : T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST  '{' T_CLASS_MEMBERS '}' {
           // create a node for the statement ...
}

どこで(フレックススキャナールールから):

"class"                     return T_CLASS;
"extends"                   return T_EXTENDS;
[a-zA-Z\_][a-zA-Z0-9\_]*    return T_IDENT;

(そして T_IDENT_LIST はカンマ区切りの識別子の規則です)。

「T_EXTENDS T_IDENT_LIST」をオプションとして設定して、これらすべてを1つのルールでのみ指定する方法はありますか? 私はすでに試しました

 T_CLASS T_IDENT (T_EXTENDS T_IDENT_LIST)? '{' T_CLASS_MEMBERS '}' {
     // create a node for the statement ...
 } 

しかし、バイソンは私にエラーを出しました。

ありがとう

4

3 に答える 3

14

To make a long story short, no. Bison only deals with LALR(1) grammars, which means it only uses one symbol of lookahead. What you need is something like this:

statement: T_CLASS T_IDENT extension_list '{' ...

extension_list: 
              | T_EXTENDS T_IDENT_LIST
              ;

There are other parser generators that work with more general grammars though. If memory serves, some of them support optional elements relatively directly like you're asking for.

于 2010-04-19T17:40:50.093 に答える
1

|選択 ( ) 演算子を使用してそれらを分割してみませんか?

statement:
  T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST  '{' T_CLASS_MEMBERS '}'
  | T_CLASS T_IDENT  '{' T_CLASS_MEMBERS '}'

これが LALR(1) ボトムアップ パーサーであるという理由だけでそれができるとは思いません。やりたいことを行うには、LL(k) (ANTLR?) のような別のものが必要になるでしょう。

于 2010-04-19T17:43:02.223 に答える
0

I think the most you can do is

statement : T_CLASS T_IDENT  '{' T_CLASS_MEMBERS '}'
    | T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST  '{' T_CLASS_MEMBERS '}' {
}
于 2010-04-19T17:41:33.523 に答える