📄 lex.c
字号:
#ifndef lintstatic char *sccsid = " @(#)lex.c 1.3 (ULTRIX) 1/15/86";#endif lint/************************************************************************ * * * Copyright (c) 1986 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************** Modification History** David Metsky 14-Jan-86** 001 Replaced old version with BSD 4.3 version as part of upgrade.** Based on: lex.c 5.2 8/29/85**************************************************************************//* * lex.c * * Lexical scanner routines for the f77 compiler, pass 1, 4.2 BSD. * * University of Utah CS Dept modification history: * * $Log: lex.c,v $ * Revision 5.2 85/08/10 04:45:41 donn * Jerry Berkman's changes to ifdef 66 code and handle -r8/double flag. * * Revision 5.1 85/08/10 03:48:20 donn * 4.3 alpha * * Revision 1.2 84/10/27 02:20:09 donn * Fixed bug where the input file and the name field of the include file * structure shared -- when the input file name was freed, the include file * name got stomped on, leading to peculiar error messages. * */#include "defs.h"#include "tokdefs.h"# 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;LOCAL int lastend = 1;ftnint yystno;flag intonly;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;LOCAL char *newname = NULL;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; char notinf66; } ;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)int *n;{*n = (lastch - nextch) + 1;return(nextch);}doinclude(name)char *name;{FILEP fp;struct Inclfile *t;char temp[100];register char *lastslash, *s;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 >= MAXINCLUDES) fatal("includes nested too deep");if(name[0] == '\0') fp = stdin;else if(name[0]=='/' || inclp==NULL) fp = fopen(name, "r");else { lastslash = NULL; for(s = inclp->inclname ; *s ; ++s) if(*s == '/') lastslash = s; if(lastslash) { *lastslash = '\0'; sprintf(temp, "%s/%s", inclp->inclname, name); *lastslash = '/'; } else strcpy(temp, name); if( (fp = fopen(temp, "r")) == NULL ) { sprintf(temp, "/usr/include/%s", name); fp = fopen(temp, "r"); } if(fp) name = copys(temp); }if( fp ) { t = inclp; inclp = ALLOC(Inclfile); inclp->inclnext = t; prevlin = thislin = 0; inclp->inclname = name; infname = copys(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->inclname);free( (charptr) inclp);inclp = t;if(inclp == NULL) return(NO);infile = inclp->inclfp;infname = copys(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( (charptr) (inclp->incllinp) ); }else nextcd = NULL;return(YES);}yylex(){static int tokno; switch(lexstate) {case NEWSTMT : /* need a new statement */ if(getcds() == STEOF) return(SEOF); lastend = stkey == SEND; 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); }fatali("impossible lexstate %d", lexstate);/* NOTREACHED */}LOCAL getcds(){register char *p, *q; if (newname) { free(infname); infname = newname; newname = NULL; }top: if(nextcd == NULL) { code = getcd( nextcd = s ); stno = nxtstno; if (newname) { free(infname); infname = newname; newname = NULL; } prevlin = thislin; } if(code == STEOF) if( popinclude() ) goto top; else return(STEOF); if(code == STCONTINUE) { if (newname) { free(infname); infname = newname; newname = NULL; } 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;int num;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 == '#') { c = getc(infile); while (c == BLANK || c == '\t') c = getc(infile); num = 0; while (isdigit(c)) { num = 10*num + c - '0'; c = getc(infile); } thislin = num - 1; while (c == BLANK || c == '\t') c = getc(infile); if (c == '"') { char fname[1024]; int len = 0; c = getc(infile); while (c != '"' && c != '\n') { fname[len++] = c; c = getc(infile); } fname[len++] = '\0'; if (newname) free(newname); newname = (char *) ckalloc(len); strcpy(newname, fname); } while (c != '\n') if (c == EOF) return (STEOF); else c = getc(infile); 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 { if (newname) { free(infname); infname = newname; newname = NULL; } 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=='"') {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -