exp解析
1 #pragma once
2 #include <string>
3 #include <functional>
4 #include <type_traits>
5 #include <stack>
6 struct OpratorObject
7 {
8 OpratorObject(int a)
9 {
10
11 }
12 OpratorObject(double a)
13 {
14
15 }
16 OpratorObject()
17 {
18
19 }
20 };
21 enum ExpType {
22 ADD, //加
23 SUB, //减
24 MULT, //乘
25 DIV, //除
26 VALUE, //直接取值
27 FUNC
28 };
29 struct ExpNode
30 {
31 //每一个表达式都有值
32 virtual std::string GetValue() = 0;
33 };
34 struct ExpNodeString : public ExpNode
35 {
36 public:
37 ExpType t;
38 ExpNodeString* left;
39 ExpNodeString* right;
40 std::string val;
41 std::string GetValue()
42 {
43 if (t == VALUE)
44 {
45 return val;
46 }
47 std::string lval = left->t == VALUE ? left->val : left->GetValue();
48 std::string rval = right->t == VALUE ? right->val : right->GetValue();
49 if (t == ADD)
50 {
51 return std::to_string(std::stof(lval) + std::stof(rval));
52 }
53 if (t == SUB)
54 {
55 return std::to_string(std::stof(lval) - std::stof(rval));
56 }
57 if (t == MULT)
58 {
59 return std::to_string(std::stof(lval) * std::stof(rval));
60 }
61 if (t == DIV)
62 {
63 return std::to_string(std::stof(lval) / std::stof(rval));
64 }
65
66 return "";
67 }
68 };
69 struct ExpNodeStringValFunc : public ExpNodeString
70 {
71 public:
72 std::string result; //结果
73 std::function<std::string(void)> func;
74 std::string exp;
75 };
76
77 std::string right; //
78 struct Exp
79 {
80 //我目前先声明了一个node然后先放入左操作数,遇到(才创建新的子node
81 //这里应该是遇到操作符 也要创建新的node
82
83
84 static bool Parse(std::string s, ExpNodeString*& root)
85 {
86 root = new ExpNodeString();
87 ExpNodeString* pCur = root;
88 std::stack<ExpNodeString*> pCurStack;
89 pCurStack.push(root);
90 bool bLeft = true; //先从左操作数开始
91 for (int i = 0; i < s.size(); i++)
92 {
93 pCur = pCurStack.top();
94 char ch = s[i];
95 if (ch != ' ')
96 {
97 if (isdigit(ch))
98 {
99 if (bLeft)
100 {
101 if (pCur->left == nullptr)
102 {
103 pCur->left = new ExpNodeString();
104 }
105 pCur->left->t = VALUE;
106 pCur->left->val.push_back(ch);
107 }
108 else {
109 if (pCur->right == nullptr)
110 {
111 pCur->right = new ExpNodeString();
112 }
113 pCur->right->t = VALUE;
114 pCur->right->val.push_back(ch);
115 }
116 }
117 else if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
118 {
119 if (bLeft)
120 {
121 bLeft = false;
122 }
123 if (pCur->left != nullptr && pCur->right != nullptr)
124 {
125 ExpNodeString* pTemp = new ExpNodeString();
126 //pCur->right = new ExpNodeString();
127 pTemp->left = pCur;
128 pCurStack.pop();
129 pCurStack.push(pTemp);
130 pCur = pCurStack.top();
131 }
132 //左子节点如果为空就不需要创建新的node了实际情况:(5+2)/3
133 //if (pCur->left != nullptr)
134 //{
135 // ExpNodeString* pTemp = new ExpNodeString();
136 // pTemp->left = pCur;
137 // pCurStack.pop();
138 // pCurStack.push(pTemp);
139 // //pCurStack.push(pTemp->left);
140 // if (pCur == root)
141 // {
142 // root = pTemp;
143 // }
144 // pCur = pTemp;
145 // pCur = pCurStack.top();
146 //}
147 //bLeft = false;
148
149 if (ch == '+')
150 {
151 pCur->t = ADD;
152 }
153 else if (ch == '-')
154 {
155 pCur->t = SUB;
156 }
157 else if (ch == '*')
158 {
159 pCur->t = MULT;
160 }
161 else if (ch == '/')
162 {
163 pCur->t = DIV;
164 }
165 }
166 else if (ch == '(')
167 {
168 //if (root == pCur) continue;
169 if (bLeft)
170 {
171 pCur->left = new ExpNodeString();
172 pCurStack.push(pCur->left);
173 pCur = pCur->left;
174 }
175 else
176 {
177 pCur->right = new ExpNodeString();
178 pCurStack.push(pCur->right);
179 }
180 bLeft = true;
181 }
182 else if (ch == ')')
183 {
184 pCur = pCurStack.top();
185 //这里要一直弹出
186 while (pCur->left != nullptr && pCur->right != nullptr)
187 {
188 pCurStack.pop();
189 if (pCurStack.size() == 0)
190 {
191 ExpNodeString* pTemp = new ExpNodeString();
192 pTemp->left = pCur;
193 pCurStack.push(pTemp);
194 root = pTemp;
195 }
196 pCur = pCurStack.top();
197 }
198 pCur = pCurStack.top();
199 //}
200
201 //if (root == pCur)
202 //{
203 // //小括号开头的
204 // ExpNodeString* pTemp = new ExpNodeString();
205 // pTemp->left = pCur;
206 // pCurStack.pop();
207 // pCurStack.push(pTemp);
208
209 // //pCur = pCur->left;
210 // root = pTemp;
211 //}
212 bLeft = !bLeft;
213 }
214 }
215 }
216 if (pCurStack.size() == 0 || pCurStack.size() == 1)
217 {
218 if (pCurStack.size() == 1)
219 {
220 root = pCurStack.top();
221 if (root->t != VALUE && root->left != nullptr && root->right != nullptr)
222 {
223
224 }
225 else {
226 root = root->left;
227 }
228 }
229 return true;
230 }
231 return false;
232 }
233 static bool Parse2(std::string s, ExpNodeString*& root)
234 {
235 //这里的思路是先组装一个left操作数,然后遇到operator然后在组装一个父节点
236 //中间遇到小括号出问题了
237 root = new ExpNodeString();
238 ExpNodeString* pCur = root;
239 std::stack<ExpNodeString*> pCurStack;
240 pCurStack.push(root);
241 bool bLeft = true; //先从左操作数开始
242 for (int i = 0; i < s.size(); i++)
243 {
244 pCur = pCurStack.top();
245 char ch = s[i];
246 if (ch != ' ')
247 {
248 if (isdigit(ch))
249 {
250 if (pCur->left == nullptr && pCur->right == nullptr)
251 {
252 pCur->t = VALUE;
253 pCur->val.push_back(ch);
254 }
255 else
256 if (bLeft == true)
257 {
258 pCur->left->t = VALUE;
259 pCur->left->val.push_back(ch);
260 }
261 else
262 {
263 pCur->right->t = VALUE;
264 pCur->right->val.push_back(ch);
265 }
266 /*if (pCur->left == nullptr)
267 {
268 pCur->left = new ExpNodeString();
269 }
270
271 /*}
272 else {
273 if (pCur->right == nullptr)
274 {
275 pCur->right = new ExpNodeString();
276 }
277 pCur->right->t = VALUE;
278 pCur->right->val.push_back(ch);
279 }*/
280 }
281 else if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
282 {
283
284 //if (bLeft)
285 //{
286 // bLeft = false;
287 //}
288 //else {
289 // //左子节点如果为空就不需要创建新的node了实际情况:(5+2)/3
290 // if (pCur->left != nullptr)
291 // {
292
293 ExpNodeString* pTemp = new ExpNodeString();
294 ExpNodeString* pTempRight = new ExpNodeString();
295 /* if (root == pCur)
296 {
297 pTemp->left = pCur;
298 pCurStack.pop();
299 pCurStack.push(pTemp);
300 pCurStack.push(pTemp->right);
301 }
302 else {*/
303 pCurStack.pop();
304 if (pCurStack.size() == 0)
305 {
306 pTemp->left = pCur;
307 root = pTemp;
308 }
309 else
310 pTemp->left = pCurStack.top();
311 pTemp->right = pTempRight;
312 pCurStack.push(pTemp);
313 bLeft = false;
314 //pCurStack.push(pTemp->left);
315 /* if (pCur == root)
316 {*/
317
318 //}
319 pCur = pTemp;
320 // }
321 // bLeft = false;
322 if (ch == '+')
323 {
324 pCur->t = ADD;
325 }
326 else if (ch == '-')
327 {
328 pCur->t = SUB;
329 }
330 else if (ch == '*')
331 {
332 pCur->t = MULT;
333 }
334 else if (ch == '/')
335 {
336 pCur->t = DIV;
337 }
338 }
339 if (ch == '(')
340 {
341 if (!bLeft)
342 {
343 //if (root != pCur)
344 {
345 //pCur->right = new ExpNodeString();
346 pCurStack.push(pCur->right);
347 pCur = pCur->right;
348 /*pCur->right = new ExpNodeString();
349 pCur->left = new ExpNodeString();*/
350 bLeft = true;
351 }
352 }
353 }
354 if (ch == ')')
355 {
356 pCurStack.pop();
357 //同时意味着这个exp结束
358 }
359 }
360 }
361 if (pCurStack.size() == 0 || pCurStack.size() == 1)
362 {
363 return true;
364 }
365 return false;
366 }
367 static bool Parse3(std::string s, ExpNodeString* pRoot)
368 {
369 // value operator
370 // func
371 // val
372 //
373 }
374
375 };
exp解析的更多相关文章
- FastFel解析一个公式的步骤
FastFel 查看源码后,理解的运算步骤: 1) 创建一个 FelEngine,FelEngine fel = new FelEngineIml(); 2) 将表达式 exp 解析成为一个节点树 F ...
- 好用的Google漏洞爬虫:Google Mass Explorer
这是一款基于谷歌搜索引擎的自动化爬虫. 爬虫介绍 爬虫大体机制就是: 先进行一次谷歌搜索,将结果解析为特定格式,然后再提供给exp使用. 大家可以尝试使用–help来列出所有参数. 这个项目笔者会持续 ...
- Object.defineProperties()
w https://docs.microsoft.com/en-us/scripting/javascript/reference/object-defineproperty-function-jav ...
- 如何在 messager/alert/confirm等消息提示框中 获取 / 设置 嵌入 html内容中的 input[type=checkbox]等的选中状态?
总结, 有3点: 不能/不要 在 这些消息框 / 提示框/ 对话框中的 回调函数中去写代码: 获取嵌入 内容中input.checkbox的选中状态, 因为 虽然在这些框存在的时候, 这个 check ...
- ORM开发之解析lambda实现完整查询(附测试例子)
上次讲解了怎么解析匿名对象(ORM开发之解析lambda实现group查询),这次来实现解析二元运算,完成基本条件语法 先看一个表达式 query.Where(b => b.Number == ...
- GBDT算法原理深入解析
GBDT算法原理深入解析 标签: 机器学习 集成学习 GBM GBDT XGBoost 梯度提升(Gradient boosting)是一种用于回归.分类和排序任务的机器学习技术,属于Boosting ...
- Atitit 表达式原理 语法分析 原理与实践 解析java的dsl 递归下降是现阶段主流的语法分析方法
Atitit 表达式原理 语法分析 原理与实践 解析java的dsl 递归下降是现阶段主流的语法分析方法 于是我们可以把上面的语法改写成如下形式:1 合并前缀1 语法分析有自上而下和自下而上两种分析 ...
- 优化与扩展Mybatis的SqlMapper解析
接上一篇博文,这一篇来讲述怎么实现SchemaSqlMapperParserDelegate——解析SqlMapper配置文件. 要想实现SqlMapper文件的解析,还需要仔细分析一下mybatis ...
- 利用 druid 解析器解析SQL
最近参与一个开源项目,一个功能的实现,用到了 druid 解析器来解析SQL,记录下如果使用 druid 来解析SQL,实现对SQL的拦截改写. 1. 对 insert 语句进行解析: private ...
- 一起写一个JSON解析器
[本篇博文会介绍JSON解析的原理与实现,并一步一步写出来一个简单但实用的JSON解析器,项目地址:SimpleJSON.希望通过这篇博文,能让我们以后与JSON打交道时更加得心应手.由于个人水平有限 ...
随机推荐
- WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)
在 WPF 中,如果想做一个背景透明的异形窗口,基本上都要设置 WindowStyle="None".AllowsTransparency="True" 这两个 ...
- 在 Rainbond 中一键安装高可用 Nacos 集群
描述如何通过云原生应用管理平台 Rainbond 一键安装高可用 Nacos 集群.这种方式适合不太了解 Kubernetes.容器化等复杂技术的用户使用,降低了在 Kubernetes 中部署 Na ...
- testArticle
Test Article This is a test article for ArticleSync. Test Edit...... test Edit
- python相关常见安装问题
1 Centos7安装pip 参考链接:centos7 pip升级 - fuhaizi - 博客园 (cnblogs.com) Centos7默认pip版本: 使用默认pip版本安装numpy库,会报 ...
- python安装OCR识别库
(1)安装过程 参考的这个博客:https://blog.csdn.net/lanxianghua/article/details/100516187?depth_1-utm_source=distr ...
- python-判断两个序列的成员是否一样
目的:判断两个序列的成员是否一样,如:list1 = [1, 2],list2 = [2, 1],则两个序列的成员是一样的. 实现:借助集合set()的性质实现. 代码如下: 1 if __name_ ...
- web服务器 传统开发和前后端分离开发 服务器相关概念
web服务器 Web服务器一般指的是网站服务器,是指驻留因特网上某一台或N台计算机的程序,可以处理浏览器等Web客户端的请求并返回相应响应,目前最主流的三个Web服务器是Apache. Nginx . ...
- Android Media Framework(三)OpenMAX API阅读与分析
这篇文章我们将聚焦Control API的功能与用法,为实现OMX Core.Component打下坚实的基础. 1.OMX_Core.h OMX Core在OpenMAX IL架构中的位置位于IL ...
- idea 中的 jrebel
1.打开idea设置 ,下载 jrebel 2搜索下载jrebel 3.重启之后,在右下角有个弹窗,这时候选择enable,然后右边的侧边栏工具会弹出一个界面,总共应该有4步,第一步是展开的,点击蓝色 ...
- windows nexus-3.20安装
1.Nexus官网:https://www.sonatype.com/download-oss-sonatype 2.环境变量NEXUS_HOME = D:\nexus-3.20.1-01-win64 ...