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

隨筆-341  評論-2670  文章-0  trackbacks-0
    其實Vczh Library++3.0提供的parser combinator并不能大量減少語法分析器的代碼量,其實真正降低的是語法分析器的復雜程度。當你想比較快速的完成一個功能的時候,有兩種代碼量差不多的設計,一種實現起來比較難并且調試起來很慘,一種實現起來比較簡單而且基本不用怎么調試,那相對來說肯定會選擇后一種方法了。除非你純粹是想獲得鍛煉。

    使用parser combinator開發語法分析器的時候,你可以直接往C++里面寫EBNF語法,當然語法的具體形式因為受到C++語言本身的限制我做了一點點修改,譬如說A*和A+只好寫成*A和+A,A B只好寫成A + B、A>>B或者A<<B了。空明流產跟我抱怨說boost::spirit編譯速度奇慢(據說要一個多小時,不知道是不是他機器太爛……)而且容易出現C1060 compiler is out of heap space的錯誤,相比之下我在用我自己開發的parser combinator的時候,我一個充滿語法的cpp文件只需要一秒多一點(Thinkpad R61i, Vista Home Basic, 3G內存),而且不會出現C1060這種離譜的錯誤。至少從這個程度上來說,開發boost::spirit的人應該是有很大的C++潔癖癥,才會把好好地一個parser combinator折騰成那個樣子。

    我是用的文法模型是帶類型修飾的文法,從文法的類型只能看出文法最終給你什么數據,而不是文法他本身是怎么寫的。Vczh Library++2.0的parser combinator采用了后面一中的做法,據說boost::spirit也是這么做的,不過奇怪的是舊的parser combinator也沒出現那兩種錯誤,取而代之是VC++經常抱怨我一個表達式的類型簽名超過了4000個字符(囧)。于是Vczh Library++3.0的parser combinator做了一點修改。

    假設你一條文法A的結果是node<input, type>,第二條文法B的結果是node<input, string>,那么A+B的結果就是node<input, pair<type, string>>。這是什么意義呢?我們看表達文法type name semicolon的意思,大概可以理解為他可以接受“int a;”的這種語句。首先由于C++的限制我們替換成type + name + semicolon,其次由于那個semicolon,也就是分號,其實僅僅是語法的要求而不是語法樹的一個必須成分,因此改成type + name << semicolon。這樣的話,這個文法依舊會要求輸入的字符串分別是一個類型、一個名字和一個分號,但是返回的結果就自動把分號給忽略掉了。那么我們如何表示一個同時包含type和name的類型呢?因為文法不可能替你創建一個struct,所以就定義了一個泛型的pair來表達。于是type + name << semicolon的結果類型就是node<input, pair<type, string>>了。這里input代表輸入的記號列表的類型。

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

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

    在聽了空明流產的抱怨之后,我去搜了一下使用boost::spirit的人的反應,好像都是遇到了那兩個嚴重的問題。幸好我喜歡造車輪,不然的話也許也會深陷地獄了。不過boost::spirit還是提供了解決辦法的,就是把你的長的文法拆開成短的。寫過編譯器的人都會知道,這么做的嚴重后果就是你的分析器變成一團亂麻,根本不知道自己在寫什么,不僅不可能有我上一篇文章描寫的優美結果,更不可能把NativeX的分析器寫成下面這個樣子了:
 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];

    啊,簡直就跟EBNF沒什么區別啊。

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

評論:
# re: Vczh Library++3.0之我的語法分析器和boost::spirit 2010-03-20 23:58 | 空明流轉

啊,簡直就跟EBNF沒什么區別啊。

啊,簡直就跟YY沒什么區別啊。  回復  更多評論
  
