home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / progs / sc / lex.c < prev    next >
C/C++ Source or Header  |  1990-07-19  |  10KB  |  438 lines

  1. /*    SC    A Spreadsheet Calculator
  2.  *        Lexical analyser
  3.  *
  4.  *        original by James Gosling, September 1982
  5.  *        modifications by Mark Weiser and Bruce Israel,
  6.  *            University of Maryland
  7.  *
  8.  *              More mods Robert Bond, 12/86
  9.  *        Major mods to run on VMS and AMIGA, 1/17/87
  10.  *   OS/2 Modifications by Brady Flowers, 7/19/90
  11.  *
  12.  */
  13.  
  14.  
  15.  
  16. #include "sc.h"
  17. #include <ctype.h>
  18.  
  19. #ifdef VMS
  20. #include "y_tab.h"
  21. extern char *malloc();
  22. char *strtof();
  23. #else
  24.  
  25. #ifdef OS2
  26. #include <stdlib.h>
  27. #include <stdarg.h>
  28. #include <string.h>
  29. #include "curs.h"
  30. #include "ytab.h"
  31. #define VOID void
  32. #else
  33. #include "y.tab.h"
  34. extern char *malloc();
  35. char *strtof();
  36. #endif
  37.  
  38. #endif
  39.  
  40. #ifndef VOID
  41. #define VOID
  42. #endif
  43.  
  44.  
  45. struct key {
  46.     char *key;
  47.     int val;
  48. };
  49.  
  50. struct key experres[] = {
  51. #include "experres.h"
  52.     0, 0};
  53.  
  54. struct key statres[] = {
  55. #include "statres.h"
  56.     0, 0};
  57.  
  58. #define ctl(x) (x&037)
  59.  
  60. int yylex ()
  61. {
  62.   register char *p = line+linelim;
  63.   int ret = -1;
  64.  
  65.   while (isspace(*p)) p++;
  66.   if (*p==0)
  67.     ret = -1;
  68.   else if (isalpha(*p))
  69.   {
  70.       char *tokenst = p;
  71.       register tokenl;
  72.       register struct key *tbl;
  73.  
  74.       while (isalpha(*p)) p++;
  75.       if (p-tokenst <= 2) { /* a COL is 1 or 2 char alpha */
  76.         register  col;
  77.         ret = COL;
  78.         col = ((tokenst[0] & 0137) - 'A');
  79.         if (p == tokenst+2)
  80.         col = (col + 1)*26 + ((tokenst[1] & 0137) - 'A');
  81.         yylval.ival =  col;
  82.     } else {
  83.         ret = WORD;
  84.         tokenl = p-tokenst;
  85.         for (tbl = linelim ? experres : statres; tbl->key; tbl++)
  86.             if (((tbl->key[0]^tokenst[0])&0137)==0
  87.              && tbl->key[tokenl]==0) {
  88.             register i = 1;
  89.             while (i<tokenl && ((tokenst[i]^tbl->key[i])&0137)==0)
  90.                 i++;
  91.             if (i>=tokenl) {
  92.                 ret = tbl->val;
  93.                 break;
  94.             }
  95.             }
  96.         if (ret==WORD) {
  97.         linelim = p-line;
  98.         yyerror ("Unintelligible word");
  99.         }
  100.     }
  101.     } else if ((*p == '.') || isdigit(*p)) {
  102.     register long v = 0;
  103.     char *nstart = p;
  104.     if (*p != '.') {
  105.         do v = v*10 + (*p-'0');
  106.         while (isdigit(*++p));
  107.     }
  108.     if (*p=='.' || *p == 'e' || *p == 'E') {
  109.         ret = FNUMBER;
  110.         p = strtof(nstart, &yylval.fval);
  111.     } else {
  112.             if((long)((int)v) != v)
  113.             {
  114.                 ret = FNUMBER;
  115.                 yylval.fval = (double)v;
  116.             }
  117.             else
  118.             {
  119.  
  120.                 ret = NUMBER;
  121.                 yylval.ival = (int)v;
  122.             }
  123.     }
  124.     } else if (*p=='"') {
  125.     /* This storage is never freed.  Oh well.  -MDW */
  126.     char *ptr;
  127.         ptr = p+1;
  128.         while(*ptr && *ptr++ != '"');
  129.         ptr = (char *)malloc((unsigned)(ptr-p));
  130.     yylval.sval = ptr;
  131.     p += 1;
  132.     while (*p && *p!='"') *ptr++ = *p++;
  133.     *ptr = 0;
  134.     if (*p) p += 1;
  135.     ret = STRING;
  136.     } else if (*p=='[') {
  137.     while (*p && *p!=']') p++;
  138.     if (*p) p++;
  139.     linelim = p-line;
  140.     return yylex();
  141.     } else ret = *p++;
  142.     linelim = p-line;
  143.     return ret;
  144. }
  145.  
  146. #define N_KEY 26
  147.  
  148. struct key_map {
  149.     char *k_str;
  150.     char k_val;
  151.     char k_index;
  152. };
  153.  
  154. struct key_map km[N_KEY];
  155.  
  156.  
  157. #ifdef OS2
  158. #define N_KEY2  8
  159.  
  160. struct key_map2
  161. {
  162.   char k2_scan;
  163.   char k2_val;
  164. };
  165.  
  166. struct key_map2 km2[N_KEY2];
  167. #endif
  168.  
  169. VOID initkbd()
  170. {
  171.  
  172.   /* cursor set mode */
  173.   km[0].k_str  = "\033OD"; km[0].k_val  = ctl('b');
  174.   km[1].k_str  = "\033OC"; km[1].k_val  = ctl('f');
  175.   km[2].k_str  = "\033OA"; km[2].k_val  = ctl('p');
  176.   km[3].k_str  = "\033OB"; km[3].k_val  = ctl('n');
  177.   /* cursor reset mode */
  178.   km[4].k_str  = "\033[D"; km[4].k_val  = ctl('b');
  179.   km[5].k_str  = "\033[C"; km[5].k_val  = ctl('f');
  180.   km[6].k_str  = "\033[A"; km[6].k_val  = ctl('p');
  181.   km[7].k_str  = "\033[B"; km[7].k_val  = ctl('n');
  182.   /* CSI arrows */
  183.   km[8].k_str  = "\233D";  km[8].k_val  = ctl('b');
  184.   km[9].k_str  = "\233C";  km[9].k_val  = ctl('f');
  185.   km[10].k_str = "\233A";  km[10].k_val = ctl('p');
  186.   km[11].k_str = "\233B";  km[11].k_val = ctl('n');
  187.   /* application keypad mode */
  188.   km[12].k_str = "\033Op"; km[12].k_val = '0';
  189.   km[13].k_str = "\033Oq"; km[13].k_val = '1';
  190.   km[14].k_str = "\033Or"; km[14].k_val = '2';
  191.   km[15].k_str = "\033Os"; km[15].k_val = '3';
  192.   km[16].k_str = "\033Ot"; km[16].k_val = '4';
  193.   km[17].k_str = "\033Ou"; km[17].k_val = '5';
  194.   km[18].k_str = "\033Ov"; km[18].k_val = '6';
  195.   km[19].k_str = "\033Ow"; km[19].k_val = '7';
  196.   km[20].k_str = "\033Ox"; km[20].k_val = '8';
  197.   km[21].k_str = "\033Oy"; km[21].k_val = '9';
  198.   km[22].k_str = "\033Om"; km[22].k_val = '-';
  199.   km[23].k_str = "\033Ol"; km[23].k_val = ',';
  200.   km[24].k_str = "\033On"; km[24].k_val = '.';
  201.   km[25].k_str = "\033OM"; km[25].k_val = ctl('m');
  202.  
  203. #ifdef OS2
  204.   /* PC Cursor Keys */
  205.   km2[0].k2_scan = 75; km2[0].k2_val = ctl('b'); /* left */
  206.   km2[1].k2_scan = 77; km2[1].k2_val = ctl('f'); /* right */
  207.   km2[2].k2_scan = 72; km2[2].k2_val = ctl('p'); /* up */
  208.   km2[3].k2_scan = 80; km2[3].k2_val = ctl('n'); /* down */
  209.   km2[4].k2_scan = 71; km2[4].k2_val = '0';      /* home */
  210.   km2[5].k2_scan = 79; km2[5].k2_val = '$';      /* end */
  211.   /* PC Function Keys */
  212.   km2[6].k2_scan = 59; km2[6].k2_val = '?';      /* F1 */
  213.   km2[7].k2_scan = 61; km2[7].k2_val = ctl('c'); /* F3 */
  214. #endif
  215. }
  216.  
  217. int nmgetch()
  218. {
  219.   register int c;
  220.   register struct key_map *kp;
  221.   register struct key_map *biggest;
  222.   register int i;
  223.   int almost;
  224.  
  225.   static char dumpbuf[10];
  226.   static char *dumpindex;
  227.  
  228. #ifdef OS2
  229.   register struct key_map2 *kp2;
  230.   static int PCKey = 0;
  231. #else
  232.   void timeout();
  233. #endif
  234.  
  235.   if (dumpindex && *dumpindex)
  236.       return (*dumpindex++);
  237.  
  238.   c = ttgetc();
  239.   biggest = 0;
  240.   almost = 0;
  241.  
  242. #ifdef OS2
  243.   if (PCKey)
  244.   {
  245.     PCKey = 0;
  246.     for (kp2 = &km2[0]; kp2 < &km2[N_KEY2]; kp2++)
  247.       if (c == kp2->k2_scan)
  248.         return (kp2->k2_val);
  249.   }
  250.   else if (c == 0)
  251.   {
  252.     PCKey = 1;
  253.     return (nmgetch());
  254.   }
  255. #endif
  256.  
  257.   for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  258.   {
  259.       if (!kp->k_str)
  260.       continue;
  261.  
  262.       if (c == (kp->k_str[kp->k_index] & 0xFF))
  263.     {
  264.         almost = 1;
  265.         kp->k_index++;
  266.         if (kp->k_str[kp->k_index] == 0)
  267.       {
  268.             c = kp->k_val;
  269.            for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  270.             kp->k_index = 0;
  271.           return(c);
  272.         }
  273.       }
  274.       if (!biggest && kp->k_index)
  275.         biggest = kp;
  276.     else if (kp->k_index && biggest->k_index < kp->k_index)
  277.         biggest = kp;
  278.   }
  279.  
  280.   if (almost) return(nmgetch());
  281.  
  282.   if (biggest)
  283.   {
  284.       for (i = 0; i<biggest->k_index; i++)
  285.         dumpbuf[i] = biggest->k_str[i];
  286.       dumpbuf[i++] = (char)c;
  287.       dumpbuf[i] = 0;
  288.       dumpindex = &dumpbuf[1];
  289.        for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  290.         kp->k_index = 0;
  291.       return (dumpbuf[0]);
  292.   }
  293.  
  294.   return(c);
  295. }
  296.  
  297.  
  298. int dbline;
  299.  
  300. #ifdef OS2
  301.  
  302. static char buf[256];
  303.  
  304. VOID debug(char *fmt, ... )
  305. {
  306.   va_list args;
  307.  
  308.   va_start(args, fmt);
  309.     move(2+(dbline++%22),80-60);
  310.   vsprintf(buf, fmt, args);
  311.     printw("%s", buf);
  312.     clrtoeol();
  313. }
  314.  
  315. #else
  316.  
  317. debug(fmt, a, b, c)
  318. {
  319.     move(2+(dbline++%22),80-60);
  320.     printw(fmt,a,b,c);
  321.     clrtoeol();
  322. }
  323.  
  324. #endif
  325.  
  326. /*
  327.  * This converts a floating point number of the form
  328.  * [s]ddd[.d*][esd*]  where s can be a + or - and e is E or e.
  329.  * to floating point.
  330.  * p is advanced.
  331.  */
  332.  
  333. char *
  334. strtof(p, res)
  335. register char *p;
  336. double *res;
  337. {
  338.     double acc;
  339.     int sign;
  340.     double fpos;
  341.     int exp;
  342.     int exps;
  343.  
  344.     acc = 0.0;
  345.     sign = 1;
  346.     exp = 0;
  347.     exps = 1;
  348.     if (*p == '+')
  349.         p++;
  350.     else if (*p == '-') {
  351.         p++;
  352.         sign = -1;
  353.     }
  354.     while (isdigit(*p)) {
  355.         acc = acc * 10.0 + (double)(*p - '0');
  356.         p++;
  357.     }
  358.     if (*p == 'e' || *p == 'E') {
  359.         p++;
  360.         if (*p == '+')
  361.         p++;
  362.         else if (*p == '-') {
  363.         p++;
  364.         exps = -1;
  365.         }
  366.         while(isdigit(*p)) {
  367.         exp = exp * 10 + (*p - '0');
  368.         p++;
  369.         }
  370.     }
  371.     if (*p == '.') {
  372.     fpos = 1.0/10.0;
  373.     p++;
  374.     while(isdigit(*p)) {
  375.         acc += (*p - '0') * fpos;
  376.         fpos *= 1.0/10.0;
  377.         p++;
  378.     }
  379.     }
  380.     if (*p == 'e' || *p == 'E') {
  381.     exp = 0;
  382.     exps = 1;
  383.         p++;
  384.     if (*p == '+')
  385.         p++;
  386.     else if (*p == '-') {
  387.         p++;
  388.         exps = -1;
  389.     }
  390.     while(isdigit(*p)) {
  391.         exp = exp * 10 + (*p - '0');
  392.         p++;
  393.     }
  394.     }
  395.     if (exp) {
  396.     if (exps > 0)
  397.         while (exp--)
  398.         acc *= 10.0;
  399.     else
  400.         while (exp--)
  401.         acc *= 1.0/10.0;
  402.     }
  403.     if (sign > 0)
  404.         *res = acc;
  405.     else
  406.     *res = -acc;
  407.  
  408.     return(p);
  409. }
  410.  
  411. VOID help ()
  412. {
  413.     move(2,0);
  414.     clrtobot();
  415.     dbline = 0;
  416.     debug ("                 Cursor cmds:");
  417.     debug ("  ^n j next row       ^p k prev. row      ^g erase cmd");
  418.     debug ("  ^f l fwd col        ^b h back col       ^r redraw screen");
  419.     debug ("   0 $ first, end col");
  420.     debug ("                 Cell cmds:");
  421.     debug (" \" < > enter label       = enter value     x clear cell");
  422.     debug ("     c copy cell         m mark cell      ^t line 1 on/off");
  423.     debug ("    ^a type value       ^e type expr.     ^v type vbl name");
  424.     debug ("                 Row, Column cmds:");
  425.     debug (" ar ac dup           ir ic insert      sr sc show");
  426.     debug (" dr dc delete        zr zc hide        pr pc pull");
  427.     debug (" vr vc value only        f format");
  428.     debug ("                 File cmds:");
  429.     debug ("     G get database      M merge database  T write tbl fmt");
  430.     debug ("     P put database      W write listing");
  431.     debug ("                 Misc. cmds:");
  432.     debug (" ^c, q quit              / copy region    pm pull (merge)");
  433.     debug ("                 Expression Operators");
  434.     debug ("  +-*/ arithmetic     ?e:e conditional   & | booleans");
  435.     debug (" < = > relations     <= >= relations      != relations");
  436.     debug ("       @sum(v1:v2)         @avg(v1:v2)       @prod(v1:v2)");
  437. }
  438.