這個分析器包含了四個文件:
VL_Data_Basic.h(使用了其中的智能指針VL_AutoPtr和一些類型重命名)
VL_CpData.h(數(shù)據(jù)結構)
VL_CpKernel.h/cpp(詞法分析器和語法分析器)
昨天剛寫好的,可能有Bug,這個東西供給熟悉編譯原理(至少熟悉BNF notation)的人互相學習交流,并不打算作為一個成品出現(xiàn)。以下是將一個四則運算式子的字符串進行詞法分析,分割成記號之后求值的代碼:
1 #include "..\..\..\..\VL++\Library\Platform\VL_Console.h"
2 #include "..\..\..\..\VL++\Library\Data\Grammar2\VL_CpKernel.h"
3
4 using namespace vl;
5 using namespace vl::platform;
6 using namespace vl::grammar;
7
8 enum Operator
9 {
10 opAdd,
11 opSub,
12 opMul,
13 opDiv
14 };
15
16 enum TokenID
17 {
18 tiNumber,
19 tiLeft,
20 tiRight,
21 tiAdd,
22 tiSub,
23 tiMul,
24 tiDiv
25 };
26
27 VDouble Number(const VL_CpToken& Input)
28 {
29 return VUnicodeString(Input.Start,Input.Length).ToDouble();
30 }
31
32 Operator Op(const VL_CpToken& Input)
33 {
34 switch(Input.ID)
35 {
36 case tiAdd:return opAdd;
37 case tiSub:return opSub;
38 case tiMul:return opMul;
39 case tiDiv:return opDiv;
40 default:return (Operator)-1;
41 }
42 }
43
44 VDouble RemoveBracket(const VL_CpPair<VL_CpPair<VL_CpToken , VDouble> , VL_CpToken>& Input)
45 {
46 return Input.First.Second;
47 }
48
49 VDouble Calculate(const VL_CpPair<VDouble,VL_CpList<VL_CpPair<Operator,VDouble>>>& Numbers)
50 {
51 VDouble Result=Numbers.First;
52 VL_CpList<VL_CpPair<Operator,VDouble>>::Node::Ptr Current=Numbers.Second.Head;
53 while(Current)
54 {
55 switch(Current->Data.First)
56 {
57 case opAdd:
58 Result+=Current->Data.Second;
59 break;
60 case opSub:
61 Result-=Current->Data.Second;
62 break;
63 case opMul:
64 Result*=Current->Data.Second;
65 break;
66 case opDiv:
67 Result/=Current->Data.Second;
68 break;
69 }
70 Current=Current->Next;
71 }
72 return Result;
73 }
74
75 void Parse()
76 {
77 VL_CpLexer Lexer;
78 Lexer
79 <<Token(false,L"(",tiLeft)
80 <<Token(false,L")",tiRight)
81 <<Token(false,L"+",tiAdd)
82 <<Token(false,L"-",tiSub)
83 <<Token(false,L"*",tiMul)
84 <<Token(false,L"/",tiDiv)
85 <<Token(false,_Float,tiNumber)
86 ;
87
88 _Wrapper<VL_CpTokenNodePtr , VDouble> Factor,Term,Expr;
89 Factor = (Number<<=Token(tiNumber)) | (RemoveBracket <<= Token(tiLeft) + Expr + Token(tiRight));
90 Term = Calculate <<= Factor + *((Op<<=Token(tiMul)|Token(tiDiv)) + Factor);
91 Expr = Calculate <<= Term + *((Op<<=Token(tiAdd)|Token(tiSub)) + Term);
92
93 VL_CpParser<VL_CpTokenNodePtr , VDouble> p=Expr;
94 VL_CpParser<VL_CpTokenNodePtr , VDouble>::_FullResult Value=p.Parse(Lexer.Parse(L"(1+2)*(3+4)").First.Head);
95 GetConsole()->Write(L"結果:\t"+VUnicodeString(Value.Head->Data.First)+L"\r\n");
96 }
97
98 void vlmain()
99 {
100 GetConsole()->SetTitle(L"Vczh Combinator Parser");
101 GetConsole()->SetTestMemoryLeaks(true);
102 GetConsole()->SetPauseOnExit(true);
103
104 Parse();
105 }
點擊
這里下載。
posted on 2009-04-03 01:21
陳梓瀚(vczh) 閱讀(6310)
評論(9) 編輯 收藏 引用 所屬分類:
作品