锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
鍦ㄨ繖閲屾垜綆鍗曞湴浠嬬粛涓涓嬬敤娉曘傚亣璁懼ぇ瀹惰寰梫lpp錛圴czh Library++錛屼篃灝辨槸GacUI鐢ㄧ殑閭d釜搴擄級鐨刉String鍟奓ist榪欎簺涓滆タ鍦ㄨ皟璇曞櫒閲岄潰鏄劇ず鍑烘潵鐨勪笢瑗垮お涓戯紝灝卞彲浠ョ敤浠ヤ笅涓夋鏉ヤ慨鏀瑰畠銆?/p>
1錛氬幓http://gac.codeplex.com/SourceControl/changeset/view/99419#2395529涓嬭澆鎴戝啓鐨勯偅涓猲atvis鏂囦歡銆傝繖涓枃浠跺湪鏁翠釜zip鍖呴噷闈㈢殑浣嶇疆鏄疌ommon\vlpp.natvis
2錛氭妸榪欎釜鏂囦歡澶嶅埗鍒癈:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers錛堝鏋滀嬌鐢ㄩ粯璁ゅ畨瑁呰礬寰勭殑璇濓級
3錛氶噸鍚綘鏈鍠滅埍鐨刅isual Studio 2012錛屽氨鍙互鐪嬪埌涓嬮潰鐨勪笢瑗夸簡錛?/p>
鏈夊唴瀹逛絾鏄繕娌¤綆楃殑“鎯版ц綆?#8221;綾?/p>
List<Nullable<vint>>鐨勪簰鐩稿祵濂椾篃鏄姝ょ殑瀹岀編
濡傛灉澶у鎯沖啓鑷繁鐨凜ustomized Visualizer鐨勮瘽錛屽彲浠ュ幓鍙傝冨井杞壇蹇冩彁渚涚殑鏂囨。http://msdn.microsoft.com/en-us/library/vstudio/jj620914.aspx錛岀劧鍚庢寜鐓т笂闈㈢殑姝ラ鍐欒嚜宸辯殑natvis鏂囦歡銆傚湪榪欓噷鎴戞妸鎴戠殑natvis璐翠笂鏉ワ紝浠ヤ緵鍙傝冿細
<?xml version="1.0" encoding="utf-8"?> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <Type Name="vl::ObjectString<wchar_t>"> <DisplayString>{{ size={length}, buffer={buffer+start,su} }}</DisplayString> <StringView>buffer+start,su</StringView> <Expand> <Item Name="[size]">length</Item> <ArrayItems> <Size>length</Size> <ValuePointer>buffer+start</ValuePointer> </ArrayItems> </Expand> </Type> <Type Name="vl::ObjectString<char>"> <DisplayString>{{ size={length}, buffer={buffer+start,s} }}</DisplayString> <StringView>buffer+start,s</StringView> <Expand> <Item Name="[size]">length</Item> <ArrayItems> <Size>length</Size> <ValuePointer>buffer+start</ValuePointer> </ArrayItems> </Expand> </Type> <Type Name="vl::collections::List<*,*>"> <AlternativeType Name="vl::collections::SortedList<*,*>"/> <AlternativeType Name="vl::collections::Array<*,*>"/> <DisplayString>{{ size={count} }}</DisplayString> <Expand> <Item Name="[size]">count</Item> <ArrayItems> <Size>count</Size> <ValuePointer>buffer</ValuePointer> </ArrayItems> </Expand> </Type> <Type Name="vl::collections::Dictionary<*,*,*,*>"> <AlternativeType Name="vl::collections::Group<*,*,*,*>"/> <DisplayString>{{ size={keys.count} }}</DisplayString> <Expand> <Item Name="[size]">keys.count</Item> <Item Name="Keys">keys</Item> <Item Name="Values">values</Item> </Expand> </Type> <Type Name="vl::Ptr<*>"> <AlternativeType Name="vl::ComPtr<*>"/> <DisplayString Condition="reference == 0">[empty]</DisplayString> <DisplayString Condition="reference != 0">{*reference}</DisplayString> <Expand> <Item Condition="reference != 0" Name="[ptr]">reference</Item> </Expand> </Type> <Type Name="vl::Lazy<*>"> <DisplayString Condition="internalValue.reference == 0">[empty]</DisplayString> <DisplayString Condition="internalValue.reference != 0 && internalValue.reference->evaluated == false">[not evaluated]</DisplayString> <DisplayString Condition="internalValue.reference != 0 && internalValue.reference->evaluated == true">{internalValue.reference->value}</DisplayString> <Expand> <Item Condition="internalValue.reference != 0 && internalValue.reference->evaluated == true" Name="[value]">internalValue.reference->value</Item> </Expand> </Type> <Type Name="vl::ObjectBox<*>"> <DisplayString>{object}</DisplayString> <Expand> <ExpandedItem>object</ExpandedItem> </Expand> </Type> <Type Name="vl::Nullable<*>"> <DisplayString Condition="object == 0">[empty]</DisplayString> <DisplayString Condition="object != 0">{*object}</DisplayString> <Expand> <ExpandedItem Condition="object != 0">*object</ExpandedItem> </Expand> </Type> </AutoVisualizer>
鎵浠ュ湪榪欓噷鎴戜滑鍏堟妸鍑犳潯鏂囨硶鐨勬渶鍚庣殑鐘舵佹満閮藉垪鍑烘潵錛堝ぇ鍥撅級錛?/p>
鎺ヤ笅鏉ョ殑榪欎竴姝ワ紝灝辨槸瑕佸鎵鏈夐潬闈炵粓緇撶錛圗xp鍟奣erm榪欎簺錛夎繘琛岃煩杞殑transition閮芥墽琛屼笂涓綃囨枃绔犳墍璇寸殑浼犺涓殑浜ゅ弶閾炬帴銆傚湪浜х敓閾炬帴鐨勬椂鍊欙紝鎴戜滑緇檚hift鍜宺educe鐨勮竟鍒嗗埆鍔犱笂shift鍜宺educe銆傝宻hift鍜宺educe鏄湁鍙傛暟鐨?#8212;—灝辨槸琚玸hift璧扮殑鐘舵佺殑id銆傝繖鏍峰彲浠ュ湪parse鐨勬椂鍊欏尮閰嶅拰澶勭悊鐘舵佸爢鏍堛傚湪榪欓噷鎴戦棬瀵筫3->e1榪欎竴姝ュ仛涓涓嬫搷浣滃仛涓轟緥瀛愩傜孩鑹茬殑杈規槸琚垹鎺夌殑錛岃岀矖澹殑緇胯壊杈規槸琚柊鍔犺繘鍘葷殑錛?/p>
綰㈣壊鐨勮竟鍙樻垚浜嗕袱鏉$豢鑹茬殑杈癸紝綰㈣壊鐨勮竟闄勫甫鐨勪俊鎭垯琚鍒跺埌浜嗙豢鑹茬殑reduce杈逛笂銆傚綋鎴戜滑浣跨敤榪欎釜鐘舵佹満鐨勬椂鍊欙紝shift(s3)灝辮〃紺哄線鍫嗘爤閲岄潰鍘嬪叆s3錛宺educe(s3)灝辮〃紺轟粠鍫嗘爤閲岄潰寮瑰嚭(s3)銆傚綋鐒跺脊鍑轟笉涓瀹氫細鎴愬姛錛屾墍浠ュ鏋滀笉鎴愬姛鐨勮瘽錛岃繖鏉¤竟灝變笉鑳藉湪褰撴椂浣跨敤銆傚洜姝よ繖涔熷氨鏄負浠涔堝湪e3璺寵漿鍒皌0涔嬪悗錛宼1鐭ラ亾寰鍥炶煩鐨勬槸e1鑰屼笉鏄埆鐨勪粈涔堝湴鏂?#8212;—灝卞鍚屼負浠涔圕++鐨勫嚱鏁版墽琛屽畬涔嬪悗鎬繪槸鐭ラ亾濡備綍璺寵漿鍥炶皟鐢ㄥ畠鐨勫湴鏂逛竴鏍?#8212;—鍥犱負鎶婁俊鎭帹鍏ヤ簡鍫嗘爤銆?/p>
閭g幇鍦ㄦ垜浠氨鏉ョ湅涓涓嬶紝褰撴墍鏈夌殑闈炵粓緇撶璺寵漿閮藉鐞嗘帀涔嬪悗錛屼細鍙樻垚浠涔堟牱瀛愬惂錛堣繖涓浘鐪熸槸澶嶆潅鍜屼貢鍒版垜涓嶆兂鐢誨晩錛夛紝涓轟簡璁╁浘鍙樺緱涓嶉偅涔堢碂緋曪紝鎴戞妸shift閮藉彉鎴愮傳鑹詫紝reduce閮藉彉鎴愮豢鑹詫細
鍦ㄦ坊鍔爏hift鍜宺educe杈逛箣鍓嶏紝姣忎竴鏉¤竟閮芥槸鏈夎緭鍏oken鐨勩備絾鏄垜浠垰鍒氭坊鍔犱笂鍘葷殑shift鍜宺educe杈瑰嵈鏄笉杈撳叆token鐨勶紝鎵浠ヤ粬浠槸epsilon杈癸紝涓嬩竴姝ュ氨鏄娑堥櫎浠栦滑銆備笂闈㈣繖涓浘娑堥櫎浜唀psilon杈逛箣鍚庯紝浼氬彉鎴愪竴涓姸鎬佸緢灝戯紝浣嗘槸姣忎竴鏉¤竟闄勫甫鐨勪俊鎭兘浼氶潪甯稿錛岃屼笖鍍弉1榪欑緇忓父鍒拌揪鐨勭姸鎬侊紙鍥犱負鍥涘垯榪愮畻閲岄潰鏈夊緢澶氭暟瀛楋級灝嗘仮澶嶅皠鍑烘棤鏁版潯杈廣傚埌浜嗚繖閲岃繖涓姸鎬佹満宸茬粡鍐嶄篃鐢諱笉鍑烘潵浜嗐傛墍浠ユ垜涓嬮潰灝卞彧鎷夸袱涓緥瀛愭潵鐢匯備笅闈㈣灞曠ず鐨勬槸鐢‥xp鏉arse鍗曠嫭鐨勪竴涓暟瀛椾細璧扮殑杈癸紝褰撶劧灝辨槸Exp –> Term –> Factor –> Number浜嗭細
灝變細琚鐞嗘垚錛?/p>
娉ㄦ剰杈逛笂闈㈢殑淇℃伅鏄鎸夐『搴忛噸鏂板彔鍔犲湪涓璧風殑銆傚綋鎵鏈夌殑epsilon杈歸兘鍘繪帀浜嗕箣鍚庯紝鎴戜滑灝卞緱鍒頒簡鏈緇堢殑涓涓姸鎬佹満銆傛渶閲嶈鐨勪竴浠朵簨鎯呭嚭鐜頒簡銆傛垜浠煡閬擄紝鍙戞槑LR鍜孡ALR榪欑涓滆タ灝卞熀鏈笂鏄負浜嗗鐞嗗乏閫掑綊鐨勶紝鎵浠ヨ繖縐嶅浘灝卞彲浠ュ湪鍘婚櫎epsilon杈圭殑榪囩▼涓嚜鍔ㄥ彂鐜板乏閫掑綊銆傝繖鏄庝箞鍋氬埌鐨勫憿錛熷彧瑕佸湪鍘婚櫎epsilon杈圭殑鏃跺欙紝鍙戠幇浜嗕竴鏉″畬鍏ㄧ敱shift榪欑epsilon杈圭粍鎴愮殑鐜紝閭d箞宸﹂掑綊灝卞彂鐜頒簡銆備負浜嗘柟渚匡紝鎴戜滑鍙互鍙鐞嗙洿鎺ュ乏閫掑綊——灝辨槸榪欑鐜殑闀垮害鏄?鐨勩備笉鍖呭惈闂存帴宸﹂掑綊鐨勯棶娉曟槸寰堝鏄撳啓鍑烘潵鐨勩傚綋鐒惰繖縐嶇幆騫朵笉涓瀹氭槸棣栧熬鐩告帴鐨勶紝璀璇存垜浠湪澶勭悊e0鐨勬椂鍊欏氨浼氬彂鐜癳0->t0->t0榪欑鐜紙褰撶劧涓ユ牸鏉ヨ鐜彧鏈夋渶鍚庝竴鎴殑榪欎釜閮ㄥ垎錛夈傛垜浠殑紼嬪簭瑕佸緢濂藉湴搴斿榪欑鎯呭喌銆傚洜涓烘垜浠彧鎺ュ彈鐩存帴宸﹂掑綊錛屾墍浠ョ被浼艱繖縐嶇粨鏋勭殑epsilon璺緞鍙互鐩存帴鐨勬姏寮冧粬錛屽洜涓簍0->t0浼氳t0鐘舵佸崟鐙鐞嗘帀銆傚洜姝よ繖鏍峰仛騫朵笉浼氭紡鎺変粈涔堛?/p>
緇嗗績鐨勬湅鍙嬪彲鑳戒細鍙戠幇錛岃繖涓粨鏋勭殑鍥炬槸涓嶈兘鐩存帴澶勭悊鍙抽掑綊鐨勶紙鎬諱箣宸﹂掑綊鍜屽彸閫掑綊鎬昏鏈変竴涓細璁╀綘鐨勭姸鎬佹満鍌婚煎氨鏄簡錛侊級銆傚叧浜庡浣曞鐞嗘湁閫掑綊錛堝叾瀹炲唴瀹逛篃涓嶅鏉傦級鍦版柟娉曚細鍦?#8220;涓嬬瘒”鎻忚堪鍑烘潵銆傞偅澶勭悊宸﹂掑綊鏈変粈涔堢敤鍛紵涓句釜渚嬪瓙錛屾垜浠殑e0->e2灝辨槸涓涓乏閫掑綊錛岃屼粬浼氬湪涔嬪墠鐨勬楠よ澶勭悊鎴恠hift(e0->e0)鍜宺educe(e1->e2)銆傛垜浠璁頒笅shift鍜宺educe鐨勫搴斿叧緋伙紝閭d箞褰撴垜浠壘鍒頒竴涓乏閫掑綊鐨剆hift涔嬪悗錛屾垜浠氨鍙互鎶婂搴旂殑reduce緇欐爣璁版垚“left-recursive-reduce”銆傝繖鏄竴涓湪鏋勯犺娉曟爲鐨勬椂鍊欙紝闈炲父鍏抽敭鐨勪竴縐嶆瀯閫犳寚浠ゃ?/p>
澶勭悊瀹岃繖浜涗箣鍚庯紝鎴戜滑鍙互鎶婂乏閫掑綊鐨剆hift杈瑰叏閮ㄥ垹鎺夛紝鏈鍚庢妸token鍜宻tate閮界粺緇熷鐞嗘垚榪炵畫鐨勬暟瀛楋紝鍋氭垚涓寮燵state, token] –> [transitions]鐨勪簩緇磋〃錛屾瘡涓涓〃鐨勫厓绱犳槸transition鐨勫垪琛ㄣ備負浠涔堟槸榪欐牱鍛紵鍥犱負鎴戜滑瀵逛竴涓猻tate杈撳叆涓涓猼oken涔嬪悗錛岀敱浜庝繚瀛樼潃state鐨勫爢鏍堬紙浣犺繕璁板緱鍚楋紵shift==push錛宺educe==pop錛夌殑鏍堥《鑻ュ共涓厓绱犵殑涓嶅悓錛屽彲鑳戒細璧頒笉閫氱殑璺嚎銆備簬鏄渶鍚庢垜浠氨寰楀埌浜嗚繖涔堜竴寮犲浘銆?/p>
涓嬮潰榪欏紶鍥懼彲浠ラ氳繃榪愯gac.codeplex.com涓婇潰鐨凜ommon\UnitTest\UnitTest.sln錛圴S2012闄愬畾錛変箣鍚庯紝鍦–ommon\UnitTest\TestFiles\Parsing.Calculator.Table.txt閲岄潰鎵懼埌銆傝繖涓緇勬枃浠墮兘鏄垜鍦ㄦ祴璇曠姸鎬佹満鐨勬椂鍊檒og涓嬫潵鐨勩?/p>
濡傛灉澶у鏈塚S2012鐨勮瘽錛岄氳繃榪愯鎴戝噯澶囩殑鍑犱釜杈撳叆錛岃濡傝“1*2+3*4”錛屽氨鍙互鍦≒arsing.Calculator.[2].txt閲岄潰鎵懼埌鎵鏈夌姸鎬佽煩杞殑杞ㄨ抗銆傚洜涓烘垜浠繪槸闇瑕乸arse涓涓狤xp錛屾墍浠ユ垜浠粠22: Exp.RootStart寮濮嬨傛垜浠亣璁総oken stream鐨勭涓涓拰鏈鍚庝竴涓垎鍒槸$TokenBegin鍜?TokenFinish銆備笂鍥劇殑$TryReduce鏄負浜嗗簲瀵瑰彸閫掑綊鑰岃璁″嚭鏉ョ殑涓縐嶇壒孌婅緭鍏ャ傜敱浜庡洓鍒欒繍綆楅噷闈㈠茍娌℃湁鍙抽掑綊錛屾墍浠ヨ繖涓鍒楀氨鏄┖鐨勶細
StartState: 22[Exp.RootStart]
$TokenBegin => 23[Exp.Start]
State Stack:
NUMBER[1] => 2[Number.1]
State Stack: 23[Exp.Start], 21[Term.Start], 19[Factor.Start]
Shift 23[Exp]
Shift 21[Term]
Shift 19[Factor]
Assign value
Create NumberExpression
MUL[*] => 5[Term.3]
State Stack: 23[Exp.Start]
Reduce 19[Factor]
Using
Reduce 21[Term]
Using
LR-Reduce 21[Term]
Assign firstOperand
Setter binaryOperator = Mul
Create BinaryExpression
NUMBER[2] => 2[Number.1]
State Stack: 23[Exp.Start], 5[Term.3], 19[Factor.Start]
Shift 5[Term]
Shift 19[Factor]
Assign value
Create NumberExpression
ADD[+] => 10[Exp.3]
State Stack:
Reduce 19[Factor]
Using
Reduce 5[Term]
Assign secondOperand
Reduce 23[Exp]
Using
LR-Reduce 23[Exp]
Assign firstOperand
Setter binaryOperator = Add
Create BinaryExpression
NUMBER[3] => 2[Number.1]
State Stack: 10[Exp.3], 21[Term.Start], 19[Factor.Start]
Shift 10[Exp]
Shift 21[Term]
Shift 19[Factor]
Assign value
Create NumberExpression
MUL[*] => 5[Term.3]
State Stack: 10[Exp.3]
Reduce 19[Factor]
Using
Reduce 21[Term]
Using
LR-Reduce 21[Term]
Assign firstOperand
Setter binaryOperator = Mul
Create BinaryExpression
NUMBER[4] => 2[Number.1]
State Stack: 10[Exp.3], 5[Term.3], 19[Factor.Start]
Shift 5[Term]
Shift 19[Factor]
Assign value
Create NumberExpression
$TokenFinish => 11[Exp.RootEnd]
State Stack:
Reduce 19[Factor]
Using
Reduce 5[Term]
Assign secondOperand
Reduce 10[Exp]
Assign secondOperand
鎴戜滑鎶婃墍鏈夎煩杞繃鐨則ransition鐨勪俊鎭兘璁板綍涓嬫潵錛屽氨鍙互鏋勯犺娉曡嫃浜嗐傛垜浠兂璞′竴涓嬶紝鍦ㄦ墽琛岃繖浜涙寚浠ょ殑鏃跺欙紝閬囧埌NUMBER[4]灝辯瓑浜庤幏寰椾簡涓涓唴瀹逛負4鐨則oken錛宻hift鐨勮瘽灝辨槸寰鍫嗘爤閲岄潰push榪涗竴涓姸鎬佺殑鍚嶅瓧錛岃宺educe鍒欐槸寮瑰嚭銆?/p>
鐩稿搴旂殑錛屽洜涓烘瘡涓涓枃娉曢兘浼氬垱寤轟竴涓璞★紝鎵浠ユ垜浠湪鍒濆鍖栫殑鏃跺欙紝瑕佸厛鏀句竴涓┖瀵硅薄鍦ㄥ爢鏍堜笂銆俿hift涓嬈″氨鍐嶅垱寤轟竴涓┖鐨勫璞ush榪涘幓錛宺educe鐨勬椂鍊欏氨鎶婃爤欏剁殑瀵硅薄寮瑰嚭鏉ヤ綔涓?#8220;寰呭鐞嗗璞?#8221;錛寀sing浜嗗氨鎶婂緟澶勭悊瀵硅薄鍜屾爤欏跺璞″悎騫訛紝left-reduce灝辨槸鎶婃爤欏跺璞″脊鍑烘潵浣滀負寰呭鐞嗗璞$殑鍚屾椂錛宲ush涓涓┖瀵硅薄榪涘幓銆俛ssign fieldName灝辨槸鎶?#8220;寰呭鐞嗗璞?#8221;淇濆瓨鍒版爤欏跺璞$殑鍙仛fieldName鐨勬垚鍛樺彉閲忛噷闈㈠幓銆傚鏋滄爤欏跺璞′負絀猴紝閭d箞琚繚瀛樼殑瀵硅薄灝辨槸鍒氬垰杈撳叆鐨勯偅涓猼oken浜嗐傚洜姝ゆ垜浠粠澶村埌灝炬墽琛屼竴閬嶄箣鍚庯紝灝卞彲浠ュ緱鍒頒笅闈㈢殑涓棰楄娉曟爲錛?/p>
BinaryExpression {
binaryOperator = [Add]
firstOperand = BinaryExpression {
binaryOperator = [Mul]
firstOperand = NumberExpression {
value = [1]
}
secondOperand = NumberExpression {
value = [2]
}
}
secondOperand = BinaryExpression {
binaryOperator = [Mul]
firstOperand = NumberExpression {
value = [3]
}
secondOperand = NumberExpression {
value = [4]
}
}
}
鍩烘湰涓妏arsing鐨勮繃紼嬪氨緇撴潫浜嗐傚湪“涓嬬瘒”——涔熷氨鏄紙鍏級——閲岄潰錛屾垜浼氳榪板浣曞鐞嗗彸閫掑綊錛岀劧鍚庤繖涓郴鍒楀熀鏈笂灝辮瀹岀粨浜嗐?/p>
灝卞儚銆?a href="http://www.shnenglu.com/vczh/archive/2008/05/22/50763.html" target="_blank">鏋勯犳鍒欒〃杈懼紡寮曟搸銆嬩竴鑸粰鐘舵佹満娣誨姞淇℃伅鐨勬柟娉曪紝灝辨槸鎶婁竴浜涢檮鍔犵殑鏁版嵁鍔犲埌鐘舵佷笌鐘舵佷箣闂寸殑璺寵漿綆ご閲岄潰鍘匯備負浜嗗艦璞$殑琛ㄨ揪榪欎釜浜嬫儏錛屾垜灝辨嬁絎竴綃囨枃绔犵殑鍥涘垯榪愮畻寮忓瓙鏉ヤ婦渚嬨傚湪榪欓噷鎴戜負浜嗗ぇ瀹舵柟渚匡紝閲嶅涓涓嬭繖涓枃娉曠殑鍐呭錛堥櫎鍘諱簡璇爲涔﹀0鏄庯級錛?/p>
token NAME = "[a-zA-Z_]/w*"; token NUMBER = "/d+(./d+)"; token ADD = "/+"; token SUB = "-"; token MUL = "/*"; token DIV = "//"; token LEFT = "/("; token RIGHT = "/)"; token COMMA = ","; rule NumberExpression Number = NUMBER : value; rule FunctionExpression Call = NAME : functionName "(" [ Exp : arguments { "," Exp : arguments } ] ")"; rule Expression Factor = !Number | !Call; rule Expression Term = !Factor; = Term : firstOperand "*" Factor : secondOperand as BinaryExpression with { binaryOperator = "Mul" }; = Term : firstOperand "/" Factor : secondOperand as BinaryExpression with { binaryOperator = "Div" }; rule Expression Exp = !Term; = Exp : firstOperand "+" Term : secondOperand as BinaryExpression with { binaryOperator = "Add" }; = Exp : firstOperand "-" Term : secondOperand as BinaryExpression with { binaryOperator = "Sub" };
閭d箞鎴戜滑鎶婅繖涓枃鍙戣漿鎴愮姸鎬佹満涔嬪悗錛岃緇欒煩杞姞涓婁粈涔堝憿錛熶粠鐩磋涓婃潵璇達紝璺寵漿鐨勬椂鍊欐垜浠細鏈夊叚縐嶈騫茬殑浜嬫儏錛?br />1銆丆reate錛氳繖涓枃娉曞垱寤虹殑璇硶鏍戣妭鐐規槸鏌愪釜綾誨瀷鐨勶紙鍖哄埆浜庡湪榪欎竴鍒葷粰榪欎釜闂硶鍒涘緩涓涓繑鍥炰粈涔堢被鍨嬬殑璇硶鏍戣妭鐐癸級
2銆丼et錛氱粰鍒涘緩鐨勮娉曟爲鑺傜偣鐨勬煇涓垚鍛樺彉閲忚緗竴涓寚瀹氱殑鍊?br />3銆丄ssign錛氱粰鍒涘緩鐨勮娉曟爲鑺傜偣鐨勬煇涓垚鍛樺彉閲忚緗繖涓嬈¤煩杞殑絎﹀彿浜х敓鐨勮娉曟爲鑺傜偣錛堣濡傝Exp = Exp: firstOperand “+” Term: secondOperand錛岃蛋Term鐨勬椂鍊欙紝涓涓娉曟爲鑺傜偣灝變細琚玜ssign緇欓偅涓彨鍋歴econdOperand鐨勬垚鍛樺彉閲忥級
4銆乁sing錛氫嬌鐢ㄨ繖涓嬈¤煩杞殑絎﹀彿浜х敓鐨勮娉曟爲鑺傜偣鏉ュ仛榪欐鏂囨硶鐨勮繑鍥炲鹼紙璀璇碏actor = !Number | !Caller榪欎竴鏉★級
5銆丼hift錛氱暐
6銆丷educe錛氱暐
鍦ㄨ繖閲屾垜浠茍娌℃湁鏍囪鏁翠釜鏂囨硶浠庡摢涓涓潪緇堢粨絎﹀紑濮嬶紝鍥犱負鍦ㄥ疄闄呰繃紼嬩腑錛屽叾瀹炲垎鏋愬笀鍙互浠庝換浣曚竴涓枃娉曞紑濮嬬殑銆傝濡傝鍐橧DE鐨勬椂鍊欙紝鎴戜滑鍙兘鍦ㄦ煇浜涙儏鍐典笅浠呬粎鍙渶瑕佸垎鏋愪竴涓〃杈懼紡銆傛墍浠ヨ冭檻鍒版瘡涓涓潪緇堢粨絎﹂兘鏈夊彲鑳借鐢ㄥ埌錛屽洜姝ゆ垜浠殑“Token嫻佸紑濮?#8221;鍜?#8220;Token嫻佺粨鏉?#8221;灝變細鍦ㄦ瘡涓涓潪緇堢粨絎︾殑鐘舵佹満涓兘鍑虹幇銆傚洜姝ゅ湪絎竴姝ュ垱寤篍psilon PDA錛堜笅鎺ㄨ嚜鍔ㄦ満錛夌殑鏃跺欙紝灝卞彲浠ュ厛鐩存帴鐢熸垚銆傚湪榪欓噷鎴戜滑鎷縀xp鍋氫緥瀛愶細
鍙岃櫄綰夸唬琛ㄧ殑鏄疶oken嫻佸拰Token嫻佺粨鏉燂紝榪欏茍涓嶆槸鎴戜滑鐜板湪鍏沖績鐨勪簨鎯呫傚湪鍓╀笅鐨勮漿鎹腑錛屽疄鐜版槸鍏鋒湁杈撳叆鐨勮漿鎹紝鑰岃櫄綰垮垯鏄病鏈夎緭鍏ョ殑杞崲錛堜竴鑸О涓篹psilon杈癸級銆?/p>
鍦ㄨ繖閲屾垜浠鏄庣‘涓涓蹇?#8212;—鍒嗘瀽璺緞銆傚垎鏋愯礬寰勪唬琛ㄧ殑鏄痶oken鍦?#8220;嫻?#8221;榪囩姸鎬佹満鐨勬椂鍊欙紝鐘舵佹槸濡備綍璺寵漿鐨勩傚洜姝ゅ浜庡疄闄呯殑鍒嗘瀽榪囩▼錛屽垎鏋愯礬寰勫叾瀹炲氨鏄垎鏋愭爲鐨勪竴縐嶈〃杈懼艦寮忋傝屽湪鐘舵佹満閲岄潰錛屽垎鏋愯礬寰勫垯浠h〃涓鏉′粠寮濮嬪埌緇撳熬鐨勫彲鑳界殑璺緞銆傝濡傝鍦ㄨ繖閲岋紝鍒嗘瀽璺緞鍙互鏈変笁鏉★細
$e –> e1 –> e2 –> e$
$e –> e3 –> e8 –> e7 –> e6 –> e5 –> e4 –> e$
$e –> e9 –> e14 –> e13 –> e12 –> e11 –> e10 –> e$
鍥犳鎴戜滑鍙互娓呮錛屼竴鏉¤礬寰勪笂鏄笉鑳藉嚭鐜板涓猚reate鐨勶紝鍚﹀垯浣犲氨涓嶇煡閬撳簲璇ュ垱寤虹殑鏄粈涔堜簡銆傚綋鐒禼reate鍜寀sing閮戒笉鑳藉悓鏃跺嚭鐜幫紝using涔熶笉鑳芥湁澶氫釜銆傝屼笖鐢變簬create鍜宻et閮芥槸鍦ㄦ弿榪拌繖涓潪緇堢粨絎︼紙鍦ㄨ繖閲屾槸Exp錛夋墍鍒涘緩鐨勮娉曟爲鑺傜偣鐨勭被鍨嬪拰灞炴э紝璺熸墽琛屼粬浠殑鏃舵満鏃犲叧錛屾墍浠ュ叾瀹炲湪鍚屼竴鏉″垎鏋愯礬寰勯噷闈紝create鍜宻et鏀懼湪鍝噷閮芥病鍏崇郴銆傚氨璀璇村湪涓婇潰鐨勭浜屾潯鍒嗘瀽璺緞閲岄潰錛宑reate鏄湪e6->e5閲岄潰鏍囪鍑烘潵鐨勩傚氨綆椾粬縐誨姩鍒頒簡e3->e8錛屽仛鐨勪簨鎯呬篃涓鏍楓傚弽姝e彧瑕佷竴鏉¤礬寰勪笂鏍囪浜哻reate錛岄偅涔堜粬鍦ㄨ繖鏉¤礬寰勮紜畾涔嬪悗錛屽氨涓瀹氫細create鎵鎸囧畾鐨勫叿浣撶被鍨嬬殑璇硶鏍戣妭鐐廣傝繖鏄浉褰撻噸瑕佺殑錛屽洜涓哄湪鍚庨潰鐨勫垎鏋愪腑錛屾垜浠緢鍙兘闇瑕佺Щ鍔╟reate鍜宻et鐨勫叿浣撲綅緗?/p>
璺熶笂涓綃囨枃绔犺鐨勪竴鏍鳳紝鎺ヤ笅鏉ョ殑涓姝ュ氨鏄幓闄psilon杈逛簡銆傜粨鏋滃涓嬶細
闈㈠榪欑鐘舵佹満錛屽幓闄psilon杈瑰氨涓嶈兘璺熷鐞嗘鍒欒〃杈懼紡涓鏍風畝鍗曠殑鍘婚櫎浜嗐傞鍏堬紝鎵鏈夌殑緇堢粨鐘舵?#8212;—涔熷氨鏄墍鏈夌粡榪囨垨鑰呬笉緇忚繃epsilon杈逛箣鍚庯紝閫氳繃“Token嫻佺粨鏉?#8221;絎﹀彿榪炴帴鍒版渶鍚庝竴涓姸鎬佺殑鐘舵侊紝鍦ㄨ繖閲屽垎鍒槸e2銆乪6鍜宔12——閮芥槸涓嶈兘鍒犳帀鐨勩傝屼笖鎵鏈夌殑“Token嫻佸紑濮?#8221;鍜?#8220;Token嫻佺粨鏉?#8221;——涔熷氨鏄浘閲岄潰鐨?杞崲——鏄笉鑳藉甫鏈変俊鎭殑銆傛墍浠ユ垜浠氨浼氱湅鍒癳6鍚庨潰鐨勪俊鎭叏閮ㄨ縐誨姩鍒頒簡e7->e6榪欐潯杈逛笂闈€傜敱浜巆reate鍜宻et鐨勬祦鍔ㄦэ紝鎴戜滑榪欎箞鍋氬浜庣姸鎬佹満鐨勫畾涔夊畬鍏ㄦ病鏈夊獎鍝嶃?/p>
鍒頒簡榪欓噷榪樻病瀹岋紝鍥犱負榪欎釜鐘舵佹満榪樻槸鏈夊緢澶氬啑浣欑殑鐘舵佺殑銆傝濡傝e8鍜宔14銆乪7鍜宔13銆乪2鍜宔6鍜宔12瀹為檯涓婃槸鍙互鍚堝茍鐨勩傚悎騫剁殑絳栫暐鍏跺疄鍗佸垎綆鍗曪細
1銆佸鏋滄垜浠湁璺寵漿e0->e1鍜宔0->e2錛屽茍涓斾袱涓煩杞墍鎼哄甫鐨則oken杈撳叆鍜屼俊鎭畬鍏ㄤ竴鑷寸殑璇濓紝閭d箞e1鍜宔2灝卞彲浠ュ悎騫躲?br />2銆佸鏋滄垜浠湁璺寵漿e1->e0鍜宔2->e0錛屽茍涓斾袱涓煩杞墍鎼哄甫鐨則oken杈撳叆鍜屼俊鎭畬鍏ㄤ竴鑷寸殑璇濓紝閭d箞e1鍜宔2灝卞彲浠ュ悎騫躲?/p>
鎵浠ュ浜巈8鍜宔14鎴戜滑鏄畬鍏ㄥ彲浠ュ悎騫剁殑銆傞偅涔坋7鍜宔13鎬庝箞鍔炲憿錛熸牴鎹甤reate鍜宻et鐨勬祦鍔ㄦэ紝鎴戜滑鍙鎶婅繖涓や釜涓滆タ鎸埌浠栫殑鍓嶉潰涓涓垨鑰呰嫢騫蹭釜璺寵漿鍘伙紝閭h繖涓や釜鐘舵佸氨鍙互鍚堝茍浜嗐備負浜嗚綆楁硶鏇村姞鐨勭畝鍗曪紝鎴戜滑閬囧埌涓や釜璺寵漿綾諱技鐨勬椂鍊欙紝鎬繪槸鍏堟尓鍔╟reate鍜宻et錛岀劧鍚庡啀鐪嬬湅鏄笉鏄湡鐨勫彲浠ュ悎騫躲傛墍浠ヨ繖涓姝ュ鐞嗗畬涔嬪悗灝變細鍙樻垚涓嬮潰榪欎釜鏍峰瓙錛?/p>
鎴戜滑鍦ㄤ笉鏀瑰彉鐘舵佹満璇箟鐨勬儏鍐典笅錛屾妸Exp鐨勪笁涓姸鎬佹満鏈緇堝帇緙╂垚浜嗚繖涓牱瀛愩傜湅榪囦笂涓綃囨枃绔犵殑鍚屽浠兘鐭ラ亾錛屼笅涓姝ュ氨鏄鎶婃墍鏈夌殑鐘舵佹満緇熺粺閮借繛鎺ヨ搗鏉ヤ簡銆傚叧浜庡湪榪炴帴鐨勬椂鍊欏浣曞叿浣撴搷浣滆漿鎹㈤檮甯︾殑淇℃伅銆佷互鍙婂仛鍑轟竴涓‘瀹氭х殑涓嬫帹鐘舵佹満鐨勬墍鏈変簨鎯呭皢鍦ㄤ笅涓綃囨枃绔犺緇嗚В閲娿傚ぇ瀹舵暚璇鋒湡寰呫?/p>
鏁呬簨灝變粠鐘舵佹満寮濮嬨傛枃娉曟垜灝變笉閲嶅浜嗭紝瑙佷笂涓綃囨枃绔犮傜幇鍦ㄦ垜浠粠鐘舵佹満寮濮嬨傜涓涓姸鎬佹満鏄洿鎺ヤ粠鏂囨硶鍙樿繃鏉ョ殑錛?/p>
鐒跺悗鎴戜滑鎶婃墍鏈夌殑闈炵粓緇撶璺寵漿閮介氳繃Shift鍜孯educe榪炴帴鍒拌闈炵粓緇撶鎵浠h〃鐨勭姸鎬佹満鐨勭姸鎬佷笂闈紝灝變細鍙樻垚涓嬮潰鐨勫浘銆傚叿浣撶殑鍋氭硶鏄紝瀵逛簬姣忎竴鏉¢潪緇堢粨絎︾殑璺寵漿錛岃濡傝S0 –> Symbol –> S1銆傞鍏堟姽鎺夎繖鏉¤煩杞傜劧鍚庡鍔犱袱鏉¤竟錛屽垎鍒槸S0鍒癝ymbol鐨勮搗濮嬭妭鐐癸紝鎿嶄綔鏄疭hift<S0>銆傝繕鏈変粠Symbol鐨勭粓緇撹妭鐐瑰埌S0錛屾搷浣滄槸Pop<S0> Reduce銆係hift<S>絳変簬鎶婄姸鎬丼緇檖ush鍒板爢鏍堥噷錛岀劧鍚嶱op<S>絳変簬鍦ㄧ姸鎬侀噷闈㈠脊鍑哄唴瀹規槸S鐨勬爤欏跺厓绱犮傚鏋滃け璐ヤ簡鎬庝箞鍔炲憿錛熼偅灝變笉鑳界敤榪欐潯璺寵漿銆傝窡涓婂浘涓鏍鳳紝鎵鏈夎緭鍏?璺寵漿鍒癋inish鐨勮竟錛屾搷浣滈兘鏄Pop<Null>鐨勩傚湪鍒氬紑濮嬪垎鏋愮殑鏃跺欙紝鍫嗘爤鏈変竴涓狽ull鍊鹼紝鐢ㄦ潵浠h〃“璇硶鍒嗘瀽浠庤繖閲屽紑濮?#8221;銆?/p>
榪欎釜鍥劇殑綺楄櫄杈逛唬琛ㄦ墍鏈夎窡宸﹂掑綊鏈夊叧鐨勮煩杞傝繖浜涜竟鏄垚瀵圭殑錛屽垎鍒槸宸﹂掑綊璺寵漿鐨凷hift鍜孯educe銆傚鏋滀笉鏄負浜嗗疄鐜伴珮鎬ц兘鐨勮娉曞垎鏋愮殑璇濓紝鍏跺疄榪欎釜鐘舵佹満宸茬粡瓚沖浜嗐傝繖涓浘璺熻娉曞垎鏋愮殑“鐘舵佽煩杞建榪?#8221;鏈夊緢澶х殑鍏崇郴銆傝櫧鐒禝DList0浣犱笉鐭ラ亾絎竴姝ヨ璺寵漿鍒癐DList0榪樻槸ID0錛屼笉榪囨病鍏崇郴錛岀幇鍦ㄦ垜浠厛鍋囪鎴戜滑鍙互閫氳繃鏌愮紲炵鐨勬柟娉曟潵棰勬祴鍒般傞偅涔堬紝褰撹緭鍏ユ槸A,B,C$鐨勬椂鍊欙紝鐘舵佽煩杞建榪瑰氨浼氭槸濡備笅鐨勬牱瀛愶細
涓轟粈涔堣榪欎箞鍋氬憿錛熸垜浠妸榪欏箙鍥炬兂璞℃垚涓?br>1錛氭兂鍋氱殑綆ご琛ㄧずpush涓涓姸鎬?br>2錛氬悜涓嬬殑綆ご琛ㄧず淇敼褰撳墠鐘舵?br>3錛氬悜鍙崇殑鐘舵佽〃紺簆op涓涓姸鎬佸茍淇敼褰撳墠鐘舵?/p>
鍥犳褰撹緭鍏ュ埌B鐨勬椂鍊欙紝鍒拌揪ID1錛屽茍璺寵漿鍒癐DList1銆傝繖涓椂鍊橧DList1銆愬乏杈廣戠殑鎵鏈夈愯繕鐣欏湪鍫嗘爤閲屻戠殑鐘舵佹椂Null鍜孖DList0錛屽綋鍓嶇姸鎬両DList1錛岃緭鍏ュ墿涓?C$銆傝繖涓浘鐗瑰埆鐨勬湁鐢ㄣ傚綋鎴戜滑鍒嗘瀽瀹屽茍涓旀妸鏋勯犺娉曟爲鐨勬寚浠ら檮鐫鍦ㄨ繖浜涚澶翠笂闈箣鍚庯紝鎸夐『搴忔墽琛岃繖浜涙寚浠ゅ氨鍙互鏋勯犲嚭涓棰楀畬鏁寸殑璇硶鏍戜簡銆?/p>
浣嗘槸鍦ㄥ疄闄呮搷浣滈噷闈紝鎴戜滑騫舵病鏈夊姙娉曢嫻?#8220;榪欓噷瑕佸乏閫掑綊涓ゆ”錛屼篃娌″姙娉曞湪澶氭reduce鐨勬椂鍊欓夋嫨絀剁珶瑕佷粠鍝噷璺沖埌鍝噷銆傛墍浠ュ疄闄呬笂鎴戜滑瑕佸涔犱粠EpsilonNFA鍒癉FA鐨勯偅涓綆楄繃紼嬶紝鎶奡hift鍜孯educe褰撴垚Epsilon錛屾妸鍚冩帀涓涓猼oken褰撴垚闈濫psilon杈癸紝鐒跺悗鎵ц鎴戜箣鍓嶅啓鐨勩?a href="http://www.shnenglu.com/vczh/archive/2008/05/22/50763.html" target="_blank">鏋勯犲彲閰嶇疆璇嶆硶鍒嗘瀽鍣?/a>銆嬩竴鏂囦腑鐨勯偅涓幓Epsilon杈圭畻娉曪紙濡備綍浠嶯ondeterministic鍒癉eterministic錛屼互鍙婄浉鍏崇殑Look Ahead錛屾槸涓嬩竴綃囨枃绔犵殑鍐呭錛夛紝鐒跺悗灝卞彲浠ユ妸鐘舵佹満鍙樻垚榪欐牱錛?/p>
涓婇潰綺椾綋鐨凱op<IDList0>琛ㄧず錛岃繖涓涓狿op鏄搴斾簬閭d釜宸﹂掑綊Shifting鎿嶄綔鐨勩傚疄闄呬笂榪欐槸鍋氫簡涓涓庢牱鐨勫彉鍖栧憿錛熶粠“鐗╃悊瑙i噴”涓婃潵璁詫紝鍏跺疄鏄妸“鐘舵佽煩杞建榪?#8221;閲岄潰閭d簺闄や簡宸﹂掑綊shifting涔嬪鐨勬墍鏈変笉鍚冩帀token鐨勮竟閮藉幓鎺変簡錛?/p>
鍦ㄨ繖閲屾垜浠彲浠ョ湅鍒幫紝涓轟粈涔堝綋鍫嗘爤鏄疘DList0, IDList0鍜孖DList0, IDList3鐨勬椂鍊欙紝浠嶪D0閮藉彲浠ラ氳繃鍚冩帀涓涓?#8221;,”浠庤岃煩杞埌IDList3銆傚湪涓婇潰榪欏紶“鐘舵佽煩杞建榪?#8221;閲岄潰錛岃繖涓や釜浜嬫儏閮藉彂鐢熶簡錛屽垎鍒槸絎竴鏉″悜宸︾殑綆ご鍜岀浜屾潯鍚戝乏鐨勬柟鍚戙傝屼笖榪欎袱鏉¤竟鍒氬ソ瀵瑰簲浜庝笂鍥懼甫鏈夎摑鑹茬矖浣撴枃瀛楃殑璺寵漿錛屽睘浜庡乏閫掑綊Reducing鎿嶄綔銆?/p>
鎵浠ワ紝鍏跺疄鍦ㄨ繖涓椂鍊欙紝鎴戜滑鍚屾椂瑙e喅浜?#8220;搴旇鍦ㄤ粈涔堟椂鍊欒繘琛屽乏閫掑綊Shifting”鐨勯棶棰樸傚彧瑕佸綋宸﹂掑綊Reducing宸插彂鐢燂紝鎴戜滑绔嬪埢鍦ㄨ建榪逛笂闈㈣ˉ涓婁竴鏉″乏閫掑綊Shifting灝卞ソ浜嗐傚洜姝わ紝鎴戜滑鍦ㄤ竴寮濮嬪仛parsing鐨勬椂鍊欙紝鏍規湰涓嶉渶瑕侀鍏堝仛宸﹂掑綊Shifting銆傛墍浠ュ綋鍒氬垰杈撳叆A鐨勬椂鍊欙紝“鐘舵佽煩杞建榪?#8221;鏄繖鏍峰瓙鐨勶細
鐒跺悗閬囧埌涓涓?#8221;,”錛屽彂鐜頒箣鍓?#8220;鍋氭紡”浜嗕竴涓乏閫掑綊Shifting錛屽洜姝ゅ氨鍙樻垚涓嬮潰榪欎釜鏍峰瓙錛?/p>
榪欎篃灝辨槸涓婁竴綃囨枃绔犻偅涓狥ake-Shift鎵鍋氱殑浜嬫儏浜嗐?/p>
錛堝瀛︽湳鎰熷叴瓚g殑浜哄彲浠ュ幓wiki涓涓?#8220;涓嬫帹鑷姩鏈?#8221;錛?/p>
涓嬫帹鑷姩鏈哄拰鏈夐檺鑷姩鏈虹殑鍖哄埆鏄紝涓嬫帹鑷姩鏈烘墿灞曟垚鏅氱殑鑷姩鏈虹殑鏃跺欙紝浠栫殑鐘舵佺殑鏁扮洰鏄棤闄愮殑錛堝簾璇濓級銆備絾鏄棤闄愮殑涓滆タ鏄病鍔炴硶鐢ㄧ紪紼嬫潵琛ㄨ揪鐨勶紝閭f庝箞鍔炲憿錛熼偅灝卞姞鍏ヤ竴涓笉瀹氶暱搴︾殑“鐘舵佹弿榪?#8221;銆備笅闈㈡垜涓句竴涓畝鍗曠殑鏂囨硶錛?/p>
ID = NAME
IDList = ID | IDList “,” ID
榪欐牱灝辨瀯鎴愪簡涓涓畝鍗曠殑鏂囨硶錛岀敤鏉ュ垎鏋愬甫閫楀彿鍒嗗壊鐨勫悕瀛楀垪琛ㄧ殑銆傞偅涔堝啓鎴愮姸鎬佹満灝辨槸濡備笅鐨勫艦寮忥細
ID0 = 鈼?NAME
ID1 = NAME 鈼?br>IDList0 = 鈼?(ID | IDList “," ID)
IDList1 = (ID | IDList “,” ID) 鈼?br>IDList2 = (ID | IDList 鈼?“,” ID)
IDList3 = (ID | IDList “,” 鈼?ID)
ID0 –> NAME –> ID1
IDList0 –> ID –> IDList1
IDList0 –> IDList –> IDList2
IDList2 –> “,” –> IDList3
IDList3 –> ID –> IDList1
鍙互寰堝鏄撶殑鐪嬪嚭錛孖D0鍜孖DList0鏄枃娉曠殑璧峰鐘舵侊紝鑰孖D1鍜孖DList1鏄枃娉曠殑緇堢粨鐘舵侊紝鐢繪垚鍥懼涓嬶細
錛圥owerPoint鐢誨浘澶嶅埗鍒癓iveWriter閲岄潰鏄竴騫呭浘闈㈢畝鐩村お鏂逛究浜嗭級
浣嗘槸榪欐牱榪樻病瀹屻侷DList0璺沖埌IDList2鐨勬椂鍊欑殑杈撳叆“IDList”鍏跺疄榪樹笉澶燂紝鍥犱負鐢ㄤ綔杈撳叆鐨則oken鍏跺疄鍙湁NAME鍜?,"涓ょ銆備笅涓姝ュ嵆灝嗘紨紺哄浣曚粠榪欎釜鐘舵佹満緙栫▼鍚嶅壇鍏跺疄鐨勪笅鎺ㄧ姸鎬佹満銆?/p>
鍦ㄨ繖閲屾垜鍏堜粙緇嶅嚑涓蹇點傜涓涓槸縐昏繘錛岀浜屼釜鏄綰︺備負浠涔堣鐢ㄨ繖涓や釜鍚嶅瓧鍛紵鍥犱負澶ч儴鍒嗕漢鐪嬬殑鍌婚兼竻鍗庡ぇ瀛﹀嚭鐗堢ぞ鐨勪綆鑳界紪璇戝師鐞嗚鏈兘鏄繖涔堣鐨勶紝榛戝寲鍒嗗埆鍙玈hift鍜孯educe銆傚ソ浜嗭紝浠涔堟槸Shift鍛紵IDList0璺沖埌IDList2鐨勬椂鍊欙紝瑕佺Щ榪汭DList銆侷DList3璺沖埌IDList1錛岃縐昏繘鍒癐D銆侷DList0璺沖埌IDList1涔熻縐昏繘鍒癐D銆傝繖涔熷氨鏄錛?strong>鐘舵佽漿縐葷粡榪囦竴鏉¢潪緇堢粨絎︾殑杈圭殑鏃跺欎細縐昏繘鍒板彟涓鏉℃枃娉曠殑鐘舵佹満閲?/strong>銆侷D1鍜孖DList1浣滀負ID鍜孖DList鐨勭粓緇撹妭鐐癸紝瑕佹牴鎹?#8220;浠庨偅閲岀Щ榪涙潵鐨?#8221;鍒嗗埆瑙勭害鐒跺悗璺寵漿鍒?#8220;IDList2鎴栬匢DList1”銆傝繖涔熷氨鏄錛?strong>涓鏃︿綘鍒拌揪浜嗕竴鏉¢椈娉曠殑鐘舵佹満鐨勭粓緇撶姸鎬侊紝灝辮寮濮嬭綰︾劧鍚庤煩杞埌涓婁竴綰х殑鐘舵佷簡銆?/p>
鏈変漢瑕侀棶錛岄偅鎴戞庝箞鐭ラ亾瑙勭害緇撴潫鐨勬椂鍊欒璺寵漿鍘誨摢閲屽憿錛熻繖涓棶棰橀棶寰楅潪甯稿ソ銆傝鎴戜滑鍥炴兂涓涓嬫垜浠ュ墠鍐欑殑濡備綍鎵嬪啓璇硶鍒嗘瀽鍣?/a>榪欎竴綃囨枃绔犮傞噷闈㈡庝箞璇寸殑錛熷綋浣犳墜鍐欓掑綊涓嬮檷鐨勮娉曞垎鏋愬櫒鐨勬椂鍊欙紝姣忎竴鏉℃枃娉曞叾瀹為兘鏄竴涓嚱鏁般傞偅璋冪敤鍑芥暟鐨勬椂鍊欑▼搴忔庝箞灝辯煡閬撳嚱鏁扮粨鏉熺殑鏃跺欎笅涓鏉℃寚浠ゆ槸浠涔堝憿錛熼偅褰撶劧鏄洜涓虹紪璇戝櫒甯垜浠妸“璋冪敤鍑芥暟鐨勬椂鍊欑殑涓嬩竴鏉℃寚浠ょ殑鍦板潃”緇檖ush榪涗簡璋冪敤鍫嗘爤銆備絾鏄垜浠幇鍦ㄤ笉鎵嬪啓璇硶鍒嗘瀽鍣ㄤ簡錛岃岀敤涓嬫帹鐘舵佹満鏉ュ仛錛岄亾鐞嗕篃鏄竴鏍風殑銆傚湪“縐昏繘”鐨勬椂鍊欙紝鍏堟妸褰撳墠鐨勭姸鎬乸ush榪涘爢鏍堬紝瑙勭害鐨勬椂鍊欙紝灝卞彲浠ョ湅涓涓?#8220;鏍堥《閭e嚑涓姸鎬侀兘鏄粈涔?#8221;錛岄厤鍚堜竴嬈″悜鍓嶆煡鐪嬶紙榪欏氨鏄疞ook Ahead銆侺ALR鐨勯偅涓狶A錛孡ALR(1)灝辨槸鍦↙A鐨勬椂鍊欏伔鐪嬩竴涓猼oken錛夛紝鏉ュ喅瀹氳綰﹀埌鍝噷鍘匯傝嚦浜嶭A鍦ㄨ繖閲岀殑娣卞埢鍐呮兜鎴戝皢涓嬩竴綃囨枃绔犲啀璇淬傚洜涓虹幇鍦ㄦ垜榪樻病鏈夊仛鍒癗ondeterministic鍒癉eterministic鐨勪竴姝ワ紝閲岄潰鏈夊緢澶氶粦縐戞妧錛屾垜鎯抽泦涓璁恒?/p> 閭g幇鍦ㄨ鎴戜滑鎶婁笂闈㈤偅騫呭浘鐨勪袱涓姸鎬佹満榪炶搗鏉ワ紝浜х敓涓涓笅鎺ㄨ嚜鍔ㄦ満銆備絾鏄湪榪欓噷鎴戝厛鍋氱涓姝ャ傚洜涓篒DList0鍒癐DList1鐨勮煩杞槸涓涓乏閫掑綊鐨勮繃紼嬶紝鍏堟殏鏃朵笉綆°?/p> 姍欒壊鐨勮竟閮芥槸涓涓緭鍏ラ潪緇堢粨絎︾殑璺寵漿錛屾墍浠ュ疄闄呬笂鍦ㄤ笅鎺ㄧ姸鎬佹満閲岄潰鏄笉瀛樺湪鐨勩傚湪榪欏紶鍥鵑噷闈㈡垜浠鐞嗕簡涓ゆ潯ID鐨勮竟銆侷DList0浼歴hift錛堝氨鏄湪鍫嗘爤閲岄潰push錛夎嚜宸辯劧鍚庤煩杞埌ID0錛屽洜姝D1鍦ㄦ煡鐪嬪埌鏍堥《鏄疘DList0鐨勬椂鍊欙紝浠栧氨鐭ラ亾璧扮殑鏄疘DList0 –> ID –> IDList1榪欐潯璺紝鍥犳灝眗educe騫惰煩杞埌浜咺DList1銆侷DList3鍚岀悊銆?/p> 浣嗘槸Shift鐨勬椂鍊欏茍娌℃湁浜х敓杈撳叆錛屾墍浠ュ疄闄呬笂搴旇鏀規垚涓嬮潰榪欎釜鏍峰瓙銆?/p> 榪欐牱Shift杈逛篃灝辨湁杈撳叆浜嗐傝屼笖ID0鍒癐D1涔熷簾鎺変簡銆傚疄闄呬笂ID0鑷繁涔熷簲璇ュ簾鎺夈傜幇鍦ㄨ繕鏈変竴涓棶棰樻病瑙e喅錛屽氨鏄乏閫掑綊鍜孯educe涓嶄駭鐢熻緭鍏ョ殑闂銆傝繖涓や釜闂瀹為檯涓婃槸涓璧風殑銆傛垜浠厛鏉ヨ冭檻涓涓嬩負浠涔堣繖閲屾病鍔炴硶鐢ㄧ浉鍚岀殑鍔炴硶鏉ユ妸Reduce澶勭悊鎴愪駭鐢熻緭鍏ョ殑銆傚疄闄呬笂鏄洜涓猴紝浣犲湪榪欎竴涓樁孌佃繕涓嶇煡閬撶┒绔烺educe瑕佽緭鍏ヤ粈涔堟墠鑳借煩杞紝鐗瑰埆鏄痶oken宸茬粡緇撴潫騫朵笖parse鍑轟簡涓涓畬鏁寸殑IDList鐨勬椂鍊欍備互鍓嶄綘浠槸涓嶆槸鍦ㄧ湅銆奝arsing Techniques銆嬪拰銆婇緳涔︺嬮兘瀵逛負浠涔堜竴涓瓧絎︿覆緇撳熬瑕佷駭鐢熶竴涓?瀛楃鎰熷埌寰堝洶鎯戝憿錛熷疄闄呬笂浠栨槸鐗瑰埆鏈夌敤鐨勩傜幇鍦ㄦ垜浠潵緇欎粬鍔犱笂澶у灝辨槑鐧戒簡銆傚湪榪欓噷錛岃繖涓枃娉曠殑鐩爣鏄駭鐢熶竴涓狪DList緇撴瀯錛屾墍浠?褰撶劧涔熻鍔犲湪IDList鐨勭粓緇撶姸鎬佲斺擨DList1涓婏細 鐒跺悗灝辮疆鍒癛educe銆侷D1搴旇鏄疪educe鍒板摢閲屼簡錛熺涓姝ヨ嚜鐒舵槸Reduce鍒癐DList1銆傞偅涔圛DList1鍙堣Reduce鍒板摢閲屽憿錛熸垜浠彲浠ョ湅鍒幫紝鍦↖DList緇撴潫鐨勬椂鍊欙紝瑕佷箞灝辨槸璺沖埌IDList2錛岃涔堝氨鏄煩鍒癋INISH銆備絾鏄疘DList2鏄氳繃宸﹂掑綊浜х敓鐨勶紝鎴戜滑鍏堜笉綆′粬銆傝煩鍒癋INISH闇瑕佷粈涔堟潯浠跺憿錛熺涓涓槸杈撳叆$錛岀浜屼釜鏄疨op瀹岀姸鎬佷箣鍚庡爢鏍堜細涓虹┖銆傛墍浠ヨ繖涓椂鍊欐垜浠彲浠ュ厛淇敼涓涓婭D1鍒癐DList1鐨凴educe杈癸細 鏈鍚庡氨鏄乏閫掑綊浜嗐傚乏閫掑綊鐨勫鐞嗘湁鐐瑰儚hack錛屽洜涓哄疄闄呬笂浣犱笉鑳介鍏堝垽鏂綘瑕佷笉瑕佸乏閫掑綊錛堜篃灝辨槸鐪嬩竴涓媡oken stream鏈夊灝戜釜閫楀彿錛夛紝鐒跺悗鍏坰hift鍑犱釜IDList0榪涘幓錛屽啀鎱㈡參鏉ャ傛墍浠ユ垜浠彧鏈夊湪婊¤凍璺寵漿鍏崇郴鐨勬椂鍊欎復鏃舵彃鍏ヤ竴浜汭DList0銆傞偅涔堣繖涓叧緋繪槸浠涔堝憿錛熷乏閫掑綊鐨処DList緇撴潫鈥斺斾篃灝辨槸浠嶪DList0璺沖埌IDList2鈥斺斾箣鍚庡彧鏈変竴縐嶅彲鑳斤紝灝辨槸杈撳叆","銆傝屼笖鎵鏈夋寚鍚慖DList1鐨勮竟閮芥槸杈撳叆ID錛屾墍浠ヨ繖鏉″乏閫掑綊鐨勭嚎搴旇浠嶪D1錛圛D鐨勭粓緇撶姸鎬侊級榪炲埌IDList2錛屽茍涓斿湪閾炬帴鐨勬椂鍊欒ˉ鍏?#8220;鍋噑hift IDList0”錛?/p> 姍欒壊鐨勪袱涓姸鎬佸垎鍒槸鏁翠釜parsing榪囩▼鐨勮搗濮嬬姸鎬佸拰緇堢粨鐘舵併傝繖涓椂鍊欐垜浠妸鎵鏈夋病鐢ㄧ殑杈瑰拰鐘舵侀兘騫叉帀錛屽氨鍙樻垚浜嗭細 鏄笉鏄寰楃壒鍒翰鍒囧憿錛岃繖涓嶅氨鏄鍒欒〃杈懼紡NAME ( “,” NAME)*鐨勭姸鎬佹満鍚楋紵榪欎篃鏄洜涓鴻繖涓枃娉曞垰濂藉彲浠ヨ〃杈句負涓涓鍒欐枃娉曟墠鏈夎繖鏍風殑緇撴灉錛屽鏋滄垜浠粰浠栧姞鐐瑰効鎷彿鏀瑰彉鐐逛紭鍏堢駭浠涔堢殑錛岄偅灝變細鍙樻垚涓涓鏉傚緱澶氱殑鐘舵佹満浜嗐傚ソ浜嗐傜幇鍦ㄦ垜浠潵妯℃嫙涓涓嬩笅鎺ㄧ姸鎬佹満鐨勭姸鎬佽漿鎹㈠拰鍫嗘爤鎿嶄綔榪囩▼錛屾潵鍒嗘瀽涓涓婣,B,C$榪欎釜杈撳叆鍚с?/p> 鍦ㄤ笅闈㈢殑鏍囩ず鍥鵑噷闈紝鎴戜滑鐢╯|abc|def鏉ュ垎鍒〃杈懼綋鍓嶇姸鎬乻銆佸綋鍓嶅爢鏍堥噷鐨勭姸鎬乤bc錛堟爤欏跺湪鍙寵竟錛夊拰姝e湪絳夊緟鐨勮緭鍏ef銆傞偅涔堝垵濮嬬姸鎬佽偗瀹氬氨鏄?br>IDList0 | null | A,B,C$ 鐒跺悗灝卞紑濮嬩簡錛侊紙鐢ㄦ枃瀛楄〃杈懼疄鍦ㄦ槸澶毦鐪嬩簡錛屾墍浠ヨ創鎴愬浘錛?/p> 濡傛灉鎴愬姛鍒拌揪FINISH騫朵笖鍫嗘爤鍜岃緭鍏ラ兘鍏ㄩ儴娌℃湁浜嗙殑璇濓紝閭e氨璇佹槑錛宲arsing榪囩▼瀹岀編緇撴潫錛屾病鏈変換浣曢敊璇彂鐢熴?/p> 濡備綍浠庢枃娉曠敓鎴愪笅鎺ㄨ嚜鍔ㄦ満騫跺畬鎴恜arsing宸ヤ綔鐨勫ぇ姒傝繃紼嬪氨鍐欏埌榪欓噷浜嗐傜洰鍓嶅紑鍙戣繘搴︽槸鍒?#8220;鐢熸垚闈炵‘瀹氭т笅鎺ㄨ嚜鍔ㄦ満”榪欓噷銆傚綋鎴戝畬鎴愪簡鐢熸垚“紜畾鎬т笅鎺ㄨ嚜鍔ㄦ満”鈥斺斾篃灝辨槸涓婇潰鐨勬渶鍚庝竴涓姸鎬佹満鍥劇殑鏃跺欌斺斿氨浼氬紑濮嬪啓涓嬩竴綃囨枃绔狅紝璁查潰瀵瑰鏉傜殑鏂囨硶鐨勬椂鍊欙紝涓嬫帹鑷姩鏈哄皢瑕佸浣曡皟鏁淬傚悓鏃跺皢閲嶇偣鎻忚堪Look Ahead閮ㄥ垎錛屼互鍙婁負浠涔圠ALR(1)瑕佽璁℃垚閭d釜鏍峰瓙銆?/p>
1銆佸ぇ閮ㄥ垎鎯呭喌涓嬮兘鏄湡鐨勯渶瑕佹湁璇硶鏍?br>2銆佸鏋滆鐩存帴榪斿洖璁$畻緇撴灉涔嬬被鐨勪簨鎯呯殑璇濓紝鍙渶瑕佸啓涓涓獀isitor榪愯涓涓嬭娉曟爲灝卞ソ浜嗭紝闄ゅ幓鑷姩鐢熸垚鐨勪唬鐮佷互澶栵紙鍙嶆榪欎笉鐢ㄤ漢鍐欙紝涓嶈鍏ヤ唬浠鳳級錛屼唬鐮侀噺鍩烘湰涓婃病浠涔堝尯鍒?br>3銆佸姞鍏ヨ娉曟爲鍙互璁╂枃娉曟湰韜弿榪拌搗鏉ユ洿綆鍗曪紝濡傛灉瑕佽紼嬪簭鍛樻妸鏂囨硶鍗曠嫭鏀懼湪涓杈癸紝鐒跺悗鑷繁鍐欏畬鏁寸殑璇箟鍑芥暟鏉ヨ浠栫敓鎴愯娉曟爲鐨勮瘽錛屼細璁╁ぇ閮ㄥ垎鎯呭喌錛堥渶瑕佽娉曟爲錛夊彉寰楃壒鍒鏉傦紝鑰屽皯鏁版儏鍐碉紙涓嶉渶瑕佽娉曟爲錛夊張娌℃湁鑾峰緱浠涔堝ソ澶勩?/p>
灝界綾諱技yacc榪欐牱鐨勪笢瑗跨殑紜槸涓嶅寘鍚娉曟爲鐨勫唴瀹硅岃浣犺嚜宸卞啓鐨勶紝浣嗘槸鐢ㄨ搗鏉ラ毦閬撲笉鏄緢闅懼彈鍚楋紵
鐜板湪杞叆姝i銆傝繖涓綃囨枃绔犺鐨勪富瑕佹槸鏋勯犵鍙瘋〃鐨勯棶棰樸傛兂瑕佹妸絎﹀彿琛ㄦ瀯閫犵殑濂芥槸涓浠跺緢楹葷儲鐨勯棶棰樸傛垜鏇劇粡灝濊瘯榪囧緢澶氱鏂規硶錛屽寘鎷己綾誨瀷鐨勭鍙瘋〃錛屽急綾誨瀷鐨勭鍙瘋〃錛屽熀浜巑ap鐨勭鍙瘋〃絳夌瓑錛屾渶鍚庤繕鏄寫閫変簡璺烿isual Studio鑷甫鐨勭敤鏉ヨpdb鏂囦歡鐨凞IA綾誨叾涓殑IDIASymbol錛?a title="http://msdn.microsoft.com/en-us/library/w0edf0x4.aspx" target="_blank">http://msdn.microsoft.com/en-us/library/w0edf0x4.aspx錛夊熀鏈笂涓鏍風殑緇撴瀯錛氭墍鏈夌殑絎﹀彿閮藉彧鏈夎繖涔堜竴涓猻ymbol綾伙紝鐒跺悗鍖呯綏涓囪薄錛屼粈涔堥兘鏈夈備負浠涔堟渶鍚庨夋嫨榪欎箞鍋氬憿錛熷洜涓哄湪鍋氳涔夊垎鏋愮殑鏃跺欙紝鍏跺疄鍋氱殑鏈澶氱殑浜嬫儏涓嶆槸鏋勯犵鍙瘋〃錛岃屾槸鏌ヨ絎﹀彿琛ㄣ傚鏋滅鍙瘋〃鏄己綾誨瀷鐨勭敾錛岃濡傝綾誨瀷瑕佷竴涓被錛屽彉閲忚涓涓被錛屽嚱鏁拌涓涓被涔嬬被鐨勶紝鎬繪槸闇瑕佸埌澶刢ast鏉ast鍘伙紝涔熸壘涓嶅埌浠涔堝ソ鏂規硶鏉ュ湪瀹屾垚鐩稿悓浜嬫儏鐨勬儏鍐典笅錛屼繚鐣欏己綾誨瀷鑰屼笉鍦ㄤ唬鐮侀噷闈㈠嚭鐜癱ast銆備負浠涔堣娉曟爲灝辮鐢╲isitor鏉ヨВ鍐寵繖涓棶棰橈紝鑰岀鍙瘋〃灝變笉琛屽憿錛熷洜涓洪氬父鎴戜滑鍦ㄥ鐞嗚娉曟爲鐨勬椂鍊欓兘鏄掑綊鐨勫艦寮忥紝鑰岀鍙瘋〃騫朵笉鏄傚湪涓涓笂涓嬫枃閲岄潰錛屽疄闄呬笂鎴戜滑鏄煡閬撻偅涓猻ymbol瀵硅薄絀剁珶鏄粈涔堜笢瑗跨殑錛堣濡傝鎴戜滑鏌ヨ浜嗕竴涓彉閲忕殑type錛岄偅榪欒繑鍥炲艱偗瀹氬彧鑳芥槸type浜嗭級銆傝繖涓椂鍊欐垜浠cast鎵嶈兘鐢紝鏈韓涔熷彧鏄氮璐硅〃鎯呰屽凡銆傝繖涓椂鍊欙紝visitor妯″紡灝變笉鏄拰闈㈠榪欑鎯呭喌浜嗐傚鏋滅‖瑕佺敤visitor妯″紡鏉ュ啓錛屼細瀵艱嚧璇箟鍒嗘瀽鐨勪唬鐮佸垎鏁e緱榪囦簬紱昏氨瀵艱嚧鍙鎬у嚑涔庡氨涓уけ浜嗐傝繖鏄竴涓京璇佺殑闂錛屽ぇ瀹跺彲浠ュソ濂戒綋浼氫綋浼氥?/p>
璇翠簡榪欎箞涓澶ф錛屽疄闄呬笂灝辨槸鎬庝箞鏍峰憿錛熻鎴戜滑鏉ョ湅“鏂囨硶瑙勫垯”鏈韓鐨勭鍙瘋〃鍚с傛棦鐒惰繖涓柊鐨勫彲閰嶇疆璇硶鍒嗘瀽鍣ㄤ篃鏄氳繃parse涓涓枃鏈艦寮忕殑鏂囨硶瑙勫垯鏉ョ敓鎴恜arser錛岄偅瀹為檯涓婂氨璺熺紪璇戝櫒涓鏍瘋緇忓巻閭d箞澶氶樁孌碉紝鍏朵腑鑲畾鏈夌鍙瘋〃錛?/p>
class ParsingSymbol : public Object { public: enum SymbolType { Global, EnumType, ClassType, // descriptor == base type ArrayType, // descriptor == element type TokenType, EnumItem, // descriptor == parent ClassField, // descriptor == field type TokenDef, // descriptor == token type RuleDef, // descriptor == rule type }; public: ~ParsingSymbol(); ParsingSymbolManager* GetManager(); SymbolType GetType(); const WString& GetName(); vint GetSubSymbolCount(); ParsingSymbol* GetSubSymbol(vint index); ParsingSymbol* GetSubSymbolByName(const WString& name); ParsingSymbol* GetDescriptorSymbol(); ParsingSymbol* GetParentSymbol(); bool IsType(); ParsingSymbol* SearchClassSubSymbol(const WString& name); ParsingSymbol* SearchCommonBaseClass(ParsingSymbol* classType); };
鍥犱負鏂囨硶瑙勫垯鏈韓鐨勪笢瑗夸篃涓嶅錛屾墍浠ヨ繖閲岀殑symbol鍙兘鏄笂闈㈣杞界殑9縐嶅璞°傝繖浜涘璞″叾瀹炵壒鍒殑鐩鎬技錛屾墍浠ユ垜浠彲浠ョ湅鍑哄敮涓鐨勫尯鍒氨鏄綋GetType榪斿洖鍊間笉涓鏍風殑鏃跺欙紝GetDescriptorSymbol榪斿洖鐨勫璞$殑鎰忔濅篃涓嶄竴鏍楓傝岃繖涓尯鍒杞藉湪浜唀num SymbolType鐨勬敞閲婇噷闈€傚疄闄呬笂榪欑鍋氭硶鍦ㄩ潰瀵硅秴綰у鏉傜殑絎﹀彿琛紙鑰冭檻涓涓婥++緙栬瘧鍣級鐨勬椂鍊欏茍涓嶅お濂姐傞偅濂界殑鍋氭硶絀剁珶鏄粈涔堝憿錛熺湅涓婇潰IDIASymbol鐨勯摼鎺ワ紝閭e氨鏄瓟妗堛?/p>
涓嶅彲鍚﹁錛屽井杞璁″嚭鏉ョ殑API澶ч儴鍒嗚繕鏄緢鏈夐亾鐞嗙殑錛岄櫎浜哤in32鐨勫師鐢烥UI閮ㄥ垎銆?/p>
鎴戜滑榪樺彲浠ョ湅鍒幫紝榪欎釜ParsingSymbol綾葷殑鍑犱箮鎵鏈夋垚鍛樺嚱鏁伴兘鏄敤鏉ユ煡璇㈣繖涓猄ymbol鐨勫唴瀹圭殑銆傝繖閲岃繕鏈変袱涓壒孌婄殑鍑芥暟錛屽氨鏄疭earchClassSubSymbol鍜孲earchCommonBaseClass鈥斺斿綋涓斾粎褰搒ymbol鏄疌lassType鐨勬椂鍊欐墠璧蜂綔鐢ㄣ備負浠涔堟湁浜咷etSubSymbolByName錛岃繕瑕佽繖涓や釜api鍛紵鍥犱負鎴戜滑鍦ㄦ悳绱竴涓被鐨勬垚鍛樼殑鏃跺欙紝鏄鎼滅儲浠栫殑鐖剁被鐨勩傝屼竴涓被鐨勭埗綾葷殑sub symbol騫朵笉鏄被鑷繁鐨剆ub symbol錛屾墍浠ュ氨鏈変簡榪欎袱涓猘pi銆傛墍璋撶殑sub symbol鐨勬剰鎬濈幇鍦ㄤ篃寰堟槑浜嗕簡銆俥num綾誨瀷閲岄潰鐨勫煎氨鏄痚num鐨剆ub symbol錛屾垚鍛樺彉閲忔槸綾葷殑sub symbol錛屾諱箣鍙鏄0鏄庡湪涓涓鍙峰唴閮ㄧ殑絎﹀彿閮芥槸榪欎釜絎﹀彿鐨剆ub symbol銆傝繖灝辨槸鎵鏈夌鍙烽兘鏈夌殑鍏辨с?/p>
褰撶劧錛屾湁浜哖arsingSymbol錛岃繕瑕佹湁浠栫殑manager鎵嶅彲浠ュ畬鎴愭暣涓鍙瘋〃鐨勬搷浣滐細
class ParsingSymbolManager : public Object { public: ParsingSymbolManager(); ~ParsingSymbolManager(); ParsingSymbol* GetGlobal(); ParsingSymbol* GetTokenType(); ParsingSymbol* GetArrayType(ParsingSymbol* elementType); ParsingSymbol* AddClass(const WString& name, ParsingSymbol* baseType, ParsingSymbol* parentType=0); ParsingSymbol* AddField(const WString& name, ParsingSymbol* classType, ParsingSymbol* fieldType); ParsingSymbol* AddEnum(const WString& name, ParsingSymbol* parentType=0); ParsingSymbol* AddEnumItem(const WString& name, ParsingSymbol* enumType); ParsingSymbol* AddTokenDefinition(const WString& name); ParsingSymbol* AddRuleDefinition(const WString& name, ParsingSymbol* ruleType); ParsingSymbol* CacheGetType(definitions::ParsingDefinitionType* type, ParsingSymbol* scope); bool CacheSetType(definitions::ParsingDefinitionType* type, ParsingSymbol* scope, ParsingSymbol* symbol); ParsingSymbol* CacheGetSymbol(definitions::ParsingDefinitionGrammar* grammar); bool CacheSetSymbol(definitions::ParsingDefinitionGrammar* grammar, ParsingSymbol* symbol); ParsingSymbol* CacheGetType(definitions::ParsingDefinitionGrammar* grammar); bool CacheSetType(definitions::ParsingDefinitionGrammar* grammar, ParsingSymbol* type); };
榪欎釜ParsingSymbolManager鏈夌潃絎﹀彿琛ㄧ鐞嗗櫒鐨勪互涓嬩袱涓吀鍨嬩綔鐢?/p>
1銆佸垱寤虹鍙楓?br>2銆佽絎﹀彿涓庤娉曟爲鐨勫璞$粦瀹氳搗鏉ャ傝濡傝鎴戜滑鍦ㄤ竴涓猚ontext涓嬮潰鎺ㄥ浜嗕竴涓猠xpression鐨勭被鍨嬶紝閭d笅嬈″浜庡悓鏍風殑context鍚屾牱鐨別xpression灝變笉闇瑕佸啀鎺ㄥ涓嬈′簡錛堣涔夊垎鏋愭湁寰堝涓猵ass錛屽鍚屼竴涓猠xpression姹傜被鍨嬬殑鎿嶄綔緇忓父浼氶噸澶嶅緢澶氭錛夛紝鎶婂畠cache涓嬫潵灝卞彲浠ヤ簡銆?br>3銆佹悳绱㈢鍙楓傚叿浣撳埌榪欎釜絎﹀彿琛紝榪欎釜鍔熻兘琚仛榪涗簡ParsingSymbol閲岄潰銆?br>4銆佷繚瀛樻牴鑺傜偣銆侴etGlobal鍑芥暟灝辨槸騫茶繖涓綔鐢ㄧ殑銆傛墍鏈夌殑鏍圭鍙烽兘灞炰簬global絎﹀彿鐨剆ub symbol銆?/p>
鍥犳鎴戜滑鍙互鎬庝箞浣跨敤浠栧憿錛熼鍏堢湅涓婇潰鐨凙dd鍑芥暟銆傝繖浜涘嚱鏁頒笉浠呬細甯綘鍦ㄤ竴涓鍙瘋〃閲岄潰娣誨姞涓涓猻ub symbol錛岃繕浼氭浛浣犲仛涓浜涙鏌ワ紝璀璇撮樆姝綘娣誨姞鐩稿悓鍚嶅瓧鐨剆ub symbol涔嬬被鐨勩傝娉曟爲寰堝鏉傜殑鏃跺欙紝寰堝鏃跺欐垜浠湁寰堝涓嶅悓鐨勬柟娉曟潵緇欎竴涓鍙鋒坊鍔犲瓙絎﹀彿錛岃濡傝C#鐨勬垚鍛樺彉閲忓拰鎴愬憳鍑芥暟銆傛垚鍛樺彉閲忎笉鑳藉悓鍚嶏紝鎴愬憳鍑芥暟鍙互錛屼絾鏄垚鍛樺嚱鏁板拰鎴愬憳鍙橀噺鍗翠笉鑳藉悓鍚嶃傝繖涓椂鍊欐垜浠氨闇瑕佹妸榪欎簺娣誨姞鎿嶄綔灝佽璧鋒潵錛岃繖鏍鋒墠鍙互鍦ㄥ鐞嗚娉曟爲錛堝0鏄庝竴涓嚱鏁扮殑鏂規硶鍙互鏈夊緢澶氾紝鎵浠ユ坊鍔犲嚱鏁扮鍙風殑鍦版柟涔熷彲浠ユ湁寰堝錛夌殑鏃跺欎笉闇瑕侀噸澶嶅啓楠岃瘉閫昏緫銆?/p>
鍏舵灝辨槸Cache鍑芥暟銆傚叾瀹濩ache鍑芥暟榪欎箞鍐欙紝涓嶆槸鐢ㄦ潵鐩存帴璋冪敤鐨勩備婦涓緥瀛愶紝鍦ㄥ垎鏋愪竴涓枃娉曠殑鏃跺欙紝鎴戜滑闇瑕佹妸涓涓?#8220;綾誨瀷”璇硶鏍戣漿鎴愪竴涓?#8220;綾誨瀷”絎﹀彿錛堣濡傝瑕佸喅瀹氫竴涓枃娉曡create浠涔堢被鍨嬬殑璇硶鏍戣妭鐐圭殑鏃跺欙級銆傚洜姝ゅ氨鏈変簡涓嬮潰鐨勫嚱鏁幫細
ParsingSymbol* FindType(Ptr<definitions::ParsingDefinitionType> type, ParsingSymbolManager* manager, ParsingSymbol* scope, collections::List<Ptr<ParsingError>>& errors) { ParsingSymbol* result=manager->CacheGetType(type.Obj(), scope); if(!result) { FindTypeVisitor visitor(manager, (scope?scope:manager->GetGlobal()), errors); type->Accept(&visitor); result=visitor.result; manager->CacheSetType(type.Obj(), scope, result); } return result; }
寰堟槑鏄撅紝榪欎釜鍑芥暟鍋氱殑浜嬫儏灝辨槸錛屾煡璇竴涓狿arsingDefinitionType鑺傜偣鏈夋病鏈夎鏌ヨ榪囷紝濡傛灉鏈夌洿鎺ョ敤cache錛屾病鏈夌殑璇濆啀浠庡ご璁$畻浠栫劧鍚巆ache璧鋒潵銆傚洜姝よ繖浜汣ache鍑芥暟灝辨槸緇欑被浼糉indType鐨勫嚱鏁扮敤鐨勶紝鑰岃涔夊垎鏋愮殑浠g爜鍒欑洿鎺ヤ嬌鐢‵indType錛岃屼笉鏄疌ache鍑芥暟錛屾潵鑾峰彇涓涓被鍨嬬殑絎﹀彿銆傝仾鏄庣殑鏈嬪弸浠彲浠ョ湅鍑烘潵錛岃繖縐嶅啓娉曡暣鍚潃涓涓潯浠訛紝灝辨槸璇硶鏍戝垱寤哄畬灝變笉浼氭敼浜嗭紙搴熻瘽錛屽綋鐒朵笉浼氭敼錛侊級銆?/p>
榪欎竴綃囩殑鍐呭灝辮鍒拌繖閲屼簡銆傜幇鍦ㄧ殑榪涘害鏄鍦ㄥ啓鏂囨硶鐢熸垚鐘舵佹満鐨勭畻娉曘備笅涓綃囨枃绔犲簲璇ヨ鐨勫氨鏄姸鎬佹満絀剁珶鏄庝箞榪愪綔鐨勪簡銆傛枃娉曟墍闇瑕佺殑鐘舵佹満鍙仛涓嬫帹鐘舵佹満錛坧ush down automaton錛夛紝璺焤egex鐢ㄧ殑NFA鍜孌FA涓嶅お涓鏍鳳紝鐞嗚В璧鋒潵鐣ユ湁闅懼害銆傛墍浠ユ垜鎯抽渶瑕佺敤鍗曠嫭鐨勪竴綃囨枃绔犳潵閫氫織鐨勮涓璁層?/p>
鍏跺疄璇村埌寮鍙戣娉曞垎鏋愬櫒錛屾垜浠?007騫村氨宸茬粡寮濮嬪湪鎬濊冪被浼肩殑闂浜嗐傚綋鏃禖++榪樺浜庣敤鐨勪笉澶啛緇冪殑鏃跺欙紝闅懼厤浼氬仛鍑轟竴浜涘偦閫肩殑浜嬫儏錛屼笉榪囨葷殑鏉ヨ褰撳勾鐨刬dea榪樻槸鑳界敤鐨勩備粠閭f椂鍊欏紑濮嬶紝鎴戜負浜嗛敾鐐艱嚜宸憋紝涓鐩村湪瀹炵幇鍚勭涓嶅悓鐨勮璦銆傛墍浠ョ粰鑷繁寮鍙戜竴涓彲閰嶇疆璇硶鍒嗘瀽鍣ㄤ篃鏄湪鎵闅懼厤鐨勪簨鎯呬簡銆備簬鏄氨鏈夛細
絎竴鐗堬細http://hi.baidu.com/geniusvczh/archive/tag/syngram%E6%97%A5%E5%BF%97
絎簩鐗堬細http://www.shnenglu.com/vczh/archive/2009/04/06/79122.html
絎笁鐗堬細http://www.shnenglu.com/vczh/archive/2009/12/13/103101.html
榪樻湁絎笁鐗堢殑鏁欑▼錛?a title="http://www.shnenglu.com/vczh/archive/2010/04/28/113836.html" href="http://www.shnenglu.com/vczh/archive/2010/04/28/113836.html">http://www.shnenglu.com/vczh/archive/2010/04/28/113836.html
涓婇潰鐨勬墍鏈夊垎鏋愬櫒閮借嚧鍔涗簬鍦–++閲岄潰鍙互閫氳繃鐩存帴鎻忚堪鏂囨硶鍜屼竴浜涜涔夎涓烘潵璁╃郴緇熷彲浠ヨ繀閫熸瀯閫犲嚭涓涓拡瀵圭壒瀹氱洰鐨勭殑鐢ㄨ搗鏉ユ柟渚跨殑璇硶鍒嗘瀽鍣紝鑰屸滅涓夌増鈥濆氨鏄埌鐩墠涓烘榪樺湪鐢ㄧ殑涓涓増鏈傝嚦浜庝負浠涔堟垜瑕佸仛涓涓柊鐨勨斺斾篃灝辨槸絎洓鐗堚斺?a href="http://www.shnenglu.com/vczh/archive/2012/10/30/194052.html" target="_blank">涔嬪墠鐨勬枃绔?/a>宸茬粡璇翠簡銆?/p>
鑰屼粖澶╋紝絎洓鐗堢殑寮鍙戝凡緇忓紑濮嬩簡鏈夊ソ鍑犲ぉ銆傚鏋滃ぇ瀹跺叧蹇冭繘搴︾殑璇濓紝鍙互鍘?a target="_blank">GacUI鐨凜odeplex欏甸潰涓嬭澆浠g爜錛岀劧鍚庨槄璇籆ommon\Source\Parsing涓嬮潰鐨勬簮鏂囦歡銆傚搴旂殑鍗曞厓嫻嬭瘯鍙互鍦–ommon\UnitTest\UnitTest\TestParsing.cpp閲屾壘鍒般?/p>
浜庢槸浠婂ぉ灝辮璇村叧浜庢瀯閫犺娉曟爲鐨勪簨鎯呫?/p>
鐢–++鍐欒繃parser鐨勪漢閮界煡閬擄紝鏋勯犺娉曟爲浠ュ強璇箟鍒嗘瀽鐢ㄧ殑絎﹀彿琛ㄦ槸涓浠舵瀬鍏剁箒鐞愶紝鑰屼笖涓涓嶅皬蹇冨氨瀹規槗鍐欏嚭緲旂殑浜嬫儏銆備絾鏄牴鎹垜鍐欒繃鏃犵┓澶氭5璇硶鏍戜互鍙婃瀯閫犺繃鏃犵┓澶氫釜絎﹀彿琛ㄤ互鍙婇檮甯︾殑鍓綔鐢紝緲旓紝鍟婁笉錛岀粡楠岋紝鍋氳繖涓簨鎯呰繕鏄湁涓浜涙柟娉曠殑銆?/p>
鍦ㄤ粙緇嶈繖涓柟娉曚箣鍓嶏紝棣栧厛瑕佽涓鍙ワ紝浜鴻倝鍋氬畬涓嬮潰鐨勬墍鏈変簨鎯呮槸鑲畾瑕佺柉鎺夌殑錛屾墍浠ヨ繖涓嬈$殑鍙厤緗娉曞垎鏋愬櫒鎴戝凡緇忓喅瀹氫簡涓瀹氳TMD鍐欏嚭涓涓敓鎴愯娉曟爲鐨凜++浠g爜鐨勫伐鍏楓?/p>
涓棰楄娉曟爲錛屽叾瀹炲氨鏄竴澶у爢浜掔浉緇ф壙鐨勭被銆備竴鍒囨垚鐔熺殑璇硶鏍戠粨鏋勬墍鍏鋒湁鐨勫叡鍚岀壒寰侊紝涓嶆槸浠栫殑鎴愬憳鎬庝箞瀹夋帓錛岃屾槸浠栦竴瀹氫細闄勫甫涓涓?a target="_blank">visitor妯″紡鐨勬満鍒躲傝嚦浜庝粈涔堟槸visitor妯″紡錛屽ぇ瀹惰鑷鍙傝冭璁℃ā寮忥紝鎴戝氨涓嶅璇村簾璇濅簡銆傝繖涓嬈$殑鍙厤緗娉曞垎鏋愬櫒鏄甫鏈変竴涓弿榪版ц娉曠殑銆備篃灝辨槸璇達紝璺烝ntlr鎴栬匶acc涓鏍鳳紝棣栧厛鍦ㄤ竴涓枃鏈枃浠墮噷闈㈠噯澶囧ソ璇硶鏍戠粨鏋勫拰鏂囨硶瑙勫垯錛岀劧鍚庢垜鐨勫伐鍏蜂細甯綘鐢熸垚涓涓唴瀛樹腑鐨勮娉曞垎鏋愬櫒錛屼互鍙婄敤C++鎻忚堪鐨勮娉曟爲鐨勫0鏄庡拰瀹炵幇鏂囦歡銆傝繖涓弿榪版ц娉曞氨綾諱技涓嬮潰鐨勮繖涓ぇ瀹剁啛鎮夊埌涓嶈兘鍐嶇啛鎮夌殑甯﹀嚱鏁扮殑鍥涘垯榪愮畻琛ㄨ揪寮忕粨鏋勶細
class Expression
{
}
class NumberExpression : Expression
{
token value;
}
class BinaryExpression : Expression
{
enum BinaryOperator
{
Add,
Sub,
Mul,
Div,
}
Expression firstOperand;
Expression secondOperand;
BinaryOperator binaryOperator;
}
class FunctionExpression : Expression
{
token functionName;
Expression[] arguments;
}
token NAME = "[a-zA-Z_]/w*";
token NUMBER = "/d+(./d+)";
token ADD = "/+";
token SUB = "-";
token MUL = "/*";
token DIV = "http://";
token LEFT = "/(";
token RIGHT = "/)";
token COMMA = ",";
rule NumberExpression Number
= NUMBER : value;
rule FunctionExpression Call
= NAME : functionName "(" [ Exp : arguments { "," Exp : arguments } ] ")";
rule Expression Factor
= !Number | !Call;
rule Expression Term
= !Factor;
= Term : firstOperand "*" Factory : secondOperand as BinaryExpression with { binaryOperator = "Mul" };
= Term : firstOperand "/" Factory : secondOperand as BinaryExpression with { binaryOperator = "Div" };
rule Expression Exp
= !Term;
= Exp : firstOperand "+" Term : secondOperand as BinaryExpression with { binaryOperator = "Add" };
= Exp : firstOperand "-" Term : secondOperand as BinaryExpression with { binaryOperator = "Sub" };
涓婇潰鐨勮娉曟爲澹版槑鍊熺敤鐨凜#璇硶錛屾弿榪拌搗鏉ョ壒鍒畝鍗曘備絾鏄鍦–++閲岄潰杈懼埌鍙互浣跨敤鐨勭▼搴︼紝鑲畾瑕佹湁涓涓嚜甯︾殑visitor妯″紡銆傛墍浠ュ嚭鏉ヤ箣鍚庣殑浠g爜澶ф灝辯被浼間簬涓嬮潰榪欎釜鏍峰瓙錛?/p>
class Expression;
class NumberExpression;
class BinaryExpression;
class FunctionExpression;
class Expression : public ParsingTreeCustomBase
{
public:
class IVisitor : public Interface
{
public:
virtual void Visit(NumberExpression* node)=0;
virtual void Visit(BinaryExpression* node)=0;
virtual void Visit(FunctionExpression* node)=0;
};
virtual void Accept(IVisitor* visitor)=0;
};
class NumberExpression : public Expression
{
public:
TokenValue value;
void Accept(IVisitor* visitor){visitor->Visit(this);}
};
class BinaryExpression : public Expression
{
public:
enum BinaryOperator
{
Add, Sub, Mul, Div,
};
Ptr<Expression> firstOperator;
Ptr<Expression> secondOperator;
BinaryOperator binaryOperator;
void Accept(IVisitor* visitor){visitor->Visit(this);}
};
class FunctionExpression : public Expression
{
public:
TokenValue functionName;
List<Ptr<Expression>> arguments;
void Accept(IVisitor* visitor){visitor->Visit(this);}
};
涓轟粈涔堣榪欐牱鍋氬憿錛熷涔犺繃闈㈠悜瀵硅薄寮鍙戞柟娉曠殑閮界煡閬擄紝鎶婁竴涓槑鏄炬槸緇ф壙緇撴瀯鐨勪笢瑗垮啓鎴愪竴鍫唘nion/struct鍜屼竴涓猠num鏉ュ垽鏂粬浠紝鏄笉瀵圭殑銆傜涓涓笉濂界殑鍦版柟灝辨槸錛屽鏋滃叾涓殑鎴愬憳闇瑕佹瀯閫犲嚱鏁板拰鏋愭瀯鍑芥暟錛岄偅union灝辯敤涓嶄簡浜嗭紝struct灝變竴瀹氫細閫犳垚澶ч噺鐨勫唴瀛樻氮璐廣傚洜涓轟竴棰楄娉曟爲鏄彲浠ュ緢澶х殑銆傚叾嬈★紝褰撹娉曟爲鐨勭粨鏋勶紙涓昏鏄坊鍔犲垹闄や簡鏂扮殑璇硶鏍戠被鍨嬶級涔嬪悗錛屾垜浠牴鏈笉鍙兘淇濊瘉鎴戜滑鎵鏈夌殑swtich(node->enumType)璇彞閮芥帴鍙楀埌浜嗘紜殑鏇存柊銆?/p>
閭h濡備綍瑙e喅榪欎袱涓棶棰樺憿錛熺瓟妗堜箣涓灝辨槸浣跨敤visitor妯″紡銆傚敖綆″垰寮濮嬪啓璧鋒潵鐨勬椂鍊欏彲鑳戒細鏈夌偣鍒壄錛屼絾鏄垜浠彧瑕佹妸鍘熸湰鏄痵wtich緇撴瀯鐨勪唬鐮佸仛涓涓?a target="_blank">Continuation Passing Style鍙樻崲錛屽氨鍙互鍐欏嚭浣跨敤visitor鐨勭増鏈簡銆傚湪榪欓噷鎴戝仛涓涓皬灝忕殑婕旂ず錛屽浣曟妸涓涓滄妸涓婇潰鐨勮娉曟爲榪樺師鎴愬洓鍒欒繍綆楀紡瀛愮殑鍑芥暟鈥濈粰鐢‥xpression::IVisitor鐨勬鏋朵笅瀹炵幇鍑烘潵錛?/p>
class FunctionExpression : public Expression
{
public:
TokenValue functionName;
List<Ptr<Expression>> arguments;
void Accept(IVisitor* visitor){visitor->Visit(this);}
};
class ExpressionPrinter : public Expression::IVisitor
{
public:
WString result;
void Visit(NumberExpression* node)
{
result+=node->value.stringValue;
}
void Visit(BinaryExpression* node)
{
result+=L"(";
node->firstOperand->Accept(this);
switch(binaryOperator)
{
case Add: result+=L" + "; break;
case Sub: result+=L" - "; break;
case Mul: result+=L" * "; break;
case Div: result+=L" / "; break;
}
node->secondOperand->Accept(this);
result+=L")";
}
void Visit(FunctionExpression* node)
{
result+=node->functionName.stringValue+L"(";
for(int i=0;i<arguments.Count();i++)
{
if(i>0) result+=L", ";
arguments[i]->Accept(this);
}
result+=L")";
}
};
WString PrintExpression(Ptr<Expression> expression)
{
ExpressionPrinter printer;
expression->Accept(&printer);
return printer.result;
}
鍏跺疄澶у鍙互鐪嬪埌錛屼嬌鐢ㄤ簡visitor妯″紡錛屼唬鐮侀噺鍏跺疄涔熸病鏈夊澶у彉鍖栵紝鏈潵鏄掑綊鐨勫湴鏂硅繕鏄掑綊錛屾湰鏉ヨ璁$畻浠涔堣繕璁$畻浠涔堬紝鍞竴涓嶅悓鐨勫氨鏄師鏈繖涓滃嚱鏁扳濈殑鍙傛暟鍜岃繑鍥炲奸兘璺戝埌浜嗕竴涓獀isitor綾葷殑鎴愬憳鍙橀噺閲岄潰鍘諱簡銆傚綋鐒訛紝涓轟簡渚夸簬浣跨敤錛屼竴鑸潵璇存垜浠細鎶婂師鏈殑鍑芥暟鐨勫師鍨嬪啓鍑烘潵錛屽茍涓斿湪閲岄潰璋冪敤visitor妯″紡錛屽氨鍍忎笂闈㈢殑PrintExpression鍑芥暟涓鏍楓傚鏋滄垜浠珮鍏寸殑璇濓紝瀹屽叏鍙互鍦‥xpressionPrinter榪欎釜visitor綾婚噷闈嬌鐢≒rintExpression錛屾棤闈炲氨鏄湪閲岄潰鏋勯犳柊鐨凟xpressionPrinter鐒跺悗鑾峰彇緇撴瀯緗簡銆備竴鑸潵璇達紝visitor綾婚兘鏄潪甯哥殑杞婚噺綰х殑錛屽湪鐜頒粖鐨凜PU鎬ц兘涓嬮潰錛屾瀯閫犲鍑犱釜瀹屽叏涓嶄細甯︽潵澶氬ぇ褰卞搷銆?/p>
鍙厤緗娉曞垎鏋愬櫒鏃㈢劧鎷ユ湁涓涓弿榪版ц娉曪紝閭d箞鎴戣偗瀹氫篃閽堝榪欎釜鎻忚堪鎬ц娉曞啓浜嗕竴棰楄娉曟爲鐨勩傝繖棰楄娉曟爲鐨勪唬鐮佸湪Common\Source\Parsing\ParsingDefinition.h閲岄潰錛岃孭arsingLogging.cpp鍒欐槸璺熶笂闈㈣鐨勪竴鏍鳳紝鐢╲isitor鐨勬柟娉曞啓浜嗕竴涓簽澶х殑鎶婅娉曟爲杞洖鎻忚堪鎬ц娉曠殑鍑芥暟銆傝繖涓嚱鏁伴潪甯告湁鐢紝涓嶄粎鍙互鐢ㄦ潵鎵搇og錛岃繕鍙互鐢ㄦ潵淇濆瓨紼嬪簭鐢熸垚鐨勪竴涓娉曡鍒欙紙鍙嶆鍙互parse鍥炴潵錛屾墍浠ヤ繚瀛樻垚鏂囨湰鏄竴浠剁壒鍒柟渚跨殑浜嬫儏錛夛紝鐢氳嚦鏄敓鎴愰敊璇秷鎭殑鐗囨絳夌瓑銆?/p>
浠婂ぉ灝卞厛璁插埌榪欓噷浜嗐傜幇鍦ㄧ殑鍙厤緗娉曞垎鏋愬櫒鐨勫紑鍙戣繘搴︽槸姝e湪鍐欒涔夊垎鏋愮殑閮ㄥ垎銆傜瓑鍒拌涔夊垎鏋愬啓瀹屼簡錛屾垜浼氬啀鍐欎竴綃囩邯浜嬫潵璇存槑寮鍙戣涔夊垎鏋愮▼搴忓拰鏋勯犵鍙瘋〃鐨勪竴鑸仛娉曘?/p>
涓轟粈涔堣閲嶅啓vlpp鐨勮繖涓閮ㄥ垎鍛紵鍥犱負緇忚繃澶氭鍙厤緗娉曞垎鏋愬櫒鐨勫紑鍙戯紝鎴戞劅瑙夊埌浜咰++鐩存帴鐢ㄦ潵琛ㄨ揪鏂囨硶鏈夊緢澶氬急鐐癸細
1銆丆++鑷韓鐨勭被鍨嬬郴緇熷鑷磋〃杈懼嚭鏉ョ殑鏂囨硶浼氭湁寰堝鍣煶銆傚綋鐒惰繖騫朵笉鏄疌++鐨勯敊錛岃屾槸閫氱敤鐨勮璦鍋氳繖縐嶄簨鎯呮繪槸浼氭湁鐐瑰櫔闊崇殑銆傛棤璁烘槸銆?a target="_blank">Monadic Parser Combinators using C# 3.0
銆嬩篃濂斤紝鎴戝ぇ寰蔣鐮旂┒闄㈢殑鍩轟簬Haskell鐨?a target="_blank">Parsec涔熷ソ錛岃繕鏄痓oost鐨?a target="_blank">spirit涔熷ソ錛岀敋鑷蟲槸F#鐨?a target="_blank">Fsyacc涔熷ソ錛岄兘鍦ㄥ睍紺轟簡parser combinator榪欎釜寮哄ぇ鐨勬蹇電殑鍚屾椂錛屼篃鏆撮湶鍑轟簡parser combinator鐨勫急鐐癸細鍦ㄨ娉曞垎鏋愮粨鏋滃拰璇█鐨勬暟鎹粨鏋勭殑緇撳悎鏂歸潰鐗瑰埆鐨勯夯鐑︺傝繖閲岀殑楹葷儲涓嶄粎鍦ㄤ簬浼氱粰鏂囨硶閫犳垚寰堝鍣煶錛岃屼笖澶嶆潅鐨刾arser榪樹細浣垮緱浣犵殑緇撴瀯鐗瑰埆鐨勮噧鑲匡紙鍙傝傾ntlr鐨勬煇浜涘鏉傜殑搴旂敤錛岃繖閲屽氨涓嶄竴涓鍒椾婦浜嗭級銆?/p>2銆侀毦浠ョ淮鎶ゃ傚鏋滅洿鎺ョ敤C++鎻忚堪涓涓己綾誨瀷鏂囨硶鐨勮瘽錛屽娍蹇呮槸瑕佸熷姪parser combinator榪欎釜姒傚康鐨勩傛蹇墊湰韜槸寰堝帀瀹崇殑錛岃屼笖瀹炵幇鐨勫ソ鐨勮瘽寮鍙戞晥鐜囦細鐗瑰埆鐨勯珮銆備絾鏄浜嶤++榪欑闈炲嚱鏁板紡璇█鏉ヨ錛宲arser combinator榪欑鐗瑰埆鍑芥暟寮忕殑鎻忚堪鏀懼湪C++閲岄潰灝變細澶氬嚭寰堝楹葷儲錛岃濡傞棴鍖呯殑璇硶涓嶅婕備寒鍟︺佹病鏈夊瀮鍦炬敹闆嗗櫒鐨勯棶棰樺鑷磖ule涓巖ule鐨勫驚鐜紩鐢ㄩ棶棰樿繕瑕佽嚜琛屽鐞嗗暒錛堝湪寰堟棭浠ュ墠鐨勪竴綃囧崥瀹㈣璇佽繃浜嗭紝鍙鏄甫瀹屾暣闂寘鍔熻兘鐨勮璦錛岄兘涓瀹氫笉鑳芥槸鐢ㄥ紩鐢ㄨ鏁版潵澶勭悊鍐呭瓨錛岃屽繀欏昏涓涓瀮鍦炬敹闆嗗櫒鐨勶級銆傚敖綆℃垜涓鐩翠互鏉ラ兘榪樻槸娌″仛鍑鴻繃榪欐柟闈㈢殑bug錛屼絾鏄敱浜庯紙涓昏鏄敤鏉ュ鐞嗕綍鏃跺簲璇elete瀵硅薄閮ㄥ垎鐨勶級閫昏緫澶嶆潅錛屽鑷存暟鎹粨鏋勫繀欏諱負delete瀵硅薄鐨勯儴鍒嗚姝ワ紝浠g爜緇存姢璧鋒潵涔熺浉褰撶殑铔嬬柤銆?/p>
3銆佹湁浜涗紭鍖栨棤娉曞仛銆備婦涓畝鍗曠殑渚嬪瓙錛宲arser combinator灝辨牴鏈病鍔炴硶澶勭悊宸﹂掑綊銆傛病鏈夊乏閫掑綊錛屽啓璧鋒煇浜涙枃娉曟潵涔熸槸鐗瑰埆鐨勮泲鐤箋傝繕鏈夊悎騫跺叡鍚屽墠緙絳夌瓑鐨勪紭鍖栦篃涓嶈兘鍋氾紝榪欏鑷存垜浠繀欏諱負浜嗘ц兘鐗虹壊鏈潵灝卞凡緇忓厖婊′簡鍣煶鐨勬枃娉曠殑琛ㄨ揪錛岃漿鑰屼漢宸ヤ綔鏂囨硶鐨勫叡鍚屽墠緙鍚堝茍錛屾枃娉曠湅璧鋒潵灝辨洿涔變簡銆?/p>
褰撶劧涓婇潰涓変釜鐞嗙敱鐪嬭搗鏉ュソ鍍忎笉澶洿瑙傦紝閭f垜灝變婦涓涓吀鍨嬬殑渚嬪瓙銆傚ぇ瀹跺簲璇ヨ繕璁板緱鎴戜互鍓嶅啓榪囦竴涓彨鍋?a href="http://www.shnenglu.com/vczh/archive/2011/03/20/142261.html" target="_blank">NativeX鐨勮璦錛岃繕緇欏畠鍋氫簡涓涓?a href="http://www.shnenglu.com/vczh/archive/2011/02/25/140618.html" target="_blank">甯︽櫤鑳芥彁紺虹殑緙栬緫鍣?/a>錛堣繕鏈?a href="http://www.shnenglu.com/vczh/archive/2010/11/07/132876.html" target="_blank">榪欓噷鍜?a href="http://www.shnenglu.com/vczh/archive/2010/12/05/135505.html" target="_blank">榪欓噷錛夈侼ativeX鏄竴涓狢++瀹炵幇鐨凜+template+concept mapping鐨勮璦錛岃娉曞垎鏋愬櫒褰撶劧鏄敤涓婁竴涓増鏈殑鍙厤緗娉曞垎鏋愬櫒鏉ュ仛鐨勩傛枃娉曡鍒欏緢澶嶆潅錛屼絾鏄C++榪欎箞浠ヨ〃杈撅紝灝辨洿鍔犲鏉備簡錛?a target="_blank">.\Library\Scripting\Languages\NativeX\NativeXParser.cpp錛夛紝宸茬粡鍒頒簡涓嶄粩緇嗙湅灝辨棤娉曠淮鎶ょ殑鍦版浜嗐?/p>
緇間笂鎵榪幫紝鍋氫竴涓柊鐨勫彲閰嶇疆璇硶鍒嗘瀽鍣ㄥ嚭鏉ョ悊鐢卞厖鍒嗭紝鍔垮湪蹇呭緱銆備絾鏄艦寮忎笂鏄粈涔堟牱瀛愮殑鍛紵涓婇潰璇磋繃鎴戜互鍓嶇粰NativeX鍐欒繃涓涓甫鏅鴻兘鎻愮ず鐨勭紪杈戝櫒銆傝繖涓紪杈戝櫒鐢ㄧ殑鏄疻inForm錛岄偅褰撶劧涔熸槸鐢–#鍐欑殑錛屽洜姝ら偅涓鎬ц兘瑕佹眰楂樺埌紱昏氨鐨凬ativeX緙栬緫鍣ㄧ敤鐨勮娉曞垎鏋愬櫒褰撶劧涔熸槸鐢–#鍐欑殑銆傛祦紼嬪ぇ姒傚涓嬶細
1銆佺敤C#鎸夌収瑕佹眰澹版槑璇硶鏍戠粨鏋?br>2銆佷嬌鐢ㄦ垜鐨勫簱鐢–#鍐欎竴涓枃娉?br>3銆佹垜鐨勫簱浼氭墽琛岃繖涓枃娉曪紝鐢熸垚涓澶фC#鍐欑殑絳変環鐨勯掑綊涓嬮檷璇硶鍒嗘瀽鍣ㄧ殑浠g爜
褰撴椂鎴戞妸榪欎釜榪囩▼璁板綍鍦ㄤ簡榪欑瘒鍗氬鏂囩珷閲岄潰銆?/p>
鍥犳鐜板湪灝辨湁涓涓鍒掞紝榪欎釜鏂扮殑鍙厤緗娉曞垎鏋愬櫒褰撶劧榪樻槸瑕佸畬鍏ㄧ敤C++錛屼絾鏄繖灝辮窡姝e垯琛ㄨ揪寮忎竴鏍鳳細
1銆侀鍏堣娉曟爲緇撴瀯鍜屾枃娉曢兘澹版槑鍦ㄤ竴涓瓧絎︿覆閲岄潰
2銆佸彲閰嶇疆璇硶鍒嗘瀽鍣ㄥ彲浠ュ湪鍐呭瓨涓姩鎬佹墽琛岃繖孌墊枃娉曪紝騫舵寜鐓х粰瀹氱殑璇硶鏍戠粨鏋勭粰鍑轟竴涓湪鍐呭瓨涓殑鍔ㄦ佺殑鏁版嵁緇撴瀯
3銆佸彲閰嶇疆璇硶鍒嗘瀽鍣ㄥ綋鐒惰繕瑕侀檮甯︿竴涓懡浠よ宸ュ叿錛岀敤鏉ヨ鏂囨硶鐢熸垚C++浠g爜錛屽寘鎷嚜甯isitor妯″紡鐨勮娉曟爲緇撴瀯錛屽拰C++鍐欑殑閫掑綊涓嬮檷璇硶鍒嗘瀽鍣?/p>
鎵浠ョ幇鍦ㄥ氨鏈変竴涓崏紼匡紝灝辨槸閭d釜鈥滃0鏄庡湪瀛楃涓查噷闈⑩濈殑璇硶鏍戠粨鏋勫拰鏂囨硶鐨勮鏄庛傝繖鏄竴涓緢鏈夋剰鎬濈殑榪囩▼銆?/p>
棣栧厛錛岃繖涓彲閰嶇疆璇硶鍒嗘瀽鍣ㄩ渶瑕佸湪鍐呭瓨涓〃杈捐娉曟爲緇撴瀯錛屽拰涓涓彲浠ユ墽琛岀劧鍚庝駭鐢熷姩鎬佹暟鎹粨鏋勭殑鏂囨硶銆傚洜姝ゆ垜浠湪浣跨敤瀹冪殑鏃跺欙紝鍙互閫夋嫨鐩存帴鍦ㄥ唴瀛樹腑鍫嗗嚭璇硶鏍戠粨鏋勫拰鏂囨硶鐨勬弿榪幫紝鑰屼笉鏄潪寰楃敤閭d釜瀛楃涓茬殑琛ㄨ揪褰㈠紡銆傚綋鐒訛紝瀛楃涓茬殑琛ㄨ揪褰㈠紡鑲畾鏄崄鍒嗙揣鍑戠殑錛屼絾榪欎笉鏄繀欏葷殑錛屽彧鏄帹鑽愮殑銆?/p>
鍏舵錛宲arse榪欎釜鈥滆娉曟爲緇撴瀯鍜屾枃娉曢兘澹版槑鈥濆綋鐒朵篃闇瑕佷竴涓娉曞垎鏋愬櫒鏄笉鏄紵鎵浠ユ垜浠彲浠ョ敤涓婇潰鐨勬柟娉曪紝閫氳繃鐩存帴鍦ㄥ唴瀛樹腑鍫嗗嚭鏂囨硶鏉ョ敤鑷繁鏋勯犲嚭涓涓嚜宸辯殑璇硶鍒嗘瀽鍣ㄣ?/p>
鍐嶈咃紝鏈変簡涓涓唴瀛樹腑鐨勮娉曞垎鏋愬櫒涔嬪悗錛屾垜灝卞彲浠ュ皢涓婇潰絎笁姝ョ殑鍛戒護琛屽伐鍏峰仛鍑烘潵錛岀劧鍚庣敤瀹冩潵鎻忚堪鑷繁鐨勬枃娉曪紝浜х敓鍑轟竴孌礐++鍐欑殑閫掑綊涓嬮檷璇硶鍒嗘瀽鍣紝鐢ㄦ潵鍒嗘瀽鈥滆娉曟爲緇撴瀯鍜屾枃娉曢兘澹版槑鈥濓紝鐒跺悗灝辨湁浜嗕竴瀵笴++浠g爜鏂囦歡銆?/p>
鏈鍚庯紝鎶婁駭鐢熷嚭鏉ョ殑榪欏C++浠g爜鏂囦歡鍔犺繘鍘伙紝鎴戜滑灝辨湁浜嗕竴涓狢++鐩存帴鍐欙紝鑰屼笉鏄湪鍐呭瓨涓姩鎬佹瀯閫犲嚭鏉ョ殑鈥滆娉曟爲緇撴瀯鍜屾枃娉曢兘澹版槑鈥濈殑鍒嗘瀽鍣ㄤ簡銆傜劧鍚庤繖涓垎鏋愬櫒灝卞彲浠ユ浛鎹㈡帀鍛戒護琛屽伐鍏烽噷闈㈤偅涓師鍏堝姩鎬佹瀯閫犲嚭鏉ョ殑璇硶鍒嗘瀽鍣ㄣ傚綋鐒墮偅涓姩鎬佹瀯閫犲嚭鏉ョ殑璇硶鍒嗘瀽鍣ㄨ繖涓椂鍊欏凡緇忔病鐢ㄤ簡錛屽洜涓烘湁浜嗙敓鎴愮殑C++璇硶鍒嗘瀽鍣紝鎴戜滑灝卞彲浠ョ洿鎺ヤ嬌鐢ㄢ滆娉曟爲緇撴瀯鍜屾枃娉曢兘澹版槑鈥濇潵鎻忚堪鑷繁錛屽緱鍒拌繖涔堜竴涓弿榪扮殑瀛楃涓詫紝鐒跺悗闅忔椂閮藉彲浠ョ敤榪欎釜瀛楃涓叉潵鍔ㄦ佺敓鎴愯娉曞垎鏋愬櫒浜嗐?/p>
鎬昏岃█涔嬪氨鏄?br>1銆佸疄鐜板彲閰嶇疆璇硶鍒嗘瀽鍣紝鍙互鐩存帴鐢ㄦ暟鎹粨鏋勫仛鍑轟竴涓駭鐢熷姩鎬佹暟鎹粨鏋勭殑parser combinator錛岃涓篜C銆?br>2銆佺敤PC鍋氫竴涓滆娉曟爲緇撴瀯鍜屾枃娉曢兘澹版槑鈥濈殑璇硶鍒嗘瀽鍣ㄣ傝繖涓滆娉曟爲緇撴瀯鍜屾枃娉曢兘澹版槑鈥濊涓篜C Grammar銆?br>3銆丳C Grammar褰撶劧鍙互鐢ㄦ潵琛ㄨ揪PC Grammar鑷繁錛岃繖鏍鋒垜浠氨寰楀埌浜嗕竴涓笓闂ㄧ敤鏉ヨ鏄庝粈涔堟槸鍚堟硶鐨勨滆娉曟爲緇撴瀯鍜屾枃娉曢兘澹版槑鈥濈殑鎻忚堪鐨勫瓧絎︿覆鐨勮繖涔堜釜鏂囨硶錛岃涓篜C Grammar Syntax Definition銆?br>4銆侀氳繃榪欎喚婊¤凍PC Grammar瑕佹眰鐨凱C Grammar Syntax Definition錛屾垜浠氨鍙互鐢≒C鏉ヨВ閲奝C Grammar Syntax Definition錛屽姩鎬佷駭鐢熶竴涓В閲奝C Grammar鐨勮娉曞垎鏋愬櫒
5銆佹湁浜哖C Grammar鐨勮娉曞垎鏋愬櫒PC Grammar Parser (in memory version)錛屼箣鍚庢垜浠氨鍙互鎶娾滄枃娉?>C++浠g爜鈥濈殑浠g爜鐢熸垚鍣ㄥ仛鍑烘潵錛岀О涔嬩負PC Grammar C++ Codegen銆?br>6銆佹湁浜哖C Grammar C++ Codegen錛屾垜浠氨鍙互鐢ㄤ粬璇誨叆PC Grammar Syntax Definition錛屼駭鐢熶竴涓洿鎺ョ敤C++鍐欑殑PC Grammar鐨勮娉曞垎鏋愬櫒錛屽彨鍋歅C Grammar Parser (C++ version)銆?/p>
鍒版涓烘錛屾垜浠幏寰楃殑涓滆タ鏈?br>1銆丳C 錛圥arser Combinator錛?br>2銆丳C Grammar
3銆丳C Grammar Syntax Definition
4銆丳C Grammar Parser (in memory version)
5銆丳C Grammar Parser (C++ version)
6銆丳C Grammar C++ Codegen
鍏朵腑錛?銆?銆?銆?銆?閮芥槸鍙互鎵ц鐨勶紝2鏄竴涓滄爣鍑嗏濄傚埌浜嗚繖涓姝ワ紝鎴戜滑灝卞彲浠ョ敤PC Grammar Parser (C++ version)鏉ユ浛鎹㈡帀PC Grammar C++ Codegen閲岄潰鐨凱C Grammar Parser (in memory version)浜嗐傝繖灝辮窡gcc瑕佺紪璇戜竴涓皬緙栬瘧鍣ㄦ潵緙栬瘧鑷繁寰楀埌涓涓畬鏁寸殑gcc涓鏍楓傝繖涓繃紼嬭繕鍙互鐢ㄦ潵嫻嬭瘯PC Grammar C++ Codegen鏄惁鍐欑殑瓚沖濂姐?/p>
閭d箞鈥滆娉曟爲緇撴瀯鍜屾枃娉曢兘澹版槑鈥濆埌鍦版槸浠涔堟牱瀛愮殑鍛紵鎴戣繖閲岀粰鍑轟竴涓畝鍗曠殑鏂囨硶錛屽氨鏄敤鏉arse璇稿int銆乿l::collections::List<WString>銆乮nt*銆乮nt&銆乮nt[]銆乿oid(int, WString, double*)鐨勮繖浜涚被鍨嬬殑瀛楃涓蹭簡銆備笅闈㈤鍏堝睍紺哄浣曠敤榪欎釜鎻忚堪鏉ヨВ鍐充笂闈㈢殑鈥滅被鍨嬧濈殑璇硶涔﹀0鏄庯細
class Type{}
class DecoratedType : Type
{
enum Decoration
{
Pointer,
Reference,
Array,
}
Decoration decoration;
Type elementType;
}
class PrimitiveType : Type
{
token name;
}
class GenericType : Type
{
Type type;
Type[] arguments;
}
class SubType : Type
{
Type type;
token name;
}
class FunctionType : Type
{
Type returnType;
Type[] arguments;
}
鐒跺悗灝辨槸澹版槑璇硶鍒嗘瀽鍣ㄦ墍闇瑕佺殑璇嶆硶鍏冪礌錛岀敤姝e垯琛ㄨ揪寮忔潵鎻忚堪錛?/p>
token SYMBOL = <|>|\[|\]|\(|\)|,|::|\*|&
token NAME = [a-zA-Z_]\w*
榪欓噷鍙渶瑕佷袱縐峵oken灝卞彲浠ヤ簡銆傛帴涓嬫潵灝辨槸涓ょ絳変環鐨勫浜庤繖涓枃娉曠殑鎻忚堪錛岀敤鏉ュ睍紺哄叏閮ㄧ殑鍔熻兘銆?/p>
========================================================
Type SubableType = NAME[name] as PrimitiveType
= SubableType[type] '<' Type[arguments] { ',' Type[arguments] } '>' as GenericType
= SubableType[type] '::' NAME[name] as SubType
Type Type = @SubableType
= Type[elementType](
( '*' {decoration = DecoratedType::Pointer}
| '&' {decoration = DecoratedType::Reference}
| '[' ']' {decoration = ecoratedType::Array}
)
) as DecoratedType
= Type[returnType] '(' Type[arguments] { ',' Type[arguments] } ')' as FunctionType
========================================================
rule PrimitiveType PrimitiveType = NAME[name]
rule GenericType GenericType = SubableType[type] '<' Type[arguments] { ',' Type[arguments] } '>'
rule SubType SubType = SubableType[type] :: NAME[name]
rule Type SubableType = @PrimitiveType | @GenericType | @SubType
rule DecoratedType DecoratedType = Type[elementType] '*' {decoration = DecoratedType::Pointer}
= Type[elementType] '&' {decoration = DecoratedType::Reference}
= Type[elementType] '[' ']' {decoration = DecoratedType::Array}
rule FunctionType FunctionType = Type[returnType] '(' Type[arguments] { ',' Type[arguments] } ')'
rule Type Type = @SubableType | @DecoratedType | @FunctionType
========================================================
濡傛灉鏁村緋葷粺寮鍙戝嚭鏉ョ殑璇濓紝閭d箞鎴戝氨浼氭彁渚涗竴涓彨鍋歅arserGen.exe鐨勫懡浠よ宸ュ叿錛屾妸涓婇潰鐨勫瓧絎︿覆杞崲涓轟竴涓?strong>鍙鐨勩佺瓑浠蜂笌榪欐鏂囨硶鐨勩佷嬌鐢ㄩ掑綊涓嬮檷鏂規硶鏉ユ弿榪扮殑銆丆++鍐欏嚭鏉ョ殑璇硶鍒嗘瀽鍣ㄥ拰璇硶鏍戝0鏄庝簡銆?/p>
鎴戝啓浜嗕竴涓狧ttpUtility搴撴潵瀹炵幇C++鎿嶄綔http/https鏈嶅姟鐨勫姛鑳斤紝榪欎喚浠g爜鍙互鍦ㄨ繖閲岃幏寰楋細
HttpUtility.h錛?a style="color: ; text-decoration: underline" target="_blank">http://gac.codeplex.com/SourceControl/changeset/view/95641#2295555
HttpUtility.cpp錛?a title="http://gac.codeplex.com/SourceControl/changeset/view/95641#2295554" style="color: ; text-decoration: underline" target="_blank">http://gac.codeplex.com/SourceControl/changeset/view/95641#2295554
浣跨敤鐨勬椂鍊欏緢綆鍗曪紝鍙渶瑕丠ttpRequest閲岄潰濉弧浜嗗弬鏁幫紝鐒跺悗灝卞彲浠ョ敤HttpQuery鍙傛暟鑾峰緱涓涓狧ttpResponse綾誨瀷錛岃繖涓被鍨嬮噷闈㈠啓婊′簡http鏈嶅姟鍣ㄧ殑榪斿洖鍊箋佽繑鍥炲唴瀹瑰拰cookie絳夌殑鏁版嵁銆傝濡傝鐢ㄦ潵post鏉ョ櫥闄嗛笩紿濓紝鐒跺悗鎷垮埌cookie涔嬪悗鏌ヨ棣栭〉鐨勬墍鏈夊笘瀛愶紝澶ф灝卞彲浠ヨ繖涔堝啓錛?/p>
WString NestleGetSession(const WString& username, const WString& password, const WString& apiKey, const WString& apiSecret)
{
WString body=L"api_key="+apiKey+L"&api_secret="+apiSecret+L"&username="+username+L"&password="+password;
HttpRequest request;
HttpResponse response;
request.SetHost(L"https://www.niaowo.me/account/token/");
request.method=L"POST";
request.contentType=L"application/x-www-form-urlencoded";
request.SetBodyUtf8(body);
HttpQuery(request, response);
if(response.statusCode==200)
{
return response.cookie;
}
else
{
return L"";
}
}
WString NestleGetXml(const WString& path, const WString& cookie)
{
HttpRequest request;
HttpResponse response;
request.SetHost(L"https://www.niaowo.me"+path+L".xml");
request.method=L"GET";
request.cookie=cookie;
request.acceptTypes.Add(L"application/xml");
HttpQuery(request, response);
if(response.statusCode==200)
{
return response.GetBodyUtf8();
}
else
{
return L"";
}
}
浜庢槸鎴戜滑緇堜簬鑾峰緱浜嗕竴涓繚瀛樺湪vl::WString鐨剎ml瀛楃涓蹭簡錛岄偅鎬庝箞鍔炲憿錛熻繖涓椂鍊欓渶瑕佸嚭鍔↖XMLDOMDocument2鏉ヨВ鏋愭垜浠殑xml銆傚彧瑕佽浜咺E鐨勮綆楁満涓婇兘鏄湁IXMLDOMDocument2鐨勶紝鑰屼笉瑁匢E鐨刉indows PC鏄笉瀛樺湪鐨勶紝鍥犳鎴戜滑鎬繪槸鍙互澶ц儐鐨勪嬌鐢ㄣ傚綋鐒訛紝鐢↖XMLDOMDocument鐩存帴鏉ラ亶鍘嗕粈涔堜笢瑗跨壒鍒殑鎱紝鎵浠ユ垜浠渶瑕佺殑鏄痻path銆倄path瀵逛簬xml灝辮窡regex瀵逛簬瀛楃涓蹭竴鏍鳳紝鍙互鐩存帴鏌ヨ鍑烘垜浠鐨勪笢瑗褲傞鍏堢湅涓涓嬪浣曟搷浣淚XMLDOMDocument2鎺ュ彛錛?/p>
IXMLDOMNodeList* XmlQuery(IXMLDOMNode* pDom, const WString& xpath)
{
IXMLDOMNodeList* nodes=0;
BSTR xmlQuery=SysAllocString(xpath.Buffer());
if(xmlQuery)
{
HRESULT hr=pDom->selectNodes(xmlQuery, &nodes);
if(FAILED(hr))
{
nodes=0;
}
SysFreeString(xmlQuery);
}
return nodes;
}
WString XmlReadString(IXMLDOMNode* node)
{
WString result;
BSTR text=0;
HRESULT hr=node->get_text(&text);
if(SUCCEEDED(hr))
{
const wchar_t* candidateItem=text;
result=candidateItem;
SysFreeString(text);
}
return result;
}
void XmlReadMultipleStrings(IXMLDOMNodeList* textNodes, List<WString>& candidates, int max)
{
candidates.Clear();
while((int)candidates.Count()<max)
{
IXMLDOMNode* textNode=0;
HRESULT hr=textNodes->nextNode(&textNode);
if(hr==S_OK)
{
candidates.Add(XmlReadString(textNode));
textNode->Release();
}
else
{
break;
}
}
}
IXMLDOMDocument2* XmlLoad(const WString& content)
{
IXMLDOMDocument2* pDom=0;
HRESULT hr=CoCreateInstance(__uuidof(DOMDocument60), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDom));
if(SUCCEEDED(hr))
{
pDom->put_async(VARIANT_FALSE);
pDom->put_validateOnParse(VARIANT_FALSE);
pDom->put_resolveExternals(VARIANT_FALSE);
BSTR xmlContent=SysAllocString(content.Buffer());
if(xmlContent)
{
VARIANT_BOOL isSuccessful=0;
hr=pDom->loadXML(xmlContent, &isSuccessful);
if(!(SUCCEEDED(hr) && isSuccessful==VARIANT_TRUE))
{
pDom->Release();
pDom=0;
}
SysFreeString(xmlContent);
}
}
return pDom;
}
鏈変簡榪欏嚑涓嚱鏁頒箣鍚庯紝鎴戜滑灝卞彲浠ュ共涓嬮潰鐨勪簨鎯咃紝璀璇翠粠楦熺獫棣栭〉涓嬭澆絎竴欏電殑鎵鏈塼opic鐨勬爣棰橈細
WString xml=NestleGetXml(L”/topics”, cookie);
IXMLDOMDocument2* pDom=XmlLoad(xml);
List<WString> titles;
IXMLNodeList* nodes=XmlQuery(pDom, L”/hash/topics/topic/title/text()”);
XmlReadMultipleStrings(nodes, titles, 100);
涓轟粈涔堜笂闈㈢殑xpath鏄痟ash/topics/topic/title/text()鍛?鍥犱負榪欎釜xml鐨勫唴瀹瑰ぇ姒傜被浼間簬錛?br /><hash>
<topics>
<topic>
<title>TITLE</title>
…
鍓╀笅鐨勫ぇ瀹跺氨鍘葷湅浠g爜鍚с傝繖涓晠浜嬪憡璇夋垜浠紝鍙鏈変竴涓悎閫傜殑灝佽錛孋++鍐欒搗榪欎簺鏈潵搴旇璁〤#鏉ュ啓鐨勪笢瑗夸篃涓嶆槸閭d箞鐨勭儲浜虹殑錛屽晩鍝堝搱鍝堝搱銆?/p>