2010-12-16 6 views
2

この小さなyaccプログラムはどのように機能しますか?私がこれまで知っている何yaccはどのように機能しますか、セクションごとに説明できますか?

%{...%}が定義 %% ... %%では、ルールですが、ルールをどのように解釈しますか? %%の後の とstuffは関数定義です。 とは%}%%の間の部分ですか?私は理解していない何

%{ 
#include <stdlib.h> 
int yylex(void); 
void yyerror(char *); 
%} 
%token INTEGER 
%left '+' '-' 
%left '*' '/' 
%% 
program: 
program expr '\n' { printf("%d\n", $2); } 
| 
; 
expr: 
INTEGER { $$ = $1; } 
| expr '*' expr { $$ = $1 * $3; } 
| expr '/' expr { $$ = $1/$3; } 
| expr '+' expr { $$ = $1 + $3; } 
| expr '-' expr { $$ = $1 - $3; } 
; 
%% 
void yyerror(char *s) { 
printf("%s\n", s); 
} 
int main(void) { 
yyparse(); 
return 0; 
} 

UPDATE

program: 
program expr '\n' { printf("%d\n", $2); } 
| 
; 

答えて

1

式expr:手段、exprはで区切られ、次のオプションの一つであります|以下。それがINTEGERトークンとして見える場合は、最初のトークンを取ります。 exprとそれに続く '*'文字とそれに続くexprと見なすことができれば、それは2番目のオプションをとります。 $$はデフォルトの戻り値、$ 1は最初のトークン、$ 2は二番目とそれ以降です。

したがって、5 + 6を解析していた場合、expr '+' exprとみなされ、4番目の定義が適用されます。これはexprとして11を返します。したがって、INTEGERトークンとして11を照合し、戻り値として11を割り当てます。

5 + 6の後にプログラムトークンを解析すると、同じことがプログラム11を取得し、プログラムexprルールをとり、スクリーンに印刷するcコードを呼び出します。

左は、演算子が左寄せであることを示します。 a + b + c =(a + b)+ cのように。同じ行の演算子は同じ大統領を持ち、それより下の演算子は大統領の下位を持つ。

私は間違いなくyaccを使用していないので、私は完全に間違っていると私に教えてください。

UPDATE:

yaccはCコードを生成しますので、あなたはそれに直接独自のコードを置くことができます。つまり、プログラムのexprを見ると、{}内のコードを生成されたコードに直接入力できます。

1

すなわちコンパイラの合計5つの段階がある:

  1. 字句解析
  2. 構文解析
  3. 意味解析(中間コード生成、オプション)
  4. コード最適化
  5. コード生成

lexとYACC(さらに別のコンパイラコンパイラ)は、プログラムを生成するためのUnixユーティリティでもあります。与えられたプログラム内の単語を照合する責任があり、一致が見つかるとyylexに値を格納し、トークンの形でlexerに返します。 yaccは、基本的にはトークンを取り出し、そこからツリーを構築してプログラムの構文をチェックするパーサーです。トークンはlexerでビルドされ、yacc指定ファイルで宣言されます。 y.tab.hファイルはlexプログラムに含まれています。

上記のプログラムには、レクサーによって返されるトークンINTEGERが含まれています。 yaccプログラムには開始状態が含まれていなければなりません... "プログラム"はすべてのプログラムが少なくとも1つの開始状態を含むべき開始状態です... yacc規則はフォーマット規則{action} にあります。上記のプログラム "program expr" n '"は、プログラムが式と改行文字を含むことができることを表します。つまり、5 + 4 'enter key'は、expr '+' exprを書いた式を表します。ここでexprはこの場合5と4の整数であるため、exprを書くことによってそのルールを組み込みます:INTEGER ....追加または他の役割のために、式のLHSは$$とRHSによって$ 1、$ 2、$ 3 ...によって表されますon.exce expr:expr '+' expr {$$ = $ 1 + $ 3;} .... ..

+0

これはかなり良い答えのようですが、フォーマットがうまくいけば明確になります。あなたが書いたものを変更することなく、私が今できるビットを整理しましたが、http://stackoverflow.com/editing-helpも見てみたいでしょう。 – Flexo

関連する問題