Combinator_Parser这个分析器包含了四个文件:
VL_Data_Basic.h(使用了其中的智能指针VL_AutoPtr和一些类型重命名)
VL_CpData.h(数据结构)
VL_CpKernel.h/cpp(词法分析器和语法分析器)
以下是将一个四则运算式子的字符串进行词法分析,分割成记号之后求值的代码:
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
}