comparison tests/agcl/parsifal/ss-fp.syn @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:13d2b8934445
1 {
2 /*
3 Copyright 1992, Jerome T. Holland
4 See the file COPYING for license and usage terms.
5 */
6
7 #include "ssd.h"
8 #include "kb.h"
9 #include "num.h"
10
11 }
12
13 cell name request = 255
14 input line request = 254
15 block request = 253
16
17 [
18 ~allow macros
19 ~backtrack
20 ~case sensitive
21 ~declare pcb
22 ~diagnose errors
23 error trace
24 ~lines and columns
25 pointer input
26 ~test range
27 rule coverage
28 parser file name = "#.cpp"
29 default token type = number
30 disregard space
31 ]
32
33 letter = 'A-Z'
34 bound variable = 'A-Z'
35 digit = '0-9'
36 nonzero digit = '1-9'
37 eof = 0
38 space = ' '
39 decimal point = '.'
40 pi = 'ã' //character code 227
41
42
43 (void) grammar
44 -> cell name request, cell name:cp, eof =goto_cell = cp;
45 -> input line request, input line
46 -> conditional expression:x,
47 ['\n', conditional expression]..., eof =xvalue = x;
48 -> block request, cell name:f, to, cell name:l,
49 eof =first_cell=f, last_cell = l;
50
51 (void) input line
52 -> cell name: loc, '=' =stuff_cell(loc);
53 -> '@',cell name:f, to, cell name:l,'/',
54 format:fmt, eof =stuff_format(fmt,f,l);
55
56 to
57 -> '.', '.'?
58
59 (format_code) format
60 ->'a',':', alignment:a, ',',
61 'c',':', conversion:c, ',',
62 'd',':', integer:n ={
63 format_code f;
64 f.alignment = a;
65 f.conversion =c;
66 f.decimals = n;
67 f.flag = 0;
68 return f;
69 }
70
71 (int) alignment
72 -> 'L' =0;
73 -> 'C' =1;
74 -> 'R' =2;
75
76 (int) conversion
77 -> 'C' =0;
78 -> 'F' =1;
79 -> 'G' =2;
80
81 (pair<int>) cell name
82 -> column id:col, integer:row =id_cell(row-1,col);
83
84 (int) column id
85 -> letter:a, letter:b =rel_column_id(a-'A'+1, b-'A');
86 -> letter:a =rel_column_id(0, a-'A');
87
88 (int) integer
89 -> nonzero digit:d =d-'0';
90 -> integer:n, digit:d =10*n + d-'0';
91
92 conditional expression
93 -> x expression
94 -> expression:x, ':', disjunction:c, ';', conditional expression:y ={
95 number z;
96 switch (c.tv){
97 case 0:
98 z = y;
99 break;
100 case 1:
101 z = x;
102 break;
103 case 2:
104 z.error = 1;
105 }
106 return z;
107 }
108
109 disjunction
110 -> conjunction
111 -> disjunction:x, '|', conjunction:y =x||y;
112
113 conjunction
114 -> logical value
115 -> conjunction:x, '&', logical value:y =x&&y;
116
117 logical value
118 -> comparison
119 -> '(', disjunction:x, ')' =x;
120 -> '!', '(', disjunction:x, ')' =!x;
121
122 comparison
123 -> partial comparison:x, '<', expression:y =x<y;
124 -> partial comparison:x, '>', expression:y =x>y;
125 -> partial comparison:x, "<=", expression:y =x<=y;
126 -> partial comparison:x, ">=", expression:y =x>=y;
127 -> partial comparison:x, "==", expression:y =x==y;
128 -> partial comparison:x, "!=", expression:y =x!=y;
129
130 partial comparison
131 -> x expression
132 -> comparison
133
134 x expression
135 -> expression
136 -> summation
137 -> expression:x, '+', summation:y =x+y;
138 -> expression:x, '-', summation:y =x-y;
139
140 expression
141 -> term
142 -> expression:x, '+', term:y =x+y;
143 -> expression:x, '-', term:y =x-y;
144
145 term
146 -> xxfactor
147 -> term:x, '*', xxfactor:y =x*y;
148
149 xxfactor
150 -> xfactor
151 -> function:f, xfactor:y =apply(f,y);
152 -> factor:x, function:f, xfactor:y =x*apply(f,y);
153
154 xfactor
155 -> yfactor
156 -> base:x, '^', xfactor:n =pow(x,n);
157 -> '-', xfactor:x =-x;
158
159 yfactor
160 -> factor
161 -> yfactor:x, '/', factor:y =x/y;
162
163 factor
164 -> simple factor
165 -> simple factor:x, r value:y =x*y;
166 -> r value
167
168 simple factor
169 -> l value
170 -> c value
171 -> simple factor:x, c value:y =x*y;
172
173 l value
174 -> number
175
176 c value
177 -> cell name:cp =cell_value(cp);
178 -> parens
179 -> pi =num(M_PI);
180 -> sigma, cell name:first, '.', '.'?, cell name:last =sum_cells(first,last);
181
182 r value
183 -> bound variable:k =bound_variable[k-'A'];
184
185 summation
186 -> sigma:xb, x expression string:xf, ':', bound variable:k, '=',
187 x expression:f, ',', x expression:s, "...", x expression:l =
188 summation(xb,xf,k-'A', f, s, l);
189
190 (char *) sigma
191 -> 'ä' =(char *)PCB.pointer; //character code 228
192
193 (char *) x expression string
194 -> x expression =(char *)PCB.pointer;
195
196 base
197 -> l value
198 -> c value
199 -> r value
200
201 parens
202 -> '(', conditional expression:x, ')' =x;
203
204 (function_name) function
205 -> "abs" =fabs;
206 -> "acos" = acos;
207 -> "asin" = asin;
208 -> "atan" = atan;
209 -> "cosh" = cosh;
210 -> "cos" =cos;
211 -> "exp" =exp;
212 -> "log10" = log10;
213 -> "log" = log;
214 -> "pow10" = pow10d;
215 -> "round" = round;
216 -> "sinh" = sinh;
217 -> "sin" =sin;
218 -> "sqr" =sqr;
219 -> "sqrt" = sqrt;
220 -> "tanh" = tanh;
221 -> "tan" = tan;
222 -> "trunc" = trunc;
223
224 number
225 -> integer part:x, decimal point? =num(x);
226 -> integer part:x, decimal point, fraction part:y =num(x+y);
227 -> decimal point, fraction part:x =num(x);
228
229 (double) integer part
230 -> digit:d =d-'0';
231 -> integer part:n, digit:d =10*n+d-'0';
232
233 (double) fraction part
234 -> digit:d =(d-'0')/10.;
235 -> digit:d, fraction part:f =(d-'0'+f)/10.;
236
237 {
238 fp_pcb_type *fp_pcb;
239 #define PCB (*fp_pcb)
240
241
242 #define CELL_NAME_REQUEST 255
243 #define INPUT_LINE_REQUEST 254
244 #define BLOCK_REQUEST 253
245
246 #define SYNTAX_ERROR
247 #define PARSER_STACK_OVERFLOW
248
249 static int cell_refs;
250 static int error_flag;
251
252 static number bound_variable[26];
253 static number xvalue;
254
255 number num(double x) {
256 number n;
257 n.error = 0;
258 n.truth = 1;
259 n.v = x;
260 return n;
261 }
262
263 void init_bv(void) {
264 int i;
265 for (i = 0; i < 26; i++) bound_variable[i].error = 1;
266 }
267
268 double round(double x) {
269 long n = x+.5;
270 return n;
271 }
272
273 double trunc(double x) {
274 long n = x;
275 return n;
276 }
277
278 double sqr(double x) {
279 return x*x;
280 }
281
282 double pow10d(double x) {
283 long n = x;
284 return pow10d(n);
285 }
286
287 number cell_value(pair<int> loc) {
288 number x;
289 cell_pointer cp;
290 int save_ef = error_flag;
291
292 cell_refs++;
293 cp = ss[loc.row][loc.col];
294 if (cp == NULL) {
295 x.truth = 1;
296 x.v = 0;
297 return x;
298 }
299 if (cp->type == text) {
300 x.error = 1;
301 x.truth = 0;
302 return x;
303 }
304 if (cp->type == formula) {
305 if ((inserted_columns || inserted_rows));
306 else if (recalc_flag) {
307 if (cp->recalc == recalc_count) eval(cp);
308 if (cp->recalc & 1) circular_flag = 1;
309 }
310 }
311 x.error = cp->error;
312 x.truth = 1;
313 x.v = cp->value;
314 return x;
315 }
316
317 void eval(cell_pointer cp) {
318 fp_pcb_type pcb, *save_pcb = fp_pcb;
319
320 fp_pcb = &pcb;
321 cell_refs = 0;
322 PCB.pointer = (unsigned char *) &cp->text;
323 cp->recalc += recalc_flag;
324 error_flag = 0;
325 fp();
326 cp->recalc += recalc_flag;
327 if (PCB.exit_flag != 1) {cp->type = text; cp->error = 1; return;}
328 else if (cell_refs == 0) cp->type = value;
329 else cp->type = formula;
330 {
331 cp->error = xvalue.error;
332 cp->value = xvalue.v;
333 }
334 fp_pcb = save_pcb;
335 }
336
337 number evalx(char *xs) {
338 fp_pcb_type pcb, *save_pcb = fp_pcb;
339 number x;
340
341 fp_pcb = &pcb;
342 PCB.pointer = (unsigned char *) xs;
343 error_flag = 0;
344 fp();
345 fp_pcb = save_pcb;
346 return xvalue;
347 }
348
349 pair<int> id_cell(int row, int col) {
350 pair<int> goto_cell = {0,0};
351 if (row >= MAXROWS || col >= MAXCOLS) {
352 PCB.exit_flag = 5;
353 return goto_cell;
354 }
355 if (inserted_rows && row >= new_row) row += inserted_rows;
356 goto_cell.row = row;
357 goto_cell.col = col;
358 if (inserted_columns == 0 && inserted_rows == 0) return goto_cell;
359 sprintf((char *)icnptr,"%d",row+1);
360 icnptr += strlen((char *)icnptr);
361 icoptr = PCB.pointer;
362 return goto_cell;
363 }
364
365 int matherr(struct exception *e) {
366 error_flag++;
367 e->retval = 0;
368 return 1;
369 }
370
371 number apply(double(*f)(double), number n) {
372 number r;
373 if (n.error) return n;
374 error_flag = 0;
375 r.v = f(n.v);
376 r.error = error_flag != 0;
377 return r;
378 }
379
380 number pow(number x, number n) {
381 number r;
382 r.error = x.error || n.error;
383 if (r.error) return r;
384 r.v = pow(x.v, n.v);
385 return r;
386 }
387
388 void parse_block(void) {
389 int flag;
390 fp_pcb_type pcb;
391
392 fp_pcb = &pcb;
393 PCB.pointer = (unsigned char *) text_buffer;
394 text_buffer[0] = BLOCK_REQUEST;
395 fp();
396 flag = PCB.exit_flag != 1
397 || first_cell.row > last_cell.row
398 || first_cell.col > last_cell.col
399 || last_cell.row > MAXROWS
400 || last_cell.col > MAXCOLS;
401 if (flag) {
402 kb_pcb.reduction_token = kb_bad_block_token;
403 display_message(&bad_block_message);
404 set_cursor(text_cursor);
405 }
406 else _setcursortype(_NOCURSOR);
407 }
408
409 void parse_cell_name(void) {
410 int flag;
411 fp_pcb_type pcb;
412
413 fp_pcb = &pcb;
414 PCB.pointer = (unsigned char *) text_buffer;
415 text_buffer[0] = CELL_NAME_REQUEST;
416 fp();
417 flag = PCB.exit_flag != 1
418 || goto_cell.row > MAXROWS
419 || goto_cell.col > MAXCOLS;
420 if (flag) {
421 kb_pcb.reduction_token = kb_bad_cell_name_token;
422 display_message(&bad_cell_message);
423 set_cursor(text_cursor);
424 }
425 else _setcursortype(_NOCURSOR);
426 }
427
428 int rel_column_id(int a, int b) {
429 int cn = 26*a + b;
430 int nidc = a?2:1;
431 int n;
432 unsigned char case_bit = 0;
433 char *cp;
434
435 if (inserted_columns == 0 && inserted_rows == 0) return cn;
436 if (cn >= new_column) cn += inserted_columns;
437 n = (PCB.pointer - icoptr) - nidc;
438 memmove((char *)icnptr, (char *)icoptr, n);
439 icnptr += n;
440 cp = (char *)PCB.pointer;
441 while (nidc--) case_bit |= *--cp;
442 case_bit &= 0x20;
443 cp = column_label(cn,case_bit);
444 strcpy((char *)icnptr,cp);
445 icnptr += strlen(cp);
446 return cn;
447 }
448
449 void relabel_formula(cell_pointer cp) {
450 fp_pcb_type pcb, *save_pcb = fp_pcb;
451
452 fp_pcb = &pcb;
453 icoptr = PCB.pointer = (unsigned char *) &cp->text;
454 icnptr = (unsigned char *) relabel_buf;
455 fp();
456 assert(PCB.exit_flag == 1);
457 strcpy((char *)icnptr, (char *)icoptr);
458 cp = (cell_descriptor *) realloc(cp, sizeof(cell_descriptor) + strlen(relabel_buf));
459 assert(cp);
460 strcpy(cp->text, relabel_buf);
461 fp_pcb = save_pcb;
462 }
463
464 void scan_input_line(void) {
465 fp_pcb_type pcb, *save_pcb = fp_pcb;
466
467 fp_pcb = &pcb;
468 PCB.pointer = (unsigned char *) text_buffer;
469 text_buffer[0] = INPUT_LINE_REQUEST;
470 fp();
471 fp_pcb = save_pcb;
472 }
473
474 void set_column_width(void) {
475 int n;
476 char *tb = text_buffer + 1;
477 int flag;
478
479 highlight_off();
480 for (n = 0; *tb;) n = 10*n + *tb++ - '0';
481 flag = n < 3 || n > 75;
482 if (flag) {
483 kb_pcb.reduction_token = kb_column_width_request_token;
484 display_message(&bad_cw_message);
485 beep();
486 set_cursor(text_cursor);
487 return;
488 }
489 _setcursortype(_NOCURSOR);
490 if (ac.scc.col + n > 81) move_data_left();
491 cols[ac.ssc.col].width = n;
492 display_column_guide();
493 update_screen();
494 highlight_on();
495 }
496
497
498 void stuff_cell(pair<int> loc) {
499 char *tb = (char *) fp_pcb->pointer;
500 cell_pointer cp = (cell_descriptor *) realloc(
501 ss[loc.row][loc.col],
502 sizeof(cell_descriptor) + strlen(tb));
503
504 assert(cp);
505 if (loc.row > max_row) max_row = loc.row;
506 if (loc.col > max_col) max_col = loc.col;
507 strcpy(cp->text, tb);
508 ss[loc.row][loc.col] = cp;
509 cp->recalc = recalc_count;
510 eval(cp);
511 }
512
513 void stuff_format(format_code f,pair<int> first,pair<int> last){
514 int i,j;
515 for (i=first.row;i<=last.row;i++) for (j=first.col;j<=last.col;j++) {
516 fmt[i][j] = f;
517 }
518 if (last.row > fmt_max_row) fmt_max_row = last.row;
519 if (last.col > fmt_max_col) fmt_max_col = last.col;
520 }
521
522 number sum_cells(pair<int> first,pair<int> last){
523 pair<int> cp;
524 number sum;
525 sum.error = sum.truth = 1;
526 sum.v = 0;
527 for (cp.row = first.row; cp.row <= last.row; cp.row++)
528 for (cp.col = first.col; cp.col <= last.col; cp.col++) {
529 number cv = cell_value(cp);
530 if (cv.error) return sum;
531 sum.v += cv.v;
532 }
533 sum.error = 0;
534 return sum;
535 }
536
537 number summation(char *xb, char *xf, int bv, number f, number s, number l) {
538 number sum;
539 int k;
540 char *xs;
541 number delta;
542 int n;
543
544 sum.error = f.error + s.error + l.error;
545 sum.v = 0;
546 if (sum.error) return sum;
547 k = (int) (xf - xb);
548 xs = (char *) malloc(k+1);
549 memmove(xs,xb,k);
550 xs[k] = 0;
551 delta = s-f;
552 if (delta.v == 0) {
553 sum.error = 1;
554 return sum;
555 }
556 n = ((l-f+delta)/delta).v + .5;
557 while (n--) {
558 bound_variable[bv] = f;
559 sum = sum + evalx(xs);
560 if (sum.error) break;
561 f = f+delta;
562 }
563 bound_variable[bv].error = 1;
564 free(xs);
565 return sum;
566 }
567
568
569 }
570
571
572