📄 reader.c
字号:
rassoc[nrules-1] = TOKEN;}static char *insert_arg_rule(char *arg, char *tag){int lineno = rescan_lineno;char *code = compile_arg(&arg, tag);int rule = lookup_arg_cache(code);FILE *f = action_file; if (rule<0) { rule = nrules; insert_arg_cache(code, rule); fprintf(f, "case %d:\n", rule - 2); if (!lflag) fprintf(f, line_format, lineno, (inc_file?inc_file_name:input_file_name)); fprintf(f, "%s;\n", code); fprintf(f, "break;\n"); insert_empty_rule(); plhs[rule]->tag = tag; plhs[rule]->class = ARGUMENT; } else { if (++nitems > maxitems) expand_items(); pitem[nitems-1] = plhs[rule]; free(code); } return arg+1;}void add_symbol(){ register int c; register bucket *bp; int s_lineno = lineno; char *args = 0; int argslen = 0; c = *cptr; if (c == '\'' || c == '"') bp = get_literal(); else bp = get_name(); c = nextc(); if (c == '(') { ++cptr; args = copy_args(&argslen); if (args == 0) no_space(); c = nextc(); } if (c == ':') { end_rule(); start_rule(bp, s_lineno); parse_arginfo(bp, args, argslen); ++cptr; return; } if (last_was_action) insert_empty_rule(); last_was_action = 0; if (bp->args < 0) bp->args = argslen; if (argslen == 0 && bp->args > 0 && pitem[nitems-1] == 0) { int i; if (plhs[nrules]->args != bp->args) error(lineno, line, cptr, "Wrong number of default arguments " "for %s", bp->name); for (i=bp->args-1; i>=0; i--) if (plhs[nrules]->argtags[i] != bp->argtags[i]) error(lineno, line, cptr, "Wrong type for default argument " "%d to %s", i+1, bp->name); } else if (bp->args != argslen) error(lineno, line, cptr, "wrong number of arguments for %s", bp->name); if (args != 0) { char *ap; int i; for (ap=args, i=0; i<argslen; i++) ap = insert_arg_rule(ap, bp->argtags[i]); free(args); } if (++nitems > maxitems) expand_items(); pitem[nitems-1] = bp;}void copy_action(){ register int c; register int i, j, n; int depth; int trialaction = 0; int haveyyval = 0; char *tag; register FILE *f = action_file; int a_lineno = lineno; char *a_line = dup_line(); char *a_cptr = a_line + (cptr - line); Yshort *offsets=0, maxoffset; bucket **rhs; if (last_was_action) insert_empty_rule(); last_was_action = 1; fprintf(f, "case %d:\n", nrules - 2); if (*cptr != '[') fprintf(f, " if (!yytrial)\n"); else trialaction = 1; if (!lflag) fprintf(f, line_format, lineno, (inc_file?inc_file_name:input_file_name)); if (*cptr == '=') ++cptr; maxoffset = n = 0; for (i = nitems - 1; pitem[i]; --i) { n++; if (pitem[i]->class != ARGUMENT) maxoffset++; } if (maxoffset > 0) { offsets = NEW2(maxoffset+1, Yshort); if (offsets == 0) no_space(); } for (j=0, i++; i<nitems; i++) if (pitem[i]->class != ARGUMENT) offsets[++j] = i - nitems + 1; rhs = pitem + nitems - 1; depth = 0;loop: c = *cptr; if (c == '$') { if (cptr[1] == '<') { int d_lineno = lineno; char *d_line = dup_line(); char *d_cptr = d_line + (cptr - line); ++cptr; tag = get_tag(); c = *cptr; if (c == '$') { fprintf(f, "yyval.%s", tag); ++cptr; FREE(d_line); goto loop; } else if (isdigit(c)) { i = get_number(); if (i > maxoffset) { dollar_warning(d_lineno, i); fprintf(f, "yyvsp[%d].%s", i - maxoffset, tag); } else fprintf(f, "yyvsp[%d].%s", offsets[i], tag); FREE(d_line); goto loop; } else if (c == '-' && isdigit(cptr[1])) { ++cptr; i = -get_number() - n; fprintf(f, "yyvsp[%d].%s", i, tag); FREE(d_line); goto loop; } else if (isalpha(c) || c == '_') { char *arg = scan_id(); for (i=plhs[nrules]->args-1; i>=0; i--) if (arg == plhs[nrules]->argnames[i]) break; if (i<0) error(d_lineno,d_line,d_cptr,"unknown argument %s",arg); fprintf(f, "yyvsp[%d].%s", i-plhs[nrules]->args+1-n, tag); FREE(d_line); goto loop; } else dollar_error(d_lineno, d_line, d_cptr); } else if (cptr[1] == '$') { if (havetags) { tag = plhs[nrules]->tag; if (tag == 0) untyped_lhs(); fprintf(f, "yyval.%s", tag); } else fprintf(f, "yyval"); cptr += 2; haveyyval = 1; goto loop; } else if (isdigit(cptr[1])) { ++cptr; i = get_number(); if (havetags) { if (i <= 0 || i > maxoffset) unknown_rhs(i); tag = rhs[offsets[i]]->tag; if (tag == 0) untyped_rhs(i, rhs[offsets[i]]->name); fprintf(f, "yyvsp[%d].%s", offsets[i], tag); } else { if (i > n) { dollar_warning(lineno, i); fprintf(f, "yyvsp[%d]", i - maxoffset); } else fprintf(f, "yyvsp[%d]", offsets[i]); } goto loop; } else if (cptr[1] == '-') { cptr += 2; i = get_number(); if (havetags) unknown_rhs(-i); fprintf(f, "yyvsp[%d]", -i - n); goto loop; } else if (isalpha(cptr[1]) || cptr[1] == '_') { char *arg; ++cptr; arg = scan_id(); for (i=plhs[nrules]->args-1; i>=0; i--) if (arg == plhs[nrules]->argnames[i]) break; if (i<0) error(lineno, line, cptr, "unknown argument %s", arg); tag = plhs[nrules]->argtags[i]; fprintf(f, "yyvsp[%d]", i - plhs[nrules]->args + 1 - n); if (tag) fprintf(f, ".%s", tag); else if (havetags) error(lineno, 0, 0, "untyped argument $%s", arg); goto loop; } } if (isalpha(c) || c == '_' || c == '$') { do { putc(c, f); c = *++cptr; } while (isalnum(c) || c == '_' || c == '$'); goto loop; } ++cptr; if (trialaction && c == '[' && depth == 0) { ++depth; putc('{', f); goto loop; } if (trialaction && c == ']' && depth == 1) { --depth; putc('}', f); c = nextc(); if (c == '[' && !haveyyval) { goto loop; } else if (c == '{' && !haveyyval) { fprintf(f, "\n"); if (!lflag) fprintf(f, "#\n"); fprintf(f, " if (!yytrial)\n"); if (!lflag) fprintf(f, line_format, lineno, (inc_file?inc_file_name:input_file_name)); trialaction = 0; goto loop; } else { fprintf(f, "\n"); if (!lflag) fprintf(f, "#\n"); fprintf(f, "break;\n"); FREE(a_line); if (maxoffset > 0) FREE(offsets); return; } } putc(c, f); switch (c) { case '\n': get_line(); if (line) goto loop; unterminated_action(a_lineno, a_line, a_cptr); case ';': if (depth > 0) goto loop; fprintf(f, "\n"); if (!lflag) fprintf(f, "#\n"); fprintf(f, "break;\n"); FREE(a_line); if (maxoffset > 0) FREE(offsets); return; case '[': ++depth; goto loop; case ']': --depth; goto loop; case '{': ++depth; goto loop; case '}': if (--depth > 0) goto loop; c = nextc(); if (c == '[' && !haveyyval) { trialaction = 1; goto loop; } else if (c == '{' && !haveyyval) { fprintf(f, "\n"); if (!lflag) fprintf(f, "#\n"); fprintf(f, " if (!yytrial)\n"); if (!lflag) fprintf(f, line_format, lineno, (inc_file?inc_file_name:input_file_name)); goto loop; } else { fprintf(f, "\n"); if (!lflag) fprintf(f, "#\n"); fprintf(f, "break;\n"); FREE(a_line); if (maxoffset > 0) FREE(offsets); return; } case '\'': case '"': copy_string(c, f, 0); goto loop; case '/': copy_comment(f, 0); goto loop; default: goto loop; }}int mark_symbol(){ register int c; register bucket *bp; c = cptr[1]; if (c == '%' || c == '\\') { cptr += 2; return (1); } if (c == '=') cptr += 2; else if ((c == 'p' || c == 'P') && ((c = cptr[2]) == 'r' || c == 'R') && ((c = cptr[3]) == 'e' || c == 'E') && ((c = cptr[4]) == 'c' || c == 'C') && ((c = cptr[5], !IS_IDENT(c)))) cptr += 5; else syntax_error(lineno, line, cptr); c = nextc(); if (isalpha(c) || c == '_' || c == '.' || c == '$') bp = get_name(); else if (c == '\'' || c == '"') bp = get_literal(); else { syntax_error(lineno, line, cptr); /*NOTREACHED*/ return 0;} if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules]) prec_redeclared(); rprec[nrules] = bp->prec; rassoc[nrules] = bp->assoc; return (0);}void read_grammar(){ register int c; initialize_grammar(); advance_to_start(); for (;;) { c = nextc(); if (c == EOF) break; if (isalpha(c) || c == '_' || c == '.' || c == '$' || c == '\'' || c == '"') add_symbol(); else if (c == '{' || c == '=' || c == '[') copy_action(); else if (c == '|') { end_rule(); start_rule(plhs[nrules-1], 0); ++cptr; } else if (c == '%') { if (mark_symbol()) break; } else syntax_error(lineno, line, cptr); } end_rule(); if (goal->args > 0) error(0, 0, 0, "start symbol %s requires arguments", goal->name);}void free_tags(){ register int i; if (tag_table == 0) return; for (i = 0; i < ntags; ++i) { assert(tag_table[i]); FREE(tag_table[i]); } FREE(tag_table);}void pack_names(){ register bucket *bp; register char *p, *s, *t; name_pool_size = 13; /* 13 == sizeof("$end") + sizeof("$accept") */ for (bp = first_symbol; bp; bp = bp->next) name_pool_size += strlen(bp->name) + 1; name_pool = MALLOC(name_pool_size); if (name_pool == 0) no_space(); strcpy(name_pool, "$accept"); strcpy(name_pool+8, "$end"); t = name_pool + 13; for (bp = first_symbol; bp; bp = bp->next) { p = t; s = bp->name; while ((*t++ = *s++)) continue; FREE(bp->name); bp->name = p; }}void check_symbols(){ register bucket *bp; if (goal->class == UNKNOWN) undefined_goal(goal->name); for (bp = first_symbol; bp; bp = bp->next) { if (bp->class == UNKNOWN) { undefined_symbol_warning(bp->name); bp->class = TERM; } }}void pack_symbols(){ register bucket *bp; register bucket **v; register int i, j, k, n; nsyms = 2; ntokens = 1; for (bp = first_symbol; bp; bp = bp->next) { ++nsyms; if (bp->class == TERM) ++ntokens; } start_symbol = ntokens; nvars = nsyms - ntokens; symbol_name = NEW2(nsyms, char *); if (symbol_name == 0) no_space(); symbol_value = NEW2(nsyms, Yshort); if (symbol_value == 0) no_space(); symbol_prec = NEW2(nsyms, Yshort); if (symbol_prec == 0) no_space(); symbol_assoc = MALLOC(nsyms); if (symbol_assoc == 0) no_space(); v = NEW2(nsyms, bucket *); if (v == 0) no_space(); v[0] = 0; v[start_symbol] = 0; i = 1; j = start_symbol + 1; for (bp = first_symbol; bp; bp = bp->next) { if (bp->class == TERM) v[i++] = bp; else v[j++] = bp; } assert(i == ntokens && j == nsyms); for (i = 1; i < ntokens; ++i) v[i]->index = i; goal->index = start_symbol + 1; k = start_symbol + 2; while (++i < nsyms) if (v[i] != goal) { v[i]->index = k; ++k; } goal->value = 0; k = 1; for (i = start_symbol + 1; i < nsyms; ++i) { if (v[i] != goal) { v[i]->value = k; ++k; } } k = 0; for (i = 1; i < ntokens; ++i) { n = v[i]->value; if (n > 256) { for (j = k++; j > 0 && symbol_value[j-1] > n; --j) symbol_value[j] = symbol_value[j-1]; symbol_value[j] = n; } } if (v[1]->value == UNDEFINED) v[1]->value = 256; j = 0; n = 257; for (i = 2; i < ntokens; ++i) { if (v[i]->value == UNDEFINED) { while (j < k && n == symbol_value[j]) { while (++j < k && n == symbol_value[j]) continue; ++n; } v[i]->value = n; ++n; } } symbol_name[0] = name_pool + 8; symbol_value[0] = 0; symbol_prec[0] = 0; symbol_assoc[0] = TOKEN; for (i = 1; i < ntokens; ++i) { symbol_name[i] = v[i]->name; symbol_value[i] = v[i]->value; symbol_prec[i] = v[i]->prec; symbol_assoc[i] = v[i]->assoc; } symbol_name[start_symbol] = name_pool; symbol_value[start_symbol] = -1; symbol_prec[start_symbol] = 0; symbol_assoc[start_symbol] = TOKEN; for (++i; i < nsyms; ++i) { k = v[i]->index; symbol_name[k] = v[i]->name; symbol_value[k] = v[i]->value; symbol_prec[k] = v[i]->prec; symbol_assoc[k] = v[i]->assoc; } FREE(v);}void pack_grammar(){ register int i, j; int assoc, prec; ritem = NEW2(nitems, Yshort); if (ritem == 0) no_space(); rlhs = NEW2(nrules, Yshort); if (rlhs == 0) no_space(); rrhs = NEW2(nrules+1, Yshort); if (rrhs == 0) no_space(); rprec = RENEW(rprec, nrules, Yshort); if (rprec == 0) no_space(); rassoc = RENEW(rassoc, nrules, char); if (rassoc == 0) no_space(); ritem[0] = -1; ritem[1] = goal->index; ritem[2] = 0; ritem[3] = -2; rlhs[0] = 0; rlhs[1] = 0; rlhs[2] = start_symbol; rrhs[0] = 0; rrhs[1] = 0; rrhs[2] = 1; j = 4; for (i = 3; i < nrules; ++i) { if (plhs[i]->args > 0) { if (plhs[i]->argnames) { FREE(plhs[i]->argnames); plhs[i]->argnames = 0; } if (plhs[i]->argtags) { FREE(plhs[i]->argtags); plhs[i]->argtags = 0; } } rlhs[i] = plhs[i]->index; rrhs[i] = j; assoc = TOKEN; prec = 0; while (pitem[j]) { ritem[j] = pitem[j]->index; if (pitem[j]->class == TERM) { prec = pitem[j]->prec; assoc = pitem[j]->assoc; } ++j; } ritem[j] = -i; ++j; if (rprec[i] == UNDEFINED) { rprec[i] = prec; rassoc[i] = assoc; } } rrhs[i] = j; FREE(plhs); FREE(pitem); clean_arg_cache();}void print_grammar(){ register int i, j, k; int spacing = 0; register FILE *f = verbose_file; if (!vflag) return; k = 1; for (i = 2; i < nrules; ++i) { if (rlhs[i] != rlhs[i-1]) { if (i != 2) fprintf(f, "\n"); fprintf(f, "%4d %s :", i - 2, symbol_name[rlhs[i]]); spacing = strlen(symbol_name[rlhs[i]]) + 1; } else { fprintf(f, "%4d ", i - 2); j = spacing; while (--j >= 0) putc(' ', f); putc('|', f); } while (ritem[k] >= 0) { fprintf(f, " %s", symbol_name[ritem[k]]); ++k; } ++k; putc('\n', f); }}extern int read_errs;void reader() { write_section("banner"); create_symbol_table(); read_declarations(); read_grammar(); if(read_errs) done(1); free_symbol_table(); free_tags(); pack_names(); check_symbols(); pack_symbols(); pack_grammar(); free_symbols(); print_grammar();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -