scan.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,127 行 · 第 1/2 页
C
1,127 行
default: ungetc( lxchar ,stdin); if( yytext[0] == '0' ){ /* convert in octal */ register char *cp; for( cp = yytext+1; *cp; ++cp ){ lastcon <<= 3; lastcon += *cp - '0'; } goto hexlong; } else { /* convert in decimal */ register char *cp; for( cp = yytext; *cp; ++cp ){ lastcon = lastcon * 10 + *cp - '0'; } } /* decide if it is long or not (decimal case) */ /* if it is positive and fits in 15 bits, or negative and and fits in 15 bits plus an extended sign, it is int; otherwise long */ /* if there is an l or L following, all bets are off... */ { CONSZ v; v = lastcon & ~077777L; if( v == 0 || v == ~077777L ) yylval.intval = 0; else yylval.intval = 1; } islong: /* finally, look for trailing L or l */ if( (lxchar = getchar()) == 'L' || lxchar == 'l' ) yylval.intval = 1; else ungetc( lxchar ,stdin); return( ICON ); } case A_DOT: /* look for a dot: if followed by a digit, floating point */ lxchar = getchar(); if( lxmask[lxchar+1] & LEXDIG ){ ungetc(lxchar,stdin); lxget( '.', LEXDIG ); goto getfp; } stwart = FUNNYNAME; goto onechar; case A_STR: /* string constant */ lxmatch = '"'; return( STRING ); case A_CC: /* character constant */ lxmatch = '\''; lastcon = 0; lxstr(0); yylval.intval = 0; return( ICON ); case A_BCD: { register i; int j; for( i=0; i<LXTSZ; ++i ){ if( ( j = getchar() ) == '`' ) break; if( j == '\n' ){ uerror( "newline in BCD constant" ); break; } yytext[i] = j; } yytext[i] = '\0'; if( i>6 ) uerror( "BCD constant exceeds 6 characters" );# ifdef gcos else strtob( yytext, &lastcon, i ); lastcon >>= 6*(6-i);# else uerror( "gcos BCD constant illegal" );# endif yylval.intval = 0; /* not long */ return( ICON ); } case A_SL: /* / */ if( (lxchar=getchar()) != '*' ) goto onechar; lxcom(); case A_WS: continue; case A_NL: ++lineno; lxtitle(); continue; case A_NOT: /* ! */ if( (lxchar=getchar()) != '=' ) goto onechar; yylval.intval = NE; return( EQUOP ); case A_MI: /* - */ if( (lxchar=getchar()) == '-' ){ yylval.intval = DECR; return( INCOP ); } if( lxchar != '>' ) goto onechar; stwart = FUNNYNAME; yylval.intval=STREF; return( STROP ); case A_PL: /* + */ if( (lxchar=getchar()) != '+' ) goto onechar; yylval.intval = INCR; return( INCOP ); case A_AND: /* & */ if( (lxchar=getchar()) != '&' ) goto onechar; return( yylval.intval = ANDAND ); case A_OR: /* | */ if( (lxchar=getchar()) != '|' ) goto onechar; return( yylval.intval = OROR ); case A_LT: /* < */ if( (lxchar=getchar()) == '<' ){ yylval.intval = LS; return( SHIFTOP ); } if( lxchar != '=' ) goto onechar; yylval.intval = LE; return( RELOP ); case A_GT: /* > */ if( (lxchar=getchar()) == '>' ){ yylval.intval = RS; return(SHIFTOP ); } if( lxchar != '=' ) goto onechar; yylval.intval = GE; return( RELOP ); case A_EQ: /* = */ switch( lxchar = getchar() ){ case '=': yylval.intval = EQ; return( EQUOP ); case '+': yylval.intval = ASG PLUS; break; case '-': yylval.intval = ASG MINUS; warn: if( lxmask[ (lxchar=getchar())+1] & (LEXLET|LEXDIG|LEXDOT) ){ werror( "ambiguous assignment: assignment op taken" ); } ungetc( lxchar ,stdin); break; case '*': yylval.intval = ASG MUL; goto warn; case '/': yylval.intval = ASG DIV; break; case '%': yylval.intval = ASG MOD; break; case '&': yylval.intval = ASG AND; break; case '|': yylval.intval = ASG OR; break; case '^': yylval.intval = ASG ER; break; case '<': if( (lxchar=getchar()) != '<' ){ uerror( "=<%c illegal", lxchar ); } yylval.intval = ASG LS; break; case '>': if( (lxchar=getchar()) != '>' ){ uerror( "=>%c illegal", lxchar ); } yylval.intval = ASG RS; break; default: goto onechar; } return( ASOP ); default: cerror( "yylex error, character %03o (octal)", lxchar ); } /* ordinarily, repeat here... */ cerror( "out of switch in yylex" ); } }struct lxrdope { /* dope for reserved, in alphabetical order */ char *lxrch; /* name of reserved word */ short lxract; /* reserved word action */ short lxrval; /* value to be returned */ } lxrdope[] = { "asm", AR_A, 0, "auto", AR_CL, AUTO, "break", AR_RW, BREAK, "char", AR_TY, CHAR, "case", AR_RW, CASE, "continue", AR_RW, CONTINUE, "double", AR_TY, DOUBLE, "default", AR_RW, DEFAULT, "do", AR_RW, DO, "extern", AR_CL, EXTERN, "else", AR_RW, ELSE, "enum", AR_E, ENUM, "for", AR_RW, FOR, "float", AR_TY, FLOAT, "fortran", AR_CL, FORTRAN, "goto", AR_RW, GOTO, "if", AR_RW, IF, "int", AR_TY, INT, "long", AR_TY, LONG, "return", AR_RW, RETURN, "register", AR_CL, REGISTER, "switch", AR_RW, SWITCH, "struct", AR_S, 0, "sizeof", AR_RW, SIZEOF, "short", AR_TY, SHORT, "static", AR_CL, STATIC, "typedef", AR_CL, TYPEDEF, "unsigned", AR_TY, UNSIGNED, "union", AR_U, 0, "void", AR_TY, UNDEF, /* tymerge adds FTN */ "while", AR_RW, WHILE, "", 0, 0, /* to stop the search */ };lxres() { /* check to see of yytext is reserved; if so, /* do the appropriate action and return */ /* otherwise, return -1 */ register c, ch; register struct lxrdope *p; ch = yytext[0]; if( !islower(ch) ) return( -1 ); switch( ch ){ case 'a': c=0; break; case 'b': c=2; break; case 'c': c=3; break; case 'd': c=6; break; case 'e': c=9; break; case 'f': c=12; break; case 'g': c=15; break; case 'i': c=16; break; case 'l': c=18; break; case 'r': c=19; break; case 's': c=21; break; case 't': c=26; break; case 'u': c=27; break; case 'v': c=29; break; case 'w': c=30; break; default: return( -1 ); } for( p= lxrdope+c; p->lxrch[0] == ch; ++p ){ if( !strcmp( yytext, p->lxrch ) ){ /* match */ switch( p->lxract ){ case AR_TY: /* type word */ stwart = instruct; yylval.nodep = mkty( (TWORD)p->lxrval, 0, p->lxrval ); return( TYPE ); case AR_RW: /* ordinary reserved word */ return( yylval.intval = p->lxrval ); case AR_CL: /* class word */ yylval.intval = p->lxrval; return( CLASS ); case AR_S: /* struct */ stwart = INSTRUCT|SEENAME|TAGNAME; yylval.intval = INSTRUCT; return( STRUCT ); case AR_U: /* union */ stwart = INUNION|SEENAME|TAGNAME; yylval.intval = INUNION; return( STRUCT ); case AR_E: /* enums */ stwart = SEENAME|TAGNAME; return( yylval.intval = ENUM ); case AR_A: /* asm */ asm_esc = 1; /* warn the world! */ lxget( ' ', LEXWS ); if( getchar() != '(' ) goto badasm; lxget( ' ', LEXWS ); if( getchar() != '"' ) goto badasm;# ifndef ONEPASS# ifndef LINT putchar(')');# endif# endif while( (c=getchar()) != '"' ){ if( c=='\n' || c==EOF ) goto badasm;# ifndef LINT putchar(c);# endif } lxget( ' ', LEXWS ); if( getchar() != ')' ) goto badasm;# ifndef LINT putchar('\n');# endif return( 0 ); badasm: uerror( "bad asm construction" ); return( 0 ); default: cerror( "bad AR_?? action" ); } } } return( -1 ); }extern int labelno;lxtitle(){ /* called after a newline; set linenumber and file name */ register c, val; register char *cp, *cq; for(;;){ /* might be several such lines in a row */ if( (c=getchar()) != '#' ){ if( c != EOF ) ungetc(c,stdin);/*#ifndef LINT if ( lastloc != PROG) return; cp = ftitle; cq = ititle; while ( *cp ) if (*cp++ != *cq++) return; if ( *cq ) return; psline();#endif CXREF */ return; } lxget( ' ', LEXWS ); val = 0; for( c=getchar(); isdigit(c); c=getchar() ){ val = val*10+ c - '0'; } ungetc( c, stdin ); lineno = val; lxget( ' ', LEXWS ); if( (c=getchar()) != '\n' ){ for( cp=ftitle; c!='\n'; c=getchar(),++cp ){ *cp = c; } *cp = '\0'; fprintf(outfp,"%s\n",ftitle); /* CXREF *//*#ifndef LINT if (ititle[0] == '\0') { cp = ftitle; cq = ititle; while ( *cp ) *cq++ = *cp++; *cq = '\0'; *--cq = '\0';#ifndef FLEXNAMES for ( cp = ititle+1; *(cp-1); cp += 8 ) { pstab(cp, N_SO); if (gdebug) printf("0,0,LL%d\n", labelno); }#else pstab(ititle+1, N_SO); if (gdebug) printf("0,0,LL%d\n", labelno); #endif *cq = '"'; printf("LL%d:\n", labelno++); }#endif CXREF */ } } }#ifdef FLEXNAMES#define NSAVETAB 4096char *savetab;int saveleft;char *savestr(cp) register char *cp;{ register int len; len = strlen(cp) + 1; if (len > saveleft) { saveleft = NSAVETAB; if (len > saveleft) saveleft = len; savetab = (char *)malloc(saveleft); if (savetab == 0) cerror("Ran out of memory (savestr)"); } strncpy(savetab, cp, len); cp = savetab; savetab += len; saveleft -= len; return (cp);}/* * The definition for the segmented hash tables. */#define MAXHASH 20#define HASHINC 1013struct ht { char **ht_low; char **ht_high; int ht_used;} htab[MAXHASH];char *hash(s) char *s;{ register char **h; register i; register char *cp; struct ht *htp; int sh; /* * The hash function is a modular hash of * the sum of the characters with the sum * doubled before each successive character * is added. */ cp = s; i = 0; while (*cp) i = i*2 + *cp++; sh = (i&077777) % HASHINC; cp = s; /* * There are as many as MAXHASH active * hash tables at any given point in time. * The search starts with the first table * and continues through the active tables * as necessary. */ for (htp = htab; htp < &htab[MAXHASH]; htp++) { if (htp->ht_low == 0) { register char **hp = (char **) calloc(sizeof (char **), HASHINC); if (hp == 0) cerror("ran out of memory (hash)"); htp->ht_low = hp; htp->ht_high = htp->ht_low + HASHINC; } h = htp->ht_low + sh; /* * quadratic rehash increment * starts at 1 and incremented * by two each rehash. */ i = 1; do { if (*h == 0) { if (htp->ht_used > (HASHINC * 3)/4) break; htp->ht_used++; *h = savestr(cp); return (*h); } if (**h == *cp && strcmp(*h, cp) == 0) return (*h); h += i; i += 2; if (h >= htp->ht_high) h -= HASHINC; } while (i < HASHINC); } cerror("ran out of hash tables");}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?