• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Prayer

            在一般中尋求卓越
            posts - 1256, comments - 190, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            使用bison和flex工具

            Posted on 2010-09-20 15:29 Prayer 閱讀(791) 評論(0)  編輯 收藏 引用 所屬分類: C/C++
            這里有一個使用bison建立一個簡單的計算器的例子:
            http://www.cs.berkeley.edu/~maratb/cs164/bison.html

            使用bison和flex工具學習編譯原理,遠比單獨看書然后自己編寫一些程序生動的多。這樣你就不會在那些復雜的字符處理,正則表達式的處理上浪費精力,最后費盡心力,卻沒有結果,失去了學習的興趣。

            我 這里有一個簡單的計算器的程序,可以實現加、減、乘、除運算,并支持括號的處理和26個字母作為變量。以前自己使用后綴表達式方式寫過一個這樣的程序,單 單中綴表達式改為后綴表達式就是幾百行的代碼,反正自己現在還是不知道怎么處理里面復雜的堆棧的(我用了STL的List實現)。


            詞法處理文件calc.lex內容如下:
            %{
                /*
                 *  一個簡單計算器的Lex詞法文件
                 */
                #include <stdlib.h>
               
                void yyerror(char*);
                #include "calc.tab.h"
            %}
            %%
                /* a-z為變量 */
            [a-z]    {
                    yylval = *yytext - 'a';
                    return VARIABLE;
                }
                /* 整數 */
            [0-9]+    {
                    yylval = atoi(yytext);
                    return INTEGER;
                }
                /* 運算符 */
            [-+()=/*\n]    {return *yytext;}
                /* 空白被忽略 */
            [ \t]    ;
                /* 其他字符都是非法的 */
            .    yyerror("無效的輸入字符");
            %%
            int    yywrap(void)
            {
                return 1;
            }
            詞法處理的目標就是區分出來每個成員到底是什么,這里有兩種 INTEGER和VARIABLE。只要區分出來各個成分詞法分析的任務就完成了。



            語法處理文件calc.y內容如下:
            %token    INTEGER VARIABLE
            %left    '+' '-'
            %left    '*' '/'
            %{
                #include <stdio.h>
                void yyerror(char*);
                int yylex(void);
                int sym[26];
            %}
            %%
            program:
                program statement '\n'
                |
                ;
            statement:
                 expr    {printf("%d\n", $1);}
                 |VARIABLE '=' expr    {sym[$1] = $3;}
                 ;
            expr:
                INTEGER
                |VARIABLE{$$ = sym[$1];}
                |expr '+' expr    {$$ = $1 + $3;}
                |expr '-' expr    {$$ = $1 - $3;}
                |expr '*' expr    {$$ = $1 * $3;}
                |expr '/' expr    {$$ = $1 / $3;}
                |'('expr')'    {$$ = $2;}
                ;
            %%
            void yyerror(char* s)
            {
                fprintf(stderr, "%s\n", s);
            }
            int main(void)
            {
                printf("A simple calculator.\n");
                yyparse();
                return 0;
            }
            語法分析文件的寫法就是將BNF表達式描述一下即可,規則隨著條目逐漸細化,變成了可以理解的內容。這里不用管如何實現這些語法的分析,只是需要告知如何構建這些語法。



            編譯命令如下:
            >bison -d calc.y
            >flex calc.lex
            >gcc calc.tab.c lex.yy.c -o calc

            色妞色综合久久夜夜| 久久精品国产精品亚洲| 亚洲v国产v天堂a无码久久| 久久www免费人成精品香蕉| 久久久久噜噜噜亚洲熟女综合 | 久久精品国产精品亚洲下载| 久久久久亚洲av毛片大| 亚洲国产欧洲综合997久久| 97精品伊人久久大香线蕉app| 久久国产香蕉视频| 久久人人爽人人爽人人av东京热 | 国产精品久久久久乳精品爆| 久久国产精品免费一区二区三区| 久久99热这里只有精品66| 久久综合给合久久狠狠狠97色| 国产巨作麻豆欧美亚洲综合久久| 亚洲精品乱码久久久久久蜜桃不卡| 日本一区精品久久久久影院| 少妇人妻综合久久中文字幕| 国内精品免费久久影院| 99久久精品毛片免费播放| 久久国产欧美日韩精品免费| 国内精品久久久久久中文字幕| 久久99国产乱子伦精品免费| 久久午夜无码鲁丝片秋霞| 久久精品免费大片国产大片| 国产精品欧美久久久久无广告| 久久香蕉超碰97国产精品| 无码伊人66久久大杳蕉网站谷歌 | 中文精品久久久久人妻| 精品国产综合区久久久久久| 777午夜精品久久av蜜臀 | 久久亚洲精品成人无码网站| 久久久婷婷五月亚洲97号色| 久久精品免费观看| 久久亚洲中文字幕精品有坂深雪| 亚洲成av人片不卡无码久久| 久久婷婷五月综合成人D啪| 久久se这里只有精品| 国产精品成人99久久久久91gav| 久久精品国产91久久麻豆自制|