昨天看完了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...