Skip to content

Commit 22925a0

Browse files
author
冷漠
committed
修改了输出&增加对加减乘除的求导运算
1 parent a64301f commit 22925a0

File tree

8 files changed

+246
-48
lines changed

8 files changed

+246
-48
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-15T12:44:16. -->
3+
<!-- Written by QtCreator 4.5.0, 2019-02-17T11:29:11. -->
44
<qtcreator>
55
<data>
66
<variable>EnvironmentId</variable>

ast.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ map<string,int> ast::BinOpPriority;
99

1010
static void ast::Init()
1111
{
12-
1312
//初始化所有内置函数实体
1413
Function* add = new Function(BuiltinFunc::hasTwoSonNodes, BuiltinFunc::add,2);
1514
Function* sub = new Function(BuiltinFunc::hasTwoSonNodes, BuiltinFunc::sub,2);
@@ -49,7 +48,7 @@ bool ast::isLetter(const char &c)
4948
return (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z');
5049
}
5150

52-
bool ast::canpush(stack<string> &stackOp, string op)
51+
bool ast::canpush(stack<string> &stackOp, const string& op)
5352
{
5453
if (stackOp.empty()) return true;
5554
return BinOpPriority[op] > BinOpPriority[stackOp.top()];
@@ -69,7 +68,7 @@ BasicNode* ast::__ToAST(string &s)
6968

7069
if ((s[j] == '+' || s[j] == '-') && (j == 0 || isBinOp(s[j - 1])))
7170
{
72-
temp += s[j];
71+
j++;
7372
}//检查负号还是减号
7473
if(j < n && isNum(s[j]))
7574
{
@@ -95,11 +94,11 @@ BasicNode* ast::__ToAST(string &s)
9594
{
9695
FunNode* node = new FunNode(record::globalScope.functionList[s.substr(i, j - i)]);
9796
//此时s[j] == '('
98-
while(s[j] != ')' && s[j] != '$')
97+
while(s[j] != ')' && s[j] != LowestPriority)
9998
{
10099
i = j;
101100
j++;
102-
while(j < n && s[j] != ',' && s[j] != ')' && s[j] != '$')
101+
while(j < n && s[j] != ',' && s[j] != ')' && s[j] != LowestPriority)
103102
j++;
104103
node->addNode(ToAST(s.substr(i + 1, j - i - 1)));
105104
}
@@ -133,7 +132,7 @@ BasicNode* ast::__ToAST(string &s)
133132
}
134133

135134

136-
if(i < n && (isBinOp(s[i]) || s[i] == '$'))//按理说,一个数字/变量/函数结束之后是一个运算符/字符串结尾
135+
if(i < n && (isBinOp(s[i]) || s[i] == LowestPriority))//按理说,一个数字/变量/函数结束之后是一个运算符/字符串结尾
137136
{
138137
if (canpush(stackOp, s.substr(i,1)))
139138
{

ast.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ class record
1515

1616
namespace ast
1717
{
18+
static const char LowestPriority = '$';
1819
extern bool isInit;
1920
extern map<string,int> BinOpPriority;
2021

2122
static void Init();
22-
static bool canpush(stack<string> &, string);
23+
static bool canpush(stack<string> &, const string &);
2324
static bool isNum(const char &);
2425
static bool isBinOp(const char &);
2526
static bool isLetter(const char &);

main.cpp

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,49 @@ using namespace std;
88

99
int main()
1010
{
11-
/*
12-
string s = "1+2-3*4/5*(7+8-b)+sin(0)+a + 2 ^ 5 ";
13-
BasicNode* ans = ast::ToAST(s);
14-
output::outputAST(ans);
11+
12+
string TestBuildTree = "1-(2+3)-(4-5)";
13+
BasicNode* ansTestBuildTree = ast::ToAST(TestBuildTree);
14+
BasicNode* ansAfterEval;
15+
output::outputASTstruct(ansTestBuildTree);
16+
output::outputAST(ansTestBuildTree);
17+
cout << endl;
18+
output::outputAST(ansAfterEval = ansTestBuildTree ->eval());
19+
cout << endl;
20+
delete ansAfterEval;
21+
output::outputAST(ansTestBuildTree);
22+
cout << endl << endl;
23+
delete ansTestBuildTree;
24+
25+
string TestSimplificate ="(1+2)*(3+4)+(a+b)/(c+d)";
26+
BasicNode* ansTestSimplificate = ast::ToAST(TestSimplificate);
27+
output::outputAST(ansTestSimplificate);
28+
cout << endl;
29+
Simplificate(ansTestSimplificate);
30+
output::outputAST(ansTestSimplificate);
31+
cout << endl << endl;
32+
delete ansTestSimplificate;
33+
34+
string TestDerivation = "a+b-c*d/e";
35+
BasicNode* ansTestDerivation = ast::ToAST(TestDerivation);
36+
BasicNode* ansAfterDerivation;
37+
output::outputAST(ansTestDerivation);
1538
cout << endl;
16-
output::outputAST(ans ->eval());
39+
ansAfterDerivation = Derivation(ansTestDerivation, "a");
40+
Simplificate(ansAfterDerivation);
41+
output::outputAST(ansAfterDerivation);
1742
cout << endl;
18-
output::outputAST(ans);
19-
*/
20-
string s ="(1+2)*(3+4)+(a+b)/(c+d)";
21-
BasicNode* ans = ast::ToAST(s);
22-
output::outputAST(ans);
43+
delete ansAfterDerivation;
44+
ansAfterDerivation = Derivation(ansTestDerivation, "c");
45+
Simplificate(ansAfterDerivation);
46+
output::outputAST(ansAfterDerivation);
2347
cout << endl;
24-
Simplificate(ans);
25-
output::outputAST(ans);
48+
delete ansAfterDerivation;
49+
ansAfterDerivation = Derivation(ansTestDerivation, "e");
50+
Simplificate(ansAfterDerivation);
51+
output::outputAST(ansAfterDerivation);
2652
cout << endl;
53+
delete ansAfterDerivation;
54+
delete ansTestDerivation;
2755
return 0;
2856
}

output.cpp

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,75 @@ bool output::isBinOp(const string &c)
88
}
99

1010

11-
void output::outputAST(BasicNode* now, int fatherpriority)
11+
void output::outputAST(BasicNode* now, const string& FatherOP)
1212
{
1313
if(now == nullptr)
1414
return;
15-
if(now->getType() == Num){
16-
cout << ((NumNode*)now)->getNum();
15+
if(now->getType() == Num)
16+
{
17+
double nownum = ((NumNode*)now)->getNum();
18+
if(nownum < 0)
19+
cout << '(' << nownum << ')';
20+
else
21+
cout << nownum;
1722
return;
1823
}
19-
if(now->getType() == Fun){
24+
if(now->getType() == Fun)
25+
{
2026
FunNode* t = (FunNode*)now;
21-
Function* l = t->getEntity();
22-
if(output::isBinOp(l->NAME)){
23-
if(ast::BinOpPriority[l->NAME] < fatherpriority)
27+
string op = t->getEntity()->NAME;
28+
if(output::isBinOp(op))
29+
{
30+
if(ast::BinOpPriority[op] < ast::BinOpPriority[FatherOP])
2431
cout << '(';
25-
outputAST(t->sonNode[0], ast::BinOpPriority[l->NAME]);
26-
cout << l->NAME;
27-
outputAST(t->sonNode[1], ast::BinOpPriority[l->NAME]);
28-
if(ast::BinOpPriority[l->NAME] < fatherpriority)
32+
outputAST(t->sonNode[0], op);
33+
cout << op;
34+
if(op == "-" && t->sonNode[1]->getType() == Fun && ast::BinOpPriority[op] == ast::BinOpPriority[((FunNode*)(t->sonNode[1]))->getEntity()->NAME])
35+
cout << '(';
36+
outputAST(t->sonNode[1], op);
37+
if(ast::BinOpPriority[op] < ast::BinOpPriority[FatherOP])
38+
cout << ')';
39+
if(op == "-" && t->sonNode[1]->getType() == Fun && ast::BinOpPriority[op] == ast::BinOpPriority[((FunNode*)(t->sonNode[1]))->getEntity()->NAME])
2940
cout << ')';
3041
return;
3142
}
32-
cout << l->NAME << '(';
33-
for(int i = 0 ; i < l->getParnum(); i++){
43+
cout << op << '(';
44+
int n = t->getEntity()->getParnum();
45+
for(int i = 0 ; i < n; i++)
46+
{
3447
outputAST(t->sonNode[i], 0);
35-
if(i != l->getParnum() - 1)
48+
if(i != n - 1)
3649
cout << ",";
3750
}
3851
cout << ')';
3952
return;
4053
}
41-
if(now->getType() == Var){
54+
if(now->getType() == Var)
55+
{
4256
cout << ((VarNode*)now)->NAME;
4357
}
4458
}
59+
60+
void output::outputASTstruct(BasicNode* now, int depth)//方便输出AST结构(并没有找到别的好方法)
61+
{
62+
for(int i = 0; i < depth; i++)
63+
cout << ' ';
64+
if(now->getType() == Num)
65+
{
66+
cout << ((NumNode*)now)->getNum() << endl;
67+
return;
68+
}
69+
if(now->getType() == Var)
70+
{
71+
cout << ((VarNode*)now)->NAME << endl;
72+
return;
73+
}
74+
if(now->getType() == Fun)
75+
{
76+
FunNode* temp = (FunNode*)now;
77+
int n = temp->getEntity()->getParnum();
78+
cout << temp->getEntity()->NAME << endl ;
79+
for(int i = 0; i < n; i++)
80+
outputASTstruct(temp->sonNode[i], depth+1);;
81+
}
82+
}

output.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
namespace output
66
{
77
static bool isBinOp(const string &c);
8-
void outputAST(BasicNode* ,int = 0);
8+
void outputAST(BasicNode* ,const string& = string(ast::LowestPriority, 1));
9+
void outputASTstruct(BasicNode*, int = 0);
910
}

0 commit comments

Comments
 (0)