lcc源代码解析之lex.c

来源:互联网 发布:2016年双十一销售数据 编辑:程序博客网 时间:2024/06/05 13:31

有了前面的铺垫,终于可以上正餐了,本节解析编译器的一个重要组件:词法分析器,即lcc的lex.c文件。

lcc出于对效率的考虑,并没有使用类似nfa思想的自动词法解析生成工具来生成,而是采用了手写的lex。

具体代码如下:

#include "c.h"#include <float.h>#include <errno.h>static char rcsid[] = "$Id: lex.c,v 1.1 2002/08/28 23:12:44 drh Exp $";#define MAXTOKEN 32/*字符的6大类别,空格/换行/字母/数字/16进制/其他*/enum { BLANK=01,  NEWLINE=02, LETTER=04,       DIGIT=010, HEX=020,    OTHER=040 };/*字符掩码,将字符归为六类中的一类或多类,如abcdef可以作为字母存在,也是作为16进制字符存在*/static unsigned char map[256] = { /* 000 nul */0,   /* 001 soh */0,   /* 002 stx */0,   /* 003 etx */0,   /* 004 eot */0,   /* 005 enq */0,   /* 006 ack */0,   /* 007 bel */0,   /* 010 bs  */0,   /* 011 ht  */BLANK,   /* 012 nl  */NEWLINE,   /* 013 vt  */BLANK,   /* 014 ff  */BLANK,   /* 015 cr  */0,   /* 016 so  */0,   /* 017 si  */0,   /* 020 dle */0,   /* 021 dc1 */0,   /* 022 dc2 */0,   /* 023 dc3 */0,   /* 024 dc4 */0,   /* 025 nak */0,   /* 026 syn */0,   /* 027 etb */0,   /* 030 can */0,   /* 031 em  */0,   /* 032 sub */0,   /* 033 esc */0,   /* 034 fs  */0,   /* 035 gs  */0,   /* 036 rs  */0,   /* 037 us  */0,   /* 040 sp  */BLANK,   /* 041 !   */OTHER,   /* 042 "   */OTHER,   /* 043 #   */OTHER,   /* 044 $   */0,   /* 045 %   */OTHER,   /* 046 &   */OTHER,   /* 047 '   */OTHER,   /* 050 (   */OTHER,   /* 051 )   */OTHER,   /* 052 *   */OTHER,   /* 053 +   */OTHER,   /* 054 ,   */OTHER,   /* 055 -   */OTHER,   /* 056 .   */OTHER,   /* 057 /   */OTHER,   /* 060 0   */DIGIT,   /* 061 1   */DIGIT,   /* 062 2   */DIGIT,   /* 063 3   */DIGIT,   /* 064 4   */DIGIT,   /* 065 5   */DIGIT,   /* 066 6   */DIGIT,   /* 067 7   */DIGIT,   /* 070 8   */DIGIT,   /* 071 9   */DIGIT,   /* 072 :   */OTHER,   /* 073 ;   */OTHER,   /* 074 <   */OTHER,   /* 075 =   */OTHER,   /* 076 >   */OTHER,   /* 077 ?   */OTHER,   /* 100 @   */0,   /* 101 A   */LETTER|HEX,   /* 102 B   */LETTER|HEX,   /* 103 C   */LETTER|HEX,   /* 104 D   */LETTER|HEX,   /* 105 E   */LETTER|HEX,   /* 106 F   */LETTER|HEX,   /* 107 G   */LETTER,   /* 110 H   */LETTER,   /* 111 I   */LETTER,   /* 112 J   */LETTER,   /* 113 K   */LETTER,   /* 114 L   */LETTER,   /* 115 M   */LETTER,   /* 116 N   */LETTER,   /* 117 O   */LETTER,   /* 120 P   */LETTER,   /* 121 Q   */LETTER,   /* 122 R   */LETTER,   /* 123 S   */LETTER,   /* 124 T   */LETTER,   /* 125 U   */LETTER,   /* 126 V   */LETTER,   /* 127 W   */LETTER,   /* 130 X   */LETTER,   /* 131 Y   */LETTER,   /* 132 Z   */LETTER,   /* 133 [   */OTHER,   /* 134 \   */OTHER,   /* 135 ]   */OTHER,   /* 136 ^   */OTHER,   /* 137 _   */LETTER,   /* 140 `   */0,   /* 141 a   */LETTER|HEX,   /* 142 b   */LETTER|HEX,   /* 143 c   */LETTER|HEX,   /* 144 d   */LETTER|HEX,   /* 145 e   */LETTER|HEX,   /* 146 f   */LETTER|HEX,   /* 147 g   */LETTER,   /* 150 h   */LETTER,   /* 151 i   */LETTER,   /* 152 j   */LETTER,   /* 153 k   */LETTER,   /* 154 l   */LETTER,   /* 155 m   */LETTER,   /* 156 n   */LETTER,   /* 157 o   */LETTER,   /* 160 p   */LETTER,   /* 161 q   */LETTER,   /* 162 r   */LETTER,   /* 163 s   */LETTER,   /* 164 t   */LETTER,   /* 165 u   */LETTER,   /* 166 v   */LETTER,   /* 167 w   */LETTER,   /* 170 x   */LETTER,   /* 171 y   */LETTER,   /* 172 z   */LETTER,   /* 173 {   */OTHER,   /* 174 |   */OTHER,   /* 175 }   */OTHER,   /* 176 ~   */OTHER, };static struct symbol tval;static char cbuf[BUFSIZE+1];static unsigned int wcbuf[BUFSIZE+1];Coordinate src;/* current source coordinate */int t;char *token;/* current token */Symbol tsym;/* symbol table entry for current token */static void *cput(int c, void *cl);static void *wcput(int c, void *cl);static void *scon(int q, void *put(int c, void *cl), void *cl);static int backslash(int q);static Symbol fcon(void);static Symbol icon(unsigned long, int, int);static void ppnumber(char *);//这个文件主要作为一个词法分析器的功能存在。/**@brief:获取词素,返回给语法分析器,*通过词素的第一个字符将词素归类,并通过后面的字符形成完整的词素*/int gettok(void) {//没有条件for循环,就是想识别出一个记号才返回for (;;) {//获取当前输入缓冲区的指针register unsigned char *rcp = cp;//去掉空白字符while (map[*rcp]&BLANK)rcp++;//判断输入缓冲区剩余的字符小于最大的记号时,就重新从文件里获取源程序,填充到缓冲区里。if (limit - rcp < MAXTOKEN) {cp = rcp;fillbuf();//重新读取rcp = cp;}//记录前记号的开始位置,以便出错时可以定位出错的源程序位置src.file = file;src.x = (char *)rcp - line;//列数src.y = lineno;//处理识别一个字符的移动指针,让它指向下一个字符cp = rcp + 1;//根据第一个字符来进行识别处理,它是使用一个switch来实的switch (*rcp++) {//识别C程序的注释,并把这些注释删除case '/': if (*rcp == '*') {  int c = 0;  for (rcp++; *rcp != '/' || c != '*'; )  if (map[*rcp]&NEWLINE) {  if (rcp < limit)  c = *rcp;  cp = rcp + 1;  nextline();  rcp = cp;  if (rcp == limit)  break;  } else  c = *rcp++;  if (rcp < limit)  rcp++;  else  error("unclosed comment\n");  cp = rcp;  continue;  }  return '/';  case '<':if (*rcp == '=') return cp++, LEQ;if (*rcp == '<') return cp++, LSHIFT;return '<';case '>':if (*rcp == '=') return cp++, GEQ;if (*rcp == '>') return cp++, RSHIFT;return '>';case '-':if (*rcp == '>') return cp++, DEREF;if (*rcp == '-') return cp++, DECR;return '-';case '=': return *rcp == '=' ? cp++, EQL    : '=';case '!': return *rcp == '=' ? cp++, NEQ    : '!';case '|': return *rcp == '|' ? cp++, OROR   : '|';case '&': return *rcp == '&' ? cp++, ANDAND : '&';case '+': return *rcp == '+' ? cp++, INCR   : '+';case ';': case ',': case ':':case '*': case '~': case '%': case '^': case '?':case '[': case ']': case '{': case '}': case '(': case ')': return rcp[-1];case '\n': case '\v': case '\r': case '\f':nextline();if (cp == limit) {tsym = NULL;return EOI;}continue;case 'i':if (rcp[0] == 'f'&& !(map[rcp[1]]&(DIGIT|LETTER))) {cp = rcp + 1;return IF;}if (rcp[0] == 'n'&&  rcp[1] == 't'&& !(map[rcp[2]]&(DIGIT|LETTER))) {cp = rcp + 2;tsym = inttype->u.sym;return INT;}goto id;//去掉关键之if,int以外的其他以i开头的词素作为id处理case 'h': case 'j': case 'k': case 'm': case 'n': case 'o':case 'p': case 'q': case 'x': case 'y': case 'z':case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':case 'G': case 'H': case 'I': case 'J': case 'K':case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':case 'Y': case 'Z'://以上这些字母开头的不会产生关键字,所以直接作为id处理,其他如abede都有可能产生关键字,在下面的case里处理id://保证缓冲区有足够的字符if (limit - rcp < MAXLINE) {cp = rcp - 1;fillbuf();rcp = ++cp;}assert(cp == rcp);token = (char *)rcp - 1;while (map[*rcp]&(DIGIT|LETTER))rcp++;token = stringn(token, (char *)rcp - token);tsym = lookup(token, identifiers);//查找这个ID是否已经声明,如果没有声明返回是空指令给tsymcp = rcp;return ID;/*数字的识别*/case '0': case '1': case '2': case '3': case '4':case '5': case '6': case '7': case '8': case '9': {unsigned long n = 0;if (limit - rcp < MAXLINE) {cp = rcp - 1;fillbuf();rcp = ++cp;}assert(cp == rcp);token = (char *)rcp - 1;//16进制数的识别if (*token == '0' && (*rcp == 'x' || *rcp == 'X')) {int d, overflow = 0;while (*++rcp) {if (map[*rcp]&DIGIT)d = *rcp - '0';else if (*rcp >= 'a' && *rcp <= 'f')d = *rcp - 'a' + 10;else if (*rcp >= 'A' && *rcp <= 'F')d = *rcp - 'A' + 10;elsebreak;if (n&~(~0UL >> 4))overflow = 1;elsen = (n<<4) + d;}if ((char *)rcp - token <= 2)error("invalid hexadecimal constant `%S'\n", token, (char *)rcp-token);cp = rcp;tsym = icon(n, overflow, 16);}//8进制数的识别else if (*token == '0') {int err = 0, overflow = 0;for ( ; map[*rcp]&DIGIT; rcp++) {if (*rcp == '8' || *rcp == '9')err = 1;if (n&~(~0UL >> 3))overflow = 1;elsen = (n<<3) + (*rcp - '0');}if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {cp = rcp;tsym = fcon();return FCON;}cp = rcp;tsym = icon(n, overflow, 8);if (err)error("invalid octal constant `%S'\n", token, (char*)cp-token);}//10进制else {int overflow = 0;for (n = *token - '0'; map[*rcp]&DIGIT; ) {int d = *rcp++ - '0';if (n > (ULONG_MAX - d)/10)overflow = 1;elsen = 10*n + d;}if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {cp = rcp;tsym = fcon();return FCON;}cp = rcp;tsym = icon(n, overflow, 10);}return ICON;}case '.':if (rcp[0] == '.' && rcp[1] == '.') {cp += 2;return ELLIPSIS;}if ((map[*rcp]&DIGIT) == 0)return '.';if (limit - rcp < MAXLINE) {cp = rcp - 1;fillbuf();rcp = ++cp;}assert(cp == rcp);cp = rcp - 1;token = (char *)cp;tsym = fcon();return FCON;case 'L':if (*rcp == '\'') {unsigned int *s = scon(*cp, wcput, wcbuf);if (s - wcbuf > 2)warning("excess characters in wide-character literal ignored\n");tval.type = widechar;tval.u.c.v.u = wcbuf[0];tsym = &tval;return ICON;} else if (*rcp == '"') {unsigned int *s = scon(*cp, wcput, wcbuf);tval.type = array(widechar, s - wcbuf, 0);tval.u.c.v.p = wcbuf;tsym = &tval;return SCON;} elsegoto id;case '\'': {char *s = scon(*--cp, cput, cbuf);if (s - cbuf > 2)warning("excess characters in multibyte character literal ignored\n");tval.type = inttype;if (chartype->op == INT)tval.u.c.v.i = extend(cbuf[0], chartype);elsetval.u.c.v.i = cbuf[0]&0xFF;tsym = &tval;return ICON;}case '"': {char *s = scon(*--cp, cput, cbuf);tval.type = array(chartype, s - cbuf, 0);tval.u.c.v.p = cbuf;tsym = &tval;return SCON;}//以下为关键字的处理case 'a':if (rcp[0] == 'u'&&  rcp[1] == 't'&&  rcp[2] == 'o'&& !(map[rcp[3]]&(DIGIT|LETTER))) {cp = rcp + 3;return AUTO;}goto id;case 'b':if (rcp[0] == 'r'&&  rcp[1] == 'e'&&  rcp[2] == 'a'&&  rcp[3] == 'k'&& !(map[rcp[4]]&(DIGIT|LETTER))) {cp = rcp + 4;return BREAK;}goto id;case 'c':if (rcp[0] == 'a'&&  rcp[1] == 's'&&  rcp[2] == 'e'&& !(map[rcp[3]]&(DIGIT|LETTER))) {cp = rcp + 3;return CASE;}if (rcp[0] == 'h'&&  rcp[1] == 'a'&&  rcp[2] == 'r'&& !(map[rcp[3]]&(DIGIT|LETTER))) {cp = rcp + 3;tsym = chartype->u.sym;return CHAR;}if (rcp[0] == 'o'&&  rcp[1] == 'n'&&  rcp[2] == 's'&&  rcp[3] == 't'&& !(map[rcp[4]]&(DIGIT|LETTER))) {cp = rcp + 4;return CONST;}if (rcp[0] == 'o'&&  rcp[1] == 'n'&&  rcp[2] == 't'&&  rcp[3] == 'i'&&  rcp[4] == 'n'&&  rcp[5] == 'u'&&  rcp[6] == 'e'&& !(map[rcp[7]]&(DIGIT|LETTER))) {cp = rcp + 7;return CONTINUE;}goto id;case 'd':if (rcp[0] == 'e'&&  rcp[1] == 'f'&&  rcp[2] == 'a'&&  rcp[3] == 'u'&&  rcp[4] == 'l'&&  rcp[5] == 't'&& !(map[rcp[6]]&(DIGIT|LETTER))) {cp = rcp + 6;return DEFAULT;}if (rcp[0] == 'o'&&  rcp[1] == 'u'&&  rcp[2] == 'b'&&  rcp[3] == 'l'&&  rcp[4] == 'e'&& !(map[rcp[5]]&(DIGIT|LETTER))) {cp = rcp + 5;tsym = doubletype->u.sym;return DOUBLE;}if (rcp[0] == 'o'&& !(map[rcp[1]]&(DIGIT|LETTER))) {cp = rcp + 1;return DO;}goto id;case 'e':if (rcp[0] == 'l'&&  rcp[1] == 's'&&  rcp[2] == 'e'&& !(map[rcp[3]]&(DIGIT|LETTER))) {cp = rcp + 3;return ELSE;}if (rcp[0] == 'n'&&  rcp[1] == 'u'&&  rcp[2] == 'm'&& !(map[rcp[3]]&(DIGIT|LETTER))) {cp = rcp + 3;return ENUM;}if (rcp[0] == 'x'&&  rcp[1] == 't'&&  rcp[2] == 'e'&&  rcp[3] == 'r'&&  rcp[4] == 'n'&& !(map[rcp[5]]&(DIGIT|LETTER))) {cp = rcp + 5;return EXTERN;}goto id;case 'f':if (rcp[0] == 'l'&&  rcp[1] == 'o'&&  rcp[2] == 'a'&&  rcp[3] == 't'&& !(map[rcp[4]]&(DIGIT|LETTER))) {cp = rcp + 4;tsym = floattype->u.sym;return FLOAT;}if (rcp[0] == 'o'&&  rcp[1] == 'r'&& !(map[rcp[2]]&(DIGIT|LETTER))) {cp = rcp + 2;return FOR;}goto id;case 'g':if (rcp[0] == 'o'&&  rcp[1] == 't'&&  rcp[2] == 'o'&& !(map[rcp[3]]&(DIGIT|LETTER))) {cp = rcp + 3;return GOTO;}goto id;case 'l':if (rcp[0] == 'o'&&  rcp[1] == 'n'&&  rcp[2] == 'g'&& !(map[rcp[3]]&(DIGIT|LETTER))) {cp = rcp + 3;return LONG;}goto id;case 'r':if (rcp[0] == 'e'&&  rcp[1] == 'g'&&  rcp[2] == 'i'&&  rcp[3] == 's'&&  rcp[4] == 't'&&  rcp[5] == 'e'&&  rcp[6] == 'r'&& !(map[rcp[7]]&(DIGIT|LETTER))) {cp = rcp + 7;return REGISTER;}if (rcp[0] == 'e'&&  rcp[1] == 't'&&  rcp[2] == 'u'&&  rcp[3] == 'r'&&  rcp[4] == 'n'&& !(map[rcp[5]]&(DIGIT|LETTER))) {cp = rcp + 5;return RETURN;}goto id;case 's':if (rcp[0] == 'h'&&  rcp[1] == 'o'&&  rcp[2] == 'r'&&  rcp[3] == 't'&& !(map[rcp[4]]&(DIGIT|LETTER))) {cp = rcp + 4;return SHORT;}if (rcp[0] == 'i'&&  rcp[1] == 'g'&&  rcp[2] == 'n'&&  rcp[3] == 'e'&&  rcp[4] == 'd'&& !(map[rcp[5]]&(DIGIT|LETTER))) {cp = rcp + 5;return SIGNED;}if (rcp[0] == 'i'&&  rcp[1] == 'z'&&  rcp[2] == 'e'&&  rcp[3] == 'o'&&  rcp[4] == 'f'&& !(map[rcp[5]]&(DIGIT|LETTER))) {cp = rcp + 5;return SIZEOF;}if (rcp[0] == 't'&&  rcp[1] == 'a'&&  rcp[2] == 't'&&  rcp[3] == 'i'&&  rcp[4] == 'c'&& !(map[rcp[5]]&(DIGIT|LETTER))) {cp = rcp + 5;return STATIC;}if (rcp[0] == 't'&&  rcp[1] == 'r'&&  rcp[2] == 'u'&&  rcp[3] == 'c'&&  rcp[4] == 't'&& !(map[rcp[5]]&(DIGIT|LETTER))) {cp = rcp + 5;return STRUCT;}if (rcp[0] == 'w'&&  rcp[1] == 'i'&&  rcp[2] == 't'&&  rcp[3] == 'c'&&  rcp[4] == 'h'&& !(map[rcp[5]]&(DIGIT|LETTER))) {cp = rcp + 5;return SWITCH;}goto id;case 't':if (rcp[0] == 'y'&&  rcp[1] == 'p'&&  rcp[2] == 'e'&&  rcp[3] == 'd'&&  rcp[4] == 'e'&&  rcp[5] == 'f'&& !(map[rcp[6]]&(DIGIT|LETTER))) {cp = rcp + 6;return TYPEDEF;}goto id;case 'u':if (rcp[0] == 'n'&&  rcp[1] == 'i'&&  rcp[2] == 'o'&&  rcp[3] == 'n'&& !(map[rcp[4]]&(DIGIT|LETTER))) {cp = rcp + 4;return UNION;}if (rcp[0] == 'n'&&  rcp[1] == 's'&&  rcp[2] == 'i'&&  rcp[3] == 'g'&&  rcp[4] == 'n'&&  rcp[5] == 'e'&&  rcp[6] == 'd'&& !(map[rcp[7]]&(DIGIT|LETTER))) {cp = rcp + 7;return UNSIGNED;}goto id;case 'v':if (rcp[0] == 'o'&&  rcp[1] == 'i'&&  rcp[2] == 'd'&& !(map[rcp[3]]&(DIGIT|LETTER))) {cp = rcp + 3;tsym = voidtype->u.sym;return VOID;}if (rcp[0] == 'o'&&  rcp[1] == 'l'&&  rcp[2] == 'a'&&  rcp[3] == 't'&&  rcp[4] == 'i'&&  rcp[5] == 'l'&&  rcp[6] == 'e'&& !(map[rcp[7]]&(DIGIT|LETTER))) {cp = rcp + 7;return VOLATILE;}goto id;case 'w':if (rcp[0] == 'h'&&  rcp[1] == 'i'&&  rcp[2] == 'l'&&  rcp[3] == 'e'&& !(map[rcp[4]]&(DIGIT|LETTER))) {cp = rcp + 4;return WHILE;}goto id;case '_':if (rcp[0] == '_'&&  rcp[1] == 't'&&  rcp[2] == 'y'&&  rcp[3] == 'p'&&  rcp[4] == 'e'&&  rcp[5] == 'c'&&  rcp[6] == 'o'&&  rcp[7] == 'd'&&  rcp[8] == 'e'&& !(map[rcp[9]]&(DIGIT|LETTER))) {cp = rcp + 9;return TYPECODE;}if (rcp[0] == '_'&&  rcp[1] == 'f'&&  rcp[2] == 'i'&&  rcp[3] == 'r'&&  rcp[4] == 's'&&  rcp[5] == 't'&&  rcp[6] == 'a'&&  rcp[7] == 'r'&&  rcp[8] == 'g'&& !(map[rcp[9]]&(DIGIT|LETTER))) {cp = rcp + 9;return FIRSTARG;}goto id;default:if ((map[cp[-1]]&BLANK) == 0)if (cp[-1] < ' ' || cp[-1] >= 0177)error("illegal character `\\0%o'\n", cp[-1]);elseerror("illegal character `%c'\n", cp[-1]);}}}//处理整形数据的后缀,如UuLl等static Symbol icon(unsigned long n, int overflow, int base) {if ((*cp=='u'||*cp=='U') && (cp[1]=='l'||cp[1]=='L')||  (*cp=='l'||*cp=='L') && (cp[1]=='u'||cp[1]=='U')) {tval.type = unsignedlong;cp += 2;} else if (*cp == 'u' || *cp == 'U') {if (overflow || n > unsignedtype->u.sym->u.limits.max.i)tval.type = unsignedlong;elsetval.type = unsignedtype;cp += 1;} else if (*cp == 'l' || *cp == 'L') {if (overflow || n > longtype->u.sym->u.limits.max.i)tval.type = unsignedlong;elsetval.type = longtype;cp += 1;} else if (overflow || n > longtype->u.sym->u.limits.max.i)tval.type = unsignedlong;else if (n > inttype->u.sym->u.limits.max.i)tval.type = longtype;else if (base != 10 && n > inttype->u.sym->u.limits.max.i)tval.type = unsignedtype;elsetval.type = inttype;switch (tval.type->op) {case INT:if (overflow || n > tval.type->u.sym->u.limits.max.i) {warning("overflow in constant `%S'\n", token,(char*)cp - token);tval.u.c.v.i = tval.type->u.sym->u.limits.max.i;} elsetval.u.c.v.i = n;break;case UNSIGNED:if (overflow || n > tval.type->u.sym->u.limits.max.u) {warning("overflow in constant `%S'\n", token,(char*)cp - token);tval.u.c.v.u = tval.type->u.sym->u.limits.max.u;} elsetval.u.c.v.u = n;break;default: assert(0);}ppnumber("integer");return &tval;}static void ppnumber(char *which) {unsigned char *rcp = cp--;for ( ; (map[*cp]&(DIGIT|LETTER)) || *cp == '.'; cp++)if ((cp[0] == 'E' || cp[0] == 'e')&&  (cp[1] == '-' || cp[1] == '+'))cp++;if (cp > rcp)error("`%S' is a preprocessing number but an invalid %s constant\n", token,(char*)cp-token, which);}//处理浮点型数据的后缀static Symbol fcon(void) {if (*cp == '.')docp++;while (map[*cp]&DIGIT);if (*cp == 'e' || *cp == 'E') {if (*++cp == '-' || *cp == '+')cp++;if (map[*cp]&DIGIT)docp++;while (map[*cp]&DIGIT);elseerror("invalid floating constant `%S'\n", token,(char*)cp - token);}errno = 0;tval.u.c.v.d = strtod(token, NULL);if (errno == ERANGE)warning("overflow in floating constant `%S'\n", token,(char*)cp - token);if (*cp == 'f' || *cp == 'F') {++cp;if (tval.u.c.v.d > floattype->u.sym->u.limits.max.d)warning("overflow in floating constant `%S'\n", token,(char*)cp - token);tval.type = floattype;} else if (*cp == 'l' || *cp == 'L') {cp++;tval.type = longdouble;} else {if (tval.u.c.v.d > doubletype->u.sym->u.limits.max.d)warning("overflow in floating constant `%S'\n", token,(char*)cp - token);tval.type = doubletype;}ppnumber("floating");return &tval;}static void *cput(int c, void *cl) {char *s = cl;if (c < 0 || c > 255)warning("overflow in escape sequence with resulting value `%d'\n", c);*s++ = c;return s;}static void *wcput(int c, void *cl) {unsigned int *s = cl;*s++ = c;return s;}/*字符常量的处理*/static void *scon(int q, void *put(int c, void *cl), void *cl) {int n = 0, nbad = 0;do {cp++;while (*cp != q) {//非双反斜杠或者""int c;if (map[*cp]&NEWLINE) {if (cp < limit)break;cp++;nextline();if (cp == limit)break;continue;}c = *cp++;if (c == '\\') {if (map[*cp]&NEWLINE) {if (cp++ < limit)continue;nextline();}if (limit - cp < MAXTOKEN)fillbuf();c = backslash(q);} else if (c < 0 || c > 255 || map[c] == 0)nbad++;if (n++ < BUFSIZE)cl = put(c, cl);}if (*cp == q)cp++;elseerror("missing %c\n", q);if (q == '"' && put == wcput && getchr() == 'L') {if (limit - cp < 2)fillbuf();if (cp[1] == '"')cp++;}} while (q == '"' && getchr() == '"');cl = put(0, cl);if (n >= BUFSIZE)error("%s literal too long\n", q == '"' ? "string" : "character");if (Aflag >= 2 && q == '"' && n > 509)warning("more than 509 characters in a string literal\n");if (Aflag >= 2 && nbad > 0)warning("%s literal contains non-portable characters\n",q == '"' ? "string" : "character");return cl;}int getchr(void) {for (;;) {while (map[*cp]&BLANK)cp++;if (!(map[*cp]&NEWLINE))return *cp;cp++;nextline();if (cp == limit)return EOI;}}static int backslash(int q) {unsigned int c;switch (*cp++) {case 'a': return 7;case 'b': return '\b';case 'f': return '\f';case 'n': return '\n';case 'r': return '\r';case 't': return '\t';case 'v': return '\v';case '\'': case '"': case '\\': case '\?': break;case 'x': {int overflow = 0;if ((map[*cp]&(DIGIT|HEX)) == 0) {if (*cp < ' ' || *cp == 0177)error("ill-formed hexadecimal escape sequence\n");elseerror("ill-formed hexadecimal escape sequence `\\x%c'\n", *cp);if (*cp != q)cp++;return 0;}for (c = 0; map[*cp]&(DIGIT|HEX); cp++) {if (c >> (8*widechar->size - 4))overflow = 1;if (map[*cp]&DIGIT)c = (c<<4) + *cp - '0';elsec = (c<<4) + (*cp&~040) - 'A' + 10;}if (overflow)warning("overflow in hexadecimal escape sequence\n");return c&ones(8*widechar->size);}case '0': case '1': case '2': case '3':case '4': case '5': case '6': case '7':c = *(cp-1) - '0';if (*cp >= '0' && *cp <= '7') {c = (c<<3) + *cp++ - '0';if (*cp >= '0' && *cp <= '7')c = (c<<3) + *cp++ - '0';}return c;default:if (cp[-1] < ' ' || cp[-1] >= 0177)warning("unrecognized character escape sequence\n");elsewarning("unrecognized character escape sequence `\\%c'\n", cp[-1]);}return cp[-1];}


0 0
原创粉丝点击