Mercurial > ~dholland > hg > ag > index.cgi
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/agcl/parsifal/ss-fp.syn Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,572 @@ +{ +/* +Copyright 1992, Jerome T. Holland +See the file COPYING for license and usage terms. +*/ + +#include "ssd.h" +#include "kb.h" +#include "num.h" + +} + +cell name request = 255 +input line request = 254 +block request = 253 + +[ + ~allow macros + ~backtrack + ~case sensitive + ~declare pcb + ~diagnose errors + error trace + ~lines and columns + pointer input + ~test range + rule coverage + parser file name = "#.cpp" + default token type = number + disregard space +] + +letter = 'A-Z' +bound variable = 'A-Z' +digit = '0-9' +nonzero digit = '1-9' +eof = 0 +space = ' ' +decimal point = '.' +pi = 'ã' //character code 227 + + +(void) grammar + -> cell name request, cell name:cp, eof =goto_cell = cp; + -> input line request, input line + -> conditional expression:x, + ['\n', conditional expression]..., eof =xvalue = x; + -> block request, cell name:f, to, cell name:l, + eof =first_cell=f, last_cell = l; + +(void) input line + -> cell name: loc, '=' =stuff_cell(loc); + -> '@',cell name:f, to, cell name:l,'/', + format:fmt, eof =stuff_format(fmt,f,l); + +to + -> '.', '.'? + +(format_code) format + ->'a',':', alignment:a, ',', + 'c',':', conversion:c, ',', + 'd',':', integer:n ={ + format_code f; + f.alignment = a; + f.conversion =c; + f.decimals = n; + f.flag = 0; + return f; +} + +(int) alignment + -> 'L' =0; + -> 'C' =1; + -> 'R' =2; + +(int) conversion + -> 'C' =0; + -> 'F' =1; + -> 'G' =2; + +(pair<int>) cell name + -> column id:col, integer:row =id_cell(row-1,col); + +(int) column id + -> letter:a, letter:b =rel_column_id(a-'A'+1, b-'A'); + -> letter:a =rel_column_id(0, a-'A'); + +(int) integer + -> nonzero digit:d =d-'0'; + -> integer:n, digit:d =10*n + d-'0'; + +conditional expression + -> x expression + -> expression:x, ':', disjunction:c, ';', conditional expression:y ={ + number z; + switch (c.tv){ + case 0: + z = y; + break; + case 1: + z = x; + break; + case 2: + z.error = 1; + } + return z; +} + +disjunction + -> conjunction + -> disjunction:x, '|', conjunction:y =x||y; + +conjunction + -> logical value + -> conjunction:x, '&', logical value:y =x&&y; + +logical value + -> comparison + -> '(', disjunction:x, ')' =x; + -> '!', '(', disjunction:x, ')' =!x; + +comparison + -> partial comparison:x, '<', expression:y =x<y; + -> partial comparison:x, '>', expression:y =x>y; + -> partial comparison:x, "<=", expression:y =x<=y; + -> partial comparison:x, ">=", expression:y =x>=y; + -> partial comparison:x, "==", expression:y =x==y; + -> partial comparison:x, "!=", expression:y =x!=y; + +partial comparison + -> x expression + -> comparison + +x expression + -> expression + -> summation + -> expression:x, '+', summation:y =x+y; + -> expression:x, '-', summation:y =x-y; + +expression + -> term + -> expression:x, '+', term:y =x+y; + -> expression:x, '-', term:y =x-y; + +term + -> xxfactor + -> term:x, '*', xxfactor:y =x*y; + +xxfactor + -> xfactor + -> function:f, xfactor:y =apply(f,y); + -> factor:x, function:f, xfactor:y =x*apply(f,y); + +xfactor + -> yfactor + -> base:x, '^', xfactor:n =pow(x,n); + -> '-', xfactor:x =-x; + +yfactor + -> factor + -> yfactor:x, '/', factor:y =x/y; + +factor + -> simple factor + -> simple factor:x, r value:y =x*y; + -> r value + +simple factor + -> l value + -> c value + -> simple factor:x, c value:y =x*y; + +l value + -> number + +c value + -> cell name:cp =cell_value(cp); + -> parens + -> pi =num(M_PI); + -> sigma, cell name:first, '.', '.'?, cell name:last =sum_cells(first,last); + +r value + -> bound variable:k =bound_variable[k-'A']; + +summation + -> sigma:xb, x expression string:xf, ':', bound variable:k, '=', + x expression:f, ',', x expression:s, "...", x expression:l = + summation(xb,xf,k-'A', f, s, l); + +(char *) sigma + -> 'ä' =(char *)PCB.pointer; //character code 228 + +(char *) x expression string + -> x expression =(char *)PCB.pointer; + +base + -> l value + -> c value + -> r value + +parens + -> '(', conditional expression:x, ')' =x; + +(function_name) function + -> "abs" =fabs; + -> "acos" = acos; + -> "asin" = asin; + -> "atan" = atan; + -> "cosh" = cosh; + -> "cos" =cos; + -> "exp" =exp; + -> "log10" = log10; + -> "log" = log; + -> "pow10" = pow10d; + -> "round" = round; + -> "sinh" = sinh; + -> "sin" =sin; + -> "sqr" =sqr; + -> "sqrt" = sqrt; + -> "tanh" = tanh; + -> "tan" = tan; + -> "trunc" = trunc; + +number + -> integer part:x, decimal point? =num(x); + -> integer part:x, decimal point, fraction part:y =num(x+y); + -> decimal point, fraction part:x =num(x); + +(double) integer part + -> digit:d =d-'0'; + -> integer part:n, digit:d =10*n+d-'0'; + +(double) fraction part + -> digit:d =(d-'0')/10.; + -> digit:d, fraction part:f =(d-'0'+f)/10.; + +{ +fp_pcb_type *fp_pcb; +#define PCB (*fp_pcb) + + +#define CELL_NAME_REQUEST 255 +#define INPUT_LINE_REQUEST 254 +#define BLOCK_REQUEST 253 + +#define SYNTAX_ERROR +#define PARSER_STACK_OVERFLOW + +static int cell_refs; +static int error_flag; + +static number bound_variable[26]; +static number xvalue; + +number num(double x) { + number n; + n.error = 0; + n.truth = 1; + n.v = x; + return n; +} + +void init_bv(void) { + int i; + for (i = 0; i < 26; i++) bound_variable[i].error = 1; +} + +double round(double x) { + long n = x+.5; + return n; +} + +double trunc(double x) { + long n = x; + return n; +} + +double sqr(double x) { + return x*x; +} + +double pow10d(double x) { + long n = x; + return pow10d(n); +} + +number cell_value(pair<int> loc) { + number x; + cell_pointer cp; + int save_ef = error_flag; + + cell_refs++; + cp = ss[loc.row][loc.col]; + if (cp == NULL) { + x.truth = 1; + x.v = 0; + return x; + } + if (cp->type == text) { + x.error = 1; + x.truth = 0; + return x; + } + if (cp->type == formula) { + if ((inserted_columns || inserted_rows)); + else if (recalc_flag) { + if (cp->recalc == recalc_count) eval(cp); + if (cp->recalc & 1) circular_flag = 1; + } + } + x.error = cp->error; + x.truth = 1; + x.v = cp->value; + return x; +} + +void eval(cell_pointer cp) { + fp_pcb_type pcb, *save_pcb = fp_pcb; + + fp_pcb = &pcb; + cell_refs = 0; + PCB.pointer = (unsigned char *) &cp->text; + cp->recalc += recalc_flag; + error_flag = 0; + fp(); + cp->recalc += recalc_flag; + if (PCB.exit_flag != 1) {cp->type = text; cp->error = 1; return;} + else if (cell_refs == 0) cp->type = value; + else cp->type = formula; + { + cp->error = xvalue.error; + cp->value = xvalue.v; + } + fp_pcb = save_pcb; +} + +number evalx(char *xs) { + fp_pcb_type pcb, *save_pcb = fp_pcb; + number x; + + fp_pcb = &pcb; + PCB.pointer = (unsigned char *) xs; + error_flag = 0; + fp(); + fp_pcb = save_pcb; + return xvalue; +} + +pair<int> id_cell(int row, int col) { + pair<int> goto_cell = {0,0}; + if (row >= MAXROWS || col >= MAXCOLS) { + PCB.exit_flag = 5; + return goto_cell; + } + if (inserted_rows && row >= new_row) row += inserted_rows; + goto_cell.row = row; + goto_cell.col = col; + if (inserted_columns == 0 && inserted_rows == 0) return goto_cell; + sprintf((char *)icnptr,"%d",row+1); + icnptr += strlen((char *)icnptr); + icoptr = PCB.pointer; + return goto_cell; +} + +int matherr(struct exception *e) { + error_flag++; + e->retval = 0; + return 1; +} + +number apply(double(*f)(double), number n) { + number r; + if (n.error) return n; + error_flag = 0; + r.v = f(n.v); + r.error = error_flag != 0; + return r; +} + +number pow(number x, number n) { + number r; + r.error = x.error || n.error; + if (r.error) return r; + r.v = pow(x.v, n.v); + return r; +} + +void parse_block(void) { + int flag; + fp_pcb_type pcb; + + fp_pcb = &pcb; + PCB.pointer = (unsigned char *) text_buffer; + text_buffer[0] = BLOCK_REQUEST; + fp(); + flag = PCB.exit_flag != 1 + || first_cell.row > last_cell.row + || first_cell.col > last_cell.col + || last_cell.row > MAXROWS + || last_cell.col > MAXCOLS; + if (flag) { + kb_pcb.reduction_token = kb_bad_block_token; + display_message(&bad_block_message); + set_cursor(text_cursor); + } + else _setcursortype(_NOCURSOR); +} + +void parse_cell_name(void) { + int flag; + fp_pcb_type pcb; + + fp_pcb = &pcb; + PCB.pointer = (unsigned char *) text_buffer; + text_buffer[0] = CELL_NAME_REQUEST; + fp(); + flag = PCB.exit_flag != 1 + || goto_cell.row > MAXROWS + || goto_cell.col > MAXCOLS; + if (flag) { + kb_pcb.reduction_token = kb_bad_cell_name_token; + display_message(&bad_cell_message); + set_cursor(text_cursor); + } + else _setcursortype(_NOCURSOR); +} + +int rel_column_id(int a, int b) { + int cn = 26*a + b; + int nidc = a?2:1; + int n; + unsigned char case_bit = 0; + char *cp; + + if (inserted_columns == 0 && inserted_rows == 0) return cn; + if (cn >= new_column) cn += inserted_columns; + n = (PCB.pointer - icoptr) - nidc; + memmove((char *)icnptr, (char *)icoptr, n); + icnptr += n; + cp = (char *)PCB.pointer; + while (nidc--) case_bit |= *--cp; + case_bit &= 0x20; + cp = column_label(cn,case_bit); + strcpy((char *)icnptr,cp); + icnptr += strlen(cp); + return cn; +} + +void relabel_formula(cell_pointer cp) { + fp_pcb_type pcb, *save_pcb = fp_pcb; + + fp_pcb = &pcb; + icoptr = PCB.pointer = (unsigned char *) &cp->text; + icnptr = (unsigned char *) relabel_buf; + fp(); + assert(PCB.exit_flag == 1); + strcpy((char *)icnptr, (char *)icoptr); + cp = (cell_descriptor *) realloc(cp, sizeof(cell_descriptor) + strlen(relabel_buf)); + assert(cp); + strcpy(cp->text, relabel_buf); + fp_pcb = save_pcb; +} + +void scan_input_line(void) { + fp_pcb_type pcb, *save_pcb = fp_pcb; + + fp_pcb = &pcb; + PCB.pointer = (unsigned char *) text_buffer; + text_buffer[0] = INPUT_LINE_REQUEST; + fp(); + fp_pcb = save_pcb; +} + +void set_column_width(void) { + int n; + char *tb = text_buffer + 1; + int flag; + + highlight_off(); + for (n = 0; *tb;) n = 10*n + *tb++ - '0'; + flag = n < 3 || n > 75; + if (flag) { + kb_pcb.reduction_token = kb_column_width_request_token; + display_message(&bad_cw_message); + beep(); + set_cursor(text_cursor); + return; + } + _setcursortype(_NOCURSOR); + if (ac.scc.col + n > 81) move_data_left(); + cols[ac.ssc.col].width = n; + display_column_guide(); + update_screen(); + highlight_on(); +} + + +void stuff_cell(pair<int> loc) { + char *tb = (char *) fp_pcb->pointer; + cell_pointer cp = (cell_descriptor *) realloc( + ss[loc.row][loc.col], + sizeof(cell_descriptor) + strlen(tb)); + + assert(cp); + if (loc.row > max_row) max_row = loc.row; + if (loc.col > max_col) max_col = loc.col; + strcpy(cp->text, tb); + ss[loc.row][loc.col] = cp; + cp->recalc = recalc_count; + eval(cp); +} + +void stuff_format(format_code f,pair<int> first,pair<int> last){ + int i,j; + for (i=first.row;i<=last.row;i++) for (j=first.col;j<=last.col;j++) { + fmt[i][j] = f; + } + if (last.row > fmt_max_row) fmt_max_row = last.row; + if (last.col > fmt_max_col) fmt_max_col = last.col; +} + +number sum_cells(pair<int> first,pair<int> last){ + pair<int> cp; + number sum; + sum.error = sum.truth = 1; + sum.v = 0; + for (cp.row = first.row; cp.row <= last.row; cp.row++) + for (cp.col = first.col; cp.col <= last.col; cp.col++) { + number cv = cell_value(cp); + if (cv.error) return sum; + sum.v += cv.v; + } + sum.error = 0; + return sum; +} + +number summation(char *xb, char *xf, int bv, number f, number s, number l) { + number sum; + int k; + char *xs; + number delta; + int n; + + sum.error = f.error + s.error + l.error; + sum.v = 0; + if (sum.error) return sum; + k = (int) (xf - xb); + xs = (char *) malloc(k+1); + memmove(xs,xb,k); + xs[k] = 0; + delta = s-f; + if (delta.v == 0) { + sum.error = 1; + return sum; + } + n = ((l-f+delta)/delta).v + .5; + while (n--) { + bound_variable[bv] = f; + sum = sum + evalx(xs); + if (sum.error) break; + f = f+delta; + } + bound_variable[bv].error = 1; + free(xs); + return sum; +} + + +} + + +