📄 scan.c
字号:
switch( lxchar=getchar() ){ case 'x': case 'X': if( yytext[0] != '0' && !yytext[1] ) uerror( "illegal hex constant" ); lxmore( lxchar, LEXHEX ); /* convert the value */ { register char *cp; for( cp = yytext+2; *cp; ++cp ){ /* this code won't work for all wild character sets, but seems ok for ascii and ebcdic */ lastcon <<= 4; if( isdigit( *cp ) ) lastcon += *cp-'0'; else if( isupper( *cp ) ) lastcon += *cp - 'A'+ 10; else lastcon += *cp - 'a'+ 10; } } hexlong: /* criterion for longness for hex and octal constants is that it fit within 0177777 */ if( lastcon & ~0177777L ) yylval.intval = 1; else yylval.intval = 0; goto islong; case '.': lxmore( lxchar, LEXDIG ); getfp: if( (lxchar=getchar()) == 'e' || lxchar == 'E' ){ /* exponent */ case 'e': case 'E': if( (lxchar=getchar()) == '+' || lxchar == '-' ){ *lxgcp++ = 'e'; } else { ungetc(lxchar,stdin); lxchar = 'e'; } lxmore( lxchar, LEXDIG ); /* now have the whole thing... */ } else { /* no exponent */ ungetc( lxchar ,stdin); } return( isitfloat( yytext ) ); 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, "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 'w': c=29; 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; yylval.intval = INSTRUCT; return( STRUCT ); case AR_U: /* union */ stwart = INUNION|SEENAME; yylval.intval = INUNION; return( STRUCT ); case AR_E: /* enums */ stwart = SEENAME; return( yylval.intval = ENUM ); case AR_A: /* asm */ 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 ); }lxtitle(){ /* called after a newline; set linenumber and file name */ register c, val; register char *cp; for(;;){ /* might be several such lines in a row */ if( (c=getchar()) != '#' ){ if( c != EOF ) ungetc(c,stdin); 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'; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -