--- /dev/null
+# include "ldefs.c"
+phead1(){
+ ratfor ? rhd1() : chd1();
+ }
+
+chd1(){
+ fprintf(fout,"# include \"stdio.h\"\n");
+ if (ZCH>NCH)
+ fprintf(fout, "# define U(x) ((x)&0377)\n");
+ else
+ fprintf(fout, "# define U(x) x\n");
+ fprintf(fout, "# define NLSTATE yyprevious=YYNEWLINE\n");
+ fprintf(fout,"# define BEGIN yybgin = yysvec + 1 +\n");
+ fprintf(fout,"# define INITIAL 0\n");
+ fprintf(fout,"# define YYLERR yysvec\n");
+ fprintf(fout,"# define YYSTATE (yyestate-yysvec-1)\n");
+ if(optim)
+ fprintf(fout,"# define YYOPTIM 1\n");
+# ifdef DEBUG
+ fprintf(fout,"# define LEXDEBUG 1\n");
+# endif
+ fprintf(fout,"# define YYLMAX 200\n");
+ fprintf(fout,"# define output(c) putc(c,yyout)\n");
+ fprintf(fout, "%s%d%s\n",
+ "# define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==",
+ ctable['\n'],
+ "?(yylineno++,yytchar):yytchar)==EOF?0:yytchar)");
+ fprintf(fout,
+"# define unput(c) {yytchar= (c);if(yytchar=='\\n')yylineno--;*yysptr++=yytchar;}\n");
+ fprintf(fout,"# define yymore() (yymorfg=1)\n");
+ fprintf(fout,"# define ECHO fprintf(yyout, \"%%s\",yytext)\n");
+ fprintf(fout,"# define REJECT { nstr = yyreject(); goto yyfussy;}\n");
+ fprintf(fout,"int yyleng; extern char yytext[];\n");
+ fprintf(fout,"int yymorfg;\n");
+ fprintf(fout,"extern char *yysptr, yysbuf[];\n");
+ fprintf(fout,"int yytchar;\n");
+ fprintf(fout,"FILE *yyin ={stdin}, *yyout ={stdout};\n");
+ fprintf(fout,"extern int yylineno;\n");
+ fprintf(fout,"struct yysvf { \n");
+ fprintf(fout,"\tstruct yywork *yystoff;\n");
+ fprintf(fout,"\tstruct yysvf *yyother;\n");
+ fprintf(fout,"\tint *yystops;};\n");
+ fprintf(fout,"struct yysvf *yyestate;\n");
+ fprintf(fout,"extern struct yysvf yysvec[], *yybgin;\n");
+ }
+
+rhd1(){
+ fprintf(fout,"integer function yylex(dummy)\n");
+ fprintf(fout,"define YYLMAX 200\n");
+ fprintf(fout,"define ECHO call yyecho(yytext,yyleng)\n");
+ fprintf(fout,"define REJECT nstr = yyrjct(yytext,yyleng);goto 30998\n");
+ fprintf(fout,"integer nstr,yylook,yywrap\n");
+ fprintf(fout,"integer yyleng, yytext(YYLMAX)\n");
+ fprintf(fout,"common /yyxel/ yyleng, yytext\n");
+ fprintf(fout,"common /yyldat/ yyfnd, yymorf, yyprev, yybgin, yylsp, yylsta\n");
+ fprintf(fout,"integer yyfnd, yymorf, yyprev, yybgin, yylsp, yylsta(YYLMAX)\n");
+ fprintf(fout,"for(;;){\n");
+ fprintf(fout,"\t30999 nstr = yylook(dummy)\n");
+ fprintf(fout,"\tgoto 30998\n");
+ fprintf(fout,"\t30000 k = yywrap(dummy)\n");
+ fprintf(fout,"\tif(k .ne. 0){\n");
+ fprintf(fout,"\tyylex=0; return; }\n");
+ fprintf(fout,"\t\telse goto 30998\n");
+ }
+
+phead2(){
+ if(!ratfor)chd2();
+ }
+
+chd2(){
+ fprintf(fout,"while((nstr = yylook()) >= 0)\n");
+ fprintf(fout,"yyfussy: switch(nstr){\n");
+ fprintf(fout,"case 0:\n");
+ fprintf(fout,"if(yywrap()) return(0); break;\n");
+ }
+
+ptail(){
+ if(!pflag)
+ ratfor ? rtail() : ctail();
+ pflag = 1;
+ }
+
+ctail(){
+ fprintf(fout,"case -1:\nbreak;\n"); /* for reject */
+ fprintf(fout,"default:\n");
+ fprintf(fout,"fprintf(yyout,\"bad switch yylook %%d\",nstr);\n");
+ fprintf(fout,"} return(0); }\n");
+ fprintf(fout,"/* end of yylex */\n");
+ }
+
+rtail(){
+ register int i;
+ fprintf(fout,"\n30998 if(nstr .lt. 0 .or. nstr .gt. %d)goto 30999\n",casecount);
+ fprintf(fout,"nstr = nstr + 1\n");
+ fprintf(fout,"goto(\n");
+ for(i=0; i<casecount; i++)
+ fprintf(fout,"%d,\n",30000+i);
+ fprintf(fout,"30999),nstr\n");
+ fprintf(fout,"30997 continue\n");
+ fprintf(fout,"}\nend\n");
+ }
+statistics(){
+ fprintf(errorf,"%d/%d nodes(%%e), %d/%d positions(%%p), %d/%d (%%n), %ld transitions\n",
+ tptr, treesize, nxtpos-positions, maxpos, stnum+1, nstates, rcount);
+ fprintf(errorf, ", %d/%d packed char classes(%%k)", pcptr-pchar, pchlen);
+ if(optim)fprintf(errorf,", %d/%d packed transitions(%%a)",nptr, ntrans);
+ fprintf(errorf, ", %d/%d output slots(%%o)", yytop, outsize);
+ putc('\n',errorf);
+ }
--- /dev/null
+# include <stdio.h>
+# define PP 1
+# ifdef unix
+
+# define CWIDTH 7
+# define CMASK 0177
+# define ASCII 1
+# endif
+
+# ifdef gcos
+# define CWIDTH 9
+# define CMASK 0777
+# define ASCII 1
+# endif
+
+# ifdef ibm
+# define CWIDTH 8
+# define CMASK 0377
+# define EBCDIC 1
+# endif
+
+# ifdef ASCII
+# define NCH 128
+# endif
+
+# ifdef EBCDIC
+# define NCH 256
+# endif
+
+
+# define TOKENSIZE 1000
+# define DEFSIZE 40
+# define DEFCHAR 1000
+# define STARTCHAR 100
+# define STARTSIZE 256
+# define CCLSIZE 1000
+# ifdef SMALL
+# define TREESIZE 600
+# define NTRANS 1500
+# define NSTATES 300
+# define MAXPOS 1500
+# define NOUTPUT 1500
+# endif
+
+# ifndef SMALL
+# define TREESIZE 1000
+# define NSTATES 500
+# define MAXPOS 2500
+# define NTRANS 2000
+# define NOUTPUT 3000
+# endif
+# define NACTIONS 100
+# define ALITTLEEXTRA 30
+
+# define RCCL NCH+90
+# define RNCCL NCH+91
+# define RSTR NCH+92
+# define RSCON NCH+93
+# define RNEWE NCH+94
+# define FINAL NCH+95
+# define RNULLS NCH+96
+# define RCAT NCH+97
+# define STAR NCH+98
+# define PLUS NCH+99
+# define QUEST NCH+100
+# define DIV NCH+101
+# define BAR NCH+102
+# define CARAT NCH+103
+# define S1FINAL NCH+104
+# define S2FINAL NCH+105
+
+# define DEFSECTION 1
+# define RULESECTION 2
+# define ENDSECTION 5
+# define TRUE 1
+# define FALSE 0
+
+# define PC 1
+# define PS 1
+
+# ifdef DEBUG
+# define LINESIZE 110
+extern int yydebug;
+extern int debug; /* 1 = on */
+extern int charc;
+# endif
+
+# ifndef DEBUG
+# define freturn(s) s
+# endif
+
+extern int sargc;
+extern char **sargv;
+extern char buf[520];
+extern int ratfor; /* 1 = ratfor, 0 = C */
+extern int yyline; /* line number of file */
+extern int sect;
+extern int eof;
+extern int lgatflg;
+extern int divflg;
+extern int funcflag;
+extern int pflag;
+extern int casecount;
+extern int chset; /* 1 = char set modified */
+extern FILE *fin, *fout, *fother, *errorf;
+extern int fptr;
+extern char *ratname, *cname;
+extern int prev; /* previous input character */
+extern int pres; /* present input character */
+extern int peek; /* next input character */
+extern int *name;
+extern int *left;
+extern int *right;
+extern int *parent;
+extern char *nullstr;
+extern int tptr;
+extern char pushc[TOKENSIZE];
+extern char *pushptr;
+extern char slist[STARTSIZE];
+extern char *slptr;
+extern char **def, **subs, *dchar;
+extern char **sname, *schar;
+extern char *ccl;
+extern char *ccptr;
+extern char *dp, *sp;
+extern int dptr, sptr;
+extern char *bptr; /* store input position */
+extern char *tmpstat;
+extern int count;
+extern int **foll;
+extern int *nxtpos;
+extern int *positions;
+extern int *gotof;
+extern int *nexts;
+extern char *nchar;
+extern int **state;
+extern int *sfall; /* fallback state num */
+extern char *cpackflg; /* true if state has been character packed */
+extern int *atable, aptr;
+extern int nptr;
+extern char symbol[NCH];
+extern char cindex[NCH];
+extern int xstate;
+extern int stnum;
+extern int ctable[];
+extern int ZCH;
+extern int ccount;
+extern char match[NCH];
+extern char extra[NACTIONS];
+extern char *pcptr, *pchar;
+extern int pchlen;
+extern int nstates, maxpos;
+extern int yytop;
+extern int report;
+extern int ntrans, treesize, outsize;
+extern long rcount;
+extern int optim;
+extern int *verify, *advance, *stoff;
+extern int scon;
+extern char *psave;
+extern char *calloc(), *myalloc();
+extern int buserr(), segviol();
--- /dev/null
+# include "ldefs.c"
+# include "once.c"
+
+ /* lex [-[drcyvntf]] [file] ... [file] */
+
+ /* Copyright 1976, Bell Telephone Laboratories, Inc.,
+ written by Eric Schmidt, August 27, 1976 */
+
+main(argc,argv)
+ int argc;
+ char **argv; {
+ register int i;
+# ifdef DEBUG
+#include <signal.h>
+ signal(SIGBUS,buserr);
+ signal(SIGSEGV,segviol);
+# endif
+ while (argc > 1 && argv[1][0] == '-' ){
+ i = 0;
+ while(argv[1][++i]){
+ switch (argv[1][i]){
+# ifdef DEBUG
+ case 'd': debug++; break;
+ case 'y': yydebug = TRUE; break;
+# endif
+ case 'r': case 'R':
+ ratfor=TRUE; break;
+ case 'c': case 'C':
+ ratfor=FALSE; break;
+ case 't': case 'T':
+ fout = stdout;
+ errorf = stderr;
+ break;
+ case 'v': case 'V':
+ report = 1;
+ break;
+ case 'f': case 'F':
+ optim = FALSE;
+ break;
+ case 'n': case 'N':
+ report = 0;
+ break;
+ default:
+ warning("Unknown option %c",argv[1][i]);
+ }
+ }
+ argc--;
+ argv++;
+ }
+ sargc = argc;
+ sargv = argv;
+ if (argc > 1){
+ fin = fopen(argv[++fptr], "r"); /* open argv[1] */
+ sargc--;
+ sargv++;
+ }
+ else fin = stdin;
+ if(fin == NULL)
+ error ("Can't read input file %s",argc>1?argv[1]:"standard input");
+ gch();
+ /* may be gotten: def, subs, sname, schar, ccl, dchar */
+ get1core();
+ /* may be gotten: name, left, right, nullstr, parent */
+ scopy("INITIAL",sp);
+ sname[0] = sp;
+ sp += slength("INITIAL") + 1;
+ sname[1] = 0;
+ if(yyparse(0)) exit(1); /* error return code */
+ /* may be disposed of: def, subs, dchar */
+ free1core();
+ /* may be gotten: tmpstat, foll, positions, gotof, nexts, nchar, state, atable, sfall, cpackflg */
+ get2core();
+ ptail();
+ mkmatch();
+# ifdef DEBUG
+ if(debug) pccl();
+# endif
+ sect = ENDSECTION;
+ if(tptr>0)cfoll(tptr-1);
+# ifdef DEBUG
+ if(debug)pfoll();
+# endif
+ cgoto();
+# ifdef DEBUG
+ if(debug){
+ printf("Print %d states:\n",stnum+1);
+ for(i=0;i<=stnum;i++)stprt(i);
+ }
+# endif
+ /* may be disposed of: positions, tmpstat, foll, state, name, left, right, parent, ccl, schar, sname */
+ /* may be gotten: verify, advance, stoff */
+ free2core();
+ get3core();
+ layout();
+ /* may be disposed of: verify, advance, stoff, nexts, nchar,
+ gotof, atable, ccpackflg, sfall */
+# ifdef DEBUG
+ free3core();
+# endif
+ if (ZCH>NCH) cname="/usr/lib/lex/ebcform";
+ fother = fopen(ratfor?ratname:cname,"r");
+ if(fother == NULL)
+ error("Lex driver missing, file %s",ratfor?ratname:cname);
+ while ( (i=getc(fother)) != EOF)
+ putc(i,fout);
+
+ fclose(fother);
+ fclose(fout);
+ if(
+# ifdef DEBUG
+ debug ||
+# endif
+ report == 1)statistics();
+ fclose(stdout);
+ fclose(stderr);
+ exit(0); /* success return code */
+ }
+get1core(){
+ register int i, val;
+ register char *p;
+ccptr = ccl = myalloc(CCLSIZE,sizeof(*ccl));
+pcptr = pchar = myalloc(pchlen, sizeof(*pchar));
+ def = myalloc(DEFSIZE,sizeof(*def));
+ subs = myalloc(DEFSIZE,sizeof(*subs));
+dp = dchar = myalloc(DEFCHAR,sizeof(*dchar));
+ sname = myalloc(STARTSIZE,sizeof(*sname));
+sp = schar = myalloc(STARTCHAR,sizeof(*schar));
+ if(ccl == 0 || def == 0 || subs == 0 || dchar == 0 || sname == 0 || schar == 0)
+ error("Too little core to begin");
+ }
+free1core(){
+ cfree(def,DEFSIZE,sizeof(*def));
+ cfree(subs,DEFSIZE,sizeof(*subs));
+ cfree(dchar,DEFCHAR,sizeof(*dchar));
+ }
+get2core(){
+ register int i, val;
+ register char *p;
+ gotof = myalloc(nstates,sizeof(*gotof));
+ nexts = myalloc(ntrans,sizeof(*nexts));
+ nchar = myalloc(ntrans,sizeof(*nchar));
+ state = myalloc(nstates,sizeof(*state));
+ atable = myalloc(nstates,sizeof(*atable));
+ sfall = myalloc(nstates,sizeof(*sfall));
+ cpackflg = myalloc(nstates,sizeof(*cpackflg));
+ tmpstat = myalloc(tptr+1,sizeof(*tmpstat));
+ foll = myalloc(tptr+1,sizeof(*foll));
+nxtpos = positions = myalloc(maxpos,sizeof(*positions));
+ if(tmpstat == 0 || foll == 0 || positions == 0 ||
+ gotof == 0 || nexts == 0 || nchar == 0 || state == 0 || atable == 0 || sfall == 0 || cpackflg == 0 )
+ error("Too little core for state generation");
+ for(i=0;i<=tptr;i++)foll[i] = 0;
+ }
+free2core(){
+ cfree(positions,maxpos,sizeof(*positions));
+ cfree(tmpstat,tptr+1,sizeof(*tmpstat));
+ cfree(foll,tptr+1,sizeof(*foll));
+ cfree(name,treesize,sizeof(*name));
+ cfree(left,treesize,sizeof(*left));
+ cfree(right,treesize,sizeof(*right));
+ cfree(parent,treesize,sizeof(*parent));
+ cfree(nullstr,treesize,sizeof(*nullstr));
+ cfree(state,nstates,sizeof(*state));
+ cfree(sname,STARTSIZE,sizeof(*sname));
+ cfree(schar,STARTCHAR,sizeof(*schar));
+ cfree(ccl,CCLSIZE,sizeof(*ccl));
+ }
+get3core(){
+ register int i, val;
+ register char *p;
+ verify = myalloc(outsize,sizeof(*verify));
+ advance = myalloc(outsize,sizeof(*advance));
+ stoff = myalloc(stnum+2,sizeof(*stoff));
+ if(verify == 0 || advance == 0 || stoff == 0)
+ error("Too little core for final packing");
+ }
+# ifdef DEBUG
+free3core(){
+ cfree(advance,outsize,sizeof(*advance));
+ cfree(verify,outsize,sizeof(*verify));
+ cfree(stoff,stnum+1,sizeof(*stoff));
+ cfree(gotof,nstates,sizeof(*gotof));
+ cfree(nexts,ntrans,sizeof(*nexts));
+ cfree(nchar,ntrans,sizeof(*nchar));
+ cfree(atable,nstates,sizeof(*atable));
+ cfree(sfall,nstates,sizeof(*sfall));
+ cfree(cpackflg,nstates,sizeof(*cpackflg));
+ }
+# endif
+char *myalloc(a,b)
+ int a,b; {
+ register int i;
+ i = calloc(a, b);
+ if(i==0)
+ warning("OOPS - calloc returns a 0");
+ else if(i == -1){
+# ifdef DEBUG
+ warning("calloc returns a -1");
+# endif
+ return(0);
+ }
+ return(i);
+ }
+# ifdef DEBUG
+buserr(){
+ fflush(errorf);
+ fflush(fout);
+ fflush(stdout);
+ fprintf(errorf,"Bus error\n");
+ if(report == 1)statistics();
+ fflush(errorf);
+ }
+segviol(){
+ fflush(errorf);
+ fflush(fout);
+ fflush(stdout);
+ fprintf(errorf,"Segmentation violation\n");
+ if(report == 1)statistics();
+ fflush(errorf);
+ }
+# endif
+
+yyerror(s)
+char *s;
+{
+ fprintf(stderr, "%s\n", s);
+}
--- /dev/null
+int yylineno =1;
+# define YYU(x) x
+# define NLSTATE yyprevious=YYNEWLINE
+char yytext[YYLMAX];
+struct yysvf *yylstate [YYLMAX], **yylsp, **yyolsp;
+char yysbuf[YYLMAX];
+char *yysptr = yysbuf;
+int *yyfnd;
+extern struct yysvf *yyestate;
+int yyprevious = YYNEWLINE;
+yylook(){
+ register struct yysvf *yystate, **lsp;
+ register struct yywork *yyt;
+ struct yysvf *yyz;
+ int yych;
+ struct yywork *yyr;
+# ifdef LEXDEBUG
+ int debug;
+# endif
+ char *yylastch;
+ /* start off machines */
+# ifdef LEXDEBUG
+ debug = 0;
+# endif
+ if (!yymorfg)
+ yylastch = yytext;
+ else {
+ yymorfg=0;
+ yylastch = yytext+yyleng;
+ }
+ for(;;){
+ lsp = yylstate;
+ yyestate = yystate = yybgin;
+ if (yyprevious==YYNEWLINE) yystate++;
+ for (;;){
+# ifdef LEXDEBUG
+ if(debug)fprintf(yyout,"state %d\n",yystate-yysvec-1);
+# endif
+ yyt = yystate->yystoff;
+ if(yyt == yycrank){ /* may not be any transitions */
+ yyz = yystate->yyother;
+ if(yyz == 0)break;
+ if(yyz->yystoff == yycrank)break;
+ }
+ *yylastch++ = yych = input();
+ tryagain:
+# ifdef LEXDEBUG
+ if(debug){
+ fprintf(yyout,"char ");
+ allprint(yych);
+ putchar('\n');
+ }
+# endif
+ yyr = yyt;
+ if ( (int)yyt > (int)yycrank){
+ yyt = yyr + yych;
+ if (yyt <= yytop && yyt->verify+yysvec == yystate){
+ if(yyt->advance+yysvec == YYLERR) /* error transitions */
+ {unput(*--yylastch);break;}
+ *lsp++ = yystate = yyt->advance+yysvec;
+ goto contin;
+ }
+ }
+# ifdef YYOPTIM
+ else if((int)yyt < (int)yycrank) { /* r < yycrank */
+ yyt = yyr = yycrank+(yycrank-yyt);
+# ifdef LEXDEBUG
+ if(debug)fprintf(yyout,"compressed state\n");
+# endif
+ yyt = yyt + yych;
+ if(yyt <= yytop && yyt->verify+yysvec == yystate){
+ if(yyt->advance+yysvec == YYLERR) /* error transitions */
+ {unput(*--yylastch);break;}
+ *lsp++ = yystate = yyt->advance+yysvec;
+ goto contin;
+ }
+ yyt = yyr + YYU(yymatch[yych]);
+# ifdef LEXDEBUG
+ if(debug){
+ fprintf(yyout,"try fall back character ");
+ allprint(YYU(yymatch[yych]));
+ putchar('\n');
+ }
+# endif
+ if(yyt <= yytop && yyt->verify+yysvec == yystate){
+ if(yyt->advance+yysvec == YYLERR) /* error transition */
+ {unput(*--yylastch);break;}
+ *lsp++ = yystate = yyt->advance+yysvec;
+ goto contin;
+ }
+ }
+ if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){
+# ifdef LEXDEBUG
+ if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1);
+# endif
+ goto tryagain;
+ }
+# endif
+ else
+ {unput(*--yylastch);break;}
+ contin:
+# ifdef LEXDEBUG
+ if(debug){
+ fprintf(yyout,"state %d char ",yystate-yysvec-1);
+ allprint(yych);
+ putchar('\n');
+ }
+# endif
+ ;
+ }
+# ifdef LEXDEBUG
+ if(debug){
+ fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1);
+ allprint(yych);
+ putchar('\n');
+ }
+# endif
+ while (lsp-- > yylstate){
+ *yylastch-- = 0;
+ if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){
+ yyolsp = lsp;
+ if(yyextra[*yyfnd]){ /* must backup */
+ while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){
+ lsp--;
+ unput(*yylastch--);
+ }
+ }
+ yyprevious = YYU(*yylastch);
+ yylsp = lsp;
+ yyleng = yylastch-yytext+1;
+ yytext[yyleng] = 0;
+# ifdef LEXDEBUG
+ if(debug){
+ fprintf(yyout,"\nmatch ");
+ sprint(yytext);
+ fprintf(yyout," action %d\n",*yyfnd);
+ }
+# endif
+ return(*yyfnd++);
+ }
+ unput(*yylastch);
+ }
+ if (yytext[0] == 0 /* && feof(yyin) */)
+ {
+ yysptr=yysbuf;
+ return(0);
+ }
+ yyprevious = yytext[0] = input();
+ if (yyprevious>0)
+ output(yyprevious);
+ yylastch=yytext;
+# ifdef LEXDEBUG
+ if(debug)putchar('\n');
+# endif
+ }
+ }
+yyback(p, m)
+ int *p;
+{
+if (p==0) return(0);
+while (*p)
+ {
+ if (*p++ == m)
+ return(1);
+ }
+return(0);
+}
+ /* the following are only used in the lex library */
+yyinput(){
+ return(input());
+ }
+yyoutput(c)
+ int c; {
+ output(c);
+ }
+yyunput(c)
+ int c; {
+ unput(c);
+ }
--- /dev/null
+ /* because of external definitions, this code should occur only once */
+# ifdef ASCII
+int ctable[2*NCH] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+100,101,102,103,104,105,106,107,108,109,
+110,111,112,113,114,115,116,117,118,119,
+120,121,122,123,124,125,126,127};
+# endif
+# ifdef EBCDIC
+int ctable[2*NCH] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+100,101,102,103,104,105,106,107,108,109,
+110,111,112,113,114,115,116,117,118,119,
+120,121,122,123,124,125,126,127,128,129,
+130,131,132,133,134,135,136,137,138,139,
+140,141,142,143,144,145,146,147,148,149,
+150,151,152,153,154,155,156,157,158,159,
+160,161,162,163,164,165,166,167,168,169,
+170,171,172,173,174,175,176,177,178,179,
+180,181,182,183,184,185,186,187,188,189,
+190,191,192,193,194,195,196,197,198,199,
+200,201,202,203,204,205,206,207,208,209,
+210,211,212,213,214,215,216,217,218,219,
+220,221,222,223,224,225,226,227,228,229,
+230,231,232,233,234,235,236,237,238,239,
+240,241,242,243,244,245,246,247,248,249,
+250,251,252,253,254,255};
+# endif
+int ZCH = NCH;
+FILE *fout = NULL, *errorf = {stdout};
+int sect = DEFSECTION;
+int prev = '\n'; /* previous input character */
+int pres = '\n'; /* present input character */
+int peek = '\n'; /* next input character */
+char *pushptr = pushc;
+char *slptr = slist;
+
+# if (unix || ibm)
+char *cname = "/usr/lib/lex/ncform";
+char *ratname = "/usr/lib/lex/nrform";
+# endif
+
+# ifdef gcos
+char *cname = "pounce/lexcform";
+char *ratname = "pounce/lexrform";
+# endif
+int ccount = 1;
+int casecount = 1;
+int aptr = 1;
+int nstates = NSTATES, maxpos = MAXPOS;
+int treesize = TREESIZE, ntrans = NTRANS;
+int yytop;
+int outsize = NOUTPUT;
+int sptr = 1;
+int optim = TRUE;
+int report = 2;
+int debug; /* 1 = on */
+int charc;
+int sargc;
+char **sargv;
+char buf[520];
+int ratfor; /* 1 = ratfor, 0 = C */
+int yyline; /* line number of file */
+int eof;
+int lgatflg;
+int divflg;
+int funcflag;
+int pflag;
+int chset; /* 1 = char set modified */
+FILE *fin, *fother;
+int fptr;
+int *name;
+int *left;
+int *right;
+int *parent;
+char *nullstr;
+int tptr;
+char pushc[TOKENSIZE];
+char slist[STARTSIZE];
+char **def, **subs, *dchar;
+char **sname, *schar;
+char *ccl;
+char *ccptr;
+char *dp, *sp;
+int dptr;
+char *bptr; /* store input position */
+char *tmpstat;
+int count;
+int **foll;
+int *nxtpos;
+int *positions;
+int *gotof;
+int *nexts;
+char *nchar;
+int **state;
+int *sfall; /* fallback state num */
+char *cpackflg; /* true if state has been character packed */
+int *atable;
+int nptr;
+char symbol[NCH];
+char cindex[NCH];
+int xstate;
+int stnum;
+char match[NCH];
+char extra[NACTIONS];
+char *pchar, *pcptr;
+int pchlen = TOKENSIZE;
+ long rcount;
+int *verify, *advance, *stoff;
+int scon;
+char *psave;
+int buserr(), segviol();
--- /dev/null
+%token CHAR CCL NCCL STR DELIM SCON ITER NEWE NULLS
+%left SCON '/' NEWE
+%left '|'
+%left '$' '^'
+%left CHAR CCL NCCL '(' '.' STR NULLS
+%left ITER
+%left CAT
+%left '*' '+' '?'
+
+%{
+# include "ldefs.c"
+%}
+%%
+%{
+int i;
+int j,k;
+int g;
+char *p;
+%}
+acc : lexinput
+ ={
+# ifdef DEBUG
+ if(debug) sect2dump();
+# endif
+ }
+ ;
+lexinput: defns delim prods end
+ | defns delim end
+ ={
+ if(!funcflag)phead2();
+ funcflag = TRUE;
+ }
+ | error
+ ={
+# ifdef DEBUG
+ if(debug) {
+ sect1dump();
+ sect2dump();
+ }
+# endif
+ }
+ ;
+end: delim | ;
+defns: defns STR STR
+ ={ scopy($2,dp);
+ def[dptr] = dp;
+ dp += slength($2) + 1;
+ scopy($3,dp);
+ subs[dptr++] = dp;
+ if(dptr >= DEFSIZE)
+ error("Too many definitions");
+ dp += slength($3) + 1;
+ if(dp >= dchar+DEFCHAR)
+ error("Definitions too long");
+ subs[dptr]=def[dptr]=0; /* for lookup - require ending null */
+ }
+ |
+ ;
+delim: DELIM
+ ={
+# ifdef DEBUG
+ if(sect == DEFSECTION && debug) sect1dump();
+# endif
+ sect++;
+ }
+ ;
+prods: prods pr
+ ={ $$ = mn2(RNEWE,$1,$2);
+ }
+ | pr
+ ={ $$ = $1;}
+ ;
+pr: r NEWE
+ ={
+ if(divflg == TRUE)
+ i = mn1(S1FINAL,casecount);
+ else i = mn1(FINAL,casecount);
+ $$ = mn2(RCAT,$1,i);
+ divflg = FALSE;
+ casecount++;
+ }
+ | error NEWE
+ ={
+# ifdef DEBUG
+ if(debug) sect2dump();
+# endif
+ }
+r: CHAR
+ ={ $$ = mn0($1); }
+ | STR
+ ={
+ p = $1;
+ i = mn0(*p++);
+ while(*p)
+ i = mn2(RSTR,i,*p++);
+ $$ = i;
+ }
+ | '.'
+ ={ symbol['\n'] = 0;
+ if(psave == FALSE){
+ p = ccptr;
+ psave = ccptr;
+ for(i=1;i<'\n';i++){
+ symbol[i] = 1;
+ *ccptr++ = i;
+ }
+ for(i='\n'+1;i<NCH;i++){
+ symbol[i] = 1;
+ *ccptr++ = i;
+ }
+ *ccptr++ = 0;
+ if(ccptr > ccl+CCLSIZE)
+ error("Too many large character classes");
+ }
+ else
+ p = psave;
+ $$ = mn1(RCCL,p);
+ cclinter(1);
+ }
+ | CCL
+ ={ $$ = mn1(RCCL,$1); }
+ | NCCL
+ ={ $$ = mn1(RNCCL,$1); }
+ | r '*'
+ ={ $$ = mn1(STAR,$1); }
+ | r '+'
+ ={ $$ = mn1(PLUS,$1); }
+ | r '?'
+ ={ $$ = mn1(QUEST,$1); }
+ | r '|' r
+ ={ $$ = mn2(BAR,$1,$3); }
+ | r r %prec CAT
+ ={ $$ = mn2(RCAT,$1,$2); }
+ | r '/' r
+ ={ if(!divflg){
+ j = mn1(S2FINAL,-casecount);
+ i = mn2(RCAT,$1,j);
+ $$ = mn2(DIV,i,$3);
+ }
+ else {
+ $$ = mn2(RCAT,$1,$3);
+ warning("Extra slash removed");
+ }
+ divflg = TRUE;
+ }
+ | r ITER ',' ITER '}'
+ ={ if($2 > $4){
+ i = $2;
+ $2 = $4;
+ $4 = i;
+ }
+ if($4 <= 0)
+ warning("Iteration range must be positive");
+ else {
+ j = $1;
+ for(k = 2; k<=$2;k++)
+ j = mn2(RCAT,j,dupl($1));
+ for(i = $2+1; i<=$4; i++){
+ g = dupl($1);
+ for(k=2;k<=i;k++)
+ g = mn2(RCAT,g,dupl($1));
+ j = mn2(BAR,j,g);
+ }
+ $$ = j;
+ }
+ }
+ | r ITER '}'
+ ={
+ if($2 < 0)warning("Can't have negative iteration");
+ else if($2 == 0) $$ = mn0(RNULLS);
+ else {
+ j = $1;
+ for(k=2;k<=$2;k++)
+ j = mn2(RCAT,j,dupl($1));
+ $$ = j;
+ }
+ }
+ | r ITER ',' '}'
+ ={
+ /* from n to infinity */
+ if($2 < 0)warning("Can't have negative iteration");
+ else if($2 == 0) $$ = mn1(STAR,$1);
+ else if($2 == 1)$$ = mn1(PLUS,$1);
+ else { /* >= 2 iterations minimum */
+ j = $1;
+ for(k=2;k<$2;k++)
+ j = mn2(RCAT,j,dupl($1));
+ k = mn1(PLUS,dupl($1));
+ $$ = mn2(RCAT,j,k);
+ }
+ }
+ | SCON r
+ ={ $$ = mn2(RSCON,$2,$1); }
+ | '^' r
+ ={ $$ = mn1(CARAT,$2); }
+ | r '$'
+ ={ i = mn0('\n');
+ if(!divflg){
+ j = mn1(S2FINAL,-casecount);
+ k = mn2(RCAT,$1,j);
+ $$ = mn2(DIV,k,i);
+ }
+ else $$ = mn2(RCAT,$1,i);
+ divflg = TRUE;
+ }
+ | '(' r ')'
+ ={ $$ = $2; }
+ | NULLS
+ ={ $$ = mn0(RNULLS); }
+ ;
+%%
+yylex(){
+ register char *p;
+ register int c, i;
+ char *t, *xp;
+ int n, j, k, x;
+ static int sectbegin;
+ static char token[TOKENSIZE];
+ static int iter;
+
+# ifdef DEBUG
+ yylval = 0;
+# endif
+
+ if(sect == DEFSECTION) { /* definitions section */
+ while(!eof) {
+ if(prev == '\n'){ /* next char is at beginning of line */
+ getl(p=buf);
+ switch(*p){
+ case '%':
+ switch(c= *(p+1)){
+ case '%':
+ lgate();
+ if(!ratfor)fprintf(fout,"# ");
+ fprintf(fout,"define YYNEWLINE %d\n",ctable['\n']);
+ if(!ratfor)fprintf(fout,"yylex(){\nint nstr; extern int yyprevious;\n");
+ sectbegin = TRUE;
+ i = treesize*(sizeof(*name)+sizeof(*left)+
+ sizeof(*right)+sizeof(*nullstr)+sizeof(*parent))+ALITTLEEXTRA;
+ c = myalloc(i,1);
+ if(c == 0)
+ error("Too little core for parse tree");
+ p = c;
+ cfree(p,i,1);
+ name = myalloc(treesize,sizeof(*name));
+ left = myalloc(treesize,sizeof(*left));
+ right = myalloc(treesize,sizeof(*right));
+ nullstr = myalloc(treesize,sizeof(*nullstr));
+ parent = myalloc(treesize,sizeof(*parent));
+ if(name == 0 || left == 0 || right == 0 || parent == 0 || nullstr == 0)
+ error("Too little core for parse tree");
+ return(freturn(DELIM));
+ case 'p': case 'P': /* has overridden number of positions */
+ while(*p && !digit(*p))p++;
+ maxpos = siconv(p);
+# ifdef DEBUG
+ if (debug) printf("positions (%%p) now %d\n",maxpos);
+# endif
+ if(report == 2)report = 1;
+ continue;
+ case 'n': case 'N': /* has overridden number of states */
+ while(*p && !digit(*p))p++;
+ nstates = siconv(p);
+# ifdef DEBUG
+ if(debug)printf( " no. states (%%n) now %d\n",nstates);
+# endif
+ if(report == 2)report = 1;
+ continue;
+ case 'e': case 'E': /* has overridden number of tree nodes */
+ while(*p && !digit(*p))p++;
+ treesize = siconv(p);
+# ifdef DEBUG
+ if (debug) printf("treesize (%%e) now %d\n",treesize);
+# endif
+ if(report == 2)report = 1;
+ continue;
+ case 'o': case 'O':
+ while (*p && !digit(*p))p++;
+ outsize = siconv(p);
+ if (report ==2) report=1;
+ continue;
+ case 'a': case 'A': /* has overridden number of transitions */
+ while(*p && !digit(*p))p++;
+ if(report == 2)report = 1;
+ ntrans = siconv(p);
+# ifdef DEBUG
+ if (debug)printf("N. trans (%%a) now %d\n",ntrans);
+# endif
+ continue;
+ case 'k': case 'K': /* overriden packed char classes */
+ while (*p && !digit(*p))p++;
+ if (report==2) report=1;
+ cfree(pchar, pchlen, sizeof(*pchar));
+ pchlen = siconv(p);
+# ifdef DEBUG
+ if (debug) printf( "Size classes (%%k) now %d\n",pchlen);
+# endif
+ pchar=pcptr=myalloc(pchlen, sizeof(*pchar));
+ continue;
+ case 't': case 'T': /* character set specifier */
+ ZCH = atoi(p+2);
+ if (ZCH < NCH) ZCH = NCH;
+ if (ZCH > 2*NCH) error("ch table needs redeclaration");
+ chset = TRUE;
+ for(i = 0; i<ZCH; i++)
+ ctable[i] = 0;
+ while(getl(p) && scomp(p,"%T") != 0 && scomp(p,"%t") != 0){
+ if((n = siconv(p)) <= 0 || n > ZCH){
+ warning("Character value %d out of range",n);
+ continue;
+ }
+ while(!space(*p) && *p) p++;
+ while(space(*p)) p++;
+ t = p;
+ while(*t){
+ c = ctrans(&t);
+ if(ctable[c]){
+ if (printable(c))
+ warning("Character '%c' used twice",c);
+ else
+ warning("Character %o used twice",c);
+ }
+ else ctable[c] = n;
+ t++;
+ }
+ p = buf;
+ }
+ {
+ char chused[2*NCH]; int kr;
+ for(i=0; i<ZCH; i++)
+ chused[i]=0;
+ for(i=0; i<NCH; i++)
+ chused[ctable[i]]=1;
+ for(kr=i=1; i<NCH; i++)
+ if (ctable[i]==0)
+ {
+ while (chused[kr] == 0)
+ kr++;
+ ctable[i]=kr;
+ chused[kr]=1;
+ }
+ }
+ lgate();
+ continue;
+ case 'r': case 'R':
+ c = 'r';
+ case 'c': case 'C':
+ if(lgatflg)
+ error("Too late for language specifier");
+ ratfor = (c == 'r');
+ continue;
+ case '{':
+ lgate();
+ while(getl(p) && scomp(p,"%}") != 0)
+ fprintf(fout, "%s\n",p);
+ if(p[0] == '%') continue;
+ error("Premature eof");
+ case 's': case 'S': /* start conditions */
+ lgate();
+ while(*p && index(*p," \t,") < 0) p++;
+ n = TRUE;
+ while(n){
+ while(*p && index(*p," \t,") >= 0) p++;
+ t = p;
+ while(*p && index(*p," \t,") < 0)p++;
+ if(!*p) n = FALSE;
+ *p++ = 0;
+ if (*t == 0) continue;
+ i = sptr*2;
+ if(!ratfor)fprintf(fout,"# ");
+ fprintf(fout,"define %s %d\n",t,i);
+ scopy(t,sp);
+ sname[sptr++] = sp;
+ sname[sptr] = 0; /* required by lookup */
+ if(sptr >= STARTSIZE)
+ error("Too many start conditions");
+ sp += slength(sp) + 1;
+ if(sp >= schar+STARTCHAR)
+ error("Start conditions too long");
+ }
+ continue;
+ default:
+ warning("Invalid request %s",p);
+ continue;
+ } /* end of switch after seeing '%' */
+ case ' ': case '\t': /* must be code */
+ lgate();
+ fprintf(fout, "%s\n",p);
+ continue;
+ default: /* definition */
+ while(*p && !space(*p)) p++;
+ if(*p == 0)
+ continue;
+ prev = *p;
+ *p = 0;
+ bptr = p+1;
+ yylval = buf;
+ if(digit(buf[0]))
+ warning("Substitution strings may not begin with digits");
+ return(freturn(STR));
+ }
+ }
+ /* still sect 1, but prev != '\n' */
+ else {
+ p = bptr;
+ while(*p && space(*p)) p++;
+ if(*p == 0)
+ warning("No translation given - null string assumed");
+ scopy(p,token);
+ yylval = token;
+ prev = '\n';
+ return(freturn(STR));
+ }
+ }
+ /* end of section one processing */
+ }
+ else if(sect == RULESECTION){ /* rules and actions */
+ while(!eof){
+ switch(c=gch()){
+ case '\0':
+ return(freturn(0));
+ case '\n':
+ if(prev == '\n') continue;
+ x = NEWE;
+ break;
+ case ' ':
+ case '\t':
+ if(sectbegin == TRUE){
+ cpyact();
+ while((c=gch()) && c != '\n');
+ continue;
+ }
+ if(!funcflag)phead2();
+ funcflag = TRUE;
+ if(ratfor)fprintf(fout,"%d\n",30000+casecount);
+ else fprintf(fout,"case %d:\n",casecount);
+ if(cpyact()){
+ if(ratfor)fprintf(fout,"goto 30997\n");
+ else fprintf(fout,"break;\n");
+ }
+ while((c=gch()) && c != '\n');
+ if(peek == ' ' || peek == '\t' || sectbegin == TRUE){
+ warning("Executable statements should occur right after %%");
+ continue;
+ }
+ x = NEWE;
+ break;
+ case '%':
+ if(prev != '\n') goto character;
+ if(peek == '{'){ /* included code */
+ getl(buf);
+ while(!eof && getl(buf) && scomp("%}",buf) != 0)
+ fprintf(fout,"%s\n",buf);
+ continue;
+ }
+ if(peek == '%'){
+ c = gch();
+ c = gch();
+ x = DELIM;
+ break;
+ }
+ goto character;
+ case '|':
+ if(peek == ' ' || peek == '\t' || peek == '\n'){
+ if(ratfor)fprintf(fout,"%d\n",30000+casecount++);
+ else fprintf(fout,"case %d:\n",casecount++);
+ continue;
+ }
+ x = '|';
+ break;
+ case '$':
+ if(peek == '\n' || peek == ' ' || peek == '\t' || peek == '|' || peek == '/'){
+ x = c;
+ break;
+ }
+ goto character;
+ case '^':
+ if(prev != '\n' && scon != TRUE) goto character; /* valid only at line begin */
+ x = c;
+ break;
+ case '?':
+ case '+':
+ case '.':
+ case '*':
+ case '(':
+ case ')':
+ case ',':
+ case '/':
+ x = c;
+ break;
+ case '}':
+ iter = FALSE;
+ x = c;
+ break;
+ case '{': /* either iteration or definition */
+ if(digit(c=gch())){ /* iteration */
+ iter = TRUE;
+ ieval:
+ i = 0;
+ while(digit(c)){
+ token[i++] = c;
+ c = gch();
+ }
+ token[i] = 0;
+ yylval = siconv(token);
+ munput('c',c);
+ x = ITER;
+ break;
+ }
+ else { /* definition */
+ i = 0;
+ while(c && c!='}'){
+ token[i++] = c;
+ c = gch();
+ }
+ token[i] = 0;
+ i = lookup(token,def);
+ if(i < 0)
+ warning("Definition %s not found",token);
+ else
+ munput('s',subs[i]);
+ continue;
+ }
+ case '<': /* start condition ? */
+ if(prev != '\n') /* not at line begin, not start */
+ goto character;
+ t = slptr;
+ do {
+ i = 0;
+ c = gch();
+ while(c != ',' && c && c != '>'){
+ token[i++] = c;
+ c = gch();
+ }
+ token[i] = 0;
+ if(i == 0)
+ goto character;
+ i = lookup(token,sname);
+ if(i < 0) {
+ warning("Undefined start condition %s",token);
+ continue;
+ }
+ *slptr++ = i+1;
+ } while(c && c != '>');
+ *slptr++ = 0;
+ /* check if previous value re-usable */
+ for (xp=slist; xp<t; )
+ {
+ if (strcmp(xp, t)==0)
+ break;
+ while (*xp++);
+ }
+ if (xp<t)
+ {
+ /* re-use previous pointer to string */
+ slptr=t;
+ t=xp;
+ }
+ if(slptr > slist+STARTSIZE) /* note not packed ! */
+ error("Too many start conditions used");
+ yylval = t;
+ x = SCON;
+ break;
+ case '"':
+ i = 0;
+ while((c=gch()) && c != '"' && c != '\n'){
+ if(c == '\\') c = usescape(c=gch());
+ token[i++] = c;
+ if(i > TOKENSIZE){
+ warning("String too long");
+ i = TOKENSIZE-1;
+ break;
+ }
+ }
+ if(c == '\n') {
+ yyline--;
+ warning("Non-terminated string");
+ yyline++;
+ }
+ token[i] = 0;
+ if(i == 0)x = NULLS;
+ else if(i == 1){
+ yylval = token[0];
+ x = CHAR;
+ }
+ else {
+ yylval = token;
+ x = STR;
+ }
+ break;
+ case '[':
+ for(i=1;i<NCH;i++) symbol[i] = 0;
+ x = CCL;
+ if((c = gch()) == '^'){
+ x = NCCL;
+ c = gch();
+ }
+ while(c != ']' && c){
+ if(c == '\\') c = usescape(c=gch());
+ symbol[c] = 1;
+ j = c;
+ if((c=gch()) == '-' && peek != ']'){ /* range specified */
+ c = gch();
+ if(c == '\\') c = usescape(c=gch());
+ k = c;
+ if(j > k) {
+ n = j;
+ j = k;
+ k = n;
+ }
+ if(!(('A' <= j && k <= 'Z') ||
+ ('a' <= j && k <= 'z') ||
+ ('0' <= j && k <= '9')))
+ warning("Non-portable Character Class");
+ for(n=j+1;n<=k;n++)
+ symbol[n] = 1; /* implementation dependent */
+ c = gch();
+ }
+ }
+ /* try to pack ccl's */
+ i = 0;
+ for(j=0;j<NCH;j++)
+ if(symbol[j])token[i++] = j;
+ token[i] = 0;
+ p = ccptr;
+ if(optim){
+ p = ccl;
+ while(p <ccptr && scomp(token,p) != 0)p++;
+ }
+ if(p < ccptr) /* found it */
+ yylval = p;
+ else {
+ yylval = ccptr;
+ scopy(token,ccptr);
+ ccptr += slength(token) + 1;
+ if(ccptr >= ccl+CCLSIZE)
+ error("Too many large character classes");
+ }
+ cclinter(x==CCL);
+ break;
+ case '\\':
+ c = usescape(c=gch());
+ default:
+ character:
+ if(iter){ /* second part of an iteration */
+ iter = FALSE;
+ if('0' <= c && c <= '9')
+ goto ieval;
+ }
+ if(alpha(peek)){
+ i = 0;
+ yylval = token;
+ token[i++] = c;
+ while(alpha(peek))
+ token[i++] = gch();
+ if(peek == '?' || peek == '*' || peek == '+')
+ munput('c',token[--i]);
+ token[i] = 0;
+ if(i == 1){
+ yylval = token[0];
+ x = CHAR;
+ }
+ else x = STR;
+ }
+ else {
+ yylval = c;
+ x = CHAR;
+ }
+ }
+ scon = FALSE;
+ if(x == SCON)scon = TRUE;
+ sectbegin = FALSE;
+ return(freturn(x));
+ }
+ }
+ /* section three */
+ ptail();
+# ifdef DEBUG
+ if(debug)
+ fprintf(fout,"\n/*this comes from section three - debug */\n");
+# endif
+ while(getl(buf) && !eof)
+ fprintf(fout,"%s\n",buf);
+ return(freturn(0));
+ }
+/* end of yylex */
+# ifdef DEBUG
+freturn(i)
+ int i; {
+ if(yydebug) {
+ printf("now return ");
+ if(i < NCH) allprint(i);
+ else printf("%d",i);
+ printf(" yylval = ");
+ switch(i){
+ case STR: case CCL: case NCCL:
+ strpt(yylval);
+ break;
+ case CHAR:
+ allprint(yylval);
+ break;
+ default:
+ printf("%d",yylval);
+ break;
+ }
+ putchar('\n');
+ }
+ return(i);
+ }
+# endif
--- /dev/null
+# include "ldefs.c"
+char *
+getl(p) /* return next line of input, throw away trailing '\n' */
+ /* returns 0 if eof is had immediately */
+ char *p;
+ {
+ register int c;
+ register char *s, *t;
+ t = s = p;
+ while(((c = gch()) != 0) && c != '\n')
+ *t++ = c;
+ *t = 0;
+ if(c == 0 && s == t) return(0);
+ prev = '\n';
+ pres = '\n';
+ return(s);
+ }
+space(ch)
+ {
+ switch(ch)
+ {
+ case ' ':
+ case '\t':
+ case '\n':
+ return(1);
+ }
+ return(0);
+ }
+
+digit(c)
+{
+ return(c>='0' && c <= '9');
+}
+error(s,p,d)
+ {
+ if(!eof)fprintf(errorf,"%d: ",yyline);
+ fprintf(errorf,"(Error) ");
+ fprintf(errorf,s,p,d);
+ putc('\n',errorf);
+# ifdef DEBUG
+ if(debug && sect != ENDSECTION) {
+ sect1dump();
+ sect2dump();
+ }
+# endif
+ if(
+# ifdef DEBUG
+ debug ||
+# endif
+ report == 1) statistics();
+ exit(1); /* error return code */
+ }
+
+warning(s,p,d)
+ {
+ if(!eof)fprintf(errorf,"%d: ",yyline);
+ fprintf(errorf,"(Warning) ");
+ fprintf(errorf,s,p,d);
+ putc('\n',errorf);
+ fflush(errorf);
+ fflush(fout);
+ fflush(stdout);
+ }
+index(a,s)
+ char *s;
+{
+ register int k;
+ for(k=0; s[k]; k++)
+ if (s[k]== a)
+ return(k);
+ return(-1);
+ }
+
+alpha(c)
+ int c; {
+# ifdef ASCII
+return('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z');
+# endif
+# ifdef EBCDIC
+return(index(c,"abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") >= 0);
+# endif
+}
+printable(c)
+{
+# ifdef ASCII
+return( c>040 && c < 0177);
+# endif
+# ifdef EBCDIC
+return(index(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,;:><+*)('&%!-=\"")>=0);
+# endif
+}
+lgate()
+{
+ char fname[20];
+ if (lgatflg) return;
+ lgatflg=1;
+ if(fout == NULL){
+ sprintf(fname, "lex.yy.%c", ratfor ? 'r' : 'c' );
+ fout = fopen(fname, "w");
+ }
+ if(fout == NULL) error("Can't open %s",fname);
+ if(ratfor) fprintf( fout, "#\n");
+ phead1();
+ }
+/* scopy(ptr to str, ptr to str) - copy first arg str to second */
+/* returns ptr to second arg */
+scopy(s,t)
+ char *s, *t; {
+ register char *i;
+ i = t;
+ while(*i++ = *s++);
+ return;
+ }
+siconv(t) /* convert string t, return integer value */
+ char *t; {
+ register int i,sw;
+ register char *s;
+ s = t;
+ while(!(('0' <= *s && *s <= '9') || *s == '-') && *s) s++;
+ sw = 0;
+ if(*s == '-'){ /* neg */
+ sw = 1;
+ s++;
+ }
+ i = 0;
+ while('0' <= *s && *s <= '9')
+ i = i * 10 + (*(s++)-'0');
+ return(sw ? -i : i);
+ }
+/* slength(ptr to str) - return integer length of string arg */
+/* excludes '\0' terminator */
+slength(s)
+ char *s; {
+ register int n;
+ register char *t;
+ t = s;
+ for (n = 0; *t++; n++);
+ return(n);
+ }
+/* scomp(x,y) - return -1 if x < y,
+ 0 if x == y,
+ return 1 if x > y, all lexicographically */
+scomp(x,y)
+ char *x,*y; {
+ register char *a,*d;
+ a = x;
+ d = y;
+ while(*a || *d){
+ if(*a > *d)
+ return(1); /* greater */
+ if(*a < *d)
+ return(-1); /* less */
+ a++;
+ d++;
+ }
+ return(0); /* equal */
+ }
+ctrans(ss)
+ char **ss;
+{
+ register int c, k;
+ if ((c = **ss) != '\\')
+ return(c);
+ switch(c= *++*ss)
+ {
+ case 'n': c = '\n'; break;
+ case 't': c = '\t'; break;
+ case 'r': c = '\r'; break;
+ case 'b': c = '\b'; break;
+ case 'f': c = 014; break; /* form feed for ascii */
+ case '\\': c = '\\'; break;
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ c -= '0';
+ while ((k = *(*ss+1)) >= '0' && k <= '7')
+ {
+ c = c*8 + k - '0';
+ (*ss)++;
+ }
+ break;
+ }
+ return(c);
+}
+cclinter(sw)
+ int sw; {
+ /* sw = 1 ==> ccl */
+ register int i, j, k;
+ int m;
+ if(!sw){ /* is NCCL */
+ for(i=1;i<NCH;i++)
+ symbol[i] ^= 1; /* reverse value */
+ }
+ for(i=1;i<NCH;i++)
+ if(symbol[i]) break;
+ if(i >= NCH) return;
+ i = cindex[i];
+ /* see if ccl is already in our table */
+ j = 0;
+ if(i){
+ for(j=1;j<NCH;j++){
+ if((symbol[j] && cindex[j] != i) ||
+ (!symbol[j] && cindex[j] == i)) break;
+ }
+ }
+ if(j >= NCH) return; /* already in */
+ m = 0;
+ k = 0;
+ for(i=1;i<NCH;i++)
+ if(symbol[i]){
+ if(!cindex[i]){
+ cindex[i] = ccount;
+ symbol[i] = 0;
+ m = 1;
+ }
+ else k = 1;
+ }
+ /* m == 1 implies last value of ccount has been used */
+ if(m)ccount++;
+ if(k == 0) return; /* is now in as ccount wholly */
+ /* intersection must be computed */
+ for(i=1;i<NCH;i++){
+ if(symbol[i]){
+ m = 0;
+ j = cindex[i]; /* will be non-zero */
+ for(k=1;k<NCH;k++){
+ if(cindex[k] == j){
+ if(symbol[k]) symbol[k] = 0;
+ else {
+ cindex[k] = ccount;
+ m = 1;
+ }
+ }
+ }
+ if(m)ccount++;
+ }
+ }
+ return;
+ }
+usescape(c)
+ int c; {
+ register char d;
+ switch(c){
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case 'b': c = '\b'; break;
+ case 'f': c = 014; break; /* form feed for ascii */
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ c -= '0';
+ while('0' <= (d=gch()) && d <= '7'){
+ c = c * 8 + (d-'0');
+ if(!('0' <= peek && peek <= '7')) break;
+ }
+ break;
+ }
+ return(c);
+ }
+lookup(s,t)
+ char *s;
+ char **t; {
+ register int i;
+ i = 0;
+ while(*t){
+ if(scomp(s,*t) == 0)
+ return(i);
+ i++;
+ t++;
+ }
+ return(-1);
+ }
+cpyact(){ /* copy C action to the next ; or closing } */
+ register int brac, c, mth;
+ int savline, sw;
+
+ brac = 0;
+ sw = TRUE;
+
+while(!eof){
+ c = gch();
+swt:
+ switch( c ){
+
+case '|': if(brac == 0 && sw == TRUE){
+ if(peek == '|')gch(); /* eat up an extra '|' */
+ return(0);
+ }
+ break;
+
+case ';':
+ if( brac == 0 ){
+ putc(c,fout);
+ putc('\n',fout);
+ return(1);
+ }
+ break;
+
+case '{':
+ brac++;
+ savline=yyline;
+ break;
+
+case '}':
+ brac--;
+ if( brac == 0 ){
+ putc(c,fout);
+ putc('\n',fout);
+ return(1);
+ }
+ break;
+
+case '/': /* look for comments */
+ putc(c,fout);
+ c = gch();
+ if( c != '*' ) goto swt;
+
+ /* it really is a comment */
+
+ putc(c,fout);
+ savline=yyline;
+ while( c=gch() ){
+ if( c=='*' ){
+ putc(c,fout);
+ if( (c=gch()) == '/' ) goto loop;
+ }
+ putc(c,fout);
+ }
+ yyline=savline;
+ error( "EOF inside comment" );
+
+case '\'': /* character constant */
+ mth = '\'';
+ goto string;
+
+case '"': /* character string */
+ mth = '"';
+
+ string:
+
+ putc(c,fout);
+ while( c=gch() ){
+ if( c=='\\' ){
+ putc(c,fout);
+ c=gch();
+ }
+ else if( c==mth ) goto loop;
+ putc(c,fout);
+ if (c == '\n')
+ {
+ yyline--;
+ error( "Non-terminated string or character constant");
+ }
+ }
+ error( "EOF in string or character constant" );
+
+case '\0':
+ yyline = savline;
+ error("Action does not terminate");
+default:
+ break; /* usual character */
+ }
+loop:
+ if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;
+ putc(c,fout);
+ }
+error("Premature EOF");
+}
+gch(){
+ register int c;
+ prev = pres;
+ c = pres = peek;
+ peek = pushptr > pushc ? *--pushptr : getc(fin);
+ if(peek == EOF && sargc > 1){
+ fclose(fin);
+ fin = fopen(sargv[++fptr],"r");
+ if(fin == NULL)
+ error("Cannot open file %s",sargv[fptr]);
+ peek = getc(fin);
+ sargc--;
+ sargv++;
+ }
+ if(c == EOF) {
+ eof = TRUE;
+ fclose(fin);
+ return(0);
+ }
+ if(c == '\n')yyline++;
+ return(c);
+ }
+mn2(a,d,c)
+ int a,d,c;
+ {
+ name[tptr] = a;
+ left[tptr] = d;
+ right[tptr] = c;
+ parent[tptr] = 0;
+ nullstr[tptr] = 0;
+ switch(a){
+ case RSTR:
+ parent[d] = tptr;
+ break;
+ case BAR:
+ case RNEWE:
+ if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE;
+ parent[d] = parent[c] = tptr;
+ break;
+ case RCAT:
+ case DIV:
+ if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE;
+ parent[d] = parent[c] = tptr;
+ break;
+ case RSCON:
+ parent[d] = tptr;
+ nullstr[tptr] = nullstr[d];
+ break;
+# ifdef DEBUG
+ default:
+ warning("bad switch mn2 %d %d",a,d);
+ break;
+# endif
+ }
+ if(tptr > treesize)
+ error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
+ return(tptr++);
+ }
+mn1(a,d)
+ int a,d;
+ {
+ name[tptr] = a;
+ left[tptr] = d;
+ parent[tptr] = 0;
+ nullstr[tptr] = 0;
+ switch(a){
+ case RCCL:
+ case RNCCL:
+ if(slength(d) == 0) nullstr[tptr] = TRUE;
+ break;
+ case STAR:
+ case QUEST:
+ nullstr[tptr] = TRUE;
+ parent[d] = tptr;
+ break;
+ case PLUS:
+ case CARAT:
+ nullstr[tptr] = nullstr[d];
+ parent[d] = tptr;
+ break;
+ case S2FINAL:
+ nullstr[tptr] = TRUE;
+ break;
+# ifdef DEBUG
+ case FINAL:
+ case S1FINAL:
+ break;
+ default:
+ warning("bad switch mn1 %d %d",a,d);
+ break;
+# endif
+ }
+ if(tptr > treesize)
+ error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
+ return(tptr++);
+ }
+mn0(a)
+ int a;
+ {
+ name[tptr] = a;
+ parent[tptr] = 0;
+ nullstr[tptr] = 0;
+ if(a >= NCH) switch(a){
+ case RNULLS: nullstr[tptr] = TRUE; break;
+# ifdef DEBUG
+ default:
+ warning("bad switch mn0 %d",a);
+ break;
+# endif
+ }
+ if(tptr > treesize)
+ error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
+ return(tptr++);
+ }
+munput(t,p) /* implementation dependent */
+ char *p;
+ int t; {
+ register int i,j;
+ if(t == 'c'){
+ *pushptr++ = peek; /* watch out for this */
+ peek = p;
+ }
+ else if(t == 's'){
+ *pushptr++ = peek;
+ peek = p[0];
+ i = slength(p);
+ for(j = i-1; j>=1; j--)
+ *pushptr++ = p[j];
+ }
+# ifdef DEBUG
+ else error("Unrecognized munput option %c",t);
+# endif
+ if(pushptr >= pushc+TOKENSIZE)
+ error("Too many characters pushed");
+ return;
+ }
+
+dupl(n)
+ int n; {
+ /* duplicate the subtree whose root is n, return ptr to it */
+ register int i;
+ i = name[n];
+ if(i < NCH) return(mn0(i));
+ switch(i){
+ case RNULLS:
+ return(mn0(i));
+ case RCCL: case RNCCL: case FINAL: case S1FINAL: case S2FINAL:
+ return(mn1(i,left[n]));
+ case STAR: case QUEST: case PLUS: case CARAT:
+ return(mn1(i,dupl(left[n])));
+ case RSTR: case RSCON:
+ return(mn2(i,dupl(left[n]),right[n]));
+ case BAR: case RNEWE: case RCAT: case DIV:
+ return(mn2(i,dupl(left[n]),dupl(right[n])));
+# ifdef DEBUG
+ default:
+ warning("bad switch dupl %d",n);
+# endif
+ }
+ return(0);
+ }
+# ifdef DEBUG
+allprint(c)
+ char c; {
+ switch(c){
+ case 014:
+ printf("\\f");
+ charc++;
+ break;
+ case '\n':
+ printf("\\n");
+ charc++;
+ break;
+ case '\t':
+ printf("\\t");
+ charc++;
+ break;
+ case '\b':
+ printf("\\b");
+ charc++;
+ break;
+ case ' ':
+ printf("\\\bb");
+ break;
+ default:
+ if(!printable(c)){
+ printf("\\%-3o",c);
+ charc =+ 3;
+ }
+ else
+ putchar(c);
+ break;
+ }
+ charc++;
+ return;
+ }
+strpt(s)
+ char *s; {
+ charc = 0;
+ while(*s){
+ allprint(*s++);
+ if(charc > LINESIZE){
+ charc = 0;
+ printf("\n\t");
+ }
+ }
+ return;
+ }
+sect1dump(){
+ register int i;
+ printf("Sect 1:\n");
+ if(def[0]){
+ printf("str trans\n");
+ i = -1;
+ while(def[++i])
+ printf("%s\t%s\n",def[i],subs[i]);
+ }
+ if(sname[0]){
+ printf("start names\n");
+ i = -1;
+ while(sname[++i])
+ printf("%s\n",sname[i]);
+ }
+ if(chset == TRUE){
+ printf("char set changed\n");
+ for(i=1;i<NCH;i++){
+ if(i != ctable[i]){
+ allprint(i);
+ putchar(' ');
+ printable(ctable[i]) ? putchar(ctable[i]) : printf("%d",ctable[i]);
+ putchar('\n');
+ }
+ }
+ }
+ }
+sect2dump(){
+ printf("Sect 2:\n");
+ treedump();
+ }
+treedump()
+ {
+ register int t;
+ register char *p;
+ printf("treedump %d nodes:\n",tptr);
+ for(t=0;t<tptr;t++){
+ printf("%4d ",t);
+ parent[t] ? printf("p=%4d",parent[t]) : printf(" ");
+ printf(" ");
+ if(name[t] < NCH) {
+ allprint(name[t]);
+ }
+ else switch(name[t]){
+ case RSTR:
+ printf("%d ",left[t]);
+ allprint(right[t]);
+ break;
+ case RCCL:
+ printf("ccl ");
+ strpt(left[t]);
+ break;
+ case RNCCL:
+ printf("nccl ");
+ strpt(left[t]);
+ break;
+ case DIV:
+ printf("/ %d %d",left[t],right[t]);
+ break;
+ case BAR:
+ printf("| %d %d",left[t],right[t]);
+ break;
+ case RCAT:
+ printf("cat %d %d",left[t],right[t]);
+ break;
+ case PLUS:
+ printf("+ %d",left[t]);
+ break;
+ case STAR:
+ printf("* %d",left[t]);
+ break;
+ case CARAT:
+ printf("^ %d",left[t]);
+ break;
+ case QUEST:
+ printf("? %d",left[t]);
+ break;
+ case RNULLS:
+ printf("nullstring");
+ break;
+ case FINAL:
+ printf("final %d",left[t]);
+ break;
+ case S1FINAL:
+ printf("s1final %d",left[t]);
+ break;
+ case S2FINAL:
+ printf("s2final %d",left[t]);
+ break;
+ case RNEWE:
+ printf("new %d %d",left[t],right[t]);
+ break;
+ case RSCON:
+ p = right[t];
+ printf("start %s",sname[*p++-1]);
+ while(*p)
+ printf(", %s",sname[*p++-1]);
+ printf(" %d",left[t]);
+ break;
+ default:
+ printf("unknown %d %d %d",name[t],left[t],right[t]);
+ break;
+ }
+ if(nullstr[t])printf("\t(null poss.)");
+ putchar('\n');
+ }
+ }
+# endif
--- /dev/null
+# include "ldefs.c"
+cfoll(v)
+ int v;
+ {
+ register int i,j,k;
+ char *p;
+ i = name[v];
+ if(i < NCH) i = 1; /* character */
+ switch(i){
+ case 1: case RSTR: case RCCL: case RNCCL: case RNULLS:
+ for(j=0;j<tptr;j++)
+ tmpstat[j] = FALSE;
+ count = 0;
+ follow(v);
+# ifdef PP
+ padd(foll,v); /* packing version */
+# endif
+# ifndef PP
+ add(foll,v); /* no packing version */
+# endif
+ if(i == RSTR) cfoll(left[v]);
+ else if(i == RCCL || i == RNCCL){ /* compress ccl list */
+ for(j=1; j<NCH;j++)
+ symbol[j] = (i==RNCCL);
+ p = left[v];
+ while(*p)
+ symbol[*p++] = (i == RCCL);
+ p = pcptr;
+ for(j=1;j<NCH;j++)
+ if(symbol[j]){
+ for(k=0;p+k < pcptr; k++)
+ if(cindex[j] == *(p+k))
+ break;
+ if(p+k >= pcptr)*pcptr++ = cindex[j];
+ }
+ *pcptr++ = 0;
+ if(pcptr > pchar + pchlen)
+ error("Too many packed character classes");
+ left[v] = p;
+ name[v] = RCCL; /* RNCCL eliminated */
+# ifdef DEBUG
+ if(debug && *p){
+ printf("ccl %d: %d",v,*p++);
+ while(*p)
+ printf(", %d",*p++);
+ putchar('\n');
+ }
+# endif
+ }
+ break;
+ case CARAT:
+ cfoll(left[v]);
+ break;
+ case STAR: case PLUS: case QUEST: case RSCON:
+ cfoll(left[v]);
+ break;
+ case BAR: case RCAT: case DIV: case RNEWE:
+ cfoll(left[v]);
+ cfoll(right[v]);
+ break;
+# ifdef DEBUG
+ case FINAL:
+ case S1FINAL:
+ case S2FINAL:
+ break;
+ default:
+ warning("bad switch cfoll %d",v);
+# endif
+ }
+ return;
+ }
+# ifdef DEBUG
+pfoll()
+ {
+ register int i,k,*p;
+ int j;
+ /* print sets of chars which may follow positions */
+ printf("pos\tchars\n");
+ for(i=0;i<tptr;i++)
+ if(p=foll[i]){
+ j = *p++;
+ if(j >= 1){
+ printf("%d:\t%d",i,*p++);
+ for(k=2;k<=j;k++)
+ printf(", %d",*p++);
+ putchar('\n');
+ }
+ }
+ return;
+ }
+# endif
+add(array,n)
+ int **array;
+ int n; {
+ register int i, *temp;
+ register char *ctemp;
+ temp = nxtpos;
+ ctemp = tmpstat;
+ array[n] = nxtpos; /* note no packing is done in positions */
+ *temp++ = count;
+ for(i=0;i<tptr;i++)
+ if(ctemp[i] == TRUE)
+ *temp++ = i;
+ nxtpos = temp;
+ if(nxtpos >= positions+maxpos)
+ error("Too many positions %s",(maxpos== MAXPOS?"\nTry using %p num":""));
+ return;
+ }
+follow(v)
+ int v;
+ {
+ register int p;
+ if(v >= tptr-1)return;
+ p = parent[v];
+ if(p == 0) return;
+ switch(name[p]){
+ /* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */
+ case RSTR:
+ if(tmpstat[p] == FALSE){
+ count++;
+ tmpstat[p] = TRUE;
+ }
+ break;
+ case STAR: case PLUS:
+ first(v);
+ follow(p);
+ break;
+ case BAR: case QUEST: case RNEWE:
+ follow(p);
+ break;
+ case RCAT: case DIV:
+ if(v == left[p]){
+ if(nullstr[right[p]])
+ follow(p);
+ first(right[p]);
+ }
+ else follow(p);
+ break;
+ case RSCON: case CARAT:
+ follow(p);
+ break;
+# ifdef DEBUG
+ default:
+ warning("bad switch follow %d",p);
+# endif
+ }
+ return;
+ }
+first(v) /* calculate set of positions with v as root which can be active initially */
+ int v; {
+ register int i;
+ register char *p;
+ i = name[v];
+ if(i < NCH)i = 1;
+ switch(i){
+ case 1: case RCCL: case RNCCL: case RNULLS: case FINAL: case S1FINAL: case S2FINAL:
+ if(tmpstat[v] == FALSE){
+ count++;
+ tmpstat[v] = TRUE;
+ }
+ break;
+ case BAR: case RNEWE:
+ first(left[v]);
+ first(right[v]);
+ break;
+ case CARAT:
+ if(stnum % 2 == 1)
+ first(left[v]);
+ break;
+ case RSCON:
+ i = stnum/2 +1;
+ p = right[v];
+ while(*p)
+ if(*p++ == i){
+ first(left[v]);
+ break;
+ }
+ break;
+ case STAR: case QUEST: case PLUS: case RSTR:
+ first(left[v]);
+ break;
+ case RCAT: case DIV:
+ first(left[v]);
+ if(nullstr[left[v]])
+ first(right[v]);
+ break;
+# ifdef DEBUG
+ default:
+ warning("bad switch first %d",v);
+# endif
+ }
+ return;
+ }
+cgoto(){
+ register int i, j, s;
+ int npos, curpos, n;
+ int tryit;
+ char tch[NCH];
+ int tst[NCH];
+ char *q;
+ /* generate initial state, for each start condition */
+ if(ratfor){
+ fprintf(fout,"blockdata\n");
+ fprintf(fout,"common /Lvstop/ vstop\n");
+ fprintf(fout,"define Svstop %d\n",nstates+1);
+ fprintf(fout,"integer vstop(Svstop)\n");
+ }
+ else fprintf(fout,"int yyvstop[] ={\n0,\n");
+ while(stnum < 2 || stnum/2 < sptr){
+ for(i = 0; i<tptr; i++) tmpstat[i] = 0;
+ count = 0;
+ if(tptr > 0)first(tptr-1);
+ add(state,stnum);
+# ifdef DEBUG
+ if(debug){
+ if(stnum > 1)
+ printf("%s:\n",sname[stnum/2]);
+ pstate(stnum);
+ }
+# endif
+ stnum++;
+ }
+ stnum--;
+ /* even stnum = might not be at line begin */
+ /* odd stnum = must be at line begin */
+ /* even states can occur anywhere, odd states only at line begin */
+ for(s = 0; s <= stnum; s++){
+ tryit = FALSE;
+ cpackflg[s] = FALSE;
+ sfall[s] = -1;
+ acompute(s);
+ for(i=0;i<NCH;i++) symbol[i] = 0;
+ npos = *state[s];
+ for(i = 1; i<=npos; i++){
+ curpos = *(state[s]+i);
+ if(name[curpos] < NCH) symbol[name[curpos]] = TRUE;
+ else switch(name[curpos]){
+ case RCCL:
+ tryit = TRUE;
+ q = left[curpos];
+ while(*q){
+ for(j=1;j<NCH;j++)
+ if(cindex[j] == *q)
+ symbol[j] = TRUE;
+ q++;
+ }
+ break;
+ case RSTR:
+ symbol[right[curpos]] = TRUE;
+ break;
+# ifdef DEBUG
+ case RNULLS:
+ case FINAL:
+ case S1FINAL:
+ case S2FINAL:
+ break;
+ default:
+ warning("bad switch cgoto %d state %d",curpos,s);
+ break;
+# endif
+ }
+ }
+# ifdef DEBUG
+ if(debug){
+ printf("State %d transitions on:\n\t",s);
+ charc = 0;
+ for(i = 1; i<NCH; i++){
+ if(symbol[i]) allprint(i);
+ if(charc > LINESIZE){
+ charc = 0;
+ printf("\n\t");
+ }
+ }
+ putchar('\n');
+ }
+# endif
+ /* for each char, calculate next state */
+ n = 0;
+ for(i = 1; i<NCH; i++){
+ if(symbol[i]){
+ nextstate(s,i); /* executed for each state, transition pair */
+ xstate = notin(stnum);
+ if(xstate == -2) warning("bad state %d %o",s,i);
+ else if(xstate == -1){
+ if(stnum >= nstates)
+ error("Too many states %s",(nstates == NSTATES ? "\nTry using %n num":""));
+ add(state,++stnum);
+# ifdef DEBUG
+ if(debug)pstate(stnum);
+# endif
+ tch[n] = i;
+ tst[n++] = stnum;
+ }
+ else { /* xstate >= 0 ==> state exists */
+ tch[n] = i;
+ tst[n++] = xstate;
+ }
+ }
+ }
+ tch[n] = 0;
+ tst[n] = -1;
+ /* pack transitions into permanent array */
+ if(n > 0) packtrans(s,tch,tst,n,tryit);
+ else gotof[s] = -1;
+ }
+ ratfor ? fprintf(fout,"end\n") : fprintf(fout,"0};\n");
+ return;
+ }
+ /* Beware -- 70% of total CPU time is spent in this subroutine -
+ if you don't believe me - try it yourself ! */
+nextstate(s,c)
+ int s,c; {
+ register int j, *newpos;
+ register char *temp, *tz;
+ int *pos, i, *f, num, curpos, number;
+ /* state to goto from state s on char c */
+ num = *state[s];
+ temp = tmpstat;
+ pos = state[s] + 1;
+ for(i = 0; i<num; i++){
+ curpos = *pos++;
+ j = name[curpos];
+ if(j < NCH && j == c
+ || j == RSTR && c == right[curpos]
+ || j == RCCL && member(c,left[curpos])){
+ f = foll[curpos];
+ number = *f;
+ newpos = f+1;
+ for(j=0;j<number;j++)
+ temp[*newpos++] = 2;
+ }
+ }
+ j = 0;
+ tz = temp + tptr;
+ while(temp < tz){
+ if(*temp == 2){
+ j++;
+ *temp++ = 1;
+ }
+ else *temp++ = 0;
+ }
+ count = j;
+ return;
+ }
+notin(n)
+ int n; { /* see if tmpstat occurs previously */
+ register int *j,k;
+ register char *temp;
+ int i;
+ if(count == 0)
+ return(-2);
+ temp = tmpstat;
+ for(i=n;i>=0;i--){ /* for each state */
+ j = state[i];
+ if(count == *j++){
+ for(k=0;k<count;k++)
+ if(!temp[*j++])break;
+ if(k >= count)
+ return(i);
+ }
+ }
+ return(-1);
+ }
+packtrans(st,tch,tst,cnt,tryit)
+ int st, *tst, cnt,tryit;
+ char *tch; {
+ /* pack transitions into nchar, nexts */
+ /* nchar is terminated by '\0', nexts uses cnt, followed by elements */
+ /* gotof[st] = index into nchr, nexts for state st */
+
+ /* sfall[st] = t implies t is fall back state for st */
+ /* == -1 implies no fall back */
+
+ int cmin, cval, tcnt, diff, p, *ast;
+ register int i,j,k;
+ char *ach;
+ int go[NCH], temp[NCH], c;
+ int swork[NCH];
+ char cwork[NCH];
+ int upper;
+
+ rcount += cnt;
+ cmin = -1;
+ cval = NCH;
+ ast = tst;
+ ach = tch;
+ /* try to pack transitions using ccl's */
+ if(!optim)goto nopack; /* skip all compaction */
+ if(tryit){ /* ccl's used */
+ for(i=1;i<NCH;i++){
+ go[i] = temp[i] = -1;
+ symbol[i] = 1;
+ }
+ for(i=0;i<cnt;i++){
+ go[tch[i]] = tst[i];
+ symbol[tch[i]] = 0;
+ }
+ for(i=0; i<cnt;i++){
+ c = match[tch[i]];
+ if(go[c] != tst[i] || c == tch[i])
+ temp[tch[i]] = tst[i];
+ }
+ /* fill in error entries */
+ for(i=1;i<NCH;i++)
+ if(symbol[i]) temp[i] = -2; /* error trans */
+ /* count them */
+ k = 0;
+ for(i=1;i<NCH;i++)
+ if(temp[i] != -1)k++;
+ if(k <cnt){ /* compress by char */
+# ifdef DEBUG
+ if(debug) printf("use compression %d, %d vs %d\n",st,k,cnt);
+# endif
+ k = 0;
+ for(i=1;i<NCH;i++)
+ if(temp[i] != -1){
+ cwork[k] = i;
+ swork[k++] = (temp[i] == -2 ? -1 : temp[i]);
+ }
+ cwork[k] = 0;
+# ifdef PC
+ ach = cwork;
+ ast = swork;
+ cnt = k;
+ cpackflg[st] = TRUE;
+# endif
+ }
+ }
+ for(i=0; i<st; i++){ /* get most similar state */
+ /* reject state with more transitions, state already represented by a third state,
+ and state which is compressed by char if ours is not to be */
+ if(sfall[i] != -1) continue;
+ if(cpackflg[st] == 1) if(!(cpackflg[i] == 1)) continue;
+ p = gotof[i];
+ if(p == -1) /* no transitions */ continue;
+ tcnt = nexts[p];
+ if(tcnt > cnt) continue;
+ diff = 0;
+ k = 0;
+ j = 0;
+ upper = p + tcnt;
+ while(ach[j] && p < upper){
+ while(ach[j] < nchar[p] && ach[j]){diff++; j++; }
+ if(ach[j] == 0)break;
+ if(ach[j] > nchar[p]){diff=NCH;break;}
+ /* ach[j] == nchar[p] */
+ if(ast[j] != nexts[++p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]]))diff++;
+ j++;
+ }
+ while(ach[j]){
+ diff++;
+ j++;
+ }
+ if(p < upper)diff = NCH;
+ if(diff < cval && diff < tcnt){
+ cval = diff;
+ cmin = i;
+ if(cval == 0)break;
+ }
+ }
+ /* cmin = state "most like" state st */
+# ifdef DEBUG
+ if(debug)printf("select st %d for st %d diff %d\n",cmin,st,cval);
+# endif
+# ifdef PS
+ if(cmin != -1){ /* if we can use st cmin */
+ gotof[st] = nptr;
+ k = 0;
+ sfall[st] = cmin;
+ p = gotof[cmin]+1;
+ j = 0;
+ while(ach[j]){
+ /* if cmin has a transition on c, then so will st */
+ /* st may be "larger" than cmin, however */
+ while(ach[j] < nchar[p-1] && ach[j]){
+ k++;
+ nchar[nptr] = ach[j];
+ nexts[++nptr] = ast[j];
+ j++;
+ }
+ if(nchar[p-1] == 0)break;
+ if(ach[j] > nchar[p-1]){
+ warning("bad transition %d %d",st,cmin);
+ goto nopack;
+ }
+ /* ach[j] == nchar[p-1] */
+ if(ast[j] != nexts[p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]])){
+ k++;
+ nchar[nptr] = ach[j];
+ nexts[++nptr] = ast[j];
+ }
+ p++;
+ j++;
+ }
+ while(ach[j]){
+ nchar[nptr] = ach[j];
+ nexts[++nptr] = ast[j++];
+ k++;
+ }
+ nexts[gotof[st]] = cnt = k;
+ nchar[nptr++] = 0;
+ }
+ else {
+# endif
+nopack:
+ /* stick it in */
+ gotof[st] = nptr;
+ nexts[nptr] = cnt;
+ for(i=0;i<cnt;i++){
+ nchar[nptr] = ach[i];
+ nexts[++nptr] = ast[i];
+ }
+ nchar[nptr++] = 0;
+# ifdef PS
+ }
+# endif
+ if(cnt < 1){
+ gotof[st] = -1;
+ nptr--;
+ }
+ else
+ if(nptr > ntrans)
+ error("Too many transitions %s",(ntrans==NTRANS?"\nTry using %a num":""));
+ return;
+ }
+# ifdef DEBUG
+pstate(s)
+ int s; {
+ register int *p,i,j;
+ printf("State %d:\n",s);
+ p = state[s];
+ i = *p++;
+ if(i == 0) return;
+ printf("%4d",*p++);
+ for(j = 1; j<i; j++){
+ printf(", %4d",*p++);
+ if(j%30 == 0)putchar('\n');
+ }
+ putchar('\n');
+ return;
+ }
+# endif
+member(d,t)
+ int d;
+ char *t; {
+ register int c;
+ register char *s;
+ c = d;
+ s = t;
+ c = cindex[c];
+ while(*s)
+ if(*s++ == c) return(1);
+ return(0);
+ }
+# ifdef DEBUG
+stprt(i)
+ int i; {
+ register int p, t;
+ printf("State %d:",i);
+ /* print actions, if any */
+ t = atable[i];
+ if(t != -1)printf(" final");
+ putchar('\n');
+ if(cpackflg[i] == TRUE)printf("backup char in use\n");
+ if(sfall[i] != -1)printf("fall back state %d\n",sfall[i]);
+ p = gotof[i];
+ if(p == -1) return;
+ printf("(%d transitions)\n",nexts[p]);
+ while(nchar[p]){
+ charc = 0;
+ if(nexts[p+1] >= 0)
+ printf("%d\t",nexts[p+1]);
+ else printf("err\t");
+ allprint(nchar[p++]);
+ while(nexts[p] == nexts[p+1] && nchar[p]){
+ if(charc > LINESIZE){
+ charc = 0;
+ printf("\n\t");
+ }
+ allprint(nchar[p++]);
+ }
+ putchar('\n');
+ }
+ putchar('\n');
+ return;
+ }
+# endif
+acompute(s) /* compute action list = set of poss. actions */
+ int s; {
+ register int *p, i, j;
+ int cnt, m;
+ int temp[300], k, neg[300], n;
+ k = 0;
+ n = 0;
+ p = state[s];
+ cnt = *p++;
+ if(cnt > 300)
+ error("Too many positions for one state - acompute");
+ for(i=0;i<cnt;i++){
+ if(name[*p] == FINAL)temp[k++] = left[*p];
+ else if(name[*p] == S1FINAL){temp[k++] = left[*p];
+ if (left[*p] >NACTIONS) error("Too many right contexts");
+ extra[left[*p]] = 1;
+ }
+ else if(name[*p] == S2FINAL)neg[n++] = left[*p];
+ p++;
+ }
+ atable[s] = -1;
+ if(k < 1 && n < 1) return;
+# ifdef DEBUG
+ if(debug) printf("final %d actions:",s);
+# endif
+ /* sort action list */
+ for(i=0; i<k; i++)
+ for(j=i+1;j<k;j++)
+ if(temp[j] < temp[i]){
+ m = temp[j];
+ temp[j] = temp[i];
+ temp[i] = m;
+ }
+ /* remove dups */
+ for(i=0;i<k-1;i++)
+ if(temp[i] == temp[i+1]) temp[i] = 0;
+ /* copy to permanent quarters */
+ atable[s] = aptr;
+# ifdef DEBUG
+ if(!ratfor)fprintf(fout,"/* actions for state %d */",s);
+# endif
+ putc('\n',fout);
+ for(i=0;i<k;i++)
+ if(temp[i] != 0){
+ ratfor ? fprintf(fout,"data vstop(%d)/%d/\n",aptr,temp[i]) : fprintf(fout,"%d,\n",temp[i]);
+# ifdef DEBUG
+ if(debug)
+ printf("%d ",temp[i]);
+# endif
+ aptr++;
+ }
+ for(i=0;i<n;i++){ /* copy fall back actions - all neg */
+ ratfor ? fprintf(fout,"data vstop(%d)/%d/\n",aptr,neg[i]) : fprintf(fout,"%d,\n",neg[i]);
+ aptr++;
+# ifdef DEBUG
+ if(debug)printf("%d ",neg[i]);
+# endif
+ }
+# ifdef DEBUG
+ if(debug)putchar('\n');
+# endif
+ ratfor ? fprintf(fout,"data vstop (%d)/0/\n",aptr) : fprintf(fout,"0,\n");
+ aptr++;
+ return;
+ }
+# ifdef DEBUG
+pccl() {
+ /* print character class sets */
+ register int i, j;
+ printf("char class intersection\n");
+ for(i=0; i< ccount; i++){
+ charc = 0;
+ printf("class %d:\n\t",i);
+ for(j=1;j<NCH;j++)
+ if(cindex[j] == i){
+ allprint(j);
+ if(charc > LINESIZE){
+ printf("\n\t");
+ charc = 0;
+ }
+ }
+ putchar('\n');
+ }
+ charc = 0;
+ printf("match:\n");
+ for(i=0;i<NCH;i++){
+ allprint(match[i]);
+ if(charc > LINESIZE){
+ putchar('\n');
+ charc = 0;
+ }
+ }
+ putchar('\n');
+ return;
+ }
+# endif
+mkmatch(){
+ register int i;
+ char tab[NCH];
+ for(i=0; i<ccount; i++)
+ tab[i] = 0;
+ for(i=1;i<NCH;i++)
+ if(tab[cindex[i]] == 0)
+ tab[cindex[i]] = i;
+ /* tab[i] = principal char for new ccl i */
+ for(i = 1; i<NCH; i++)
+ match[i] = tab[cindex[i]];
+ return;
+ }
+layout(){
+ /* format and output final program's tables */
+ register int i, j, k;
+ int top, bot, startup, omin;
+ startup = 0;
+ for(i=0; i<outsize;i++)
+ verify[i] = advance[i] = 0;
+ omin = 0;
+ yytop = 0;
+ for(i=0; i<= stnum; i++){ /* for each state */
+ j = gotof[i];
+ if(j == -1){
+ stoff[i] = 0;
+ continue;
+ }
+ bot = j;
+ while(nchar[j])j++;
+ top = j - 1;
+# if DEBUG
+ if (debug)
+ {
+ printf("State %d: (layout)\n", i);
+ for(j=bot; j<=top;j++)
+ {
+ printf(" %o", nchar[j]);
+ if (j%10==0) putchar('\n');
+ }
+ putchar('\n');
+ }
+# endif
+ while(verify[omin+ZCH]) omin++;
+ startup = omin;
+# if DEBUG
+ if (debug) printf("bot,top %d, %d startup begins %d\n",bot,top,startup);
+# endif
+ if(chset){
+ do {
+ ++startup;
+ if(startup > outsize - ZCH)
+ error("output table overflow");
+ for(j = bot; j<= top; j++){
+ k=startup+ctable[nchar[j]];
+ if(verify[k])break;
+ }
+ } while (j <= top);
+# if DEBUG
+ if (debug) printf(" startup will be %d\n",startup);
+# endif
+ /* have found place */
+ for(j = bot; j<= top; j++){
+ k = startup + ctable[nchar[j]];
+ if (ctable[nchar[j]]<=0)
+ printf("j %d nchar %d ctable.nch %d\n",j,nchar[j],ctable[nchar[k]]);
+ verify[k] = i+1; /* state number + 1*/
+ advance[k] = nexts[j+1]+1; /* state number + 1*/
+ if(yytop < k) yytop = k;
+ }
+ }
+ else {
+ do {
+ ++startup;
+ if(startup > outsize - ZCH)
+ error("output table overflow");
+ for(j = bot; j<= top; j++){
+ k = startup + nchar[j];
+ if(verify[k])break;
+ }
+ } while (j <= top);
+ /* have found place */
+# if DEBUG
+ if (debug) printf(" startup going to be %d\n", startup);
+# endif
+ for(j = bot; j<= top; j++){
+ k = startup + nchar[j];
+ verify[k] = i+1; /* state number + 1*/
+ advance[k] = nexts[j+1]+1; /* state number + 1*/
+ if(yytop < k) yytop = k;
+ }
+ }
+ stoff[i] = startup;
+ }
+
+ /* stoff[i] = offset into verify, advance for trans for state i */
+ /* put out yywork */
+ if(ratfor){
+ fprintf(fout, "define YYTOPVAL %d\n", yytop);
+ rprint(verify,"verif",yytop+1);
+ rprint(advance,"advan",yytop+1);
+ shiftr(stoff, stnum);
+ rprint(stoff,"stoff",stnum+1);
+ shiftr(sfall, stnum); upone(sfall, stnum+1);
+ rprint(sfall,"sfall",stnum+1);
+ bprint(extra,"extra",casecount+1);
+ bprint(match,"match",NCH);
+ shiftr(atable, stnum);
+ rprint(atable,"atable",stnum+1);
+ return;
+ }
+ fprintf(fout,"# define YYTYPE %s\n",stnum+1 > NCH ? "int" : "char");
+ fprintf(fout,"struct yywork { YYTYPE verify, advance; } yycrank[] ={\n");
+ for(i=0;i<=yytop;i+=4){
+ for(j=0;j<4;j++){
+ k = i+j;
+ if(verify[k])
+ fprintf(fout,"%d,%d,\t",verify[k],advance[k]);
+ else
+ fprintf(fout,"0,0,\t");
+ }
+ putc('\n',fout);
+ }
+ fprintf(fout,"0,0};\n");
+
+ /* put out yysvec */
+
+ fprintf(fout,"struct yysvf yysvec[] ={\n");
+ fprintf(fout,"0,\t0,\t0,\n");
+ for(i=0;i<=stnum;i++){ /* for each state */
+ if(cpackflg[i])stoff[i] = -stoff[i];
+ fprintf(fout,"yycrank+%d,\t",stoff[i]);
+ if(sfall[i] != -1)
+ fprintf(fout,"yysvec+%d,\t", sfall[i]+1); /* state + 1 */
+ else fprintf(fout,"0,\t\t");
+ if(atable[i] != -1)
+ fprintf(fout,"yyvstop+%d,",atable[i]);
+ else fprintf(fout,"0,\t");
+# ifdef DEBUG
+ fprintf(fout,"\t\t/* state %d */",i);
+# endif
+ putc('\n',fout);
+ }
+ fprintf(fout,"0,\t0,\t0};\n");
+
+ /* put out yymatch */
+
+ fprintf(fout,"struct yywork *yytop = yycrank+%d;\n",yytop);
+ fprintf(fout,"struct yysvf *yybgin = yysvec+1;\n");
+ if(optim){
+ fprintf(fout,"char yymatch[] ={\n");
+ if (chset==0) /* no chset, put out in normal order */
+ {
+ for(i=0; i<NCH; i+=8){
+ for(j=0; j<8; j++){
+ int fbch;
+ fbch = match[i+j];
+ if(printable(fbch) && fbch != '\'' && fbch != '\\')
+ fprintf(fout,"'%c' ,",fbch);
+ else fprintf(fout,"0%-3o,",fbch);
+ }
+ putc('\n',fout);
+ }
+ }
+ else
+ {
+ int *fbarr;
+ fbarr = myalloc(2*NCH, sizeof(*fbarr));
+ if (fbarr==0)
+ error("No space for char table reverse",0);
+ for(i=0; i<ZCH; i++)
+ fbarr[i]=0;
+ for(i=0; i<NCH; i++)
+ fbarr[ctable[i]] = ctable[match[i]];
+ for(i=0; i<ZCH; i+=8)
+ {
+ for(j=0; j<8; j++)
+ fprintf(fout, "0%-3o,",fbarr[i+j]);
+ putc('\n',fout);
+ }
+ cfree(fbarr, 2*NCH, 1);
+ }
+ fprintf(fout,"0};\n");
+ }
+ /* put out yyextra */
+ fprintf(fout,"char yyextra[] ={\n");
+ for(i=0;i<casecount;i+=8){
+ for(j=0;j<8;j++)
+ fprintf(fout, "%d,", i+j<NACTIONS ?
+ extra[i+j] : 0);
+ putc('\n',fout);
+ }
+ fprintf(fout,"0};\n");
+ return;
+ }
+rprint(a,s,n)
+ char *s;
+ int *a, n; {
+ register int i;
+ fprintf(fout,"block data\n");
+ fprintf(fout,"common /L%s/ %s\n",s,s);
+ fprintf(fout,"define S%s %d\n",s,n);
+ fprintf(fout,"integer %s (S%s)\n",s,s);
+ for(i=1; i<=n; i++)
+ {
+ if (i%8==1) fprintf(fout, "data ");
+ fprintf(fout, "%s (%d)/%d/",s,i,a[i]);
+ fprintf(fout, (i%8 && i<n) ? ", " : "\n");
+ }
+ fprintf(fout,"end\n");
+ }
+shiftr(a, n)
+ int *a;
+{
+int i;
+for(i=n; i>=0; i--)
+ a[i+1]=a[i];
+}
+upone(a,n)
+ int *a;
+{
+int i;
+for(i=0; i<=n ; i++)
+ a[i]++;
+}
+bprint(a,s,n)
+ char *s, *a;
+ int n; {
+ register int i, j, k;
+ fprintf(fout,"block data\n");
+ fprintf(fout,"common /L%s/ %s\n",s,s);
+ fprintf(fout,"define S%s %d\n",s,n);
+ fprintf(fout,"integer %s (S%s)\n",s,s);
+ for(i=1;i<n;i+=8){
+ fprintf(fout,"data %s (%d)/%d/",s,i,a[i]);
+ for(j=1;j<8;j++){
+ k = i+j;
+ if(k < n)fprintf(fout,", %s (%d)/%d/",s,k,a[k]);
+ }
+ putc('\n',fout);
+ }
+ fprintf(fout,"end\n");
+ }
+# ifdef PP
+padd(array,n)
+ int **array;
+ int n; {
+ register int i, *j, k;
+ array[n] = nxtpos;
+ if(count == 0){
+ *nxtpos++ = 0;
+ return;
+ }
+ for(i=tptr-1;i>=0;i--){
+ j = array[i];
+ if(j && *j++ == count){
+ for(k=0;k<count;k++)
+ if(!tmpstat[*j++])break;
+ if(k >= count){
+ array[n] = array[i];
+ return;
+ }
+ }
+ }
+ add(array,n);
+ return;
+ }
+# endif
--- /dev/null
+CFLAGS=-O -DNEQN -d2
+YFLAGS=-d
+
+SOURCE = e.y e.h diacrit.c eqnbox.c font.c fromto.c funny.c glob.c integral.c \
+ io.c lex.c lookup.c mark.c matrix.c move.c over.c paren.c \
+ pile.c shift.c size.c sqrt.c text.c
+
+FILES = e.o diacrit.o eqnbox.o font.o fromto.o funny.o glob.o integral.o \
+ io.o lex.o lookup.o mark.o matrix.o move.o over.o paren.o \
+ pile.o shift.o size.o sqrt.o text.o
+
+neqn: $(FILES)
+ cc $(CFLAGS) $(FILES) -o neqn
+
+e.c: e.def
+
+e.def: e.y
+ yacc -d e.y
+ mv y.tab.c e.c
+ mv y.tab.h e.def
+
+$(FILES): e.h e.def
+install: neqn
+ install -s neqn $(DESTDIR)/usr/bin
+
+clean:
+ rm -f *.o e.c e.def
+
+
+list:
+ pr TODO $(SOURCE) makefile
+
+lint: y.tab.c
+ lint -spb *.c
--- /dev/null
+# include "e.h"
+# include "e.def"
+
+diacrit(p1, type) int p1, type; {
+ int c, t;
+
+ c = oalloc();
+ t = oalloc();
+ nrwid(p1, ps, p1);
+ printf(".nr 10 %du\n", max(eht[p1]-ebase[p1]-VERT(2),0));
+ switch(type) {
+ case VEC: /* vec */
+ case DYAD: /* dyad */
+ printf(".ds %d \\v'-1'_\\v'1'\n", c);
+ break;
+ case HAT:
+ printf(".ds %d ^\n", c);
+ break;
+ case TILDE:
+ printf(".ds %d ~\n", c);
+ break;
+ case DOT:
+ printf(".ds %d \\v'-1'.\\v'1'\n", c);
+ break;
+ case DOTDOT:
+ printf(".ds %d \\v'-1'..\\v'1'\n", c);
+ break;
+ case BAR:
+ printf(".ds %d \\v'-1'\\l'\\n(%du'\\v'1'\n",
+ c, p1);
+ break;
+ case UNDER:
+ printf(".ds %d \\l'\\n(%du'\n", c, p1);
+ break;
+ }
+ nrwid(c, ps, c);
+ printf(".as %d \\h'-\\n(%du-\\n(%du/2u'\\v'0-\\n(10u'\\*(%d",
+ p1, p1, c, c);
+ printf("\\v'\\n(10u'\\h'-\\n(%du+\\n(%du/2u'\n", c, p1);
+ if (type != UNDER)
+ eht[p1] += VERT(1);
+ if (dbg) printf(".\tdiacrit: %c over S%d, h=%d, b=%d\n", type, p1, eht[p1], ebase[p1]);
+ ofree(c); ofree(t);
+}
--- /dev/null
+#include <stdio.h>
+
+#define FATAL 1
+#define ROM '1'
+#define ITAL '1'
+#define BLD '1'
+
+#define VERT(n) (20 * (n))
+#define EFFPS(p) ((p) >= 6 ? (p) : 6)
+
+extern int dbg;
+extern int ct;
+extern int lp[];
+extern int used[]; /* available registers */
+extern int ps; /* dflt init pt size */
+extern int deltaps; /* default change in ps */
+extern int gsize; /* global size */
+extern int gfont; /* global font */
+extern int ft; /* dflt font */
+extern FILE *curfile; /* current input file */
+extern int ifile; /* input file number */
+extern int linect; /* line number in current file */
+extern int eqline; /* line where eqn started */
+extern int svargc;
+extern char **svargv;
+extern int eht[];
+extern int ebase[];
+extern int lfont[];
+extern int rfont[];
+extern int yyval;
+extern int *yypv;
+extern int yylval;
+extern int eqnreg, eqnht;
+extern int lefteq, righteq;
+extern int lastchar; /* last character read by lex */
+extern int markline; /* 1 if this EQ/EN contains mark or lineup */
+
+typedef struct s_tbl {
+ char *name;
+ char *defn;
+ struct s_tbl *next;
+} tbl;
--- /dev/null
+%{#
+#include "e.h"
+#
+int fromflg;
+%}
+%term CONTIG QTEXT SPACE THIN TAB
+%term MATRIX LCOL CCOL RCOL COL
+%term MARK LINEUP
+%term SUM INT PROD UNION INTER
+%term LPILE PILE CPILE RPILE ABOVE
+%term DEFINE TDEFINE NDEFINE DELIM GSIZE GFONT INCLUDE
+%right FROM TO
+%left OVER SQRT
+%right SUP SUB
+%right SIZE FONT ROMAN ITALIC BOLD FAT
+%right UP DOWN BACK FWD
+%left LEFT RIGHT
+%right DOT DOTDOT HAT TILDE BAR UNDER VEC DYAD
+
+%%
+
+stuff : eqn { putout($1); }
+ | error { error(!FATAL, "syntax error"); }
+ | { eqnreg = 0; }
+ ;
+
+eqn : box
+ | eqn box { eqnbox($1, $2, 0); }
+ | eqn lineupbox { eqnbox($1, $2, 1); }
+ | LINEUP { lineup(0); }
+ ;
+
+lineupbox: LINEUP box { $$ = $2; lineup(1); }
+ ;
+
+matrix : MATRIX { $$ = ct; } ;
+
+collist : column
+ | collist column
+ ;
+
+column : lcol '{' list '}' { column('L', $1); }
+ | ccol '{' list '}' { column('C', $1); }
+ | rcol '{' list '}' { column('R', $1); }
+ | col '{' list '}' { column('-', $1); }
+ ;
+
+lcol : LCOL { $$ = ct++; } ;
+ccol : CCOL { $$ = ct++; } ;
+rcol : RCOL { $$ = ct++; } ;
+col : COL { $$ = ct++; } ;
+
+sbox : sup box %prec SUP { $$ = $2; }
+ ;
+
+tbox : to box %prec TO { $$ = $2; }
+ | %prec FROM { $$ = 0; }
+ ;
+
+box : box OVER box { boverb($1, $3); }
+ | MARK box { mark($2); }
+ | size box %prec SIZE { size($1, $2); }
+ | font box %prec FONT { font($1, $2); }
+ | FAT box { fatbox($2); }
+ | SQRT box { sqrt($2); }
+ | lpile '{' list '}' { lpile('L', $1, ct); ct = $1; }
+ | cpile '{' list '}' { lpile('C', $1, ct); ct = $1; }
+ | rpile '{' list '}' { lpile('R', $1, ct); ct = $1; }
+ | pile '{' list '}' { lpile('-', $1, ct); ct = $1; }
+ | box sub box sbox %prec SUB { shift2($1, $3, $4); }
+ | box sub box %prec SUB { bshiftb($1, $2, $3); }
+ | box sup box %prec SUP { bshiftb($1, $2, $3); }
+ | int sub box sbox %prec SUB { integral($1, $3, $4); }
+ | int sub box %prec SUB { integral($1, $3, 0); }
+ | int sup box %prec SUP { integral($1, 0, $3); }
+ | int { integral($1, 0, 0); }
+ | left eqn right { paren($1, $2, $3); }
+ | pbox
+ | box from box tbox %prec FROM { fromto($1, $3, $4); fromflg=0; }
+ | box to box %prec TO { fromto($1, 0, $3); }
+ | box diacrit { diacrit($1, $2); }
+ | fwd box %prec UP { move(FWD, $1, $2); }
+ | up box %prec UP { move(UP, $1, $2); }
+ | back box %prec UP { move(BACK, $1, $2); }
+ | down box %prec UP { move(DOWN, $1, $2); }
+ | matrix '{' collist '}' { matrix($1); }
+ ;
+
+int : INT { setintegral(); }
+ ;
+
+fwd : FWD text { $$ = atoi((char *) $1); } ;
+up : UP text { $$ = atoi((char *) $1); } ;
+back : BACK text { $$ = atoi((char *) $1); } ;
+down : DOWN text { $$ = atoi((char *) $1); } ;
+
+diacrit : HAT { $$ = HAT; }
+ | VEC { $$ = VEC; }
+ | DYAD { $$ = DYAD; }
+ | BAR { $$ = BAR; }
+ | UNDER { $$ = UNDER; } /* under bar */
+ | DOT { $$ = DOT; }
+ | TILDE { $$ = TILDE; }
+ | DOTDOT { $$ = DOTDOT; } /* umlaut = double dot */
+ ;
+
+from : FROM { $$=ps; ps -= 3; fromflg = 1;
+ if(dbg)printf(".\tfrom: old ps %d, new ps %d, fflg %d\n", $$, ps, fromflg);
+ }
+ ;
+
+to : TO { $$=ps; if(fromflg==0)ps -= 3;
+ if(dbg)printf(".\tto: old ps %d, new ps %d\n", $$, ps);
+ }
+ ;
+
+left : LEFT text { $$ = ((char *)$2)[0]; }
+ | LEFT '{' { $$ = '{'; }
+ ;
+
+right : RIGHT text { $$ = ((char *)$2)[0]; }
+ | RIGHT '}' { $$ = '}'; }
+ | { $$ = 0; }
+ ;
+
+list : eqn { lp[ct++] = $1; }
+ | list ABOVE eqn { lp[ct++] = $3; }
+ ;
+
+lpile : LPILE { $$ = ct; } ;
+cpile : CPILE { $$ = ct; } ;
+pile : PILE { $$ = ct; } ;
+rpile : RPILE { $$ = ct; } ;
+
+size : SIZE text { $$ = ps; setsize((char *) $2); }
+ ;
+
+font : ROMAN { setfont(ROM); }
+ | ITALIC { setfont(ITAL); }
+ | BOLD { setfont(BLD); }
+ | FONT text { setfont(((char *)$2)[0]); }
+ ;
+
+sub : SUB { shift(SUB); }
+ ;
+
+sup : SUP { shift(SUP); }
+ ;
+
+pbox : '{' eqn '}' { $$ = $2; }
+ | QTEXT { text(QTEXT, (char *) $1); }
+ | CONTIG { text(CONTIG, (char *) $1); }
+ | SPACE { text(SPACE, 0); }
+ | THIN { text(THIN, 0); }
+ | TAB { text(TAB, 0); }
+ | SUM { funny(SUM); }
+ | PROD { funny(PROD); }
+ | UNION { funny(UNION); }
+ | INTER { funny(INTER); } /* intersection */
+ ;
+
+text : CONTIG
+ | QTEXT
+ ;
+
+%%
--- /dev/null
+# include "e.h"
+
+eqnbox(p1, p2, lu) {
+ int b, h;
+ char *sh;
+
+ yyval = p1;
+ b = max(ebase[p1], ebase[p2]);
+ eht[yyval] = h = b + max(eht[p1]-ebase[p1],
+ eht[p2]-ebase[p2]);
+ ebase[yyval] = b;
+ if(dbg)printf(".\te:eb: S%d <- S%d S%d; b=%d, h=%d\n",
+ yyval, p1, p2, b, h);
+ if (rfont[p1] == ITAL && lfont[p2] == ROM)
+ sh = "\\|";
+ else
+ sh = "";
+ if (lu) {
+ printf(".nr %d \\w'\\s%d\\*(%d%s'\n", p1, ps, p1, sh);
+ printf(".ds %d \\h'|\\n(97u-\\n(%du'\\*(%d\n", p1, p1, p1);
+ }
+ printf(".as %d \"%s\\*(%d\n", yyval, sh, p2);
+ rfont[p1] = rfont[p2];
+ ofree(p2);
+}
--- /dev/null
+# include "e.h"
+
+setfont(ch1) char ch1; {
+ /* use number '1', '2', '3' for roman, italic, bold */
+ yyval = ft;
+ if (ch1 == 'r' || ch1 == 'R')
+ ft = ROM;
+ else if (ch1 == 'i' || ch1 == 'I')
+ ft = ITAL;
+ else if (ch1 == 'b' || ch1 == 'B')
+ ft = BLD;
+ else
+ ft = ch1;
+ printf(".ft %c\n", ft);
+ if(dbg)printf(".\tsetfont %c\n", ft);
+}
+
+font(p1, p2) int p1, p2; {
+ /* old font in p1, new in ft */
+ yyval = p2;
+ lfont[yyval] = rfont[yyval] = ft==ITAL ? ITAL : ROM;
+ if(dbg)printf(".\tb:fb: S%d <- \\f%c S%d \\f%c b=%d,h=%d,lf=%c,rf=%c\n",
+ yyval, ft, p2, p1, ebase[yyval], eht[yyval], lfont[yyval], rfont[yyval]);
+ printf(".ds %d \\f%c\\*(%d\\f%c\n",
+ yyval, ft, p2, p1);
+ ft = p1;
+ printf(".ft %c\n", ft);
+}
+
+fatbox(p) int p; {
+ int sh;
+
+ yyval = p;
+ sh = ps / 4;
+ nrwid(p, ps, p);
+ printf(".ds %d \\*(%d\\h'-\\n(%du+%du'\\*(%d\n", p, p, p, sh, p);
+ if(dbg)printf(".\tfat %d, sh=%d\n", p, sh);
+}
+
+globfont() {
+ char temp[20];
+
+ getstr(temp, 20);
+ yyval = eqnreg = 0;
+ gfont = temp[0];
+ switch (gfont) {
+ case 'r': case 'R':
+ gfont = '1';
+ break;
+ case 'i': case 'I':
+ gfont = '2';
+ break;
+ case 'b': case 'B':
+ gfont = '3';
+ break;
+ }
+ printf(".ft %c\n", gfont);
+ ft = gfont;
+}
--- /dev/null
+# include "e.h"
+
+fromto(p1, p2, p3) int p1, p2, p3; {
+ int b, h1, b1, pss;
+ yyval = oalloc();
+ lfont[yyval] = rfont[yyval] = 0;
+ h1 = eht[yyval] = eht[p1];
+ b1 = ebase[p1];
+ b = 0;
+ pss = EFFPS(ps);
+ ps += 3;
+ nrwid(p1, ps, p1);
+ printf(".nr %d \\n(%d\n", yyval, p1);
+ if( p2>0 ) {
+ nrwid(p2, pss, p2);
+ printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, yyval, yyval, p2);
+ eht[yyval] += eht[p2];
+ b = eht[p2];
+ }
+ if( p3>0 ) {
+ nrwid(p3, pss, p3);
+ printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p3, yyval, yyval, p3);
+ eht[yyval] += eht[p3];
+ }
+ printf(".ds %d ", yyval); /* bottom of middle box */
+ if( p2>0 ) {
+ printf("\\v'%du'\\h'\\n(%du-\\n(%du/2u'\\s%d\\*(%d\\s%d",
+ eht[p2]-ebase[p2]+b1, yyval, p2, pss, p2, EFFPS(ps));
+ printf("\\h'-\\n(%du-\\n(%du/2u'\\v'%du'\\\n",
+ yyval, p2, -(eht[p2]-ebase[p2]+b1));
+ }
+ printf("\\h'\\n(%du-\\n(%du/2u'\\*(%d\\h'\\n(%du-\\n(%du+2u/2u'\\\n",
+ yyval, p1, p1, yyval, p1);
+ if( p3>0 ) {
+ printf("\\v'%du'\\h'-\\n(%du-\\n(%du/2u'\\s%d\\*(%d\\s%d\\h'\\n(%du-\\n(%du/2u'\\v'%du'\\\n",
+ -(h1-b1+ebase[p3]), yyval, p3, pss, p3, EFFPS(ps), yyval, p3, (h1-b1+ebase[p3]));
+ }
+ printf("\n");
+ ebase[yyval] = b + b1;
+ if(dbg)printf(".\tfrom to: S%d <- %d f %d t %d; h=%d b=%d\n",
+ yyval, p1, p2, p3, eht[yyval], ebase[yyval]);
+ ofree(p1);
+ if( p2>0 ) ofree(p2);
+ if( p3>0 ) ofree(p3);
+}
--- /dev/null
+# include "e.h"
+# include "e.def"
+
+funny(n) int n; {
+ char *f;
+
+ yyval = oalloc();
+ switch(n) {
+ case SUM:
+ f = "\\(*S"; break;
+ case UNION:
+ f = "\\(cu"; break;
+ case INTER: /* intersection */
+ f = "\\(ca"; break;
+ case PROD:
+ f = "\\(*P"; break;
+ default:
+ error(FATAL, "funny type %d in funny", n);
+ }
+ printf(".ds %d %s\n", yyval, f);
+ eht[yyval] = VERT(2);
+ ebase[yyval] = 0;
+ if(dbg)printf(".\tfunny: S%d <- %s; h=%d b=%d\n",
+ yyval, f, eht[yyval], ebase[yyval]);
+ lfont[yyval] = rfont[yyval] = ROM;
+}
--- /dev/null
+#include "e.h"
+
+int dbg; /* debugging print if non-zero */
+int lp[80]; /* stack for things like piles and matrices */
+int ct; /* pointer to lp */
+int used[100]; /* available registers */
+int ps; /* default init point size */
+int deltaps = 3; /* default change in ps */
+int gsize = 10; /* default initial point size */
+int gfont = ITAL; /* italic */
+int ft; /* default font */
+FILE *curfile; /* current input file */
+int ifile;
+int linect; /* line number in file */
+int eqline; /* line where eqn started */
+int svargc;
+char **svargv;
+int eht[100];
+int ebase[100];
+int lfont[100];
+int rfont[100];
+int eqnreg; /* register where final string appears */
+int eqnht; /* inal height of equation */
+int lefteq = '\0'; /* left in-line delimiter */
+int righteq = '\0'; /* right in-line delimiter */
+int lastchar; /* last character read by lex */
+int markline = 0; /* 1 if this EQ/EN contains mark or lineup */
--- /dev/null
+# include "e.h"
+# include "e.def"
+
+integral(p, p1, p2) {
+#ifndef NEQN
+ if (p1 != 0)
+ printf(".ds %d \\h'-0.4m'\\v'0.4m'\\*(%d\\v'-0.4m'\n", p1, p1);
+ if (p2 != 0)
+ printf(".ds %d \\v'-0.3m'\\*(%d\\v'0.3m'\n", p2, p2);
+#endif
+ if (p1 != 0 && p2 != 0)
+ shift2(p, p1, p2);
+ else if (p1 != 0)
+ bshiftb(p, SUB, p1);
+ else if (p2 != 0)
+ bshiftb(p, SUP, p2);
+ if(dbg)printf(".\tintegral: S%d; h=%d b=%d\n",
+ p, eht[p], ebase[p]);
+ lfont[p] = ROM;
+}
+
+setintegral() {
+ char *f;
+
+ yyval = oalloc();
+ f = "\\(is";
+ printf(".ds %d %s\n", yyval, f);
+ eht[yyval] = VERT(2);
+ ebase[yyval] = 0;
+ lfont[yyval] = rfont[yyval] = ROM;
+}
--- /dev/null
+# include "e.h"
+#define MAXLINE 1200 /* maximum input line */
+
+char in[MAXLINE]; /* input buffer */
+int eqnexit();
+int noeqn;
+
+main(argc,argv) int argc; char *argv[];{
+
+ eqnexit(eqn(argc, argv));
+}
+
+eqnexit(n) {
+#ifdef gcos
+ if (n)
+ fprintf(stderr, "run terminated due to eqn error\n");
+ exit(0);
+#endif
+ exit(n);
+}
+
+eqn(argc,argv) int argc; char *argv[];{
+ int i, type;
+
+ setfile(argc,argv);
+ init_tbl(); /* install keywords in tables */
+ while ((type=getline(in)) != EOF) {
+ eqline = linect;
+ if (in[0]=='.' && in[1]=='E' && in[2]=='Q') {
+ for (i=11; i<100; used[i++]=0);
+ printf("%s",in);
+ printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n");
+ markline = 0;
+ init();
+ yyparse();
+ if (eqnreg>0) {
+ printf(".nr %d \\w'\\*(%d'\n", eqnreg, eqnreg);
+ /* printf(".if \\n(%d>\\n(.l .tm too-long eqn, file %s, between lines %d-%d\n", */
+ /* eqnreg, svargv[ifile], eqline, linect); */
+ printf(".nr MK %d\n", markline); /* for -ms macros */
+ printf(".if %d>\\n(.v .ne %du\n", eqnht, eqnht);
+ printf(".rn %d 10\n", eqnreg);
+ if(!noeqn)printf("\\*(10\n");
+ }
+ printf(".ps \\n(99\n.ft \\n(98\n");
+ printf(".EN");
+ if (lastchar == EOF) {
+ putchar('\n');
+ break;
+ }
+ if (putchar(lastchar) != '\n')
+ while (putchar(gtc()) != '\n');
+ }
+ else if (type == lefteq)
+ inline();
+ else
+ printf("%s",in);
+ }
+ return(0);
+}
+
+getline(s) register char *s; {
+ register c;
+ while((*s++=c=gtc())!='\n' && c!=EOF && c!=lefteq)
+ if (s >= in+MAXLINE) {
+ error( !FATAL, "input line too long: %.20s\n", in);
+ in[MAXLINE] = '\0';
+ break;
+ }
+ if (c==lefteq)
+ s--;
+ *s++ = '\0';
+ return(c);
+}
+
+inline() {
+ int ds;
+
+ printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n");
+ ds = oalloc();
+ printf(".rm %d \n", ds);
+ do{
+ if (*in)
+ printf(".as %d \"%s\n", ds, in);
+ init();
+ yyparse();
+ if (eqnreg > 0) {
+ printf(".as %d \\*(%d\n", ds, eqnreg);
+ ofree(eqnreg);
+ }
+ printf(".ps \\n(99\n.ft \\n(98\n");
+ } while (getline(in) == lefteq);
+ if (*in)
+ printf(".as %d \"%s", ds, in);
+ printf(".ps \\n(99\n.ft \\n(98\n");
+ printf("\\*(%d\n", ds);
+ ofree(ds);
+}
+
+putout(p1) int p1; {
+ extern int gsize, gfont;
+ int before, after;
+ if(dbg)printf(".\tanswer <- S%d, h=%d,b=%d\n",p1, eht[p1], ebase[p1]);
+ eqnht = eht[p1];
+ printf(".ds %d \\x'0'", p1);
+ /* suppposed to leave room for a subscript or superscript */
+ before = eht[p1] - ebase[p1] - VERT(3); /* 3 = 1.5 lines */
+ if (before > 0)
+ printf("\\x'0-%du'", before);
+ printf("\\f%c\\s%d\\*(%d%s\\s\\n(99\\f\\n(98",
+ gfont, gsize, p1, rfont[p1] == ITAL ? "\\|" : "");
+ after = ebase[p1] - VERT(1);
+ if (after > 0)
+ printf("\\x'%du'", after);
+ putchar('\n');
+ eqnreg = p1;
+}
+
+max(i,j) int i,j; {
+ return (i>j ? i : j);
+}
+
+oalloc() {
+ int i;
+ for (i=11; i<100; i++)
+ if (used[i]++ == 0) return(i);
+ error( FATAL, "no eqn strings left", i);
+ return(0);
+}
+
+ofree(n) int n; {
+ used[n] = 0;
+}
+
+setps(p) int p; {
+ printf(".ps %d\n", EFFPS(p));
+}
+
+nrwid(n1, p, n2) int n1, p, n2; {
+ printf(".nr %d \\w'\\s%d\\*(%d'\n", n1, EFFPS(p), n2);
+}
+
+setfile(argc, argv) int argc; char *argv[]; {
+ static char *nullstr = "-";
+
+ svargc = --argc;
+ svargv = argv;
+ while (svargc > 0 && svargv[1][0] == '-') {
+ switch (svargv[1][1]) {
+
+ case 'd': lefteq=svargv[1][2]; righteq=svargv[1][3]; break;
+ case 's': gsize = atoi(&svargv[1][2]); break;
+ case 'p': deltaps = atoi(&svargv[1][2]); break;
+ case 'f': gfont = svargv[1][2]; break;
+ case 'e': noeqn++; break;
+ default: dbg = 1;
+ }
+ svargc--;
+ svargv++;
+ }
+ ifile = 1;
+ linect = 1;
+ if (svargc <= 0) {
+ curfile = stdin;
+ svargv[1] = nullstr;
+ }
+ else if ((curfile = fopen(svargv[1], "r")) == NULL)
+ error( FATAL,"can't open file %s", svargv[1]);
+}
+
+yyerror() {;}
+
+init() {
+ ct = 0;
+ ps = gsize;
+ ft = gfont;
+ setps(ps);
+ printf(".ft %c\n", ft);
+}
+
+error(fatal, s1, s2) int fatal; char *s1, *s2; {
+ if (fatal>0)
+ printf("eqn fatal error: ");
+ printf(s1,s2);
+ printf("\nfile %s, between lines %d and %d\n",
+ svargv[ifile], eqline, linect);
+ fprintf(stderr, "eqn: ");
+ if (fatal>0)
+ fprintf(stderr, "fatal error: ");
+ fprintf(stderr, s1, s2);
+ fprintf(stderr, "\nfile %s, between lines %d and %d\n",
+ svargv[ifile], eqline, linect);
+ if (fatal > 0)
+ eqnexit(1);
+}
--- /dev/null
+#include "e.h"
+#include "e.def"
+
+#define SSIZE 400
+char token[SSIZE];
+int sp;
+#define putbak(c) *ip++ = c;
+#define PUSHBACK 300 /* maximum pushback characters */
+char ibuf[PUSHBACK+SSIZE]; /* pushback buffer for definitions, etc. */
+char *ip = ibuf;
+
+gtc() {
+ loop:
+ if (ip > ibuf)
+ return(*--ip); /* already present */
+ lastchar = getc(curfile);
+ if (lastchar=='\n')
+ linect++;
+ if (lastchar != EOF)
+ return(lastchar);
+ if (++ifile > svargc) {
+ return(EOF);
+ }
+ fclose(curfile);
+ linect = 1;
+ if ((curfile=fopen(svargv[ifile], "r")) != NULL)
+ goto loop;
+ error(FATAL, "can't open file %s", svargv[ifile]);
+ return(EOF);
+}
+
+pbstr(str)
+register char *str;
+{
+ register char *p;
+
+ p = str;
+ while (*p++);
+ --p;
+ if (ip >= &ibuf[PUSHBACK])
+ error( FATAL, "pushback overflow");
+ while (p > str)
+ putbak(*--p);
+}
+
+yylex() {
+ register int c;
+ tbl *tp, *lookup();
+ extern tbl **keytbl, **deftbl;
+
+ beg:
+ while ((c=gtc())==' ' || c=='\n')
+ ;
+ yylval=c;
+ switch(c) {
+
+ case EOF:
+ return(EOF);
+ case '~':
+ return(SPACE);
+ case '^':
+ return(THIN);
+ case '\t':
+ return(TAB);
+ case '{':
+ return('{');
+ case '}':
+ return('}');
+ case '"':
+ for (sp=0; (c=gtc())!='"' && c != '\n'; ) {
+ if (c == '\\')
+ if ((c = gtc()) != '"')
+ token[sp++] = '\\';
+ token[sp++] = c;
+ if (sp>=SSIZE)
+ error(FATAL, "quoted string %.20s... too long", token);
+ }
+ token[sp]='\0';
+ yylval = (int) &token[0];
+ if (c == '\n')
+ error(!FATAL, "missing \" in %.20s", token);
+ return(QTEXT);
+ }
+ if (c==righteq)
+ return(EOF);
+
+ putbak(c);
+ getstr(token, SSIZE);
+ if (dbg)printf(".\tlex token = |%s|\n", token);
+ if ((tp = lookup(&deftbl, token, NULL)) != NULL) {
+ putbak(' ');
+ pbstr(tp->defn);
+ putbak(' ');
+ if (dbg)
+ printf(".\tfound %s|=%s|\n", token, tp->defn);
+ }
+ else if ((tp = lookup(&keytbl, token, NULL)) == NULL) {
+ if(dbg)printf(".\t%s is not a keyword\n", token);
+ return(CONTIG);
+ }
+ else if (tp->defn == (char *) DEFINE || tp->defn == (char *) NDEFINE || tp->defn == (char *) TDEFINE)
+ define(tp->defn);
+ else if (tp->defn == (char *) DELIM)
+ delim();
+ else if (tp->defn == (char *) GSIZE)
+ globsize();
+ else if (tp->defn == (char *) GFONT)
+ globfont();
+ else if (tp->defn == (char *) INCLUDE)
+ include();
+ else {
+ return((int) tp->defn);
+ }
+ goto beg;
+}
+
+getstr(s, n) char *s; register int n; {
+ register int c;
+ register char *p;
+
+ p = s;
+ while ((c = gtc()) == ' ' || c == '\n')
+ ;
+ if (c == EOF) {
+ *s = 0;
+ return;
+ }
+ while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}'
+ && c != '"' && c != '~' && c != '^' && c != righteq) {
+ if (c == '\\')
+ if ((c = gtc()) != '"')
+ *p++ = '\\';
+ *p++ = c;
+ if (--n <= 0)
+ error(FATAL, "token %.20s... too long", s);
+ c = gtc();
+ }
+ if (c=='{' || c=='}' || c=='"' || c=='~' || c=='^' || c=='\t' || c==righteq)
+ putbak(c);
+ *p = '\0';
+ yylval = (int) s;
+}
+
+cstr(s, quote, maxs) char *s; int quote; {
+ int del, c, i;
+
+ while((del=gtc()) == ' ' || del == '\t' || del == '\n');
+ if (quote)
+ for (i=0; (c=gtc()) != del && c != EOF;) {
+ s[i++] = c;
+ if (i >= maxs)
+ return(1); /* disaster */
+ }
+ else {
+ s[0] = del;
+ for (i=1; (c=gtc())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) {
+ s[i++]=c;
+ if (i >= maxs)
+ return(1); /* disaster */
+ }
+ }
+ s[i] = '\0';
+ if (c == EOF)
+ error(FATAL, "Unexpected end of input at %.20s", s);
+ return(0);
+}
+
+define(type) int type; {
+ char *strsave(), *p1, *p2;
+ tbl *lookup();
+ extern tbl **deftbl;
+
+ getstr(token, SSIZE); /* get name */
+ if (type != DEFINE) {
+ cstr(token, 1, SSIZE); /* skip the definition too */
+ return;
+ }
+ p1 = strsave(token);
+ if (cstr(token, 1, SSIZE))
+ error(FATAL, "Unterminated definition at %.20s", token);
+ p2 = strsave(token);
+ lookup(&deftbl, p1, p2);
+ if (dbg)printf(".\tname %s defined as %s\n", p1, p2);
+}
+
+char *strsave(s)
+char *s;
+{
+ char *malloc();
+ register char *q;
+
+ q = malloc(strlen(s)+1);
+ if (q == NULL)
+ error(FATAL, "out of space in strsave on %s", s);
+ strcpy(q, s);
+ return(q);
+}
+
+include() {
+ error(!FATAL, "Include not yet implemented");
+}
+
+delim() {
+ yyval = eqnreg = 0;
+ if (cstr(token, 0, SSIZE))
+ error(FATAL, "Bizarre delimiters at %.20s", token);
+ lefteq = token[0];
+ righteq = token[1];
+ if (lefteq == 'o' && righteq == 'f')
+ lefteq = righteq = '\0';
+}
--- /dev/null
+# include "e.h"
+#include "e.def"
+
+#define TBLSIZE 100
+
+tbl *keytbl[TBLSIZE]; /* key words */
+tbl *restbl[TBLSIZE]; /* reserved words */
+tbl *deftbl[TBLSIZE]; /* user-defined names */
+
+struct {
+ char *key;
+ int keyval;
+} keyword[] ={
+ "sub", SUB,
+ "sup", SUP,
+ ".EN", EOF,
+ "from", FROM,
+ "to", TO,
+ "sum", SUM,
+ "hat", HAT,
+ "vec", VEC,
+ "dyad", DYAD,
+ "dot", DOT,
+ "dotdot", DOTDOT,
+ "bar", BAR,
+ "tilde", TILDE,
+ "under", UNDER,
+ "prod", PROD,
+ "int", INT,
+ "integral", INT,
+ "union", UNION,
+ "inter", INTER,
+ "pile", PILE,
+ "lpile", LPILE,
+ "cpile", CPILE,
+ "rpile", RPILE,
+ "over", OVER,
+ "sqrt", SQRT,
+ "above", ABOVE,
+ "size", SIZE,
+ "font", FONT,
+ "fat", FAT,
+ "roman", ROMAN,
+ "italic", ITALIC,
+ "bold", BOLD,
+ "left", LEFT,
+ "right", RIGHT,
+ "delim", DELIM,
+ "define", DEFINE,
+
+#ifdef NEQN /* make ndefine synonym for define, tdefine a no-op */
+
+ "tdefine", TDEFINE,
+ "ndefine", DEFINE,
+
+#else /* tdefine = define, ndefine = no-op */
+
+ "tdefine", DEFINE,
+ "ndefine", NDEFINE,
+
+#endif
+
+ "gsize", GSIZE,
+ ".gsize", GSIZE,
+ "gfont", GFONT,
+ "include", INCLUDE,
+ "up", UP,
+ "down", DOWN,
+ "fwd", FWD,
+ "back", BACK,
+ "mark", MARK,
+ "lineup", LINEUP,
+ "matrix", MATRIX,
+ "col", COL,
+ "lcol", LCOL,
+ "ccol", CCOL,
+ "rcol", RCOL,
+ 0, 0
+};
+
+struct {
+ char *res;
+ char *resval;
+} resword[] ={
+ ">=", "\\(>=",
+ "<=", "\\(<=",
+ "==", "\\(==",
+ "!=", "\\(!=",
+ "+-", "\\(+-",
+ "->", "\\(->",
+ "<-", "\\(<-",
+ "inf", "\\(if",
+ "infinity", "\\(if",
+ "partial", "\\(pd",
+ "half", "\\f1\\(12\\fP",
+ "prime", "\\f1\\(fm\\fP",
+ "dollar", "\\f1$\\fP",
+ "nothing", "",
+ "times", "\\(mu",
+ "del", "\\(gr",
+ "grad", "\\(gr",
+#ifdef NEQN
+ "<<", "<<",
+ ">>", ">>",
+ "approx", "~\b\\d~\\u",
+ "cdot", "\\v'-.5'.\\v'.5'",
+ "...", "...",
+ ",...,", ",...,",
+#else
+ "<<", "<\\h'-.3m'<",
+ ">>", ">\\h'-.3m'>",
+ "approx", "\\v'-.2m'\\z\\(ap\\v'.25m'\\(ap\\v'-.05m'",
+ "cdot", "\\v'-.3m'.\\v'.3m'",
+ "...", "\\v'-.3m'\\ .\\ .\\ .\\ \\v'.3m'",
+ ",...,", ",\\ .\\ .\\ .\\ ,\\|",
+#endif
+
+ "alpha", "\\(*a",
+ "beta", "\\(*b",
+ "gamma", "\\(*g",
+ "GAMMA", "\\(*G",
+ "delta", "\\(*d",
+ "DELTA", "\\(*D",
+ "epsilon", "\\(*e",
+ "EPSILON", "\\f1E\\fP",
+ "omega", "\\(*w",
+ "OMEGA", "\\(*W",
+ "lambda", "\\(*l",
+ "LAMBDA", "\\(*L",
+ "mu", "\\(*m",
+ "nu", "\\(*n",
+ "theta", "\\(*h",
+ "THETA", "\\(*H",
+ "phi", "\\(*f",
+ "PHI", "\\(*F",
+ "pi", "\\(*p",
+ "PI", "\\(*P",
+ "sigma", "\\(*s",
+ "SIGMA", "\\(*S",
+ "xi", "\\(*c",
+ "XI", "\\(*C",
+ "zeta", "\\(*z",
+ "iota", "\\(*i",
+ "eta", "\\(*y",
+ "kappa", "\\(*k",
+ "rho", "\\(*r",
+ "tau", "\\(*t",
+ "omicron", "\\(*o",
+ "upsilon", "\\(*u",
+ "UPSILON", "\\(*U",
+ "psi", "\\(*q",
+ "PSI", "\\(*Q",
+ "chi", "\\(*x",
+ "and", "\\f1and\\fP",
+ "for", "\\f1for\\fP",
+ "if", "\\f1if\\fP",
+ "Re", "\\f1Re\\fP",
+ "Im", "\\f1Im\\fP",
+ "sin", "\\f1sin\\fP",
+ "cos", "\\f1cos\\fP",
+ "tan", "\\f1tan\\fP",
+ "arc", "\\f1arc\\fP",
+ "sinh", "\\f1sinh\\fP",
+ "coth", "\\f1coth\\fP",
+ "tanh", "\\f1tanh\\fP",
+ "cosh", "\\f1cosh\\fP",
+ "lim", "\\f1lim\\fP",
+ "log", "\\f1log\\fP",
+ "max", "\\f1max\\fP",
+ "min", "\\f1min\\fP",
+ "ln", "\\f1ln\\fP",
+ "exp", "\\f1exp\\fP",
+ "det", "\\f1det\\fP",
+ 0, 0
+};
+
+tbl *lookup(tblp, name, defn) /* find name in tbl. if defn non-null, install */
+tbl **tblp;
+char *name, *defn;
+{
+ register tbl *p;
+ register int h;
+ register char *s = name;
+ char *malloc();
+
+ for (h = 0; *s != '\0'; )
+ h += *s++;
+ h %= TBLSIZE;
+
+ for (p = tblp[h]; p != NULL; p = p->next)
+ if (strcmp(name, p->name) == 0) { /* found it */
+ if (defn != NULL)
+ p->defn = defn;
+ return(p);
+ }
+ /* didn't find it */
+ if (defn == NULL)
+ return(NULL);
+ p = (tbl *) malloc(sizeof (tbl));
+ if (p == NULL)
+ error(FATAL, "out of space in lookup");
+ p->name = name;
+ p->defn = defn;
+ p->next = tblp[h];
+ tblp[h] = p;
+ return(p);
+}
+
+init_tbl() /* initialize all tables */
+{
+ int i;
+
+ for (i = 0; keyword[i].key != NULL; i++)
+ lookup(keytbl, keyword[i].key, keyword[i].keyval);
+ for (i = 0; resword[i].res != NULL; i++)
+ lookup(restbl, resword[i].res, resword[i].resval);
+}
--- /dev/null
+#include "e.h"
+
+mark(p1) int p1; {
+ markline = 1;
+ printf(".ds %d \\k(97\\*(%d\n", p1, p1);
+ yyval = p1;
+ if(dbg)printf(".\tmark %d\n", p1);
+}
+
+lineup(p1) {
+ markline = 1;
+ if (p1 == 0) {
+ yyval = oalloc();
+ printf(".ds %d \\h'|\\n(97u'\n", yyval);
+ }
+ if(dbg)printf(".\tlineup %d\n", p1);
+}
--- /dev/null
+#include "e.h"
+
+column(type, p1) int type, p1; {
+ int i;
+
+ lp[p1] = ct - p1 - 1;
+ if( dbg ){
+ printf(".\t%d column of", type);
+ for( i=p1+1; i<ct; i++ )
+ printf(" S%d", lp[i]);
+ printf(", rows=%d\n",lp[p1]);
+ }
+ lp[ct++] = type;
+}
+
+matrix(p1) int p1; {
+ int nrow, ncol, i, j, k, hb, b, val[100];
+ char *space;
+
+ space = "\\ \\ ";
+ nrow = lp[p1]; /* disaster if rows inconsistent */
+ ncol = 0;
+ for( i=p1; i<ct; i += lp[i]+2 ){
+ ncol++;
+ if(dbg)printf(".\tcolct=%d\n",lp[i]);
+ }
+ for( k=1; k<=nrow; k++ ) {
+ hb = b = 0;
+ j = p1 + k;
+ for( i=0; i<ncol; i++ ) {
+ hb = max(hb, eht[lp[j]]-ebase[lp[j]]);
+ b = max(b, ebase[lp[j]]);
+ j += nrow + 2;
+ }
+ if(dbg)printf(".\trow %d: b=%d, hb=%d\n", k, b, hb);
+ j = p1 + k;
+ for( i=0; i<ncol; i++ ) {
+ ebase[lp[j]] = b;
+ eht[lp[j]] = b + hb;
+ j += nrow + 2;
+ }
+ }
+ j = p1;
+ for( i=0; i<ncol; i++ ) {
+ lpile(lp[j+lp[j]+1], j+1, j+lp[j]+1);
+ val[i] = yyval;
+ j += nrow + 2;
+ }
+ yyval = oalloc();
+ eht[yyval] = eht[val[0]];
+ ebase[yyval] = ebase[val[0]];
+ lfont[yyval] = rfont[yyval] = 0;
+ if(dbg)printf(".\tmatrix S%d: r=%d, c=%d, h=%d, b=%d\n",
+ yyval,nrow,ncol,eht[yyval],ebase[yyval]);
+ printf(".ds %d \"", yyval);
+ for( i=0; i<ncol; i++ ) {
+ printf("\\*(%d%s", val[i], i==ncol-1 ? "" : space);
+ ofree(val[i]);
+ }
+ printf("\n");
+ ct = p1;
+}
--- /dev/null
+# include "e.h"
+# include "e.def"
+
+move(dir, amt, p) int dir, amt, p; {
+ int a;
+
+ yyval = p;
+ a = VERT( (amt+49)/50 ); /* nearest number of half-lines */
+ printf(".ds %d ", yyval);
+ if( dir == FWD || dir == BACK ) /* fwd, back */
+ printf("\\h'%s%du'\\*(%d\n", (dir==BACK) ? "-" : "", a, p);
+ else if (dir == UP)
+ printf("\\v'-%du'\\*(%d\\v'%du'\n", a, p, a);
+ else if (dir == DOWN)
+ printf("\\v'%du'\\*(%d\\v'-%du'\n", a, p, a);
+ if(dbg)printf(".\tmove %d dir %d amt %d; h=%d b=%d\n",
+ p, dir, a, eht[yyval], ebase[yyval]);
+}
--- /dev/null
+# include "e.h"
+
+boverb(p1, p2) int p1, p2; {
+ int h, b, treg, d;
+
+ treg = oalloc();
+ yyval = p1;
+ d = VERT(1);
+ h = eht[p1] + eht[p2];
+ b = eht[p2] - d;
+ if(dbg)printf(".\tb:bob: S%d <- S%d over S%d; b=%d, h=%d\n",
+ yyval, p1, p2, b, h);
+ nrwid(p1, ps, p1);
+ nrwid(p2, ps, p2);
+ printf(".nr %d \\n(%d\n", treg, p1);
+ printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, treg, treg, p2);
+ printf(".ds %d \\v'%du'\\h'\\n(%du-\\n(%du/2u'\\*(%d\\\n",
+ yyval, eht[p2]-ebase[p2]-d, treg, p2, p2);
+ printf("\\h'-\\n(%du-\\n(%du/2u'\\v'%du'\\*(%d\\\n",
+ p2, p1, -eht[p2]+ebase[p2]-ebase[p1], p1);
+ printf("\\h'-\\n(%du-\\n(%du-2u/2u'\\v'%du'\\l'\\n(%du'\\v'%du'\n",
+ treg, p1, ebase[p1], treg, d);
+ ebase[yyval] = b;
+ eht[yyval] = h;
+ lfont[yyval] = rfont[yyval] = 0;
+ ofree(p2);
+ ofree(treg);
+}
--- /dev/null
+# include "e.h"
+
+paren(leftc, p1, rightc) int p1, leftc, rightc; {
+ int n, m, h1, j, b1, v;
+ h1 = eht[p1]; b1 = ebase[p1];
+ yyval = p1;
+ n = max(b1+VERT(1), h1-b1-VERT(1)) / VERT(1);
+ if( n<2 ) n = 1;
+ m = n-2;
+ if (leftc=='{' || rightc == '}') {
+ n = n%2 ? n : ++n;
+ if( n<3 ) n=3;
+ m = n-3;
+ }
+ eht[yyval] = VERT(2 * n);
+ ebase[yyval] = (n)/2 * VERT(2);
+ if (n%2 == 0)
+ ebase[yyval] -= VERT(1);
+ v = b1 - h1/2 + VERT(1);
+ printf(".ds %d \\|\\v'%du'", yyval, v);
+ switch( leftc ) {
+ case 'n': /* nothing */
+ case '\0':
+ break;
+ case 'f': /* floor */
+ if (n <= 1)
+ printf("\\(lf");
+ else
+ brack(m, "\\(bv", "\\(bv", "\\(lf");
+ break;
+ case 'c': /* ceiling */
+ if (n <= 1)
+ printf("\\(lc");
+ else
+ brack(m, "\\(lc", "\\(bv", "\\(bv");
+ break;
+ case '{':
+ printf("\\b'\\(lt");
+ for(j = 0; j < m; j += 2) printf("\\(bv");
+ printf("\\(lk");
+ for(j = 0; j < m; j += 2) printf("\\(bv");
+ printf("\\(lb'");
+ break;
+ case '(':
+ brack(m, "\\(lt", "\\(bv", "\\(lb");
+ break;
+ case '[':
+ brack(m, "\\(lc", "\\(bv", "\\(lf");
+ break;
+ case '|':
+ brack(m, "|", "|", "|");
+ break;
+ default:
+ brack(m, (char *) &leftc, (char *) &leftc, (char *) &leftc);
+ break;
+ }
+ printf("\\v'%du'\\*(%d", -v, p1);
+ if( rightc ) {
+ printf("\\|\\v'%du'", v);
+ switch( rightc ) {
+ case 'f': /* floor */
+ if (n <= 1)
+ printf("\\(rf");
+ else
+ brack(m, "\\(bv", "\\(bv", "\\(rf");
+ break;
+ case 'c': /* ceiling */
+ if (n <= 1)
+ printf("\\(rc");
+ else
+ brack(m, "\\(rc", "\\(bv", "\\(bv");
+ break;
+ case '}':
+ printf("\\b'\\(rt");
+ for(j = 0; j< m; j += 2)printf("\\(bv");
+ printf("\\(rk");
+ for(j = 0; j< m; j += 2) printf("\\(bv");
+ printf("\\(rb'");
+ break;
+ case ']':
+ brack(m, "\\(rc", "\\(bv", "\\(rf");
+ break;
+ case ')':
+ brack(m, "\\(rt", "\\(bv", "\\(rb");
+ break;
+ case '|':
+ brack(m, "|", "|", "|");
+ break;
+ default:
+ brack(m, (char *) &rightc, (char *) &rightc, (char *) &rightc);
+ break;
+ }
+ printf("\\v'%du'", -v);
+ }
+ printf("\n");
+ if(dbg)printf(".\tcurly: h=%d b=%d n=%d v=%d l=%c, r=%c\n",
+ eht[yyval], ebase[yyval], n, v, leftc, rightc);
+}
+
+brack(m, t, c, b) int m; char *t, *c, *b; {
+ int j;
+ printf("\\b'%s", t);
+ for( j=0; j<m; j++)
+ printf("%s", c);
+ printf("%s'", b);
+}
--- /dev/null
+# include "e.h"
+
+lpile(type, p1, p2) int type, p1, p2; {
+ int bi, hi, i, gap, h, b, nlist, nlist2, mid;
+ yyval = oalloc();
+ gap = VERT(1);
+ if( type=='-' ) gap = 0;
+ nlist = p2 - p1;
+ nlist2 = (nlist+1)/2;
+ mid = p1 + nlist2 -1;
+ h = 0;
+ for( i=p1; i<p2; i++ )
+ h += eht[lp[i]];
+ eht[yyval] = h + (nlist-1)*gap;
+ b = 0;
+ for( i=p2-1; i>mid; i-- )
+ b += eht[lp[i]] + gap;
+ ebase[yyval] = (nlist%2) ? b + ebase[lp[mid]]
+ : b - VERT(1) - gap;
+ if(dbg) {
+ printf(".\tS%d <- %c pile of:", yyval, type);
+ for( i=p1; i<p2; i++)
+ printf(" S%d", lp[i]);
+ printf(";h=%d b=%d\n", eht[yyval], ebase[yyval]);
+ }
+ nrwid(lp[p1], ps, lp[p1]);
+ printf(".nr %d \\n(%d\n", yyval, lp[p1]);
+ for( i = p1+1; i<p2; i++ ) {
+ nrwid(lp[i], ps, lp[i]);
+ printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n",
+ lp[i], yyval, yyval, lp[i]);
+ }
+ printf(".ds %d \\v'%du'\\h'%du*\\n(%du'\\\n", yyval, ebase[yyval],
+ type=='R' ? 1 : 0, yyval);
+ for(i = p2-1; i >=p1; i--) {
+ hi = eht[lp[i]];
+ bi = ebase[lp[i]];
+ switch(type) {
+
+ case 'L':
+ printf("\\v'%du'\\*(%d\\h'-\\n(%du'\\v'0-%du'\\\n",
+ -bi, lp[i], lp[i], hi-bi+gap);
+ continue;
+ case 'R':
+ printf("\\v'%du'\\h'-\\n(%du'\\*(%d\\v'0-%du'\\\n",
+ -bi, lp[i], lp[i], hi-bi+gap);
+ continue;
+ case 'C':
+ case '-':
+ printf("\\v'%du'\\h'\\n(%du-\\n(%du/2u'\\*(%d",
+ -bi, yyval, lp[i], lp[i]);
+ printf("\\h'-\\n(%du-\\n(%du/2u'\\v'0-%du'\\\n",
+ yyval, lp[i], hi-bi+gap);
+ continue;
+ }
+ }
+ printf("\\v'%du'\\h'%du*\\n(%du'\n", eht[yyval]-ebase[yyval]+gap,
+ type!='R' ? 1 : 0, yyval);
+ for( i=p1; i<p2; i++ )
+ ofree(lp[i]);
+ lfont[yyval] = rfont[yyval] = 0;
+}
--- /dev/null
+# include "e.h"
+#include "e.def"
+
+bshiftb(p1, dir, p2) int p1, dir, p2; {
+ int shval, d1, h1, b1, h2, b2;
+ yyval = p1;
+ h1 = eht[p1];
+ b1 = ebase[p1];
+ h2 = eht[p2];
+ b2 = ebase[p2];
+ if( dir == SUB ) { /* subscript */
+ d1 = VERT(1);
+ shval = - d1 + h2 - b2;
+ if( d1+b1 > h2 ) /* move little sub down */
+ shval = b1-b2;
+ ebase[yyval] = b1 + max(0, h2-b1-d1);
+ eht[yyval] = h1 + max(0, h2-b1-d1);
+ } else { /* superscript */
+ d1 = VERT(1);
+ ebase[yyval] = b1;
+ shval = -VERT(1) - b2;
+ if( VERT(1) + h2 < h1-b1 ) /* raise little super */
+ shval = -(h1-b1) + h2-b2 - d1;
+ eht[yyval] = h1 + max(0, h2 - VERT(1));
+ }
+ if(dbg)printf(".\tb:b shift b: S%d <- S%d vert %d S%d vert %d; b=%d, h=%d\n",
+ yyval, p1, shval, p2, -shval, ebase[yyval], eht[yyval]);
+ printf(".as %d \\v'%du'\\*(%d\\v'%du'\n",
+ yyval, shval, p2, -shval);
+ ofree(p2);
+}
+
+shift(p1) int p1; {
+ ps -= deltaps;
+ yyval = p1;
+ if(dbg)printf(".\tshift: %d;ps=%d\n", yyval, ps);
+}
+
+shift2(p1, p2, p3) int p1, p2, p3; {
+ int effps, h1, h2, h3, b1, b2, b3, subsh, d1, d2, supsh;
+ int treg;
+
+ treg = oalloc();
+ yyval = p1;
+ if(dbg)printf(".\tshift2 s%d <- %d %d %d\n", yyval, p1, p2, p3);
+ effps = EFFPS(ps+deltaps);
+ h1 = eht[p1]; b1 = ebase[p1];
+ h2 = eht[p2]; b2 = ebase[p2];
+ h3 = eht[p3]; b3 = ebase[p3];
+ d1 = VERT(1);
+ subsh = -d1+h2-b2;
+ if( d1+b1 > h2 ) /* move little sub down */
+ subsh = b1-b2;
+ supsh = - VERT(1) - b3;
+ d2 = VERT(1);
+ if( VERT(1)+h3 < h1-b1 )
+ supsh = -(h1-b1) + (h3-b3) - d2;
+ eht[yyval] = h1 + max(0, h3-VERT(1)) + max(0, h2-b1-d1);
+ ebase[yyval] = b1+max(0, h2-b1-d1);
+ nrwid(p2, effps, p2);
+ nrwid(p3, effps, p3);
+ printf(".nr %d \\n(%d\n", treg, p3);
+ printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, treg, treg, p2);
+ printf(".as %d \\v'%du'\\*(%d\\h'-\\n(%du'\\v'%du'\\\n",
+ p1, subsh, p2, p2, -subsh+supsh);
+ printf("\\*(%d\\h'-\\n(%du+\\n(%du'\\v'%du'\n",
+ p3, p3, treg, -supsh);
+ ps += deltaps;
+ ofree(p2); ofree(p3); ofree(treg);
+}
--- /dev/null
+# include "e.h"
+
+setsize(p) /* set size as found in p */
+char *p;
+{
+ if (*p == '+')
+ ps += atoi(p+1);
+ else if (*p == '-')
+ ps -= atoi(p+1);
+ else
+ ps = atoi(p);
+ if(dbg)printf(".\tsetsize %s; ps = %d\n", p, ps);
+}
+
+size(p1, p2) int p1, p2; {
+ /* old size in p1, new in ps */
+ int effps, effp1;
+
+ yyval = p2;
+ if(dbg)printf(".\tb:sb: S%d <- \\s%d S%d \\s%d; b=%d, h=%d\n",
+ yyval, ps, p2, p1, ebase[yyval], eht[yyval]);
+ effps = EFFPS(ps);
+ effp1 = EFFPS(p1);
+ printf(".ds %d \\s%d\\*(%d\\s%d\n",
+ yyval, effps, p2, effp1);
+ ps = p1;
+}
+
+globsize() {
+ char temp[20];
+
+ getstr(temp, 20);
+ if (temp[0] == '+')
+ gsize += atoi(temp+1);
+ else if (temp[0] == '-')
+ gsize -= atoi(temp+1);
+ else
+ gsize = atoi(temp);
+ yyval = eqnreg = 0;
+ setps(gsize);
+ ps = gsize;
+ if (gsize >= 12) /* sub and sup size change */
+ deltaps = gsize / 4;
+ else
+ deltaps = gsize / 3;
+}
--- /dev/null
+# include "e.h"
+
+sqrt(p2) int p2; {
+ yyval = p2;
+ nrwid(p2, ps, p2);
+ printf(".ds %d \\v'%du'\\e\\L'%du'\\l'\\n(%du'",
+ p2, ebase[p2], -eht[p2], p2);
+ printf("\\v'%du'\\h'-\\n(%du'\\*(%d\n", eht[p2]-ebase[p2], p2, p2);
+ eht[p2] += VERT(1);
+ if(dbg)printf(".\tsqrt: S%d <- S%d;b=%d, h=%d\n",
+ p2, p2, ebase[p2], eht[p2]);
+}
--- /dev/null
+# include "e.h"
+# include "e.def"
+
+int csp;
+int psp;
+#define CSSIZE 400
+char cs[420];
+
+int lf, rf; /* temporary spots for left and right fonts */
+
+text(t,p1) int t; char *p1; {
+ int c;
+ char *p;
+ tbl *tp, *lookup();
+ extern tbl *restbl;
+
+ yyval = oalloc();
+ ebase[yyval] = 0;
+ eht[yyval] = VERT(2); /* 2 half-spaces */
+ lfont[yyval] = rfont[yyval] = ROM;
+ if (t == QTEXT)
+ p = p1;
+ else if ( t == SPACE )
+ p = "\\ ";
+ else if ( t == THIN )
+ p = "\\|";
+ else if ( t == TAB )
+ p = "\\t";
+ else if ((tp = lookup(&restbl, p1, NULL)) != NULL)
+ p = tp->defn;
+ else {
+ lf = rf = 0;
+ for (csp=psp=0; (c=p1[psp++])!='\0';) {
+ rf = trans(c, p1);
+ if (lf == 0)
+ lf = rf; /* save first */
+ if (csp>CSSIZE)
+ error(FATAL,"converted token %.25s... too long",p1);
+ }
+ cs[csp] = '\0';
+ p = cs;
+ lfont[yyval] = lf;
+ rfont[yyval] = rf;
+ }
+ if(dbg)printf(".\t%dtext: S%d <- %s; b=%d,h=%d,lf=%c,rf=%c\n",
+ t, yyval, p, ebase[yyval], eht[yyval], lfont[yyval], rfont[yyval]);
+ printf(".ds %d \"%s\n", yyval, p);
+}
+
+trans(c,p1) int c; char *p1; {
+ int f;
+ f = ROM;
+ switch( c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case ':': case ';': case '!': case '%':
+ case '(': case '[': case ')': case ']':
+ case ',':
+ if (rf == ITAL)
+ shim();
+ roman(c); break;
+ case '.':
+ if (rf == ROM)
+ roman(c);
+ else
+ cs[csp++] = c;
+ f = rf;
+ break;
+ case '|':
+ if (rf == ITAL)
+ shim();
+ shim(); roman(c); shim(); break;
+ case '=':
+ if (rf == ITAL)
+ shim();
+ name4('e','q');
+ break;
+ case '+':
+ if (rf == ITAL)
+ shim();
+ name4('p', 'l');
+ break;
+ case '>': case '<':
+ if (rf == ITAL)
+ shim();
+ if (p1[psp]=='=') { /* look ahead for == <= >= */
+ name4(c,'=');
+ psp++;
+ } else {
+ cs[csp++] = c;
+ }
+ break;
+ case '-':
+ if (rf == ITAL)
+ shim();
+ if (p1[psp]=='>') {
+ name4('-','>'); psp++;
+ } else {
+ name4('m','i');
+ }
+ break;
+ case '/':
+ if (rf == ITAL)
+ shim();
+ name4('s','l');
+ break;
+ case '~': case ' ':
+ shim(); shim(); break;
+ case '^':
+ shim(); break;
+ case '\\': /* troff - pass 2 or 3 more chars */
+ if (rf == ITAL)
+ shim();
+ cs[csp++] = c; cs[csp++] = c = p1[psp++]; cs[csp++] = p1[psp++];
+ if (c=='(') cs[csp++] = p1[psp++];
+ if (c=='*' && cs[csp-1] == '(') {
+ cs[csp++] = p1[psp++];
+ cs[csp++] = p1[psp++];
+ }
+ break;
+ case '\'':
+ cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = rf==ITAL ? ITAL : ROM;
+ name4('f','m');
+ cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = 'P';
+ f = rf==ITAL ? ITAL : ROM;
+ break;
+
+ case 'f':
+ if (ft == ITAL) {
+ cs[csp++] = '\\'; cs[csp++] = '^';
+ cs[csp++] = 'f';
+ cs[csp++] = '\\'; cs[csp++] = '|'; /* trying | instead of ^ */
+ f = ITAL;
+ }
+ else
+ cs[csp++] = 'f';
+ break;
+ case 'j':
+ if (ft == ITAL) {
+ cs[csp++] = '\\'; cs[csp++] = '^';
+ cs[csp++] = 'j';
+ f = ITAL;
+ }
+ else
+ cs[csp++] = 'j';
+ break;
+ default:
+ cs[csp++] = c;
+ f = ft==ITAL ? ITAL : ROM;
+ break;
+ }
+ return(f);
+}
+
+shim() {
+ cs[csp++] = '\\'; cs[csp++] = '|';
+}
+
+roman(c) int c; {
+ cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = ROM;
+ cs[csp++] = c;
+ cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = 'P';
+}
+
+name4(c1,c2) int c1,c2; {
+ cs[csp++] = '\\';
+ cs[csp++] = '(';
+ cs[csp++] = c1;
+ cs[csp++] = c2;
+}