青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-341  評(píng)論-2670  文章-0  trackbacks-0
    其實(shí)Vczh Library++3.0提供的parser combinator并不能大量減少語(yǔ)法分析器的代碼量,其實(shí)真正降低的是語(yǔ)法分析器的復(fù)雜程度。當(dāng)你想比較快速的完成一個(gè)功能的時(shí)候,有兩種代碼量差不多的設(shè)計(jì),一種實(shí)現(xiàn)起來(lái)比較難并且調(diào)試起來(lái)很慘,一種實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單而且基本不用怎么調(diào)試,那相對(duì)來(lái)說(shuō)肯定會(huì)選擇后一種方法了。除非你純粹是想獲得鍛煉。

    使用parser combinator開(kāi)發(fā)語(yǔ)法分析器的時(shí)候,你可以直接往C++里面寫(xiě)EBNF語(yǔ)法,當(dāng)然語(yǔ)法的具體形式因?yàn)槭艿紺++語(yǔ)言本身的限制我做了一點(diǎn)點(diǎn)修改,譬如說(shuō)A*和A+只好寫(xiě)成*A和+A,A B只好寫(xiě)成A + B、A>>B或者A<<B了。空明流產(chǎn)跟我抱怨說(shuō)boost::spirit編譯速度奇慢(據(jù)說(shuō)要一個(gè)多小時(shí),不知道是不是他機(jī)器太爛……)而且容易出現(xiàn)C1060 compiler is out of heap space的錯(cuò)誤,相比之下我在用我自己開(kāi)發(fā)的parser combinator的時(shí)候,我一個(gè)充滿語(yǔ)法的cpp文件只需要一秒多一點(diǎn)(Thinkpad R61i, Vista Home Basic, 3G內(nèi)存),而且不會(huì)出現(xiàn)C1060這種離譜的錯(cuò)誤。至少?gòu)倪@個(gè)程度上來(lái)說(shuō),開(kāi)發(fā)boost::spirit的人應(yīng)該是有很大的C++潔癖癥,才會(huì)把好好地一個(gè)parser combinator折騰成那個(gè)樣子。

    我是用的文法模型是帶類型修飾的文法,從文法的類型只能看出文法最終給你什么數(shù)據(jù),而不是文法他本身是怎么寫(xiě)的。Vczh Library++2.0的parser combinator采用了后面一中的做法,據(jù)說(shuō)boost::spirit也是這么做的,不過(guò)奇怪的是舊的parser combinator也沒(méi)出現(xiàn)那兩種錯(cuò)誤,取而代之是VC++經(jīng)常抱怨我一個(gè)表達(dá)式的類型簽名超過(guò)了4000個(gè)字符(囧)。于是Vczh Library++3.0的parser combinator做了一點(diǎn)修改。

    假設(shè)你一條文法A的結(jié)果是node<input, type>,第二條文法B的結(jié)果是node<input, string>,那么A+B的結(jié)果就是node<input, pair<type, string>>。這是什么意義呢?我們看表達(dá)文法type name semicolon的意思,大概可以理解為他可以接受“int a;”的這種語(yǔ)句。首先由于C++的限制我們替換成type + name + semicolon,其次由于那個(gè)semicolon,也就是分號(hào),其實(shí)僅僅是語(yǔ)法的要求而不是語(yǔ)法樹(shù)的一個(gè)必須成分,因此改成type + name << semicolon。這樣的話,這個(gè)文法依舊會(huì)要求輸入的字符串分別是一個(gè)類型、一個(gè)名字和一個(gè)分號(hào),但是返回的結(jié)果就自動(dòng)把分號(hào)給忽略掉了。那么我們?nèi)绾伪硎疽粋€(gè)同時(shí)包含type和name的類型呢?因?yàn)槲姆ú豢赡芴婺銊?chuàng)建一個(gè)struct,所以就定義了一個(gè)泛型的pair來(lái)表達(dá)。于是type + name << semicolon的結(jié)果類型就是node<input, pair<type, string>>了。這里input代表輸入的記號(hào)列表的類型。

    上面是新的parser combinator的做法,舊的parser combinator(據(jù)說(shuō)也是boost::spirit的做法)的類型表示方法比較BT:當(dāng)你有文法type : node<input, type>,string : node<input, string>和semicolon : node<input, token>的話,那么type + name << semicolon的類型會(huì)變成:
