home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: Science
/
Science.zip
/
OS2SCALC.ZIP
/
LEX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-19
|
10KB
|
438 lines
/* SC A Spreadsheet Calculator
* Lexical analyser
*
* original by James Gosling, September 1982
* modifications by Mark Weiser and Bruce Israel,
* University of Maryland
*
* More mods Robert Bond, 12/86
* Major mods to run on VMS and AMIGA, 1/17/87
* OS/2 Modifications by Brady Flowers, 7/19/90
*
*/
#include "sc.h"
#include <ctype.h>
#ifdef VMS
#include "y_tab.h"
extern char *malloc();
char *strtof();
#else
#ifdef OS2
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "curs.h"
#include "ytab.h"
#define VOID void
#else
#include "y.tab.h"
extern char *malloc();
char *strtof();
#endif
#endif
#ifndef VOID
#define VOID
#endif
struct key {
char *key;
int val;
};
struct key experres[] = {
#include "experres.h"
0, 0};
struct key statres[] = {
#include "statres.h"
0, 0};
#define ctl(x) (x&037)
int yylex ()
{
register char *p = line+linelim;
int ret = -1;
while (isspace(*p)) p++;
if (*p==0)
ret = -1;
else if (isalpha(*p))
{
char *tokenst = p;
register tokenl;
register struct key *tbl;
while (isalpha(*p)) p++;
if (p-tokenst <= 2) { /* a COL is 1 or 2 char alpha */
register col;
ret = COL;
col = ((tokenst[0] & 0137) - 'A');
if (p == tokenst+2)
col = (col + 1)*26 + ((tokenst[1] & 0137) - 'A');
yylval.ival = col;
} else {
ret = WORD;
tokenl = p-tokenst;
for (tbl = linelim ? experres : statres; tbl->key; tbl++)
if (((tbl->key[0]^tokenst[0])&0137)==0
&& tbl->key[tokenl]==0) {
register i = 1;
while (i<tokenl && ((tokenst[i]^tbl->key[i])&0137)==0)
i++;
if (i>=tokenl) {
ret = tbl->val;
break;
}
}
if (ret==WORD) {
linelim = p-line;
yyerror ("Unintelligible word");
}
}
} else if ((*p == '.') || isdigit(*p)) {
register long v = 0;
char *nstart = p;
if (*p != '.') {
do v = v*10 + (*p-'0');
while (isdigit(*++p));
}
if (*p=='.' || *p == 'e' || *p == 'E') {
ret = FNUMBER;
p = strtof(nstart, &yylval.fval);
} else {
if((long)((int)v) != v)
{
ret = FNUMBER;
yylval.fval = (double)v;
}
else
{
ret = NUMBER;
yylval.ival = (int)v;
}
}
} else if (*p=='"') {
/* This storage is never freed. Oh well. -MDW */
char *ptr;
ptr = p+1;
while(*ptr && *ptr++ != '"');
ptr = (char *)malloc((unsigned)(ptr-p));
yylval.sval = ptr;
p += 1;
while (*p && *p!='"') *ptr++ = *p++;
*ptr = 0;
if (*p) p += 1;
ret = STRING;
} else if (*p=='[') {
while (*p && *p!=']') p++;
if (*p) p++;
linelim = p-line;
return yylex();
} else ret = *p++;
linelim = p-line;
return ret;
}
#define N_KEY 26
struct key_map {
char *k_str;
char k_val;
char k_index;
};
struct key_map km[N_KEY];
#ifdef OS2
#define N_KEY2 8
struct key_map2
{
char k2_scan;
char k2_val;
};
struct key_map2 km2[N_KEY2];
#endif
VOID initkbd()
{
/* cursor set mode */
km[0].k_str = "\033OD"; km[0].k_val = ctl('b');
km[1].k_str = "\033OC"; km[1].k_val = ctl('f');
km[2].k_str = "\033OA"; km[2].k_val = ctl('p');
km[3].k_str = "\033OB"; km[3].k_val = ctl('n');
/* cursor reset mode */
km[4].k_str = "\033[D"; km[4].k_val = ctl('b');
km[5].k_str = "\033[C"; km[5].k_val = ctl('f');
km[6].k_str = "\033[A"; km[6].k_val = ctl('p');
km[7].k_str = "\033[B"; km[7].k_val = ctl('n');
/* CSI arrows */
km[8].k_str = "\233D"; km[8].k_val = ctl('b');
km[9].k_str = "\233C"; km[9].k_val = ctl('f');
km[10].k_str = "\233A"; km[10].k_val = ctl('p');
km[11].k_str = "\233B"; km[11].k_val = ctl('n');
/* application keypad mode */
km[12].k_str = "\033Op"; km[12].k_val = '0';
km[13].k_str = "\033Oq"; km[13].k_val = '1';
km[14].k_str = "\033Or"; km[14].k_val = '2';
km[15].k_str = "\033Os"; km[15].k_val = '3';
km[16].k_str = "\033Ot"; km[16].k_val = '4';
km[17].k_str = "\033Ou"; km[17].k_val = '5';
km[18].k_str = "\033Ov"; km[18].k_val = '6';
km[19].k_str = "\033Ow"; km[19].k_val = '7';
km[20].k_str = "\033Ox"; km[20].k_val = '8';
km[21].k_str = "\033Oy"; km[21].k_val = '9';
km[22].k_str = "\033Om"; km[22].k_val = '-';
km[23].k_str = "\033Ol"; km[23].k_val = ',';
km[24].k_str = "\033On"; km[24].k_val = '.';
km[25].k_str = "\033OM"; km[25].k_val = ctl('m');
#ifdef OS2
/* PC Cursor Keys */
km2[0].k2_scan = 75; km2[0].k2_val = ctl('b'); /* left */
km2[1].k2_scan = 77; km2[1].k2_val = ctl('f'); /* right */
km2[2].k2_scan = 72; km2[2].k2_val = ctl('p'); /* up */
km2[3].k2_scan = 80; km2[3].k2_val = ctl('n'); /* down */
km2[4].k2_scan = 71; km2[4].k2_val = '0'; /* home */
km2[5].k2_scan = 79; km2[5].k2_val = '$'; /* end */
/* PC Function Keys */
km2[6].k2_scan = 59; km2[6].k2_val = '?'; /* F1 */
km2[7].k2_scan = 61; km2[7].k2_val = ctl('c'); /* F3 */
#endif
}
int nmgetch()
{
register int c;
register struct key_map *kp;
register struct key_map *biggest;
register int i;
int almost;
static char dumpbuf[10];
static char *dumpindex;
#ifdef OS2
register struct key_map2 *kp2;
static int PCKey = 0;
#else
void timeout();
#endif
if (dumpindex && *dumpindex)
return (*dumpindex++);
c = ttgetc();
biggest = 0;
almost = 0;
#ifdef OS2
if (PCKey)
{
PCKey = 0;
for (kp2 = &km2[0]; kp2 < &km2[N_KEY2]; kp2++)
if (c == kp2->k2_scan)
return (kp2->k2_val);
}
else if (c == 0)
{
PCKey = 1;
return (nmgetch());
}
#endif
for (kp = &km[0]; kp < &km[N_KEY]; kp++)
{
if (!kp->k_str)
continue;
if (c == (kp->k_str[kp->k_index] & 0xFF))
{
almost = 1;
kp->k_index++;
if (kp->k_str[kp->k_index] == 0)
{
c = kp->k_val;
for (kp = &km[0]; kp < &km[N_KEY]; kp++)
kp->k_index = 0;
return(c);
}
}
if (!biggest && kp->k_index)
biggest = kp;
else if (kp->k_index && biggest->k_index < kp->k_index)
biggest = kp;
}
if (almost) return(nmgetch());
if (biggest)
{
for (i = 0; i<biggest->k_index; i++)
dumpbuf[i] = biggest->k_str[i];
dumpbuf[i++] = (char)c;
dumpbuf[i] = 0;
dumpindex = &dumpbuf[1];
for (kp = &km[0]; kp < &km[N_KEY]; kp++)
kp->k_index = 0;
return (dumpbuf[0]);
}
return(c);
}
int dbline;
#ifdef OS2
static char buf[256];
VOID debug(char *fmt, ... )
{
va_list args;
va_start(args, fmt);
move(2+(dbline++%22),80-60);
vsprintf(buf, fmt, args);
printw("%s", buf);
clrtoeol();
}
#else
debug(fmt, a, b, c)
{
move(2+(dbline++%22),80-60);
printw(fmt,a,b,c);
clrtoeol();
}
#endif
/*
* This converts a floating point number of the form
* [s]ddd[.d*][esd*] where s can be a + or - and e is E or e.
* to floating point.
* p is advanced.
*/
char *
strtof(p, res)
register char *p;
double *res;
{
double acc;
int sign;
double fpos;
int exp;
int exps;
acc = 0.0;
sign = 1;
exp = 0;
exps = 1;
if (*p == '+')
p++;
else if (*p == '-') {
p++;
sign = -1;
}
while (isdigit(*p)) {
acc = acc * 10.0 + (double)(*p - '0');
p++;
}
if (*p == 'e' || *p == 'E') {
p++;
if (*p == '+')
p++;
else if (*p == '-') {
p++;
exps = -1;
}
while(isdigit(*p)) {
exp = exp * 10 + (*p - '0');
p++;
}
}
if (*p == '.') {
fpos = 1.0/10.0;
p++;
while(isdigit(*p)) {
acc += (*p - '0') * fpos;
fpos *= 1.0/10.0;
p++;
}
}
if (*p == 'e' || *p == 'E') {
exp = 0;
exps = 1;
p++;
if (*p == '+')
p++;
else if (*p == '-') {
p++;
exps = -1;
}
while(isdigit(*p)) {
exp = exp * 10 + (*p - '0');
p++;
}
}
if (exp) {
if (exps > 0)
while (exp--)
acc *= 10.0;
else
while (exp--)
acc *= 1.0/10.0;
}
if (sign > 0)
*res = acc;
else
*res = -acc;
return(p);
}
VOID help ()
{
move(2,0);
clrtobot();
dbline = 0;
debug (" Cursor cmds:");
debug (" ^n j next row ^p k prev. row ^g erase cmd");
debug (" ^f l fwd col ^b h back col ^r redraw screen");
debug (" 0 $ first, end col");
debug (" Cell cmds:");
debug (" \" < > enter label = enter value x clear cell");
debug (" c copy cell m mark cell ^t line 1 on/off");
debug (" ^a type value ^e type expr. ^v type vbl name");
debug (" Row, Column cmds:");
debug (" ar ac dup ir ic insert sr sc show");
debug (" dr dc delete zr zc hide pr pc pull");
debug (" vr vc value only f format");
debug (" File cmds:");
debug (" G get database M merge database T write tbl fmt");
debug (" P put database W write listing");
debug (" Misc. cmds:");
debug (" ^c, q quit / copy region pm pull (merge)");
debug (" Expression Operators");
debug (" +-*/ arithmetic ?e:e conditional & | booleans");
debug (" < = > relations <= >= relations != relations");
debug (" @sum(v1:v2) @avg(v1:v2) @prod(v1:v2)");
}