# re: Vczh Library++3.0之我的語法分析器和boost::spirit 2010-03-20 23:59 | 陳梓瀚(vczh)
@空明流轉
相比起來,boost::spirit寫出來的編譯器簡直就是石器時代的產品啊,啊哈哈  回復  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久久精品欧美丰满| 欧美第一黄色网| 国产噜噜噜噜噜久久久久久久久| 亚洲国产老妈| 欧美成人一区二区三区| 久久人91精品久久久久久不卡| 国语自产在线不卡| 久久影院午夜片一区| 久久久国产精彩视频美女艺术照福利 | 亚洲精品中文字幕女同| 亚洲国产精品第一区二区三区| 免费亚洲一区二区| 亚洲图片你懂的| 亚洲欧美不卡| 1000部精品久久久久久久久| 欧美黄网免费在线观看| 国产精品av久久久久久麻豆网| 欧美亚洲综合在线| 久久久91精品国产一区二区三区| 在线国产欧美| 99精品热6080yy久久| 国产手机视频一区二区| 欧美第一黄色网| 欧美网站在线观看| 毛片av中文字幕一区二区| 蜜桃av综合| 亚洲你懂的在线视频| 久久久久久久精| 亚洲夜晚福利在线观看| 欧美资源在线观看| 99视频精品全国免费| 欧美亚洲一区| 99国产精品视频免费观看一公开| 午夜欧美理论片| 亚洲乱码国产乱码精品精可以看| 午夜久久电影网| 99精品免费| 久久综合久久美利坚合众国| 亚洲欧美日韩系列| 欧美极品在线观看| 久久天天综合| 国产精品推荐精品| 亚洲精品麻豆| 亚洲激情在线视频| 久久精品人人做人人综合| 一区二区三区四区五区精品视频| 久久国产精品99国产| 亚洲一区尤物| 欧美激情中文字幕一区二区| 久久综合久久综合这里只有精品 | 一本一本久久| 亚洲精品国产精品乱码不99按摩| 午夜精品99久久免费| 亚洲一区二区不卡免费| 免费视频最近日韩| 免费成人性网站| 国内自拍视频一区二区三区| 亚洲一区二区3| 亚洲一区二区三区久久| 欧美人与性禽动交情品| 亚洲国产99| 亚洲国产精品久久久久| 久久免费午夜影院| 美女久久网站| 影音先锋另类| 久久精品亚洲一区二区| 久久精品女人的天堂av| 国产一区免费视频| 久久成人免费视频| 久久久久久黄| 黄色成人av网站| 久久尤物视频| 亚洲国产91| 一本大道久久a久久综合婷婷| 久久最新视频| 亚洲成色777777在线观看影院| 亚洲东热激情| 欧美久久久久中文字幕| 99精品欧美一区| 亚洲欧美日韩在线观看a三区 | 久久综合久久综合久久| 麻豆精品在线视频| 在线成人激情视频| 欧美aⅴ一区二区三区视频| 亚洲国产精品va在线观看黑人 | 国产精品毛片大码女人| 午夜国产欧美理论在线播放| 久久成人这里只有精品| 尹人成人综合网| 欧美—级a级欧美特级ar全黄| 亚洲免费电影在线观看| 午夜精品久久久久久久蜜桃app | 国产精品福利在线观看网址| 亚洲午夜免费视频| 久久久久久亚洲综合影院红桃 | 99re国产精品| 国产精品久久久免费| 性刺激综合网| 欧美大色视频| 午夜亚洲福利| 亚洲高清在线视频| 欧美亚州在线观看| 久久久噜噜噜久久中文字幕色伊伊 | 正在播放亚洲| 国产欧美一区二区精品仙草咪| 久久国产一区二区| 亚洲精品综合| 久久色在线观看| 中日韩美女免费视频网站在线观看 | 亚洲欧洲一区二区三区久久| 亚洲欧美日韩国产一区| 亚洲国产一二三| 国产精品美女xx| 欧美jizzhd精品欧美喷水| 亚洲视频观看| 最新中文字幕亚洲| 久久久久久久国产| 亚洲视频一起| 亚洲精品1区2区| 国产一区二区中文字幕免费看| 欧美激情视频一区二区三区在线播放 | 欧美中文字幕在线播放| 亚洲精品国精品久久99热| 久久久国际精品| 亚洲你懂的在线视频| 亚洲三级电影全部在线观看高清| 国产日韩欧美夫妻视频在线观看| 欧美日韩国产成人在线免费| 久久久精品国产99久久精品芒果| 亚洲一区二区三区四区五区黄| 欧美激情性爽国产精品17p| 久久精品国产一区二区电影| 亚洲一区在线免费| 99在线|亚洲一区二区| 亚洲国产99| 在线国产精品播放| 黄网站色欧美视频| 国产一区二区三区免费不卡 | 欧美成人高清视频| 久久综合久久久| 久久九九免费视频| 久久精选视频| 久久裸体艺术| 久久亚裔精品欧美| 老司机67194精品线观看| 久久久综合视频| 蜜臀av在线播放一区二区三区| 久久国产欧美日韩精品| 久久久国产亚洲精品| 欧美中文字幕视频在线观看| 欧美一区二区三区男人的天堂 | 亚洲国产精品一区在线观看不卡| 欧美a级片网| 欧美粗暴jizz性欧美20| 欧美va日韩va| 亚洲精品免费在线播放| 一本久道久久久| 亚洲一区在线观看视频 | 亚洲国产日韩综合一区| 亚洲精品国久久99热| 99在线热播精品免费| 亚洲视频在线免费观看| 午夜精品在线观看| 久久一区二区精品| 欧美精品在欧美一区二区少妇| 欧美日韩二区三区| 国产精品一区二区久久久久| 国产一级揄自揄精品视频| 伊人激情综合| 亚洲精品久久在线| 亚洲与欧洲av电影| 久久久久久久高潮| 亚洲欧洲精品一区二区精品久久久| 亚洲日本va午夜在线电影 | 免费人成网站在线观看欧美高清| 欧美好骚综合网| 亚洲午夜成aⅴ人片| 久久国产精品第一页| 欧美精品一区二区久久婷婷| 国产精品久久久亚洲一区 | 国产亚洲在线| 亚洲国产精品黑人久久久| 亚洲午夜在线观看| 久久人人97超碰国产公开结果| 亚洲国产毛片完整版| 亚洲欧美日韩在线观看a三区 | 午夜精品偷拍| 老司机精品福利视频| 国产精品亚发布| 亚洲乱码精品一二三四区日韩在线 | 亚洲精品一区二区三区婷婷月| 亚洲欧美另类中文字幕| 欧美成人有码| 性色av一区二区三区| 欧美黄色免费网站| 狠狠色狠色综合曰曰| 亚洲欧美www| 亚洲区国产区| 久久频这里精品99香蕉| 国产精品免费看片|