?? reader.c
字號:
#include "defs.h"/* The line size must be a positive integer. One hundred was chosen *//* because few lines in Yacc input grammars exceed 100 characters. *//* Note that if a line exceeds LINESIZE characters, the line buffer *//* will be expanded to accomodate it. */#define LINESIZE 100char *cache;int cinc, cache_size;int ntags, tagmax;char **tag_table;char saw_eof, unionized;char *cptr, *line;int linesize;bucket *goal;int prec;int gensym;char last_was_action;int maxitems;bucket **pitem;int maxrules;bucket **plhs;int name_pool_size;char *name_pool;char line_format[] = "#line %d \"%s\"\n";cachec(c)int c;{ assert(cinc >= 0); if (cinc >= cache_size) { cache_size += 256; cache = REALLOC(cache, cache_size); if (cache == 0) no_space(); } cache[cinc] = c; ++cinc;}get_line(){ register FILE *f = input_file; register int c; register int i; if (saw_eof || (c = getc(f)) == EOF) { if (line) { FREE(line); line = 0; } cptr = 0; saw_eof = 1; return; } if (line == 0 || linesize != (LINESIZE + 1)) { if (line) FREE(line); linesize = LINESIZE + 1; line = MALLOC(linesize); if (line == 0) no_space(); } i = 0; ++lineno; for (;;) { line[i] = c; if (c == '\n') { cptr = line; return; } if (++i >= linesize) { linesize += LINESIZE; line = REALLOC(line, linesize); if (line == 0) no_space(); } c = getc(f); if (c == EOF) { line[i] = '\n'; saw_eof = 1; cptr = line; return; } }}char *dup_line(){ register char *p, *s, *t; if (line == 0) return (0); s = line; while (*s != '\n') ++s; p = MALLOC(s - line + 1); if (p == 0) no_space(); s = line; t = p; while ((*t++ = *s++) != '\n') continue; return (p);}skip_comment(){ register char *s; int st_lineno = lineno; char *st_line = dup_line(); char *st_cptr = st_line + (cptr - line); s = cptr + 2; for (;;) { if (*s == '*' && s[1] == '/') { cptr = s + 2; FREE(st_line); return; } if (*s == '\n') { get_line(); if (line == 0) unterminated_comment(st_lineno, st_line, st_cptr); s = cptr; } else ++s; }}intnextc(){ register char *s; if (line == 0) { get_line(); if (line == 0) return (EOF); } s = cptr; for (;;) { switch (*s) { case '\n': get_line(); if (line == 0) return (EOF); s = cptr; break; case ' ': case '\t': case '\f': case '\r': case '\v': case ',': case ';': ++s; break; case '\\': cptr = s; return ('%'); case '/': if (s[1] == '*') { cptr = s; skip_comment(); s = cptr; break; } else if (s[1] == '/') { get_line(); if (line == 0) return (EOF); s = cptr; break; } /* fall through */ default: cptr = s; return (*s); } }}intkeyword(){ register int c; char *t_cptr = cptr; c = *++cptr; if (isalpha(c)) { cinc = 0; for (;;) { if (isalpha(c)) { if (isupper(c)) c = tolower(c); cachec(c); } else if (isdigit(c) || c == '_' || c == '.' || c == '$') cachec(c); else break; c = *++cptr; } cachec(NUL); if (strcmp(cache, "token") == 0 || strcmp(cache, "term") == 0) return (TOKEN); if (strcmp(cache, "type") == 0) return (TYPE); if (strcmp(cache, "left") == 0) return (LEFT); if (strcmp(cache, "right") == 0) return (RIGHT); if (strcmp(cache, "nonassoc") == 0 || strcmp(cache, "binary") == 0) return (NONASSOC); if (strcmp(cache, "start") == 0) return (START); if (strcmp(cache, "union") == 0) return (UNION); if (strcmp(cache, "ident") == 0) return (IDENT); } else { ++cptr; if (c == '{') return (TEXT); if (c == '%' || c == '\\') return (MARK); if (c == '<') return (LEFT); if (c == '>') return (RIGHT); if (c == '0') return (TOKEN); if (c == '2') return (NONASSOC); } syntax_error(lineno, line, t_cptr); /*NOTREACHED*/}copy_ident(){ register int c; register FILE *f = output_file; c = nextc(); if (c == EOF) unexpected_EOF(); if (c != '"') syntax_error(lineno, line, cptr); ++outline; fprintf(f, "#ident \""); for (;;) { c = *++cptr; if (c == '\n') { fprintf(f, "\"\n"); return; } putc(c, f); if (c == '"') { putc('\n', f); ++cptr; return; } }}copy_text(){ register int c; int quote; register FILE *f = text_file; int need_newline = 0; int t_lineno = lineno; char *t_line = dup_line(); char *t_cptr = t_line + (cptr - line - 2); if (*cptr == '\n') { get_line(); if (line == 0) unterminated_text(t_lineno, t_line, t_cptr); } if (!lflag) fprintf(f, line_format, lineno, input_file_name);loop: c = *cptr++; switch (c) { case '\n': next_line: putc('\n', f); need_newline = 0; get_line(); if (line) goto loop; unterminated_text(t_lineno, t_line, t_cptr); case '\'': case '"': { int s_lineno = lineno; char *s_line = dup_line(); char *s_cptr = s_line + (cptr - line - 1); quote = c; putc(c, f); for (;;) { c = *cptr++; putc(c, f); if (c == quote) { need_newline = 1; FREE(s_line); goto loop; } if (c == '\n') unterminated_string(s_lineno, s_line, s_cptr); if (c == '\\') { c = *cptr++; putc(c, f); if (c == '\n') { get_line(); if (line == 0) unterminated_string(s_lineno, s_line, s_cptr); } } } } case '/': putc(c, f); need_newline = 1; c = *cptr; if (c == '/') { putc('*', f); while ((c = *++cptr) != '\n') { if (c == '*' && cptr[1] == '/') fprintf(f, "* "); else putc(c, f); } fprintf(f, "*/"); goto next_line; } if (c == '*') { int c_lineno = lineno; char *c_line = dup_line(); char *c_cptr = c_line + (cptr - line - 1); putc('*', f); ++cptr; for (;;) { c = *cptr++; putc(c, f); if (c == '*' && *cptr == '/') { putc('/', f); ++cptr; FREE(c_line); goto loop; } if (c == '\n') { get_line(); if (line == 0) unterminated_comment(c_lineno, c_line, c_cptr); } } } need_newline = 1; goto loop; case '%': case '\\': if (*cptr == '}') { if (need_newline) putc('\n', f); ++cptr; FREE(t_line); return; } /* fall through */ default: putc(c, f); need_newline = 1; goto loop; }}copy_union(){ register int c; int quote; int depth; int u_lineno = lineno; char *u_line = dup_line(); char *u_cptr = u_line + (cptr - line - 6); if (unionized) over_unionized(cptr - 6); unionized = 1; if (!lflag) fprintf(text_file, line_format, lineno, input_file_name); fprintf(text_file, "typedef union"); if (dflag) fprintf(union_file, "typedef union"); depth = 0;loop: c = *cptr++; putc(c, text_file); if (dflag) putc(c, union_file); switch (c) { case '\n': next_line: get_line(); if (line == 0) unterminated_union(u_lineno, u_line, u_cptr); goto loop; case '{': ++depth; goto loop; case '}': if (--depth == 0) { fprintf(text_file, " YYSTYPE;\n"); FREE(u_line); return; } goto loop; case '\'': case '"': { int s_lineno = lineno; char *s_line = dup_line(); char *s_cptr = s_line + (cptr - line - 1); quote = c; for (;;) { c = *cptr++; putc(c, text_file); if (dflag) putc(c, union_file); if (c == quote) { FREE(s_line); goto loop; } if (c == '\n') unterminated_string(s_lineno, s_line, s_cptr); if (c == '\\') { c = *cptr++; putc(c, text_file); if (dflag) putc(c, union_file); if (c == '\n') { get_line(); if (line == 0) unterminated_string(s_lineno, s_line, s_cptr); } } } } case '/': c = *cptr; if (c == '/') { putc('*', text_file); if (dflag) putc('*', union_file); while ((c = *++cptr) != '\n') { if (c == '*' && cptr[1] == '/') { fprintf(text_file, "* "); if (dflag) fprintf(union_file, "* "); } else { putc(c, text_file); if (dflag) putc(c, union_file); } } fprintf(text_file, "*/\n"); if (dflag) fprintf(union_file, "*/\n"); goto next_line; } if (c == '*') { int c_lineno = lineno; char *c_line = dup_line(); char *c_cptr = c_line + (cptr - line - 1); putc('*', text_file); if (dflag) putc('*', union_file); ++cptr; for (;;) { c = *cptr++; putc(c, text_file); if (dflag) putc(c, union_file); if (c == '*' && *cptr == '/') { putc('/', text_file); if (dflag) putc('/', union_file); ++cptr; FREE(c_line); goto loop; } if (c == '\n') { get_line(); if (line == 0) unterminated_comment(c_lineno, c_line, c_cptr); } } } goto loop; default: goto loop; }}inthexval(c)int c;{ if (c >= '0' && c <= '9') return (c - '0'); if (c >= 'A' && c <= 'F') return (c - 'A' + 10); if (c >= 'a' && c <= 'f') return (c - 'a' + 10); return (-1);}bucket *get_literal(){ register int c, quote; register int i; register int n; register char *s; register bucket *bp; int s_lineno = lineno; char *s_line = dup_line(); char *s_cptr = s_line + (cptr - line); quote = *cptr++; cinc = 0; for (;;) { c = *cptr++; if (c == quote) break; if (c == '\n') unterminated_string(s_lineno, s_line, s_cptr); if (c == '\\') { char *c_cptr = cptr - 1; c = *cptr++; switch (c) { case '\n': get_line(); if (line == 0) unterminated_string(s_lineno, s_line, s_cptr); continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': n = c - '0'; c = *cptr; if (IS_OCTAL(c)) { n = (n << 3) + (c - '0'); c = *++cptr; if (IS_OCTAL(c)) { n = (n << 3) + (c - '0'); ++cptr; } } if (n > MAXCHAR) illegal_character(c_cptr); c = n; break; case 'x': c = *cptr++; n = hexval(c); if (n < 0 || n >= 16) illegal_character(c_cptr); for (;;) { c = *cptr; i = hexval(c); if (i < 0 || i >= 16) break; ++cptr; n = (n << 4) + i; if (n > MAXCHAR) illegal_character(c_cptr); } c = n; break; case 'a': c = 7; break; case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; } } cachec(c); } FREE(s_line); n = cinc; s = MALLOC(n); if (s == 0) no_space(); for (i = 0; i < n; ++i) s[i] = cache[i]; cinc = 0; if (n == 1) cachec('\''); else cachec('"'); for (i = 0; i < n; ++i) { c = ((unsigned char *)s)[i]; if (c == '\\' || c == cache[0]) { cachec('\\'); cachec(c); } else if (isprint(c)) cachec(c); else { cachec('\\'); switch (c) { case 7: cachec('a'); break; case '\b': cachec('b'); break; case '\f': cachec('f'); break; case '\n': cachec('n'); break; case '\r': cachec('r'); break; case '\t': cachec('t'); break; case '\v': cachec('v'); break; default: cachec(((c >> 6) & 7) + '0'); cachec(((c >> 3) & 7) + '0'); cachec((c & 7) + '0'); break; } } } if (n == 1) cachec('\''); else cachec('"'); cachec(NUL); bp = lookup(cache); bp->class = TERM; if (n == 1 && bp->value == UNDEFINED) bp->value = *(unsigned char *)s; FREE(s); return (bp);}intis_reserved(name)char *name;{ char *s; if (strcmp(name, ".") == 0 || strcmp(name, "$accept") == 0 || strcmp(name, "$end") == 0) return (1); if (name[0] == '$' && name[1] == '$' && isdigit(name[2])) { s = name + 3; while (isdigit(*s)) ++s; if (*s == NUL) return (1); } return (0);}bucket *get_name(){ register int c; cinc = 0; for (c = *cptr; IS_IDENT(c); c = *++cptr) cachec(c); cachec(NUL); if (is_reserved(cache)) used_reserved(cache); return (lookup(cache));}intget_number(){ register int c; register int n; n = 0; for (c = *cptr; isdigit(c); c = *++cptr) n = 10*n + (c - '0'); return (n);}char *get_tag(){ register int c; register int i; register char *s; int t_lineno = lineno; char *t_line = dup_line(); char *t_cptr = t_line + (cptr - line); ++cptr; c = nextc(); if (c == EOF) unexpected_EOF(); if (!isalpha(c) && c != '_' && c != '$') illegal_tag(t_lineno, t_line, t_cptr); cinc = 0; do { cachec(c); c = *++cptr; } while (IS_IDENT(c)); cachec(NUL); c = nextc(); if (c == EOF) unexpected_EOF(); if (c != '>') illegal_tag(t_lineno, t_line, t_cptr); ++cptr; for (i = 0; i < ntags; ++i) { if (strcmp(cache, tag_table[i]) == 0) return (tag_table[i]); } if (ntags >= tagmax) { tagmax += 16; tag_table = (char **) (tag_table ? REALLOC(tag_table, tagmax*sizeof(char *)) : MALLOC(tagmax*sizeof(char *))); if (tag_table == 0) no_space(); } s = MALLOC(cinc); if (s == 0) no_space(); strcpy(s, cache); tag_table[ntags] = s; ++ntags; FREE(t_line); return (s);}declare_tokens(assoc)int assoc;{ register int c; register bucket *bp; int value; char *tag = 0; if (assoc != TOKEN) ++prec; c = nextc(); if (c == EOF) unexpected_EOF(); if (c == '<') { tag = get_tag(); c = nextc(); if (c == EOF) unexpected_EOF(); } for (;;) { if (isalpha(c) || c == '_' || c == '.' || c == '$') bp = get_name(); else if (c == '\'' || c == '"') bp = get_literal(); else return; if (bp == goal) tokenized_start(bp->name); bp->class = TERM; if (tag) { if (bp->tag && tag != bp->tag) retyped_warning(bp->name); bp->tag = tag; } if (assoc != TOKEN) { if (bp->prec && prec != bp->prec) reprec_warning(bp->name); bp->assoc = assoc; bp->prec = prec; } c = nextc(); if (c == EOF) unexpected_EOF(); value = UNDEFINED; if (isdigit(c)) { value = get_number(); if (bp->value != UNDEFINED && value != bp->value) revalued_warning(bp->name); bp->value = value; c = nextc(); if (c == EOF) unexpected_EOF(); } }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -