2017-02-10 9 views
1

Iは、以下の構造を有するyacc文法の一部(またはむしろjison、が、2つの共有同じ共通基盤)として:Yaccで強制的にシフトするには?

Type 
    : IDENT 
    | Type "[" "]" 
    | Type "*" 
    | "func" "(" Types ")" "=>" Type 
    ; 

Types 
    : /* No arguments */ 
    | Type /* Single argument */ 
    | Types "," Type /* Multiple arguments */ 
    ; 

これはもちろん、簡略化した例であるが、それは一般的なアイデアを与える必要がありその問題点を示しています。 Foo[]Foo*Foo*[](Foo)[](Foo)*((Foo)*)[]にそれぞれ構文解析したいと思います。

しかし、yaccは当然、それはそれは、次の構文に遭遇したときに何をすべきか知っていないと文句を言い:

func (A, B) => C[] 

それはfunc (A, B) => (C[])または(func (A, B) => C)[]のいずれかに解析することができます。私はもちろんそれが最初のものであることを望んでいるだろう(私は(Type)の2番目のケースのため)。このような状況に遭遇した場合、シフトしたいyacc(またはjison)に伝える方法はありますか?

答えて

1

%prec宣言と擬似端末のいずれかを使用して最後のTypeの生産を優先するか、最後の端末の優先度である=>の既定値を使用します。その後、[トークンの優先順位が高いことを確認してください。 (他のシフト削減の競合を解消するには、*の優先順位を=>より高くする必要があります)。

他の解決方法もありますが、最も単純です。

実際、bison/yacc/jison/etc。常にシフト・リダクションの競合を優先するので、シフトを取るために何もする必要はありません。優先ルールは警告を抑止しますが、その場合はexpect宣言を使用することもできます。

+0

まあ、 '%left'と'%prec'を手にして、本当に問題を解決しました。ありがとう! –

+0

@ B.Alfred '*'にはあいまいさがあります。少なくとも、Zaachのオンラインjisonツールで得られたものです。私はその答えを編集しました。 – rici

関連する問題