1 discard_right<input, sequence<input, node<input, type>, node<input, string>>, node<input, token>>
    寫(xiě)成這樣大概就可以理解什么是“文法他本身是怎么寫(xiě)的”了吧。

    舊的parser combinator的好處是C++為每一個(gè)文法生成了一個(gè)類型,雖然代碼會(huì)膨脹一點(diǎn)但是執(zhí)行過(guò)程會(huì)很快,只不過(guò)缺點(diǎn)比較多。第一個(gè)當(dāng)然是類型太多VC++編譯器會(huì)崩潰(C1060 compiler is out of heap space),第二個(gè)是編譯時(shí)間過(guò)長(zhǎng),第三個(gè)是當(dāng)你的文法比較長(zhǎng)的時(shí)候,類型簽名可能會(huì)超過(guò)VC++給你的限制,然后就會(huì)出現(xiàn)奇怪的問(wèn)題。所以我在Vczh Library++3.0的parser combinator就是用了一個(gè)新的做法,也就是僅保留文法的結(jié)果類型,所以也就不得不引入虛函數(shù)了。因?yàn)橐粋€(gè)文法node<input, type>有非常多種組合可能,在結(jié)構(gòu)上沒(méi)辦法表現(xiàn)出來(lái),所以必須使用虛函數(shù)。

    在聽(tīng)了空明流產(chǎn)的抱怨之后,我去搜了一下使用boost::spirit的人的反應(yīng),好像都是遇到了那兩個(gè)嚴(yán)重的問(wèn)題。幸好我喜歡造車輪,不然的話也許也會(huì)深陷地獄了。不過(guò)boost::spirit還是提供了解決辦法的,就是把你的長(zhǎng)的文法拆開(kāi)成短的。寫(xiě)過(guò)編譯器的人都會(huì)知道,這么做的嚴(yán)重后果就是你的分析器變成一團(tuán)亂麻,根本不知道自己在寫(xiě)什么,不僅不可能有我上一篇文章描寫(xiě)的優(yōu)美結(jié)果,更不可能把NativeX的分析器寫(xiě)成下面這個(gè)樣子了:
 1                     primitive        = TRUE[ToTrue] | FALSE[ToFalse]
 2                                     | ACHAR[ToAChar] | WCHAR[ToWChar]
 3                                     | ASTRING[ToAString] | WSTRING[ToWString]
 4                                     | FLOAT[ToFloat] | DOUBLE[ToDouble]
 5                                     | NULL_VALUE[ToNull]
 6                                     | INTEGER[ToInteger]
 7                                     ;
 8                     reference        = ID[ToReference];
 9 
