yacc 和 lex的上手 3

2021-08-24 22:34:47 字數 2849 閱讀 8657

昨天看完了lex相關的例子,今天開始看yacc部分的例子

sample 4 乙個簡單的恆溫控制器 (突然記起來大三時候做過的fuzzy logic的東東了)

目標:我們有乙個恆溫器,想用簡單的語言來控制它,就像下面這樣

heat on

heater on!

heat off

heater off!

target temperature 22

new temperature set!

我們需要識別token:heat, on/off (state), target, temperature, number

首先建立example4.l

%%%

[0-9]+ return number;

heat return tokheat;

on|off return state;

target return toktarget;

temperature return toktemperature;

\n /* ignore end of line */;

[ \t]+ /* ignore whitespace */;

%%

和前面相比這裡有2個大的變化,一是inlucde y.tab.h ,另乙個是不再直接print了,

而是返回token。原來是輸出了screen,而現在則輸出到yacc去了。

y.tab.h 是下面我們將要建立的檔案, 通過yacc的語法檔案來生成。

我們看看語法,bnf形式。

commands: /* empty */

| commands command

;command:

heat_switch

|target_set

;heat_switch: /* 加熱開關 */

tokheat state /* state 就是上面lex裡面定義的on off */

;target_set: /*目標溫度設定 */

toktarget toktemperature number

;

編譯

lex example4.l

yacc -d example4.y

cc -o example4 lex.yy.c y.tab.c

執行

$ ./example4

heat on

heat turned on or off

heat off

heat turned on or off

target temperature 12

temperature set

target *** 34

error: syntax error

***

我們再來擴充套件一下這個恆溫器,讓它能處理引數。

lex匹配到目標的時候,會同時將值賦到yytext中。yacc反過來又從yyval中取得值。

下面是新的lex檔案

%%%

[0-9]+ yylval=atoi(yytext); return number;

heat return tokheat;

on|off yylval=!strcmp(yytext,"on"); return state;

target return toktarget;

temperature return toktemperature;

\n /* ignore end of line */;

[ \t]+ /* ignore whitespace */;

%%

相應的yacc檔案也要修改:

%int yywrap()

main() %}

%token number tokheat state toktarget toktemperature

%%commands: /* empty */

| commands command

;command:

heat_switch

|target_set

;heat_switch: /* 這裡使用了lex裡面設定引數 */

tokheat state

;target_set: /* 這裡使用了lex裡面設定引數 */

toktarget toktemperature number;%%

再次編譯

然後執行

$ ./example4

heat on

heat turned on

heat off

heat turned off

target temperature 34

temperature set to 34

得到預期的結果。

lex和yacc格式入門

lex和yacc格式入門 lex檔案 hi oi n tchau bye n int main void int yywrap void yacc檔案 token hi bye program hi bye hi hi bye bye int yyerror char msg 會發現它們的結構都很相...

初步學習lex和yacc

因為是非計算機本科,所以沒有學編譯原理,進來想補補課,於是買了本 自製程式語言 裡面介紹了lex和yacc工具,於是裝起來試了下。原來用工具來解析字串還是挺方便的,以前知道正則以後,就覺得這東西很好,現在有了lex和yacc,把正則能做的事情又放大了,能夠做更豐富的事情。例如,寫乙個簡單的把字串裡的...

Lex和yacc工具介紹

在編譯過程中,詞法分析和語法分析是兩個重要階段。lex和yacc是unix環境下非常著名的兩個工具,可以生成分別完成詞法分析和語法分析功能 的c 在學習編譯原理過程中,可以善加利用這兩個工具,加深對兩個階段的理解。在平時的工作中,這兩個工具也會起到重要的作用。lex是lexical compiler...