"Fossies" - the Fresh Open Source Software Archive 
Member "teapot-2.3.0/parser.c" (6 Feb 2012, 7345 Bytes) of package /linux/privat/old/teapot-2.3.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "parser.c" see the
Fossies "Dox" file reference documentation.
1 /* #includes */ /*{{{C}}}*//*{{{*/
2 #ifndef NO_POSIX_SOURCE
3 #undef _POSIX_SOURCE
4 #define _POSIX_SOURCE 1
5 #undef _POSIX_C_SOURCE
6 #define _POSIX_C_SOURCE 2
7 #endif
8
9 #ifdef DMALLOC
10 #include "dmalloc.h"
11 #endif
12
13 #include <assert.h>
14 #include <ctype.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19
20 #include "eval.h"
21 #include "main.h"
22 #include "misc.h"
23 #include "parser.h"
24 #include "scanner.h"
25 #include "sheet.h"
26 /*}}}*/
27 /* #defines */ /*{{{*/
28 #define MAXARGC 16
29 /*}}}*/
30
31 /* prototypes */ /*{{{*/
32 static Token term(Token *n[], int *i);
33 /*}}}*/
34
35 /* primary -- parse and evaluate a primary term */ /*{{{*/
36 static Token primary(Token *n[], int *i)
37 {
38 /* variables */ /*{{{*/
39 int argc,j;
40 Token *ident,argv[MAXARGC],result;
41 /*}}}*/
42
43 if (n[*i]==(Token*)0)
44 /* error */ /*{{{*/
45 {
46 result.type=EEK;
47 result.u.err=strcpy(malloc(strlen(_("missing operator"))+1),_("missing operator"));
48 return result;
49 }
50 /*}}}*/
51 else switch (n[*i]->type)
52 {
53 /* STRING, FLOAT, INT */ /*{{{*/
54 case STRING:
55 case FLOAT:
56 case INT:
57 {
58 return tcopy(*n[(*i)++]);
59 }
60 /*}}}*/
61 /* OPERATOR */ /*{{{*/
62 case OPERATOR:
63 {
64 if (n[*i]->u.op==OP)
65 /* return paren term */ /*{{{*/
66 {
67 ++(*i);
68 result=term(n,i);
69 if (result.type==EEK) return result;
70 if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==CP)
71 {
72 ++(*i);
73 return result;
74 }
75 tfree(&result);
76 result.type=EEK;
77 result.u.err=strcpy(malloc(strlen(_(") expected"))+1),_(") expected"));
78 return result;
79 }
80 /*}}}*/
81 else if (n[*i]->u.op==MINUS)
82 /* return negated term */ /*{{{*/
83 {
84 ++(*i);
85 return(tneg(primary(n,i)));
86 }
87 /*}}}*/
88 else
89 /* return error, value expected */ /*{{{*/
90 {
91 result.type=EEK;
92 result.u.err=mystrmalloc(_("value expected"));
93 return result;
94 }
95 /*}}}*/
96 }
97 /*}}}*/
98 /* LIDENT */ /*{{{*/
99 case LIDENT:
100 {
101 ident=n[*i];
102 ++(*i);
103 return findlabel(upd_sheet,ident->u.lident);
104 }
105 /*}}}*/
106 /* FIDENT */ /*{{{*/
107 case FIDENT:
108 {
109 ident=n[*i];
110 ++(*i);
111 if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==OP)
112 /* parse arguments and closing paren of function call, return its value */ /*{{{*/
113 {
114 ++(*i);
115 argc=0;
116 if (!(n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==CP))
117 /* parse at least one argument */ /*{{{*/
118 {
119 if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==COMMA)
120 /* empty argument */ /*{{{*/
121 {
122 argv[argc].type=EMPTY;
123 }
124 /*}}}*/
125 else argv[argc]=term(n,i);
126 if (argv[argc].type==EEK) return argv[argc];
127 ++argc;
128 while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==COMMA)
129 /* parse the following argument */ /*{{{*/
130 {
131 ++(*i);
132 if (argc<=MAXARGC)
133 {
134 if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && (n[*i]->u.op==COMMA || n[*i]->u.op==CP))
135 {
136 argv[argc].type=EMPTY;
137 }
138 else argv[argc]=term(n,i);
139 }
140 else
141 {
142 result.type=EEK;
143 result.u.err=strcpy(malloc(strlen(_("too many arguments"))+1),_("too many arguments"));
144 for (j=0; j<=argc; ++j) tfree(&argv[j]);
145 return result;
146 }
147 ++argc;
148 }
149 /*}}}*/
150 }
151 /*}}}*/
152 if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==CP)
153 /* eval function */ /*{{{*/
154 {
155 ++(*i);
156 result=tfuncall(ident,argc,argv);
157 for (j=0; j<argc; ++j) tfree(&argv[j]);
158 }
159 /*}}}*/
160 else
161 /* ) expected */ /*{{{*/
162 {
163 for (j=0; j<argc; ++j) tfree(&argv[j]);
164 result.type=EEK;
165 result.u.err=strcpy(malloc(strlen(_(") expected"))+1),_(") expected"));
166 }
167 /*}}}*/
168 return result;
169 }
170 /*}}}*/
171 else
172 {
173 result.type=EEK;
174 result.u.err=mystrmalloc(_("( expected"));
175 return result;
176 }
177 }
178 /*}}}*/
179 default: ; /* fall through */
180 }
181 result.type=EEK;
182 result.u.err=mystrmalloc(_("value expected"));
183 return result;
184 }
185 /*}}}*/
186 /* powterm -- parse and evaluate a x^y term */ /*{{{*/
187 static Token powterm(Token *n[], int *i)
188 {
189 Token l;
190
191 l=primary(n,i);
192 if (l.type==EEK) return l;
193 while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==POW)
194 {
195 Token result,r;
196
197 ++(*i);
198 r=primary(n,i);
199 result=tpow(l,r);
200 tfree(&l);
201 tfree(&r);
202 if (result.type==EEK) return result;
203 l=result;
204 }
205 return l;
206 }
207 /*}}}*/
208 /* piterm -- parse and evaluate a product/division/modulo term */ /*{{{*/
209 static Token piterm(Token *n[], int *i)
210 {
211 Token l;
212
213 l=powterm(n,i);
214 if (l.type==EEK) return l;
215 while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && (n[*i]->u.op==DIV || n[*i]->u.op==MUL || n[*i]->u.op==MOD))
216 {
217 Operator op;
218 Token result,r;
219
220 op=n[*i]->u.op;
221 ++(*i);
222 r=powterm(n,i);
223 switch (op)
224 {
225 case MUL: result=tmul(l,r); break;
226 case DIV: result=tdiv(l,r); break;
227 case MOD: result=tmod(l,r); break;
228 default: assert(0);
229 }
230 tfree(&l);
231 tfree(&r);
232 if (result.type==EEK) return result;
233 l=result;
234 }
235 return l;
236 }
237 /*}}}*/
238 /* factor -- parse and evaluate a factor of sums/differences */ /*{{{*/
239 static Token factor(Token *n[], int *i)
240 {
241 Token l;
242
243 l=piterm(n,i);
244 if (l.type==EEK) return l;
245 while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && (n[*i]->u.op==PLUS || n[*i]->u.op==MINUS))
246 {
247 Operator op;
248 Token result,r;
249
250 op=n[*i]->u.op;
251 ++(*i);
252 r=piterm(n,i);
253 result=(op==PLUS ? tadd(l,r) : tsub(l,r));
254 tfree(&l);
255 tfree(&r);
256 if (result.type==EEK) return result;
257 l=result;
258 }
259 return l;
260 }
261 /*}}}*/
262 /* term -- parse and evaluate a relational term */ /*{{{*/
263 static Token term(Token *n[], int *i)
264 {
265 Token l;
266
267 l=factor(n,i);
268 if (l.type==EEK) return l;
269 while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op>=LT && n[*i]->u.op<=NE)
270 {
271 Operator op;
272 Token result,r;
273
274 op=n[*i]->u.op;
275 ++(*i);
276 r=factor(n,i);
277 switch (op)
278 {
279 case LT: result=tlt(l,r); break;
280 case LE: result=tle(l,r); break;
281 case GE: result=tge(l,r); break;
282 case GT: result=tgt(l,r); break;
283 case ISEQUAL: result=teq(l,r); break;
284 case ABOUTEQ: result=tabouteq(l,r); break;
285 case NE: result=tne(l,r); break;
286 default: assert(0);
287 }
288 tfree(&l);
289 tfree(&r);
290 if (result.type==EEK) return result;
291 l=result;
292 }
293 return l;
294 }
295 /*}}}*/
296
297 /* eval -- parse and evaluate token sequence */ /*{{{*/
298 Token eval(Token **n)
299 {
300 Token result;
301 int i;
302
303 assert(upd_sheet!=(Sheet*)0);
304 i=0;
305 result=term(n,&i);
306 if (result.type==EEK) return result;
307 if (n[i]!=(Token*)0)
308 {
309 tfree(&result);
310 result.type=EEK;
311 result.u.err=strcpy(malloc(strlen(_("parse error after term"))+1),_("parse error after term"));
312 return result;
313 }
314 return result;
315 }
316 /*}}}*/