📄 reader.c
字号:
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);}static int is_reserved(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);}static bucket *get_name(void){ 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));}static int get_number(void){ register int c; register int n; n = 0; for (c = *cptr; isdigit(c); c = *++cptr) n = 10 * n + (c - '0'); return (n);}static char *get_tag(void){ 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) { FREE(t_line); 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);}static void declare_tokens(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(); } }}/* * %expect requires special handling * as it really isn't part of the yacc * grammar only a flag for yacc proper. */static void declare_expect(int assoc){ register int c; if (assoc != EXPECT) ++prec; /* * Stay away from nextc - doesn't * detect EOL and will read to EOF. */ c = *++cptr; if (c == EOF) unexpected_EOF(); for (;;) { if (isdigit(c)) { SRexpect = get_number(); break; } /* * Looking for number before EOL. * Spaces, tabs, and numbers are ok, * words, punc., etc. are syntax errors. */ else if (c == '\n' || isalpha(c) || !isspace(c)) { syntax_error(lineno, line, cptr); } else { c = *++cptr; if (c == EOF) unexpected_EOF(); } }}static void declare_types(void){ register int c; register bucket *bp; char *tag; c = nextc(); if (c == EOF) unexpected_EOF(); if (c != '<') syntax_error(lineno, line, cptr); tag = get_tag(); for (;;) { c = nextc(); if (isalpha(c) || c == '_' || c == '.' || c == '$') bp = get_name(); else if (c == '\'' || c == '"') bp = get_literal(); else return; if (bp->tag && tag != bp->tag) retyped_warning(bp->name); bp->tag = tag; }}static void declare_start(void){ register int c; register bucket *bp; c = nextc(); if (c == EOF) unexpected_EOF(); if (!isalpha(c) && c != '_' && c != '.' && c != '$') syntax_error(lineno, line, cptr); bp = get_name(); if (bp->class == TERM) terminal_start(bp->name); if (goal && goal != bp) restarted_warning(); goal = bp;}static void read_declarations(void){ register int c, k; cache_size = 256; cache = MALLOC(cache_size); if (cache == 0) no_space(); for (;;) { c = nextc(); if (c == EOF) unexpected_EOF(); if (c != '%') syntax_error(lineno, line, cptr); switch (k = keyword()) { case MARK: return; case IDENT: copy_ident(); break; case TEXT: copy_text(); break; case UNION: copy_union(); break; case TOKEN: case LEFT: case RIGHT: case NONASSOC: declare_tokens(k); break; case EXPECT: declare_expect(k); break; case TYPE: declare_types(); break; case START: declare_start(); break; } }}static void initialize_grammar(void){ nitems = 4; maxitems = 300; pitem = (bucket **)MALLOC(maxitems * sizeof(bucket *)); if (pitem == 0) no_space(); pitem[0] = 0; pitem[1] = 0; pitem[2] = 0; pitem[3] = 0; nrules = 3; maxrules = 100; plhs = (bucket **)MALLOC(maxrules * sizeof(bucket *)); if (plhs == 0) no_space(); plhs[0] = 0; plhs[1] = 0; plhs[2] = 0; rprec = (short *)MALLOC(maxrules * sizeof(short)); if (rprec == 0) no_space(); rprec[0] = 0; rprec[1] = 0; rprec[2] = 0; rassoc = (char *)MALLOC(maxrules * sizeof(char)); if (rassoc == 0) no_space(); rassoc[0] = TOKEN; rassoc[1] = TOKEN; rassoc[2] = TOKEN;}static void expand_items(void){ maxitems += 300; pitem = (bucket **)REALLOC(pitem, maxitems * sizeof(bucket *)); if (pitem == 0) no_space();}static void expand_rules(void){ maxrules += 100; plhs = (bucket **)REALLOC(plhs, maxrules * sizeof(bucket *)); if (plhs == 0) no_space(); rprec = (short *)REALLOC(rprec, maxrules * sizeof(short)); if (rprec == 0) no_space(); rassoc = (char *)REALLOC(rassoc, maxrules * sizeof(char)); if (rassoc == 0) no_space();}static void advance_to_start(void){ register int c; register bucket *bp; char *s_cptr; int s_lineno; for (;;) { c = nextc(); if (c != '%') break; s_cptr = cptr; switch (keyword()) { case MARK: no_grammar(); case TEXT: copy_text(); break; case START: declare_start(); break; default: syntax_error(lineno, line, s_cptr); } } c = nextc(); if (!isalpha(c) && c != '_' && c != '.' && c != '_') syntax_error(lineno, line, cptr); bp = get_name(); if (goal == 0) { if (bp->class == TERM) terminal_start(bp->name); goal = bp; } s_lineno = lineno; c = nextc(); if (c == EOF) unexpected_EOF(); if (c != ':') syntax_error(lineno, line, cptr); start_rule(bp, s_lineno); ++cptr;}static void start_rule(register bucket *bp, int s_lineno){ if (bp->class == TERM) terminal_lhs(s_lineno); bp->class = NONTERM; if (nrules >= maxrules) expand_rules(); plhs[nrules] = bp; rprec[nrules] = UNDEFINED; rassoc[nrules] = TOKEN;}static void end_rule(void){ register int i; if (!last_was_action && plhs[nrules]->tag) { if (pitem[nitems - 1]) { for (i = nitems - 1; (i > 0) && pitem[i]; --i) continue; if (pitem[i + 1] == 0 || pitem[i + 1]->tag != plhs[nrules]->tag) default_action_warning(); } } last_was_action = 0; if (nitems >= maxitems) expand_items(); pitem[nitems] = 0; ++nitems; ++nrules;}static void insert_empty_rule(void){ register bucket *bp, **bpp; assert(cache); sprintf(cache, "$$%d", ++gensym); bp = make_bucket(cache); last_symbol->next = bp; last_symbol = bp; bp->tag = plhs[nrules]->tag; bp->class = NONTERM; if ((nitems += 2) > maxitems) expand_items(); bpp = pitem + nitems - 1; *bpp-- = bp; while ((bpp[0] = bpp[-1]) != 0) --bpp; if (++nrules >= maxrules) expand_rules(); plhs[nrules] = plhs[nrules - 1]; plhs[nrules - 1] = bp; rprec[nrules] = rprec[nrules - 1]; rprec[nrules - 1] = 0; rassoc[nrules] = rassoc[nrules - 1]; rassoc[nrules - 1] = TOKEN;}static void add_symbol(void){ register int c; register bucket *bp; int s_lineno = lineno; c = *cptr; if (c == '\'' || c == '"') bp = get_literal(); else bp = get_name(); c = nextc(); if (c == ':') { end_rule(); start_rule(bp, s_lineno); ++cptr; return; } if (last_was_action) insert_empty_rule(); last_was_action = 0; if (++nitems > maxitems) expand_items(); pitem[nitems - 1] = bp;}static void copy_action(void){ register int c; register int i, n; int depth; int quote; char *tag; register FILE *f = action_file; int a_lineno = lineno; char *a_line = dup_line(); char *a_cptr = a_line + (cptr - line); if (last_was_action) insert_empty_rule(); last_was_action = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -