どのようにポストインクリメント演算子からの競合を減らす/ YACCシフトを修正するには?

StackOverflow https://stackoverflow.com/questions/890038

質問

私はYACC(実際バイソン)で文法を書いている、と私はシフト/問題を軽減を抱えています。これは、後置インクリメントを含むことに起因します。ここでは文法のトリムダウンバージョンは次のとおりです。

%token NUMBER ID INC DEC

%left      '+' '-'
%left      '*' '/'
%right     PREINC
%left      POSTINC

%%

expr: NUMBER
|     ID
|     expr '+' expr
|     expr '-' expr
|     expr '*' expr
|     expr '/' expr
|     INC expr %prec PREINC
|     DEC expr %prec PREINC
|     expr INC %prec POSTINC
|     expr DEC %prec POSTINC
|     '(' expr ')'
;

%%

バイソンが12シフト/競合を減らすがありますが、私は後置インクリメントとデクリメントの行をコメントアウトした場合、それは正常に動作します私に語りました。誰もがこの競合を解決する方法を知っていますか?この時点で、私はそれがはるかに容易になりLL(k)はパーサジェネレータに移動検討しているが、LALR文法は常にはるかに自然書くように見えてきました。私はまた、GLRを検討しているが、私は何か良いC / C ++ GLRパーサジェネレータを知りません。

役に立ちましたか?

解決

あなたはオプションセクションで%glr-parserを指定した場合、

バイソン/ yaccはGLRパーサを生成することができます。

他のヒント

これを試してください:

%token NUMBER ID INC DEC

%left       '+' '-'
%left       '*' '/'
%nonassoc   '++' '--'
%left       '('
%%

expr: NUMBER
|     ID
|     expr '+' expr
|     expr '-' expr
|     expr '*' expr
|     expr '/' expr
|     '++' expr 
|     '--' expr 
|     expr '++'
|     expr '--'
|     '(' expr ')'
;

%%

キーの非連想のよう後置演算子を宣言することです。そうしないと次のことができるようになります。

++var++--

括弧はまた、警告を/シフトを最小限に低減するために優先順位を与えられる必要がある

私はより多くの項目を定義したいです。あなたは%の左、右%の、%precのものを必要はありません。

simple_expr: NUMBER
 | INC simple_expr
 | DEC simple_expr
 | '(' expr ')'
;

term: simple_expr
 | term '*' simple_expr
 | term '/' simple_expr
;

expr: term
 | expr '+' term
 | expr '-' term
;

このアプローチで遊んでみてください。

この基本的な問題は、あなたがINCDECトークンの優先順位を持っていないということですので、INCまたはDECの先読みを伴うあいまいさを解決する方法を知りません。あなたが追加した場合、

%right INC DEC

優先順位リストの最後に(あなたはunariesが接頭辞よりも優先順位が高いとpostfixの高いようにしたい)、それはそれを修正し、それは無関係だとして、あなたも、すべてのPREINC / POSTINCのものを取り除くことができます。

は、前置インクリメントとポストインクリメント演算子はnonassocを有するように優先セクションおよびルールでは、

%precを用いてこれらの演算子の優先順位を高くするように定義します
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top