15
{%
#include<stdio.h>
#include<stdlib.h>
%}
  
%token ID NUM IF THEN LE GE EQ NE OR AND ELSE

%right '='
%left AND OR
%left '<' '>' LE GE EQ NE
%left '+''-'
%left '*''/'
%right UMINUS
%left '!'

%%

上記のコードは、単純なIF ELSEプログラムのyaccの一部です。

どういう意味ですか%right%left

4

2 に答える 2

23

私はこれが古い質問であることを知っていますが、誰かがこの情報を探している場合に備えて:

%left%rightおよび%nonassocは、yaccが演算子の繰り返しをどのように解決するかを定義します。あなたが持っている場合:

1 + 2 + 3

両方の演算子の優先順位は同じです(同じです:))。この場合、yaccは次のことを解決できます。

// using %left
(1 + 2) + 3

また:

// using %right
1 + (2 + 3)

そして最後に:

//using %nonassoc
1 + 2 + 3 is considered illegal and a syntax error!

あなたはここでもっと読むことができます。

于 2016-01-11T01:13:05.260 に答える
11

%left演算子の結合性%right指定します。操作の結合性によって、同じ優先順位レベルの2つの操作のどちらが最初に実行されるかが決まります。

文法規則があるとします。

exp ::= exp + exp
exp ::= ID

そして、式x+yzを解析する必要があるとします。プラスとマイナスの優先順位は同じであるため、この式は(x + y)-zまたはx +(yz)として解釈できます。これは大したことではないように思われますが、文法にあいまいさが生じます。

問題と理論を解析することはさておき、式を解析していると仮定します。6 + 5-7であり、私たちの言語は自然数でしか機能せず、アンダーフローが発生すると例外をスローするとします。(4)の結果は(例外)(6+5)-7と等しくない6+(5-7)ため、演算子の結合法則を指定して評価順序を定義しない限り、結果を予測することはできません。またf()+g()+h()、オペランドが副作用のある関数である場合の、のような式の場合も考えてみてください。

于 2012-10-14T10:36:07.997 に答える