10                     exp0            = primitive
11                                     | reference
12                                     | RESULT[ToResult]
13                                     | (CAST + (LT >> type << GT) + (OPEN_BRACE >> exp << CLOSE_BRACE))[ToCastExpression]
14                                     ;
15                     exp1            = lrec(exp0 +  *(
16                                                     (OPEN_ARRAY + exp0 << CLOSE_ARRAY)
17                                                     | (OPEN_BRACE + list(opt(exp + *(COMMA >> exp)))[UpgradeArguments] << CLOSE_BRACE)
18                                                     | ((DOT | POINTER) + reference)
19                                                     | (INCREASE | DECREASE)[UpgradePostfix]
20                                                     ), ToPostUnary);
21                     exp2            = exp1 | ((INCREASE | DECREASE | BIT_AND | MUL | SUB | BIT_NOT | NOT) + exp1)[ToPreUnary];
22                     exp3            = lrec(exp2 + *((MUL | DIV | MOD) + exp2), ToBinary);
23                     exp4            = lrec(exp3 + *((ADD | SUB) + exp3), ToBinary);
24                     exp5            = lrec(exp4 + *((SHL | SHR) + exp4), ToBinary);
25                     exp6            = lrec(exp5 + *((LT | GT | LE | GE) + exp5), ToBinary);
26                     exp7            = lrec(exp6 + *((EQ | NE) + exp6), ToBinary);
27                     exp8            = lrec(exp7 + *(BIT_AND + exp7), ToBinary);
28                     exp9            = lrec(exp8 + *(XOR + exp8), ToBinary);
29                     exp10            = lrec(exp9 + *(BIT_OR + exp9), ToBinary);
30                     exp11            = lrec(exp10 + *(AND + exp10), ToBinary);
31                     exp12            = lrec(exp11 + *(OR + exp11), ToBinary);
32                     exp                = lrec(exp12 + *((OP_ASSIGN | ASSIGN) + exp12), ToBinary);
33 
34                     primType        = (FUNCTION + type + (OPEN_BRACE >> list(opt(type + *(COMMA >> type))) << CLOSE_BRACE))[ToFunctionType]
35                                     | (PRIM_TYPE | ID)[ToNamedType]
36                                     ;
37                     type            = lrec(primType + *(MUL | (OPEN_ARRAY >> INTEGER << CLOSE_ARRAY)), ToDecoratedType);
38 
39                     statement        = SEMICOLON[ToEmptyStat]
40                                     | (exp + SEMICOLON)[ToExprStat]
41                                     | (VARIABLE + type + ID + opt(ASSIGN >> exp) << SEMICOLON)[ToVarStat]
42                                     | (IF + (OPEN_BRACE >> exp << CLOSE_BRACE) + statement + opt(ELSE >> statement))[ToIfStat]
43                                     | (BREAK << SEMICOLON)[ToBreakStat]
44                                     | (CONTINUE << SEMICOLON)[ToContinueStat]
45                                     | (EXIT << SEMICOLON)[ToReturnStat]
46                                     | (OPEN_STAT + list(*statement) << CLOSE_STAT)[ToCompositeStat]
47                                     | (DO + statement + (WHILE >> OPEN_BRACE >> exp << CLOSE_BRACE << SEMICOLON))[ToDoWhileStat]
48                                     | (LOOP + statement)[ToLoopStat]
49                                     | (WHILE + (OPEN_BRACE >> exp << CLOSE_BRACE) + statement + opt(WHEN >> OPEN_BRACE >> exp << CLOSE_BRACE << SEMICOLON))[ToWhileStat]
50                                     | (FOR + list(*statement) + (WHEN >> OPEN_BRACE >> exp << CLOSE_BRACE) + (WITH >> list(*statement)) + (DO >> statement))[ToForStat]
51                                     ;
52 
53                     declaration        = (VARIABLE + type + ID + opt(ASSIGN >> exp) << SEMICOLON)[ToVarDecl]
54                                     | (TYPE + ID + (ASSIGN >> type) << SEMICOLON)[ToTypedefDecl]
55                                     | (STRUCTURE + ID << SEMICOLON)[ToStructPreDecl]
56                                     | (STRUCTURE + ID + (OPEN_STAT >> *(type + ID << SEMICOLON) << CLOSE_STAT))[ToStructDecl]
57                                     | (FUNCTION + type + ID + (OPEN_BRACE >> plist(opt((type + ID) + *(COMMA >> (type + ID)))) << CLOSE_BRACE) + statement)[ToFuncDecl]
58                                     ;
59 
60                     unit            = ((UNIT >> ID << SEMICOLON) + list(opt(USES >> (ID + *(COMMA >> ID)) << SEMICOLON)) + list(*declaration))[ToUnit];

    啊,簡(jiǎn)直就跟EBNF沒(méi)什么區(qū)別啊。

    當(dāng)前的進(jìn)度可以在Vczh Library++3.0的頁(yè)面上看到。
