📄 lex.c
字号:
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 'v': *i = '\v'; 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) { erri("%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': *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 == '(') ++parlev; else if(*i == ')') --parlev; else if(parlev == 0) if(*i == '=') expeql = 1; else if(*i == ',') expcom = 1;copychar: /*not a string or space -- copy, shifting case if necessary */ if(shiftcase && isupper(*i)) *j++ = tolower(*i); else *j++ = *i; } }lastch = j - 1;nextch = s;}LOCAL analyz(){register char *i; if(parlev != 0) { err("unbalanced parentheses, statement skipped"); stkey = SUNKNOWN; return; } if(nextch+2<=lastch && nextch[0]=='i' && nextch[1]=='f' && nextch[2]=='(') {/* assignment or if statement -- look at character after balancing paren */ parlev = 1; for(i=nextch+3 ; i<=lastch; ++i) if(*i == (MYQUOTE)) { while(*++i != MYQUOTE) ; } else if(*i == '(') ++parlev; else if(*i == ')') { if(--parlev == 0) break; } if(i >= lastch) stkey = SLOGIF; else if(i[1] == '=') stkey = SLET; else if( isdigit(i[1]) ) stkey = SARITHIF; else stkey = SLOGIF; if(stkey != SLET) nextch += 2; } else if(expeql) /* may be an assignment */ { if(expcom && nextch<lastch && nextch[0]=='d' && nextch[1]=='o') { stkey = SDO; nextch += 2; } else stkey = SLET; }/* otherwise search for keyword */ else { stkey = getkwd(); if(stkey==SGOTO && lastch>=nextch) if(nextch[0]=='(') stkey = SCOMPGOTO; else if(isalpha(nextch[0])) stkey = SASGOTO; } parlev = 0;}LOCAL getkwd(){register char *i, *j;register struct Keylist *pk, *pend;int k;if(! isalpha(nextch[0]) ) return(SUNKNOWN);k = nextch[0] - 'a';if(pk = keystart[k]) for(pend = keyend[k] ; pk<=pend ; ++pk ) { i = pk->keyname; j = nextch; while(*++i==*++j && *i!='\0') ; if(*i=='\0' && j<=lastch+1) { nextch = j;#ifdef ONLY66 if(no66flag && pk->notinf66) errstr("Not a Fortran 66 keyword: %s", pk->keyname);#endif return(pk->keyval); } }return(SUNKNOWN);}initkey(){extern struct Keylist keys[];register struct Keylist *p;register int i,j;for(i = 0 ; i<26 ; ++i) keystart[i] = NULL;for(p = keys ; p->keyname ; ++p) { j = p->keyname[0] - 'a'; if(keystart[j] == NULL) keystart[j] = p; keyend[j] = p; }}LOCAL gettok(){int havdot, havexp, havdbl;int radix, val;extern struct Punctlist puncts[];struct Punctlist *pp;extern struct Fmtlist fmts[];extern struct Dotlist dots[];struct Dotlist *pd;char *i, *j, *n1, *p; if(*nextch == (MYQUOTE)) { ++nextch; p = token; while(*nextch != MYQUOTE) *p++ = *nextch++; ++nextch; toklen = p - token; *p = '\0'; return (SHOLLERITH); }/* if(stkey == SFORMAT) { for(pf = fmts; pf->fmtchar; ++pf) { if(*nextch == pf->fmtchar) { ++nextch; if(pf->fmtval == SLPAR) ++parlev; else if(pf->fmtval == SRPAR) --parlev; return(pf->fmtval); } } if( isdigit(*nextch) ) { p = token; *p++ = *nextch++; while(nextch<=lastch && isdigit(*nextch) ) *p++ = *nextch++; toklen = p - token; *p = '\0'; if(nextch<=lastch && *nextch=='p') { ++nextch; return(SSCALE); } else return(SICON); } if( isalpha(*nextch) ) { p = token; *p++ = *nextch++; while(nextch<=lastch && (*nextch=='.' || isdigit(*nextch) || isalpha(*nextch) )) *p++ = *nextch++; toklen = p - token; *p = '\0'; return(SFIELD); } goto badchar; }/* Not a format statement */if(needkwd) { needkwd = 0; return( getkwd() ); } for(pp=puncts; pp->punchar; ++pp) if(*nextch == pp->punchar) { if( (*nextch=='*' || *nextch=='/') && nextch<lastch && nextch[1]==nextch[0]) { if(*nextch == '*') val = SPOWER; else val = SCONCAT; nextch+=2; } else { val = pp->punval; if(val==SLPAR) ++parlev; else if(val==SRPAR) --parlev; ++nextch; } return(val); } if(*nextch == '.') if(nextch >= lastch) goto badchar; else if(isdigit(nextch[1])) goto numconst; else { for(pd=dots ; (j=pd->dotname) ; ++pd) { for(i=nextch+1 ; i<=lastch ; ++i) if(*i != *j) break; else if(*i != '.') ++j; else { nextch = i+1; return(pd->dotval); } } goto badchar; } if( isalpha(*nextch) ) { p = token; *p++ = *nextch++; while(nextch<=lastch) if( isalpha(*nextch) || isdigit(*nextch) ) *p++ = *nextch++; else break; toklen = p - token; *p = '\0'; if(inioctl && nextch<=lastch && *nextch=='=') { ++nextch; return(SNAMEEQ); } if(toklen>8 && eqn(8,token,"function") && isalpha(token[8]) && nextch<lastch && nextch[0]=='(' && (nextch[1]==')' | isalpha(nextch[1])) ) { nextch -= (toklen - 8); return(SFUNCTION); } if(toklen > VL) { char buff[30]; sprintf(buff, "name %s too long, truncated to %d", token, VL); err(buff); toklen = VL; token[VL] = '\0'; } if(toklen==1 && *nextch==MYQUOTE) { switch(token[0]) { case 'z': case 'Z': case 'x': case 'X': radix = 16; break; case 'o': case 'O': radix = 8; break; case 'b': case 'B': radix = 2; break; default: err("bad bit identifier"); return(SNAME); } ++nextch; for(p = token ; *nextch!=MYQUOTE ; ) if ( *nextch == BLANK || *nextch == '\t') nextch++; else { if (isupper(*nextch)) *nextch = tolower(*nextch); if (hextoi(*p++ = *nextch++) >= radix) { err("invalid binary character"); break; } } ++nextch; toklen = p - token; return( radix==16 ? SHEXCON : (radix==8 ? SOCTCON : SBITCON) ); } return(SNAME); } if( ! isdigit(*nextch) ) goto badchar;numconst: havdot = NO; havexp = NO; havdbl = NO; for(n1 = nextch ; nextch<=lastch ; ++nextch) { if(*nextch == '.') if(havdot) break; else if(nextch+2<=lastch && isalpha(nextch[1]) && isalpha(nextch[2])) break; else havdot = YES; else if( !intonly && (*nextch=='d' || *nextch=='e') ) { p = nextch; havexp = YES; if(*nextch == 'd') havdbl = YES; if(nextch<lastch) if(nextch[1]=='+' || nextch[1]=='-') ++nextch; if( (nextch >= lastch) || ! isdigit(*++nextch) ) { nextch = p; havdbl = havexp = NO; break; } for(++nextch ; nextch<=lastch && isdigit(*nextch); ++nextch); break; } else if( ! isdigit(*nextch) ) break; } p = token; i = n1; while(i < nextch) *p++ = *i++; toklen = p - token; *p = '\0'; if(havdbl) return(SDCON); if(havdot || havexp) return( dblflag ? SDCON : SRCON); return(SICON);badchar: s[0] = *nextch++; return(SUNKNOWN);}/* KEYWORD AND SPECIAL CHARACTER TABLES*/struct Punctlist puncts[ ] = { '(', SLPAR, ')', SRPAR, '=', SEQUALS, ',', SCOMMA, '+', SPLUS, '-', SMINUS, '*', SSTAR, '/', SSLASH, '$', SCURRENCY, ':', SCOLON, 0, 0 } ;/*LOCAL struct Fmtlist fmts[ ] = { '(', SLPAR, ')', SRPAR, '/', SSLASH, ',', SCOMMA, '-', SMINUS, ':', SCOLON, 0, 0 } ;*/LOCAL struct Dotlist dots[ ] = { "and.", SAND, "or.", SOR, "not.", SNOT, "true.", STRUE, "false.", SFALSE, "eq.", SEQ, "ne.", SNE, "lt.", SLT, "le.", SLE, "gt.", SGT, "ge.", SGE, "neqv.", SNEQV, "eqv.", SEQV, 0, 0 } ;LOCAL struct Keylist keys[ ] = { { "assign", SASSIGN }, { "automatic", SAUTOMATIC, YES }, { "backspace", SBACKSPACE }, { "blockdata", SBLOCK }, { "call", SCALL }, { "character", SCHARACTER, YES }, { "close", SCLOSE, YES }, { "common", SCOMMON }, { "complex", SCOMPLEX }, { "continue", SCONTINUE }, { "data", SDATA }, { "dimension", SDIMENSION }, { "doubleprecision", SDOUBLE }, { "doublecomplex", SDCOMPLEX, YES }, { "elseif", SELSEIF, YES }, { "else", SELSE, YES }, { "endfile", SENDFILE }, { "endif", SENDIF, YES }, { "end", SEND }, { "entry", SENTRY, YES }, { "equivalence", SEQUIV }, { "external", SEXTERNAL }, { "format", SFORMAT }, { "function", SFUNCTION }, { "goto", SGOTO }, { "implicit", SIMPLICIT, YES }, { "include", SINCLUDE, YES }, { "inquire", SINQUIRE, YES }, { "intrinsic", SINTRINSIC, YES }, { "integer", SINTEGER }, { "logical", SLOGICAL },#ifdef NAMELIST { "namelist", SNAMELIST, YES },#endif { "none", SUNDEFINED, YES }, { "open", SOPEN, YES }, { "parameter", SPARAM, YES }, { "pause", SPAUSE }, { "print", SPRINT }, { "program", SPROGRAM, YES }, { "punch", SPUNCH, YES }, { "read", SREAD }, { "real", SREAL }, { "return", SRETURN }, { "rewind", SREWIND }, { "save", SSAVE, YES }, { "static", SSTATIC, YES }, { "stop", SSTOP }, { "subroutine", SSUBROUTINE }, { "then", STHEN, YES }, { "undefined", SUNDEFINED, YES }, { "write", SWRITE }, { 0, 0 } };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -