2012-04-12 10 views
2

ルックアヘッドトークンが指定された値の場合、Bisonルールが一致しないように指定する方法はありますか?BisonはC関数ポインタを関数呼び出しとしてピックアップしますか?

私は現在、次のBison文法(簡体字)があります。

void (*ident)(char* some_arg); 

をそれがvoid(* IDENT)を見て、それがなければならないことを推測です:

var_decl: 
     type ident 
     { 
      $$ = new NVariableDeclaration(*$1, *$2); 
     } | 
     type ident ASSIGN_EQUAL expr 
     { 
      $$ = new NVariableDeclaration(*$1, *$2, $4); 
     } | 
     type CURVED_OPEN STAR ident CURVED_CLOSE CURVED_OPEN func_decl_args CURVED_CLOSE 
     { 
      $$ = new NVariableDeclaration(*(new NFunctionPointerType(*$1, *$7)) /* TODO: free this memory */, *$4); 
     } | 
     type CURVED_OPEN STAR ident CURVED_CLOSE CURVED_OPEN func_decl_args CURVED_CLOSE ASSIGN_EQUAL expr 
     { 
      $$ = new NVariableDeclaration(*(new NFunctionPointerType(*$1, *$7)) /* TODO: free this memory */, *$4, $10); 
     } ; 

... 

deref: 
     STAR ident 
     { 
      $$ = new NDereferenceOperator(*$<ident>2); 
     } | 

... 

type: 
     ident 
     { 
      $$ = new NType($<type>1->name, 0, false); 
      delete $1; 
     } | 
     ... ; 

... 

expr: 
     deref 
     { 
      $$ = $1; 
     } | 
     ... 
     ident 
     { 
      $<ident>$ = $1; 
     } | 
     ... 
     ident CURVED_OPEN call_args CURVED_CLOSE 
     { 
      $$ = new NMethodCall(*$1, *$3); 
      delete $3; 
     } | 
     ... 
     CURVED_OPEN expr CURVED_CLOSE 
     { 
      $$ = $2; 
     } ; 

... 

call_args: 
     /* empty */ 
     { 
      $$ = new ExpressionList(); 
     } | 
     expr 
     { 
      $$ = new ExpressionList(); 
      $$->push_back($1); 
     } | 
     call_args COMMA expr 
     { 
      $1->push_back($3); 
     } ; 

を問題は解析するときということです関数宣言の代わりに関数呼び出しを使用します。 * identとreduceをderefsとexprsに減らすのではなく、var_declに一致するように先を見越すことをBisonに伝える方法はありますか?

+0

あなたは全体の話をしているわけではありません。あなたの文法では、式はタイプで始めることはできません。どのように表現として始まったのでしょうか? –

+0

'type'の文法を追加しました。ご覧のとおり、どの識別子もタイプになります。文法全体を投稿していないのは、それが520行で、人々を恐れるかもしれないからです。P –

+1

C++で 'Most Vexing Parse'を検索する必要があるかもしれません。そこには何かが宣言になることができれば、それは何かがあるというルールがあります。 –

答えて

3

任意の識別子は、まさに問題だタイプ

することができます。 Cのような言語のLALR(1)文法(または型のCのような構文を持つ言語)は、トークンレベルで型と他の識別子を区別する必要があります。つまり、IDENTとTYPEIDENTを2つの異なるトークンにする必要があります。 (コンパイラの識別子に関するデータをトークナイザに戻す必要があります)。そうでなければあいまいな文法を明確にする最も標準的な方法です。

更新たとえば、this ANSI C grammar for Yaccを参照してください。

+0

ありがとう!実際には、このようにしなければならないということを、実際には静かにしています。 –

関連する問題