posted on 2010-03-20 23:49 陳梓瀚(vczh) 閱讀(4575) 評(píng)論(2)  編輯 收藏 引用 所屬分類: VL++3.0開(kāi)發(fā)紀(jì)事

評(píng)論:
# re: Vczh Library++3.0之我的語(yǔ)法分析器和boost::spirit 2010-03-20 23:58 | 空明流轉(zhuǎn)

啊,簡(jiǎn)直就跟EBNF沒(méi)什么區(qū)別啊。

啊,簡(jiǎn)直就跟YY沒(méi)什么區(qū)別啊。  回復(fù)  更多評(píng)論
  
# re: Vczh Library++3.0之我的語(yǔ)法分析器和boost::spirit 2010-03-20 23:59 | 陳梓瀚(vczh)
@空明流轉(zhuǎn)
相比起來(lái),boost::spirit寫(xiě)出來(lái)的編譯器簡(jiǎn)直就是石器時(shí)代的產(chǎn)品啊,啊哈哈  回復(fù)  更多評(píng)論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产精品久久久久久一区二区三区 | 99在线精品视频在线观看| 午夜精品久久久久久久99黑人| 亚洲国产精品一区在线观看不卡| 国产精品一区二区欧美| 欧美精品麻豆| 老鸭窝亚洲一区二区三区| 亚洲免费在线电影| 日韩一区二区精品在线观看| 欧美国产亚洲精品久久久8v| 久久久久久久综合日本| 亚洲综合三区| 亚洲一区二区三区免费观看| 亚洲精品日韩久久| 黑人一区二区| 国产人妖伪娘一区91| 欧美日韩在线观看视频| 欧美精品一区二区三区在线看午夜 | 国产精品www994| 欧美激情视频网站| 开元免费观看欧美电视剧网站| 久久成人亚洲| 久久都是精品| 久久av资源网| 久久精品二区三区| 亚洲欧美日韩中文视频| 亚洲自拍啪啪| 亚洲欧美中文字幕| 亚洲欧美国产精品va在线观看 | 国产一区二区三区精品久久久| 国产美女精品视频免费观看| 国产精品视频久久| 国产精品理论片| 国产伦精品一区二区| 国产精品爽黄69| 国产视频在线观看一区二区三区 | 夜色激情一区二区| 亚洲免费播放| 亚洲香蕉网站| 午夜精品视频在线观看| 欧美在线播放| 久热re这里精品视频在线6| 久久综合久久久久88| 麻豆九一精品爱看视频在线观看免费| 久久婷婷国产综合精品青草| 欧美 日韩 国产精品免费观看| 欧美成人午夜激情在线| 亚洲国产天堂久久综合网| 91久久国产综合久久| 亚洲美女福利视频网站| 亚洲一区网站| 久久精品亚洲一区二区| 免费精品视频| 欧美色图五月天| 国产乱码精品一区二区三区五月婷| 国产亚洲综合性久久久影院| 亚洲高清网站| 99在线精品免费视频九九视| 亚洲欧美制服另类日韩| 久久先锋影音| 亚洲精品国久久99热| 亚洲午夜性刺激影院| 久久国产精品亚洲77777| 免费日韩成人| 国产精品男gay被猛男狂揉视频| 精品不卡一区| 亚洲视频二区| 久久亚洲影院| 亚洲裸体在线观看| 午夜欧美不卡精品aaaaa| 久热精品视频在线观看| 欧美小视频在线| 激情伊人五月天久久综合| 99精品欧美一区二区三区| 欧美一区二区三区免费看| 老牛国产精品一区的观看方式| 亚洲日韩欧美视频一区| 午夜精品视频在线观看一区二区| 免费成人你懂的| 国产精品美女www爽爽爽| 亚洲国产成人在线| 亚洲欧美一区在线| 欧美高清视频在线播放| 亚洲免费视频在线观看| 免费成人av| 国产精品视频男人的天堂| 91久久在线观看| 久久国产精品毛片| 91久久精品一区二区别| 亚洲欧美在线观看| 欧美精品一区二区三区蜜桃| 一区精品在线播放| 亚洲欧美国产精品专区久久| 亚洲国产精品一区在线观看不卡| 午夜精品成人在线| 欧美精品一区二区视频| 在线不卡中文字幕| 欧美在线高清视频| 亚洲精选大片| 免费一级欧美在线大片| 国产一区二区三区久久精品| 亚洲影视综合| 亚洲精品日韩激情在线电影| 裸体一区二区三区| 国内精品久久久| 欧美自拍偷拍| 亚洲一卡久久| 欧美色一级片| 在线一区视频| 亚洲精品中文字幕女同| 免费看亚洲片| 亚洲高清不卡| 美女啪啪无遮挡免费久久网站| 香蕉久久久久久久av网站| 欧美性猛交一区二区三区精品| 日韩午夜电影在线观看| 亚洲大胆美女视频| 久久久久久一区二区| 国产一区欧美| 久久国产精品一区二区三区四区| 亚洲一区二区成人| 欧美三级小说| 亚洲影视九九影院在线观看| 99精品国产99久久久久久福利| 欧美人在线视频| 亚洲美女精品成人在线视频| 亚洲国产一区二区三区在线播| 裸体素人女欧美日韩| 亚洲第一免费播放区| 欧美aⅴ99久久黑人专区| 久久视频一区二区| 亚洲第一天堂av| 欧美成人免费观看| 美日韩丰满少妇在线观看| 亚洲国产高清一区| 欧美激情精品久久久六区热门| 麻豆成人综合网| 亚洲精品中文字幕女同| 亚洲人成高清| 国产精品av一区二区| 亚洲欧美在线网| 性做久久久久久免费观看欧美| 国产一区二区三区在线观看免费| 久久久久久久综合日本| 久久国产精品网站| 亚洲国产精品成人综合色在线婷婷| 欧美激情一区二区三区在线| 欧美日韩精品免费观看视频| 亚洲女人小视频在线观看| 亚洲欧美日本国产专区一区| 激情综合中文娱乐网| 亚洲成色www8888| 欧美日韩网站| 久久久国产精品一区二区中文| 久久综合福利| 一本一本a久久| 亚洲女女女同性video| 狠狠色综合色区| 亚洲高清在线| 国产精品免费区二区三区观看| 久久亚裔精品欧美| 欧美freesex8一10精品| 亚洲一区二区在线看| 新狼窝色av性久久久久久| 亚洲国产精品成人一区二区| 99精品欧美一区二区三区| 国产日韩成人精品| 亚洲国产91色在线| 国产精品男gay被猛男狂揉视频| 久久亚洲捆绑美女| 欧美久色视频| 久久久久久亚洲精品中文字幕| 欧美韩日一区二区三区| 亚洲免费一在线| 噜噜噜躁狠狠躁狠狠精品视频 | 国产精品videosex极品| 久久精品九九| 欧美日韩aaaaa| 久久综合给合久久狠狠狠97色69| 欧美伦理a级免费电影| 久久精品论坛| 欧美日韩一区二区在线观看视频| 久久婷婷蜜乳一本欲蜜臀| 欧美日韩国产一级片| 久久中文字幕一区| 欧美日韩伊人| 亚洲大胆av| 国产一区二区三区久久| 亚洲美女av网站| 亚洲二区在线视频| 亚洲欧美美女| 夜夜嗨av一区二区三区免费区| 久久精品国产综合精品| 亚洲综合视频网| 欧美精品免费在线| 久久久久久91香蕉国产| 欧美日韩专区| 亚洲国产天堂久久国产91| 一区二区三区我不卡| 亚洲影视综合|