📄 lex.c
字号:
#include "defs"#include "tokdefs"# define BLANK ' '# define MYQUOTE (2)# define SEOF 0/* card types */# define STEOF 1# define STINITIAL 2# define STCONTINUE 3/* lex states */#define NEWSTMT 1#define FIRSTTOKEN 2#define OTHERTOKEN 3#define RETEOS 4LOCAL int stkey;ftnint yystno;LOCAL long int stno;LOCAL long int nxtstno;LOCAL int parlev;LOCAL int expcom;LOCAL int expeql;LOCAL char *nextch;LOCAL char *lastch;LOCAL char *nextcd = NULL;LOCAL char *endcd;LOCAL int prevlin;LOCAL int thislin;LOCAL int code;LOCAL int lexstate = NEWSTMT;LOCAL char s[1390];LOCAL char *send = s+20*66;LOCAL int nincl = 0;struct inclfile { struct inclfile *inclnext; FILEP inclfp; char *inclname; int incllno; char *incllinp; int incllen; int inclcode; ftnint inclstno; } ;LOCAL struct inclfile *inclp = NULL;LOCAL struct keylist { char *keyname; int keyval; } ;LOCAL struct punctlist { char punchar; int punval; };LOCAL struct fmtlist { char fmtchar; int fmtval; };LOCAL struct dotlist { char *dotname; int dotval; };LOCAL struct keylist *keystart[26], *keyend[26];inilex(name)char *name;{nincl = 0;inclp = NULL;doinclude(name);lexstate = NEWSTMT;return(NO);}/* throw away the rest of the current line */flline(){lexstate = RETEOS;}char *lexline(n)ftnint *n;{*n = (lastch - nextch) + 1;return(nextch);}doinclude(name)char *name;{FILEP fp;struct inclfile *t;if(inclp) { inclp->incllno = thislin; inclp->inclcode = code; inclp->inclstno = nxtstno; if(nextcd) inclp->incllinp = copyn(inclp->incllen = endcd-nextcd , nextcd); else inclp->incllinp = 0; }nextcd = NULL;if(++nincl >= MAXINCLUDE) fatal("includes nested too deep");if(name[0] == '\0') fp = stdin;else fp = fopen(name, "r");if( fp ) { t = inclp; inclp = ALLOC(inclfile); inclp->inclnext = t; prevlin = thislin = 0; infname = inclp->inclname = name; infile = inclp->inclfp = fp; }else { fprintf(diagfile, "Cannot open file %s", name); done(1); }}LOCAL popinclude(){struct inclfile *t;register char *p;register int k;if(infile != stdin) clf(&infile);free(infname);--nincl;t = inclp->inclnext;free(inclp);inclp = t;if(inclp == NULL) return(NO);infile = inclp->inclfp;infname = inclp->inclname;prevlin = thislin = inclp->incllno;code = inclp->inclcode;stno = nxtstno = inclp->inclstno;if(inclp->incllinp) { endcd = nextcd = s; k = inclp->incllen; p = inclp->incllinp; while(--k >= 0) *endcd++ = *p++; free(inclp->incllinp); }else nextcd = NULL;return(YES);}yylex(){static int tokno; switch(lexstate) {case NEWSTMT : /* need a new statement */ if(getcds() == STEOF) return(SEOF); crunch(); tokno = 0; lexstate = FIRSTTOKEN; yystno = stno; stno = nxtstno; toklen = 0; return(SLABEL);first:case FIRSTTOKEN : /* first step on a statement */ analyz(); lexstate = OTHERTOKEN; tokno = 1; return(stkey);case OTHERTOKEN : /* return next token */ if(nextch > lastch) goto reteos; ++tokno; if((stkey==SLOGIF || stkey==SELSEIF) && parlev==0 && tokno>3) goto first; if(stkey==SASSIGN && tokno==3 && nextch<lastch && nextch[0]=='t' && nextch[1]=='o') { nextch+=2; return(STO); } return(gettok());reteos:case RETEOS: lexstate = NEWSTMT; return(SEOS); }fatal1("impossible lexstate %d", lexstate);/* NOTREACHED */}LOCAL getcds(){register char *p, *q;top: if(nextcd == NULL) { code = getcd( nextcd = s ); stno = nxtstno; prevlin = thislin; } if(code == STEOF) if( popinclude() ) goto top; else return(STEOF); if(code == STCONTINUE) { lineno = thislin; err("illegal continuation card ignored"); nextcd = NULL; goto top; } if(nextcd > s) { q = nextcd; p = s; while(q < endcd) *p++ = *q++; endcd = p; } for(nextcd = endcd ; nextcd+66<=send && (code = getcd(nextcd))==STCONTINUE ; nextcd = endcd ) ; nextch = s; lastch = nextcd - 1; if(nextcd >= send) nextcd = NULL; lineno = prevlin; prevlin = thislin; return(STINITIAL);}LOCAL getcd(b)register char *b;{register int c;register char *p, *bend;int speclin;static char a[6];static char *aend = a+6;top: endcd = b; bend = b+66; speclin = NO; if( (c = getc(infile)) == '&') { a[0] = BLANK; a[5] = 'x'; speclin = YES; bend = send; } else if(c=='c' || c=='C' || c=='*') { while( (c = getc(infile)) != '\n') if(c == EOF) return(STEOF); ++thislin; goto top; } else if(c != EOF) { /* a tab in columns 1-6 skips to column 7 */ ungetc(c, infile); for(p=a; p<aend && (c=getc(infile)) != '\n' && c!=EOF; ) if(c == '\t') { while(p < aend) *p++ = BLANK; speclin = YES; bend = send; } else *p++ = c; } if(c == EOF) return(STEOF); if(c == '\n') { while(p < aend) *p++ = BLANK; if( ! speclin ) while(endcd < bend) *endcd++ = BLANK; } else { /* read body of line */ while( endcd<bend && (c=getc(infile)) != '\n' && c!=EOF ) *endcd++ = c; if(c == EOF) return(STEOF); if(c != '\n') { while( (c=getc(infile)) != '\n') if(c == EOF) return(STEOF); } if( ! speclin ) while(endcd < bend) *endcd++ = BLANK; } ++thislin; if( !isspace(a[5]) && a[5]!='0') return(STCONTINUE); for(p=a; p<aend; ++p) if( !isspace(*p) ) goto initline; for(p = b ; p<endcd ; ++p) if( !isspace(*p) ) goto initline; goto top;initline: nxtstno = 0; for(p = a ; p<a+5 ; ++p) if( !isspace(*p) ) if(isdigit(*p)) nxtstno = 10*nxtstno + (*p - '0'); else { lineno = thislin; err("nondigit in statement number field"); nxtstno = 0; break; } return(STINITIAL);}LOCAL crunch(){register char *i, *j, *j0, *j1, *prvstr;int ten, nh, quote;/* i is the next input character to be looked atj is the next output character */parlev = 0;expcom = 0; /* exposed ','s */expeql = 0; /* exposed equal signs */j = s;prvstr = s;for(i=s ; i<=lastch ; ++i) { if(isspace(*i) ) continue; if(*i=='\'' || *i=='"') { quote = *i; *j = MYQUOTE; /* special marker */ for(;;) { if(++i > lastch) { err("unbalanced quotes; closing quote supplied"); break; } if(*i == quote) if(i<lastch && i[1]==quote) ++i; else break; else if(*i=='\\' && i<lastch) switch(*++i) { case 't': *i = '\t'; break; case 'b': *i = '\b'; break; case 'n': *i = '\n'; break; case 'f': *i = '\f'; break; case '0': *i = '\0'; break; default: break; } *++j = *i; } j[1] = MYQUOTE; j += 2; prvstr = j; } else if( (*i=='h' || *i=='H') && j>prvstr) /* test for Hollerith strings */ { if( ! isdigit(j[-1])) goto copychar; nh = j[-1] - '0'; ten = 10; j1 = prvstr - 1; if (j1<j-5) j1=j-5; for(j0=j-2 ; j0>j1; -- j0) { if( ! isdigit(*j0 ) ) break; nh += ten * (*j0-'0'); ten*=10; } if(j0 <= j1) goto copychar;/* a hollerith must be preceded by a punctuation mark. '*' is possible only as repetition factor in a data statement not, in particular, in character*2h*/ if( !(*j0=='*'&&s[0]=='d') && *j0!='/' && *j0!='(' && *j0!=',' && *j0!='=' && *j0!='.') goto copychar; if(i+nh > lastch) { err1("%dH too big", nh); nh = lastch - i; } j0[1] = MYQUOTE; /* special marker */ j = j0 + 1; while(nh-- > 0) { if(*++i == '\\') switch(*++i) { case 't': *i = '\t'; break; case 'b':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -