0
|
1 /*
|
|
2 Very Simple Calculator
|
|
3 */
|
|
4
|
|
5 #include <stdio.h>
|
|
6
|
|
7 static char *ptr,*last_ptr;
|
|
8 static int value,lvalue;
|
|
9 static int last_token;
|
|
10 static int variable[48];
|
|
11
|
|
12 static int expr();
|
|
13 static int aexpr();
|
|
14 static int mexpr();
|
|
15 static int term();
|
|
16 static int token();
|
11
|
17 static void error(char *);
|
0
|
18
|
|
19
|
|
20 static int
|
|
21 token()
|
|
22 {
|
|
23 int c,d;
|
|
24
|
|
25 last_ptr = ptr; /* for error position */
|
|
26 c= *ptr;
|
|
27 if(!c) {
|
|
28 last_token = EOF;
|
|
29 return last_token;
|
|
30 }
|
|
31 ptr++;
|
|
32 if (c<=' ') { /* comment */
|
|
33 while(*ptr++);
|
|
34 ptr--;
|
|
35 last_token = EOF;
|
|
36 last_ptr = ptr;
|
|
37 return last_token;
|
|
38 }
|
|
39 if('0'<=c && c<='9') { /* Decimal */
|
|
40 d = c-'0';
|
15
|
41 while((c= *ptr++)) {
|
0
|
42 if('0'<=c && c<='9') {
|
|
43 d = d*10 + (c - '0');
|
|
44 } else {
|
|
45 break;
|
|
46 }
|
|
47 }
|
|
48 c && ptr--;
|
|
49 value = d;
|
|
50 last_token = '0';
|
|
51 return last_token;
|
|
52 } else if ('a'<=c && c<='z') { /* variable */
|
|
53 value = c-'a'; /* return variable reference */
|
|
54 last_token = 'v';
|
|
55 return last_token;
|
|
56 } else {
|
|
57 last_token = c;
|
|
58 return last_token;
|
|
59 return c;
|
|
60 }
|
|
61 }
|
|
62
|
|
63 static int
|
|
64 expr()
|
|
65 {
|
|
66 int d,assign;
|
|
67
|
|
68 d = aexpr();
|
|
69 assign = lvalue;
|
|
70 switch(last_token) {
|
|
71 case '>':
|
|
72 d = (d > aexpr());
|
|
73 return d;
|
|
74 case '=':
|
|
75 if(assign>=0) {
|
|
76 d = expr();
|
|
77 variable[assign] = d;
|
|
78 return d;
|
|
79 } else {
|
|
80 error("Bad assignment");
|
|
81 return 0;
|
|
82 }
|
|
83 case ')':
|
|
84 return d;
|
|
85 case EOF:
|
|
86 return d;
|
|
87 default:
|
|
88 error("Bad expression");
|
|
89 return d;
|
|
90 }
|
|
91 }
|
|
92
|
|
93 static int
|
|
94 aexpr()
|
|
95 {
|
|
96 int d;
|
|
97
|
|
98 d = mexpr();
|
|
99 switch(last_token) {
|
|
100 case '-':
|
|
101 d -= aexpr();
|
|
102 return d;
|
|
103 case '+':
|
|
104 d += aexpr();
|
|
105 return d;
|
|
106 default:
|
|
107 return d;
|
|
108 }
|
|
109 }
|
|
110
|
|
111 static int
|
|
112 mexpr()
|
|
113 {
|
|
114 int d;
|
|
115
|
|
116 d = term();
|
|
117 switch(last_token) {
|
|
118 case '*':
|
|
119 d *= mexpr();
|
|
120 return d;
|
|
121 case '/':
|
|
122 d /= mexpr();
|
|
123 return d;
|
|
124 default:
|
|
125 return d;
|
|
126 }
|
|
127 }
|
|
128
|
|
129 static int
|
|
130 term()
|
|
131 {
|
|
132 int d;
|
|
133
|
|
134 lvalue= -1;
|
|
135 token();
|
|
136 if(last_token==EOF) {
|
|
137 error("Term expected");
|
|
138 }
|
|
139 switch(last_token) {
|
|
140 case '0':
|
|
141 d = value;
|
|
142 token();
|
|
143 return d;
|
|
144 case 'v':
|
|
145 d = lvalue = value;
|
|
146 token();
|
|
147 return variable[d];
|
|
148 case '(':
|
|
149 d = expr();
|
|
150 if(last_token != ')') {
|
|
151 error("Unbalanced parenthsis");
|
|
152 }
|
|
153 token();
|
|
154 return d;
|
|
155 default:
|
|
156 token();
|
|
157 error("Unknown term");
|
|
158 return 0;
|
|
159 }
|
|
160 }
|
|
161
|
11
|
162 static int lineno = 0;
|
|
163
|
|
164 void
|
|
165 error(char *msg)
|
|
166 {
|
|
167 fprintf(stderr,"%s on line %d\n",msg, lineno);
|
|
168 }
|
|
169
|
0
|
170 int
|
|
171 main()
|
|
172 {
|
|
173 int d;
|
|
174 char buf[BUFSIZ];
|
|
175
|
|
176 while (fgets(buf,BUFSIZ,stdin)) {
|
|
177 ptr = buf;
|
|
178 d = expr();
|
|
179 printf("%s = 0x%08x = %d\n",buf,d,d);
|
|
180 fflush(stdout);
|
11
|
181 lineno++;
|
0
|
182 }
|
|
183 return 0;
|
|
184 }
|
|
185
|
|
186 /* end */
|