2012-05-19 14 views
11

私はC11用のlex/yacc文法をN1570に基づいて書こうとしています。私の文法のほとんどは、有益な構文の要約からそのままコピーされていますが、yaccの競合が起きています。私は1つを除いてすべてを解決することに成功しました。「_Atomic」が型指定子として使用されているときと、型修飾子として使用されているときのあいまいさがあるようです。_Atomic型指定子と修飾子の間のC11文法のあいまいさ

_Atomicの直後に括弧が付いているので、宣言子を括弧で囲んで括弧を修飾子の直後に置くことができるようにする、Cの少し使われている構文と関係があると仮定しています。しかし、私の文法はすでにtypedefの名前を他の識別子と区別する方法を知っているので、yaccはその違いを知っていなければなりません。

私の人生にとっては、実際には曖昧な場合は考えられません。

yaccの-vフラグを使用すると、それが役に立つ状態になることがあります。 "ATOMIC"は明らかに "_Atomic"のトークン名です

state 23 

    152 atomic_type_specifier: ATOMIC . '(' type_name ')' 
    156 type_qualifier: ATOMIC . 

    '(' shift, and go to state 49 

    '('  [reduce using rule 156 (type_qualifier)] 
    $default reduce using rule 156 (type_qualifier) 
+0

宣言では、指定子と修飾子を「const unsigned int」、「unsigned const int」、「int unsigned const'、...のいずれかの順序で混在させることができるため、文法の区別指定子と修飾子は大体非標準です。 – Kaz

答えて

7

はい、私は仕様にあいまいさがあると思います。テイク

_Atomic int (*f)(int); 

_Atomicはタイプ修飾子です。 (関数の戻り値の型としてあまり意味がないが、有効であると私は考える)。今

int _Atomic (*f)(int); 

通常型-修飾子がintの後に来ることができ、これは他の宣言と同等である必要があり、この代替形をとります。しかし今では_Atomicの後にかっこが付いているので、をタイプ指定子として解釈する必要があります。これは構文エラーです。 *fが有効なtypedefで置き換えられるかもしれない例を調理することさえ可能であると私は思う。

は、原子の種類に関連付けられたプロパティのみが左辺値です 式の意味がある6.7.2.4 P4

の最初のフレーズを見てください。

これは、返される関数のタイプが_Atomicと予想されていないことを示しています。

編集:

同じ曖昧さが完璧な感覚我々は

として書き換えることができるはずですし、その(3つの原子の整数の配列へのポインタ)を行う

_Atomic int (*A)[3]; 

ために起こるであろう

int _Atomic (*A)[3]; 

編集2: ty括弧内のPEは、次の有効なC99コードを取る一義化されていません。

typedef int toto; 

int main(void) { 
    const int toto(void); 
    int const toto(void); 
    const int (toto)(void); 
    int const (toto)(void); 
    return toto(); 
} 

これは関数としてmain内部totoを再宣言します。また、4行はすべて同じ関数の有効なプロトタイプです。今これはconstとバージョンとして有効である必要があり修飾子

typedef int toto; 

int main(void) { 
    int _Atomic (toto)(void); 
    return toto(); 
} 

として_Atomicを使用しています。ここでは、_Atomicの後に型がinsideの括弧が続きますが、型指定子ではない場合があります。

+0

しかし、今では_Atomicの後にかっこが付いているので、型修飾子として解釈する必要があります。「私はあなたが意味すると思いますが、今は_Atomicの後に括弧が続くので、型指定子として解釈する必要がありますか? –

+2

原子型指定子ルールは、宣言子ではなく、かっこ内の型名を呼び出すので、私は思っていません。 '_Atomic(* anything)' アスタリスクは有効なアトミック型 - 指定子。 しかし、私は最近標準(6.7.2.4 - 4)にこれを気付きました: ** _Atomicキーワードの直後に左括弧が続くと、それは型指定子(型名付き)として解釈されます。 ** この場合、決して曖昧さはありません。括弧は型指定子を意味し、括弧は修飾子を意味するものではない。何とか私の文法にそのルールを取り入れるために... –

+0

@MichaelBurr、はい、ありがとう、私はそれを編集します。 –

9

わかりました。文法的にあいまいな場合があるかどうかは関係ありません。 _atomicキーワードがすぐに左括弧が続いている場合、それはない型修飾子として、(型名を持つ)型指定子として解釈され

:N1570のセクション6.7.2.4項4は、と述べています。

これを実行するために、私は単に_Atomicを指定子にし、_Atomicをレックス規則の中の別個のトークンとして修飾子にしました。

"_Atomic"/{WHITESPACE}*"(" {return ATOMIC_SPECIFIER;} 
"_Atomic"     {return ATOMIC_QUALIFIER;} 

私はlex/yaccとparserジェネレータの方が一般的ですが、これはちょっとしたことです。同時に、lexの文脈構文の後ろには何があるでしょうか?

+1

間にコメントがある場合、これは失敗します。 – o11c

関連する問題