📄 c-parse.y
字号:
if (token == CONSTANT && TREE_CODE (yylval.ttype) == INTEGER_CST) { if (TREE_INT_CST_LOW (yylval.ttype) == 1) { struct file_stack *p = (struct file_stack *) xmalloc (sizeof (struct file_stack)); input_file_stack->line = old_lineno; p->next = input_file_stack; p->name = input_filename; input_file_stack = p; input_file_stack_tick++; } else if (input_file_stack->next) { struct file_stack *p = input_file_stack; input_file_stack = p->next; free (p); input_file_stack_tick++; } else error ("#-lines for entering and leaving files don't match"); } } else error ("invalid #-line"); /* skip the rest of this line. */ skipline: if (c == '\n') return c; while ((c = getc (finput)) != EOF && c != '\n'); return c;}#define isalnum(char) ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9'))#define isdigit(char) (char >= '0' && char <= '9')#define ENDFILE -1 /* token that represents end-of-file */static intreadescape (){ register int c = getc (finput); register int count, code; int firstdig; switch (c) { case 'x': code = 0; count = 0; while (1) { c = getc (finput); if (!(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F') && !(c >= '0' && c <= '9')) { ungetc (c, finput); break; } code *= 16; if (c >= 'a' && c <= 'f') code += c - 'a' + 10; if (c >= 'A' && c <= 'F') code += c - 'A' + 10; if (c >= '0' && c <= '9') code += c - '0'; if (count == 0) firstdig = code; count++; } if (count == 0) error ("\\x used with no following hex digits"); else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) || (count > 1 && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4)) <= firstdig))) warning ("hex escape out of range"); return code; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': code = 0; count = 0; while ((c <= '7') && (c >= '0') && (count++ < 3)) { code = (code * 8) + (c - '0'); c = getc (finput); } ungetc (c, finput); return code; case '\\': case '\'': case '"': return c; case '\n': lineno++; return -1; case 'n': return TARGET_NEWLINE; case 't': return TARGET_TAB; case 'r': return TARGET_CR; case 'f': return TARGET_FF; case 'b': return TARGET_BS; case 'a': return TARGET_BELL; case 'v': return TARGET_VT; case 'E': return 033; case '?': /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */ case '(': case '{': case '[': return c; } if (c >= 040 && c <= 0177) warning ("unknown escape sequence `\\%c'", c); else warning ("unknown escape sequence: `\\' followed by char code 0x%x", c); return c;}voidyyerror (string) char *string;{ char buf[200]; strcpy (buf, string); /* We can't print string and character constants well because the token_buffer contains the result of processing escapes. */ if (end_of_file) strcat (buf, " at end of input"); else if (token_buffer[0] == 0) strcat (buf, " at null character"); else if (token_buffer[0] == '"') strcat (buf, " before string constant"); else if (token_buffer[0] == '\'') strcat (buf, " before character constant"); else if (token_buffer[0] < 040 || token_buffer[0] >= 0177) sprintf (buf + strlen (buf), " before character 0%o", token_buffer[0]); else strcat (buf, " before `%s'"); error (buf, token_buffer);}static intyylex (){ register int c; register char *p; register int value; int wide_flag = 0; if (nextchar >= 0) c = nextchar, nextchar = -1; else c = getc (finput); /* Effectively do c = skip_white_space (c) but do it faster in the usual cases. */ while (1) switch (c) { case ' ': case '\t': case '\f': case '\r': case '\v': case '\b': c = getc (finput); break; case '\n': case '/': case '\\': c = skip_white_space (c); default: goto found_nonwhite; } found_nonwhite: token_buffer[0] = c; token_buffer[1] = 0;/* yylloc.first_line = lineno; */ switch (c) { case EOF: end_of_file = 1; token_buffer[0] = 0; value = ENDFILE; break; case '$': if (dollars_in_ident) goto letter; return '$'; case 'L': /* Capital L may start a wide-string or wide-character constant. */ { register int c = getc (finput); if (c == '\'') { wide_flag = 1; goto char_constant; } if (c == '"') { wide_flag = 1; goto string_constant; } ungetc (c, finput); } 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': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': 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': case '_': letter: p = token_buffer; while (isalnum (c) || c == '_' || c == '$') { if (p >= token_buffer + maxtoken) p = extend_token_buffer (p); if (c == '$' && ! dollars_in_ident) break; *p++ = c; c = getc (finput); } *p = 0; nextchar = c; value = IDENTIFIER; yylval.itype = 0; /* Try to recognize a keyword. Uses minimum-perfect hash function */ { register struct resword *ptr; if (ptr = is_reserved_word (token_buffer, p - token_buffer)) { if (ptr->rid) yylval.ttype = ridpointers[(int) ptr->rid]; if ((! flag_no_asm /* -fno-asm means don't recognize the non-ANSI keywords. */ || ((int) ptr->token != ASM && (int) ptr->token != TYPEOF && ptr->rid != RID_INLINE) /* Recognize __asm and __inline despite -fno-asm. */ || token_buffer[0] == '_') /* -ftraditional means don't recognize nontraditional keywords typeof, const, volatile, signed or inline. */ && (! flag_traditional || ((int) ptr->token != TYPE_QUAL && (int) ptr->token != TYPEOF && ptr->rid != RID_SIGNED && ptr->rid != RID_INLINE) /* Recognize __inline, etc. despite -ftraditional. */ || token_buffer[0] == '_')) { value = (int) ptr->token; /* Even if we decided to recognize asm, still perhaps warn. */ if (pedantic && (value == ASM || value == TYPEOF || ptr->rid == RID_INLINE) && token_buffer[0] != '_') warning ("ANSI does not permit the keyword `%s'", token_buffer); } } } /* If we did not find a keyword, look for an identifier (or a typename). */ if (value == IDENTIFIER) { yylval.ttype = get_identifier (token_buffer); lastiddecl = lookup_name (yylval.ttype); if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL) value = TYPENAME; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': { int base = 10; int count = 0; int largest_digit = 0; int numdigits = 0; /* for multi-precision arithmetic, we store only 8 live bits in each short, giving us 64 bits of reliable precision */ short shorts[8]; int overflow = 0; enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag = NOT_FLOAT; for (count = 0; count < 8; count++) shorts[count] = 0; p = token_buffer; *p++ = c; if (c == '0') { *p++ = (c = getc (finput)); if ((c == 'x') || (c == 'X')) { base = 16; *p++ = (c = getc (finput)); } else { base = 8; numdigits++; } } /* Read all the digits-and-decimal-points. */ while (c == '.' || (isalnum (c) && (c != 'l') && (c != 'L') && (c != 'u') && (c != 'U') && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F'))))) { if (c == '.') { if (base == 16) error ("floating constant may not be in radix 16"); if (floatflag == AFTER_POINT) { error ("malformed floating constant"); floatflag = TOO_MANY_POINTS; } else floatflag = AFTER_POINT; base = 10; *p++ = c = getc (finput); /* Accept '.' as the start of a floating-point number only when it is followed by a digit. Otherwise, unread the following non-digit and use the '.' as a structural token. */ if (p == token_buffer + 2 && !isdigit (c)) { if (c == '.') { c = getc (finput); if (c == '.') { *p++ = c; *p = 0; return ELLIPSIS; } error ("parse error at `..'"); } ungetc (c, finput); token_buffer[1] = 0; value = '.'; goto done; } } else { /* It is not a decimal point. It should be a digit (perhaps a hex digit). */ if (isdigit (c)) { c = c - '0'; } else if (base <= 10) { if ((c&~040) == 'E') { base = 10; floatflag = AFTER_POINT; break; /* start of exponent */ } error ("nondigits in number and not hexadecimal"); c = 0; } else if (c >= 'a') { c = c - 'a' + 10; } else { c = c - 'A' + 10; } if (c >= largest_digit) largest_digit = c; numdigits++; for (count = 0; count < 8; count++) { shorts[count] *= base; if (count) { shorts[count] += (shorts[count-1] >> 8); shorts[count-1] &= (1<<8)-1; } else shorts[0] += c; } if (shorts[7] >= 1<<8 || shorts[7] < - (1 << 8)) overflow = TRUE; if (p >= token_buffer + maxtoken - 3) p = extend_token_buffer (p); *p++ = (c = getc (finput)); } } if (numdigits == 0) error ("numeric constant with no digits"); if (largest_digit >= base) error ("numeric constant contains digits beyond the radix"); /* Remove terminating char from the token buffer and delimit the string */ *--p = 0; if (floatflag != NOT_FLOAT) { tree type = double_type_node; char f_seen = 0; char l_seen = 0; REAL_VALUE_TYPE value; /* Read explicit exponent if any, and put it in tokenbuf. */ if ((c == 'e') || (c == 'E')) { if (p >= token_buffer + maxtoken - 3) p = extend_token_buffer (p); *p++ = c; c = getc (finput
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -