Skip to content

Commit 0e217e4

Browse files
author
冷漠
committed
增加对正余弦函数的求导&优化对数函数的输出
1 parent 0db2fd7 commit 0e217e4

File tree

10 files changed

+199
-123
lines changed

10 files changed

+199
-123
lines changed

SCMath.pro.user

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!DOCTYPE QtCreatorProject>
3-
<!-- Written by QtCreator 4.5.0, 2019-02-17T13:56:02. -->
3+
<!-- Written by QtCreator 4.5.0, 2019-02-17T15:06:51. -->
44
<qtcreator>
55
<data>
66
<variable>EnvironmentId</variable>

ast.cpp

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ static void ast::Init()
1616
Function* div = new Function(BuiltinFunc::hasTwoSonNodes, BuiltinFunc::div,2);
1717
Function* pow = new Function(BuiltinFunc::hasTwoSonNodes, BuiltinFunc::pow,2);
1818
Function* sin = new Function(BuiltinFunc::hasOneSonNode, BuiltinFunc::sin,1);
19+
Function* cos = new Function(BuiltinFunc::hasOneSonNode, BuiltinFunc::cos,1);
1920
Function* log = new Function(BuiltinFunc::hasTwoSonNodes, BuiltinFunc::log, 2);
2021
//将这些函数置入函数域
2122
record::globalScope.addFunction("+",add);
@@ -24,6 +25,7 @@ static void ast::Init()
2425
record::globalScope.addFunction("/",div);
2526
record::globalScope.addFunction("^",pow);
2627
record::globalScope.addFunction("sin",sin);
28+
record::globalScope.addFunction("cos",cos);
2729
record::globalScope.addFunction("log", log);
2830
//Function* entity=runtime::globalScope.functionList["+"]; //在parse阶段,可以这样从函数域中找到函数名对应的函数实体
2931
//FunNode* testNode=new FunNode(entity); //然后这样通过函数实体创建相应的函数节点
@@ -58,7 +60,7 @@ bool ast::canpush(stack<string> &stackOp, const string& op)
5860

5961
BasicNode* ast::__ToAST(string &s)
6062
{
61-
s += '$';
63+
s += LowestPriority;
6264
stack<BasicNode*> stackAST;
6365
stack<string> stackOp;
6466
int n = s.size();
@@ -69,23 +71,23 @@ BasicNode* ast::__ToAST(string &s)
6971
int j = i;
7072

7173
if ((s[j] == '+' || s[j] == '-') && (j == 0 || isBinOp(s[j - 1])))
72-
{
74+
{
7375
j++;
7476
}//检查负号还是减号
7577
if(j < n && isNum(s[j]))
7678
{
7779
while (j < n && isNum(s[j]))
7880
j++;//整数部分
79-
if (s[j] == '.' && j + 1 < n && isNum(s[j + 1])) {
81+
if (s[j] == '.' && j + 1 < n && isNum(s[j + 1])) {
8082
j++;//小数部分
8183
while (j < n && isNum(s[j + 1]))
8284
{
8385
j++;
8486
}
85-
}
86-
temp += s.substr(i,j-i);
87-
i = j;
88-
stackAST.push(new NumNode(stod(temp)));
87+
}
88+
temp += s.substr(i,j-i);
89+
i = j;
90+
stackAST.push(new NumNode(stod(temp)));
8991
}
9092

9193
else if (j < n && isLetter(s[j]))
@@ -94,18 +96,18 @@ BasicNode* ast::__ToAST(string &s)
9496
j++;
9597
if(j < n && s[j] == '(')//函数
9698
{
97-
FunNode* node = new FunNode(record::globalScope.functionList[s.substr(i, j - i)]);
98-
//此时s[j] == '('
99-
while(s[j] != ')' && s[j] != LowestPriority)
100-
{
101-
i = j;
102-
j++;
99+
FunNode* node = new FunNode(record::globalScope.functionList[s.substr(i, j - i)]);
100+
//此时s[j] == '('
101+
while(s[j] != ')' && s[j] != LowestPriority)
102+
{
103+
i = j;
104+
j++;
103105
while(j < n && s[j] != ',' && s[j] != ')' && s[j] != LowestPriority)
104106
j++;
105107
node->addNode(ToAST(s.substr(i + 1, j - i - 1)));
106-
}
107-
stackAST.push(node);
108-
i = j + 1;
108+
}
109+
stackAST.push(node);
110+
i = j + 1;
109111
}
110112

111113
else//变量
@@ -136,13 +138,13 @@ BasicNode* ast::__ToAST(string &s)
136138

137139
if(i < n && (isBinOp(s[i]) || s[i] == LowestPriority))//按理说,一个数字/变量/函数结束之后是一个运算符/字符串结尾
138140
{
139-
if (canpush(stackOp, s.substr(i,1)))
140-
{
141+
if (canpush(stackOp, s.substr(i,1)))
142+
{
141143
stackOp.push(s.substr(i,1));
142-
}
143-
else {
144-
while (!canpush(stackOp, s.substr(i,1)))
145-
{
144+
}
145+
else {
146+
while (!canpush(stackOp, s.substr(i,1)))
147+
{
146148
BasicNode* a = stackAST.top();
147149
stackAST.pop();
148150
BasicNode* b = stackAST.top();
@@ -159,7 +161,7 @@ BasicNode* ast::__ToAST(string &s)
159161
}
160162
else
161163
{
162-
throw string("Error string");
164+
throw string("Error string");
163165
}
164166

165167
}

funinterface.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ BasicNode* BuiltinFunc::sin(vector<BasicNode *> &sonNode)
4646
return new NumNode(std::sin(BuiltinFunc::getNum(sonNode[0])));
4747
}
4848

49+
BasicNode* BuiltinFunc::cos(vector<BasicNode *> &sonNode)
50+
{
51+
return new NumNode(std::cos(BuiltinFunc::getNum(sonNode[0])));
52+
}
53+
4954
BasicNode* BuiltinFunc::log(vector<BasicNode *> &sonNode)
5055
{
5156
return new NumNode(std::log(BuiltinFunc::getNum(sonNode[0])) / std::log(BuiltinFunc::getNum(sonNode[1])));

funinterface.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ class BuiltinFunc
1616
static BasicNode* mul(vector<BasicNode*>&sonNode);
1717
static BasicNode* div(vector<BasicNode*>&sonNode);
1818
static BasicNode* pow(vector<BasicNode*>&sonNode);
19+
1920
static BasicNode* sin(vector<BasicNode*>&sonNode);
21+
static BasicNode* cos(vector<BasicNode*>&sonNode);
22+
2023
static BasicNode* log(vector<BasicNode*>&sonNode);
2124
};

main.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ int main()
3131
cout << endl << endl;
3232
delete ansTestSimplificate;
3333

34-
string TestDerivation = "a+b-c*d/e+f^g";
34+
string TestDerivation = "a+b-c*d/e+f^g-2^a";
3535
BasicNode* ansTestDerivation = ast::ToAST(TestDerivation);
3636
BasicNode* ansAfterDerivation;
3737
output::outputAST(ansTestDerivation);
@@ -59,8 +59,17 @@ int main()
5959
ansAfterDerivation = Derivation(ansTestDerivation, "g");
6060
Simplificate(ansAfterDerivation);
6161
output::outputAST(ansAfterDerivation);
62-
cout << endl;
62+
cout << endl << endl;
6363
delete ansAfterDerivation;
6464
delete ansTestDerivation;
65+
66+
TestDerivation = "sin(x)*cos(x)";
67+
ansTestDerivation = ast::ToAST(TestDerivation);
68+
output::outputAST(ansTestDerivation);
69+
cout << endl;
70+
ansAfterDerivation = Derivation(ansTestDerivation, "x");
71+
Simplificate(ansAfterDerivation);
72+
output::outputAST(ansAfterDerivation);
73+
cout << endl << endl;
6574
return 0;
6675
}

nodetype.cpp

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -168,22 +168,22 @@ void FunNode::addNode(BasicNode *node)
168168

169169
BasicNode* FunNode::eval()
170170
{
171-
#ifdef PARTEVAL
171+
#ifdef PARTEVAL
172172
this->giveupEval=false;
173-
#endif
173+
#endif
174174

175175
if(this->funEntity==nullptr)
176176
throw string("funEntity is null");
177177

178-
#ifdef PARTEVAL
178+
#ifdef PARTEVAL
179179
try
180180
{
181-
#endif
182-
return this->funEntity->eval(this->sonNode);
181+
#endif
182+
return this->funEntity->eval(this->sonNode);
183183
}
184-
#ifdef PARTEVAL
184+
#ifdef PARTEVAL
185185
catch(callCheckMismatchExcep e) //因为未赋值变量未求值使得参数类型不匹配,放弃对这个函数求值
186-
//控制流节点对条件的求值会在此处进行,该节点放弃求值会被上层控制流节点检查到,控制流节点也会放弃求值
186+
//控制流节点对条件的求值会在此处进行,该节点放弃求值会被上层控制流节点检查到,控制流节点也会放弃求值
187187
{
188188
if(e.getType()==TypeMisMatch)
189189
{
@@ -193,17 +193,17 @@ BasicNode* FunNode::eval()
193193
else
194194
throw e;
195195
}
196-
#endif
196+
#endif
197197
}
198198

199199
#ifdef PARTEVAL
200200
bool isNotGiveupEval(BasicNode* node)
201201
{
202202
if(!(node->getType()==Fun&&dynamic_cast<FunNode*>(node)->giveupEval))
203-
if(!(node->getType()==If&&dynamic_cast<IfNode*>(node)->giveupEval))
204-
if(!(node->getType()==While&&dynamic_cast<WhileNode*>(node)->giveupEval))
205-
//warn:支持新的控制流节点后要在此处添加
206-
return true;
203+
if(!(node->getType()==If&&dynamic_cast<IfNode*>(node)->giveupEval))
204+
if(!(node->getType()==While&&dynamic_cast<WhileNode*>(node)->giveupEval))
205+
//warn:支持新的控制流节点后要在此处添加
206+
return true;
207207
return false;
208208
}
209209
#endif
@@ -215,22 +215,22 @@ void recursionEval(BasicNode* &node)
215215
else
216216
{
217217
BasicNode* result;
218-
#ifdef PARTEVAL
218+
#ifdef PARTEVAL
219219
try
220220
{
221-
#endif
222-
result=node->eval();
223-
#ifdef PARTEVAL
221+
#endif
222+
result=node->eval();
223+
#ifdef PARTEVAL
224224
}
225225
catch(unassignedEvalExcep) //对未赋值变量求值,保持原样
226226
{result=node;}
227-
#endif
227+
#endif
228228

229229
if(node->getType()!=Var&&node->getType()!=VarRef)
230-
#ifdef PARTEVAL
230+
#ifdef PARTEVAL
231231
if(isNotGiveupEval(node)) //对放弃求值的节点,不进行删除
232-
#endif
233-
delete node;
232+
#endif
233+
delete node;
234234
node=result; //节点的替换在这里(父节点)完成,子节点只需要返回即可
235235
//对于已经赋值的变量,整体过程是用值替代本身变量在AST中的位置,不过变量本身并没有被析构,因为变量的所有权在scope(后面可能还要访问)
236236
}
@@ -313,42 +313,42 @@ BasicNode* ProNode::eval()
313313

314314
BasicNode* conditionalControlNode::evalCondition()
315315
{
316-
#ifdef PARTEVAL
316+
#ifdef PARTEVAL
317317
this->giveupEval=false;
318-
#endif
318+
#endif
319319

320320
BasicNode* recon;
321-
#ifdef PARTEVAL
321+
#ifdef PARTEVAL
322322
try
323323
{
324-
#endif
325-
recon=this->condition->eval();
326-
#ifdef PARTEVAL
324+
#endif
325+
recon=this->condition->eval();
326+
#ifdef PARTEVAL
327327
}
328328
catch(unassignedEvalExcep) //condition直接就是个符号变量,放弃求值返回自身
329329
{throw string("conditionalControlNode return");}
330-
#endif
330+
#endif
331331

332-
#ifdef PARTEVAL
332+
#ifdef PARTEVAL
333333
if(recon->getType()==Fun&&dynamic_cast<FunNode*>(recon)->giveupEval) //是一个函数里面有放弃求值的变量
334334
{
335335
this->giveupEval=true; //本控制流节点也放弃求值
336336
throw string("conditionalControlNode return");
337337
}
338-
#endif
338+
#endif
339339

340340
return recon;
341341
}
342342

343343
BasicNode* IfNode::eval()
344344
{
345345
BasicNode* recon;
346-
#ifdef PARTEVAL
346+
#ifdef PARTEVAL
347347
try
348348
{
349-
#endif
350-
recon=this->evalCondition();
351-
#ifdef PARTEVAL
349+
#endif
350+
recon=this->evalCondition();
351+
#ifdef PARTEVAL
352352
}
353353
catch(string e)
354354
{
@@ -357,7 +357,7 @@ BasicNode* IfNode::eval()
357357
else
358358
throw e;
359359
}
360-
#endif
360+
#endif
361361

362362
if(recon->getType()!=Num)
363363
throw string("IfNode condition value's type mismatch");
@@ -384,12 +384,12 @@ BasicNode* WhileNode::eval()
384384
while(1)
385385
{
386386
BasicNode* recon;
387-
#ifdef PARTEVAL
387+
#ifdef PARTEVAL
388388
try
389389
{
390-
#endif
390+
#endif
391391
recon=this->evalCondition();
392-
#ifdef PARTEVAL
392+
#ifdef PARTEVAL
393393
}
394394
catch(string e)
395395
{
@@ -398,7 +398,7 @@ BasicNode* WhileNode::eval()
398398
else
399399
throw e;
400400
}
401-
#endif
401+
#endif
402402

403403
if(recon->getType()!=Num)
404404
throw string("WhileNode condition value's type mismatch");
@@ -425,7 +425,7 @@ void ArrNode::clearArray()
425425
{
426426
//ArrayNode所有权由域持有,内含变量所有权由类本身持有,因此所有elm全部释放
427427
for(BasicNode* node:this->allelm)
428-
delete node;
428+
delete node;
429429
}
430430

431431
ArrNode::ArrNode(int valtype, int len)

0 commit comments

Comments
 (0)