Analyse.h
1 #include<iostream>
2 #include<map>
3 #include<string>
4 using namespace std;
5
6 enum Token_value
7 {
8 NAME, NUMBER, END,
9 PLUS='+', MINUS='-', MUL='*', DIV='/',
10 PRINT=';', ASSIGN='=', LP='(',RP=')'
11 };
12
13 Token_value curr_tok = PRINT;
14
15 double number_value;
16 string string_value;
17
18 map<string,double>table;
19
20 //------------error_status-----------
21 int no_of_errors;
22
23 double error(const string& s)
24 {
25 no_of_errors++;
26 cerr<<"错误:"<<s<<'\n';
27 return 1;
28 }
29
30
31 //------------get_token--------------
32 Token_value get_token()
33 {
34 char ch;
35 do{
36 if(!cin.get(ch))return curr_tok = END;
37 }while(ch!='\n' && isspace(ch));
38
39 switch(ch)
40 {
41 case ';':
42 case '\n':
43 return curr_tok = PRINT;
44
45 case '+':
46 case '-':
47 case '*':
48 case '/':
49 case '(':
50 case ')':
51 case '=':
52 return curr_tok = Token_value(ch);
53
54 case '0':case '1':case '2':case '3':case '4':
55 case '5':case '6':case '7':case '8':case '9':
56 case '.':
57 cin.putback(ch);
58 cin>>number_value;
59 return curr_tok = NUMBER;
60
61 default:
62 if(isalpha(ch))
63 {
64 string_value = ch;
65 while(cin.get(ch) && isalnum(ch))string_value.push_back(ch);
66 cin.putback(ch);
67 return curr_tok = NAME;
68 }
69 error("非法变量名");
70 return curr_tok = PRINT;
71 }
72 }
73
74
75 //------------analyse----------------
76 double prim(bool get);
77
78 double term(bool get)
79 {
80 double left = prim(get);
81 for(;;)
82 {
83 switch(curr_tok)
84 {
85 case MUL:
86 left *= prim(true);
87 break;
88 case DIV:
89 if(double d = prim(true))
90 {
91 left /= d;
92 break;
93 }
94 return error("除以0溢出");
95
96 default:
97 return left;
98 }
99 }
100 }
101
102 double expr(bool get)
103 {
104 double left = term(get);
105
106 for(;;)
107 {
108 switch(curr_tok)
109 {
110 case PLUS:
111 left += term(true);
112 break;
113 case MINUS:
114 left -= term(true);
115 break;
116 default:
117 return left;
118 }
119 }
120 }
121
122 double prim(bool get)
123 {
124 if(get)get_token();
125
126 switch(curr_tok)
127 {
128 case NUMBER:{double v = number_value;
129 get_token();
130 return v;
131 }
132
133 case NAME: {double& v = table[string_value];
134 if(get_token() == ASSIGN){v = expr(true);}
135 return v;
136 }
137
138 case MINUS: {return -prim(true);}
139
140 case LP: {double e = expr(true);
141 if(curr_tok != RP){return error("没有匹配右括号");}
142 get_token();
143 return e;
144 }
145 default:
146 return error("初等项异常");
147 }
148 }
149
150
main.cpp
1 #include"Analyse.h"
2 int main()
3 {
4 table["pi"] = 3.1415926535897932385;
5 table["e"] = 2.7182818284590452354;
6
7 while(cin){
8 get_token();
9 if(curr_tok == END)break;
10 if(curr_tok == PRINT)continue;
11 cout<<expr(false)<<'\n';
12 }
13
14 return no_of_errors;
15 }