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;
+}
+
+
+}
+
+
+