• <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>
            隨筆-341  評(píng)論-2670  文章-0  trackbacks-0

            除了錯(cuò)誤處理文件還沒有定義好以外,現(xiàn)在語(yǔ)法定義跟語(yǔ)法樹的數(shù)據(jù)結(jié)構(gòu)定義以及分析器都完成了!有了這兩個(gè)文件,我的工具就可以替你生成一個(gè)函數(shù)和一堆類,讓你使用這個(gè)函數(shù)就可以將一份代碼轉(zhuǎn)換為一顆語(yǔ)法樹啦。娃哈哈……

             

            現(xiàn)在讓我們來看一個(gè)例子,這個(gè)例子展示了一個(gè)科學(xué)計(jì)算器的表達(dá)式的結(jié)構(gòu)定義以及語(yǔ)法定義。首先是數(shù)據(jù)結(jié)構(gòu)的定義:

            enum BinopType

            {

              Plus

              Minus

              Mul

              Div

            }

            enum SinopType

            {

              Negative

            }

             

            class Expression

            {

            }

            class Number Expression

            {

              double                              Number

            }

            class Binop Expression

            {

              BinopType                      Operator

              Expression^                   LeftOp

              Expression^                   RightOp

            }

            class Sinop Expression

            {

              SinopType                       Operator

              Expression^                   Operand

            }

            class Invoke Expression

            {

              string                               Name;

              list<Expression^>         Parameters;

            }

             

            Type^的意思是autoptr<Type>。因?yàn)檎Z(yǔ)義已經(jīng)決定了這玩意兒是生成樹的,所以我們不需要考慮循環(huán)引用的問題。如果你不改動(dòng)這個(gè)樹的話,你可以不必刪除,autoptr自己會(huì)將這些問題處理掉的。內(nèi)存管理是一件多么麻煩的事情啊,于是我解決掉了。class后面的第一個(gè)名稱是類名,如果第二個(gè)名稱存在的話則代表父類的類名,可以用來表達(dá)繼承關(guān)系。

             

            那么現(xiàn)在看看語(yǔ)法的定義:

            num                   ="\d+(.\d+)?"            ;

            ident                  ="[a-zA-Z_]\w*"       ;

            plus                    ="\+"                           ;

            minus                ="\-"                                     ;

            mul                    ="\*"                           ;

            div                      ="/"                             ;

            leftbrace           ="\("                                     ;

            rightbrace        ="\)"                                     ;

            comma              =","                             ;

            discard              ="\s+"                         ;

             

            Number^                    factor=num{Number};

            Sinop^                         factor=minus{Operator=Negative} factor{Operand};

            Expression^               factor=leftbrace exp{#result} rightbrace;

            Invoke^                       factor=ident{Name}[leftbrace param_list{Parameters} rightbrace];

            Expression^               term =factor{#result};

            Binop^                       term=term{LeftOp} (mul{Operator=Mul}|div{Operator=Div}) factor{RightOp};

            Expression^               exp=term{#result};

            Binop^                        exp=exp{LeftOp} (plus{Operator=Plus}|minus{Operator=Minus}) term{RightOp};

            list<Expression^>    param_list=exp{#insert} [comma param_list{#result}];

            Expression^               program=exp{#result};

             

            我們來看其中的兩條文法。第一條文法:list<Expression^>param_list=exp{#insert}[comma param_list{#result}];。文法推導(dǎo)式子返回list<Expression^>類型的對(duì)象。如果param_list存在那么將param_list當(dāng)成當(dāng)前的列表,否則創(chuàng)建一個(gè)新列表。然后將exp使用insert方法插入列表的頭部。最后返回列表。

             

            第二條文法:Binop^ exp=exp{LeftOp} (plus{Operator=Plus}|minus{Operator=Minus}) term{RightOp};。文法推導(dǎo)式子返回Binop^類型的對(duì)象。將exp放入成員LeftOp,將term放入成員RightOp,如果遇到plus則將Operator設(shè)置為BinopType::Plus,否則設(shè)置為BinopType::Minus。參考一下前面對(duì)于類Binop以及枚舉類型BinopType的定義就知道了。

             

            文法從program開始,分析器檢查輸入的字符串,得到一個(gè)正確的推倒之后,就是用這些語(yǔ)義命令來構(gòu)造所需的數(shù)據(jù)結(jié)構(gòu)。當(dāng)整個(gè)過程被生成為C++代碼之后,一切都變得非常的方便。等代碼生成部分完成之后(這一部分由于將產(chǎn)生基于我半年前做的Syngram庫(kù)的代碼,由于Syngram支持在C++里面直接寫文法,所以代碼生成是沒有什么難度的,而且做起來很快)就算不會(huì)處理字符串也可以寫文法分析器啦!

            posted on 2008-09-14 00:53 陳梓瀚(vczh) 閱讀(1429) 評(píng)論(3)  編輯 收藏 引用 所屬分類: 腳本技術(shù)

            評(píng)論:
            # re: 語(yǔ)法分析器定義接近完成! 2008-09-14 00:56 | Real
            博主辛苦了,那么多作品。  回復(fù)  更多評(píng)論
              
            # re: 語(yǔ)法分析器定義接近完成! 2008-09-14 02:23 | jx
            您可真是個(gè)強(qiáng)人,不知道你考研不?  回復(fù)  更多評(píng)論
              
            # re: 語(yǔ)法分析器定義接近完成! 2008-09-14 03:14 | 陳梓瀚(vczh)
            国内精品伊人久久久久av一坑 | 麻豆亚洲AV永久无码精品久久| 一个色综合久久| 色欲综合久久躁天天躁蜜桃| Xx性欧美肥妇精品久久久久久| 2021国内久久精品| 伊人热人久久中文字幕| 久久国产亚洲精品| 国产精品成人无码久久久久久 | 嫩草影院久久国产精品| 伊人久久大香线蕉综合热线| 国产AV影片久久久久久| 伊人热热久久原色播放www| 久久国产乱子伦精品免费强| 亚洲狠狠婷婷综合久久蜜芽| 亚洲国产精品无码久久九九| 久久91精品综合国产首页| 久久天天躁狠狠躁夜夜96流白浆| 久久无码AV中文出轨人妻| 久久九九亚洲精品| 国产成人精品久久二区二区| 中文字幕日本人妻久久久免费 | 久久亚洲AV成人无码电影| 久久91精品国产91| 婷婷久久精品国产| 无码乱码观看精品久久| 久久久久亚洲AV成人网人人软件| 99久久综合国产精品二区| 久久精品国产免费| 亚洲一区中文字幕久久| 国产精品99久久不卡| 国产高潮国产高潮久久久91| 国产精品九九久久精品女同亚洲欧美日韩综合区 | 亚洲精品午夜国产VA久久成人| 久久综合久久综合亚洲| 亚洲人成无码www久久久| 色播久久人人爽人人爽人人片aV | 精品久久一区二区三区| 久久福利青草精品资源站免费| 久久精品成人免费看| 精品久久久久久无码人妻热|