C++轻量级可配置语法分析器(开源) - λ-calculus(惊愕到手了欧耶,GetBlogPostIds.aspx) - C++博客
2013-01-24 13:17
721 查看
C++轻量级可配置语法分析器(开源) - λ-calculus(惊愕到手了欧耶,GetBlogPostIds.aspx) - C++博客
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 {
GetConsole()->SetTitle(L"Vczh Combinator Parser");
GetConsole()->SetTestMemoryLeaks(true);
GetConsole()->SetPauseOnExit(true);
Parse();
}
点击这里下载。
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 {
GetConsole()->SetTitle(L"Vczh Combinator Parser");
GetConsole()->SetTestMemoryLeaks(true);
GetConsole()->SetPauseOnExit(true);
Parse();
}
点击这里下载。
相关文章推荐
- 《构造正则表达式引擎》新鲜出炉啦! - λ-calculus(惊愕到手了欧耶,GetBlogPostIds.aspx) - C++博客
- C++实用技巧(一) - λ-calculus(惊愕到手了欧耶,GetBlogPostIds.aspx) - C++博客
- λ-calculus(惊愕到手了欧耶,GetBlogPostIds.aspx) - C++博客
- 【转】C++轻量级可配置语法分析器
- 【我的笔记BLOG4】搭建多人博客<内含http请求的get post方法区别>
- 开源博客QBlog开发者视频教程:开篇-开发基础配置与系统运行(一)
- Vue------第五天(Vue的Ajax请求,使用Axios,目前熟悉了一下,主要包括GET请求、POST请求、并发请求、请求参数的配置、服务器响应的结构以及对服务器响应错误的简单处理)
- 09_android入门_採用android-async-http开源项目的GET方式或POST方式实现登陆案例
- 水印+微图图(转http://tb.blog.csdn.net/TrackBack.aspx?PostId=721170)
- 【实战】(三)android模拟qq登录(开源框架get和post)
- EntLib.com Blog 开源ASP.NET/C# 博客平台 v3.1 发布(提供源码下载)
- C++开源跨平台类库及在VC++.net中应用的配置
- C++ 简单实现HTTP GET/POST 请求
- 【我的笔记BLOG1】配置webstorm + node.js +express + mongodb开发博客的环境
- CSDN的Blog要如何配置才能够用Windows Live Writer发布带有图片的Post?
- OOPHP开源博客:Zend Framework 1.8或1.9版本以上配置教程
- Open Source Blog 开源ASP.NET/C# 博客平台 v3.0 发布(提供源码下载)
- http://tb.blog.csdn.net/TrackBack.aspx?PostId=1571046
- C++ 中通过GetAdaptersInfo获取网卡配置和Ip地址信息
- 2011年国庆发布:(cppblog)C++博客十八罗汉造像