C++轻量级可配置语法分析器(开源) - λ-calculus(惊愕到手了欧耶,GetBlogPostIds.aspx) - C++博客
这个分析器包含了四个文件:
VL_Data_Basic.h(使用了其中的智能指针VL_AutoPtr和一些类型重命名)
VL_CpData.h(数据结构)
VL_CpKernel.h/cpp(词法分析器和语法分析器)
昨天刚写好的,可能有Bug,这个东西供给熟悉编译原理(至少熟悉BNF notation)的人互相学习交流,并不打算作为一个成品出现。以下是将一个四则运算式子的字符串进行词法分析,分割成记号之后求值的代码:
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 }
点击 这里下载。