2010-12-16 81 views
2

這個微小的yacc程序是如何工作的?yacc是如何工作的,你可以逐節解釋它嗎?

我知道到目前爲止什麼:

%{...%}是定義 %% ... %%是規則的,但如何解釋規則? 和%%之後的東西是函數定義。 %}%%之間的%token INTEGER是什麼?

%{ 
#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,那麼它會採用第二個選項,依此類推。 $$是默認的返回值,$ 1是第一個標記,第二個是$ 2。

所以如果是解析5 + 6,它會將其視爲expr'+'expr,因此它將採用第4個定義。它返回11作爲expr,所以它匹配11作爲INTEGER標記並將11作爲返回值。

如果我們解析一個程序標記後跟5 + 6,它會做同樣的事情來獲得程序11,然後採取程序expr規則,並調用打印到屏幕上的c代碼。

左表示運算符爲左關聯。如在a + b + c =(a + b)+ c中。同一行上的操作員具有相同的總裁,而下面的操作員具有較低的總裁。

我承認在一段時間內沒有使用yacc,所以隨時告訴我我完全錯了。

UPDATE:

YACC生成C代碼,這樣你就可以直接把自己的代碼到它。所以當它解析時,如果它看到一個「程序表達式」,那麼它可以直接將{}中的代碼輸入到生成的代碼中。

1

總共有編譯器即五個階段:

  1. 詞法分析
  2. 語法分析
  3. 語義分析(中間代碼生成-可選)
  4. 代碼優化
  5. 代碼生成

lex和YACC(另一個編譯器編譯器)都是生成程序的Unix實用程序.lexer負責匹配給定程序中的單詞,當匹配被找到時,它將值存儲在yylex中,並以令牌的形式返回給詞法分析器。 yacc基本上是一個解析器,它接受令牌並從中構建一棵樹來檢查程序的語法。令牌由詞法分析器構建,並在yacc規範文件中聲明。 所以y.tab.h文件包含在lex程序中。

上述程序包含一個由詞法分析器返回的令牌INTEGER。 yacc程序應該包含一個開始狀態...「程序」是開始狀態,每個程序應該包含至少一個開始狀態... yacc規則的格式是規則{action} 。在上面的程序「program expr'\ n'表示程序可以包含表達式,然後是換行符。即5 + 4'輸入鍵'表示我們寫了expr'+'expr的表達式;這裏expr在這種情況下可以是5和4,所以我們通過寫入expr來包含該規則:INTEGER ....或者任何其他角色,表達的LHS由$$和RHS表示爲$ 1,$ 2,$ 3 ...等等。表達式:expr'+'expr {$$ = $ 1 + $ 3;} .... ..

+0

這看起來像是一個很好的答案,但如果格式更好,它會更清晰。我已經清理了我現在可以使用的部分,而無需更改您寫得太多的內容,但是您也可以參閱http://stackoverflow.com/editing-help。 – Flexo 2011-11-08 13:02:18

相關問題