📄 reader.c
字号:
}}/* read in a %left, %right or %nonassoc declaration and record its information. *//* assoc is either LEFT_ASSOC, RIGHT_ASSOC or NON_ASSOC. */voidparse_assoc_decl (assoc)int assoc;{ register int k; register char *name = NULL; register int prev = 0; lastprec++; /* Assign a new precedence level, never 0. */ for (;;) { register int t; if(ungetc(skip_white_space(), finput) == '%') return; t = lex(); switch (t) { case TYPENAME: k = strlen(token_buffer); name = NEW2(k + 1, char); strcpy(name, token_buffer); break; case COMMA: break; case IDENTIFIER: if (symval->prec != 0) warns("redefining precedence of %s", symval->tag); symval->prec = lastprec; symval->assoc = assoc; if (symval->class == SNTERM) warns("symbol %s redefined", symval->tag); symval->class = STOKEN; if (name) { /* record the type, if one is specified */ if (symval->type_name == NULL) symval->type_name = name; else if (strcmp(name, symval->type_name) != 0) warns("type redeclaration for %s", symval->tag); } break; case NUMBER: if (prev == IDENTIFIER) { symval->user_token_number = numval; translations = 1; } else { warns("invalid text (%s) - number should be after identifier", token_buffer); skip_to_char('%'); } break; case SEMICOLON: return; default: warns("unexpected item: %s", token_buffer); skip_to_char('%'); } prev = t; }}/* copy the union declaration into fattrs (and fdefines), where it is made into the definition of YYSTYPE, the type of elements of the parser value stack. */voidparse_union_decl(){ register int c; register int count; register int in_comment; int cplus_comment; if (typed) warn("multiple %union declarations"); typed = 1; if (!nolinesflag) fprintf(fattrs, "\n#line %d \"%s\"\n", lineno, infile); else fprintf(fattrs, "\n"); fprintf(fattrs, "typedef union"); if (fdefines) fprintf(fdefines, "typedef union"); count = 0; in_comment = 0; c = getc(finput); while (c != EOF) { putc(c, fattrs); if (fdefines) putc(c, fdefines); switch (c) { case '\n': lineno++; break; case '/': c = getc(finput); if (c != '*' && c != '/') ungetc(c, finput); else { putc(c, fattrs); if (fdefines) putc(c, fdefines); cplus_comment = (c == '/'); in_comment = 1; c = getc(finput); while (in_comment) { putc(c, fattrs); if (fdefines) putc(c, fdefines); if (c == '\n') { lineno++; if (cplus_comment) { in_comment = 0; break; } } if (c == EOF) fatal("unterminated comment at end of file"); if (!cplus_comment && c == '*') { c = getc(finput); if (c == '/') { putc('/', fattrs); if (fdefines) putc('/', fdefines); in_comment = 0; } } else c = getc(finput); } } break; case '{': count++; break; case '}': if (count == 0) warn ("unmatched close-brace (`}')"); count--; if (count <= 0) { fprintf(fattrs, " YYSTYPE;\n"); if (fdefines) fprintf(fdefines, " YYSTYPE;\n"); /* JF don't choke on trailing semi */ c=skip_white_space(); if(c!=';') ungetc(c,finput); return; } } c = getc(finput); }}/* parse the declaration %expect N which says to expect N shift-reduce conflicts. */voidparse_expect_decl(){ register int c; register int count; char buffer[20]; c = getc(finput); while (c == ' ' || c == '\t') c = getc(finput); count = 0; while (c >= '0' && c <= '9') { if (count < 20) buffer[count++] = c; c = getc(finput); } buffer[count] = 0; ungetc (c, finput); if (count <= 0 || count > 10) warn("argument of %expect is not an integer"); expected_conflicts = atoi (buffer);}/* that's all of parsing the declaration section *//* Get the data type (alternative in the union) of the value for symbol n in rule rule. */char *get_type_name(n, rule)int n;symbol_list *rule;{ static char *msg = "invalid $ value"; register int i; register symbol_list *rp; if (n < 0) { warn(msg); return NULL; } rp = rule; i = 0; while (i < n) { rp = rp->next; if (rp == NULL || rp->sym == NULL) { warn(msg); return NULL; } i++; } return (rp->sym->type_name);}/* after %guard is seen in the input file,copy the actual guard into the guards file.If the guard is followed by an action, copy that into the actions file.stack_offset is the number of values in the current rule so far,which says where to find $0 with respect to the top of the stack,for the simple parser in which the stack is not popped until after the guard is run. */voidcopy_guard(rule, stack_offset)symbol_list *rule;int stack_offset;{ register int c; register int n; register int count; register int match; register int ended; register char *type_name; int brace_flag = 0; int cplus_comment; /* offset is always 0 if parser has already popped the stack pointer */ if (semantic_parser) stack_offset = 0; fprintf(fguard, "\ncase %d:\n", nrules); if (!nolinesflag) fprintf(fguard, "#line %d \"%s\"\n", lineno, infile); putc('{', fguard); count = 0; c = getc(finput); while (brace_flag ? (count > 0) : (c != ';')) { switch (c) { case '\n': putc(c, fguard); lineno++; break; case '{': putc(c, fguard); brace_flag = 1; count++; break; case '}': putc(c, fguard); if (count > 0) count--; else { warn("unmatched right brace (`}')"); c = getc(finput); /* skip it */ } break; case '\'': case '"': match = c; putc(c, fguard); c = getc(finput); while (c != match) { if (c == EOF) fatal("unterminated string at end of file"); if (c == '\n') { warn("unterminated string"); ungetc(c, finput); c = match; /* invent terminator */ continue; } putc(c, fguard); if (c == '\\') { c = getc(finput); if (c == EOF) fatal("unterminated string"); putc(c, fguard); if (c == '\n') lineno++; } c = getc(finput); } putc(c, fguard); break; case '/': putc(c, fguard); c = getc(finput); if (c != '*' && c != '/') continue; cplus_comment = (c == '/'); putc(c, fguard); c = getc(finput); ended = 0; while (!ended) { if (!cplus_comment && c == '*') { while (c == '*') { putc(c, fguard); c = getc(finput); } if (c == '/') { putc(c, fguard); ended = 1; } } else if (c == '\n') { lineno++; putc(c, fguard); if (cplus_comment) ended = 1; else c = getc(finput); } else if (c == EOF) fatal("unterminated comment"); else { putc(c, fguard); c = getc(finput); } } break; case '$': c = getc(finput); type_name = NULL; if (c == '<') { register char *cp = token_buffer; while ((c = getc(finput)) != '>' && c > 0) *cp++ = c; *cp = 0; type_name = token_buffer; c = getc(finput); } if (c == '$') { fprintf(fguard, "yyval"); if (!type_name) type_name = rule->sym->type_name; if (type_name) fprintf(fguard, ".%s", type_name); if(!type_name && typed) warns("$$ of `%s' has no declared type", rule->sym->tag); } else if (isdigit(c) || c == '-') { ungetc (c, finput); n = read_signed_integer(finput); c = getc(finput); if (!type_name && n > 0) type_name = get_type_name(n, rule); fprintf(fguard, "yyvsp[%d]", n - stack_offset); if (type_name) fprintf(fguard, ".%s", type_name); if(!type_name && typed) warnss("$%s of `%s' has no declared type", int_to_string(n), rule->sym->tag); continue; } else warni("$%s is invalid", printable_version(c)); break; case '@': c = getc(finput); if (isdigit(c) || c == '-') { ungetc (c, finput); n = read_signed_integer(finput); c = getc(finput); } else { warni("@%s is invalid", printable_version(c)); n = 1; } fprintf(fguard, "yylsp[%d]", n - stack_offset); yylsp_needed = 1; continue; case EOF: fatal("unterminated %%guard clause"); default: putc(c, fguard); } if (c != '}' || count != 0) c = getc(finput); } c = skip_white_space(); fprintf(fguard, ";\n break;}"); if (c == '{') copy_action(rule, stack_offset); else if (c == '=') { c = getc(finput); /* why not skip_white_space -wjh */ if (c == '{') copy_action(rule, stack_offset); } else ungetc(c, finput);}/* Assuming that a { has just been seen, copy everything up to the matching }into the actions file.stack_offset is the number of values in the current rule so far,which says where to find $0 with respect to the top of the stack. */voidcopy_action(rule, stack_offset)symbol_list *rule;int stack_offset;{ register int c; register int n; register int count; register int match; register int ended; register char *type_name; int cplus_comment; /* offset is always 0 if parser has already popped the stack pointer */ if (semantic_parser) stack_offset = 0; fprintf(faction, "\ncase %d:\n", nrules); if (!nolinesflag) fprintf(faction, "#line %d \"%s\"\n", lineno, infile); putc('{', faction); count = 1; c = getc(finput); while (count > 0) { while (c != '}') { switch (c) { case '\n': putc(c, faction); lineno++; break; case '{': putc(c, faction); count++; break; case '\'': case '"': match = c; putc(c, faction); c = getc(finput); while (c != match) { if (c == '\n') { warn("unterminated string"); ungetc(c, finput); c = match; continue; } else if (c == EOF) fatal("unterminated string at end of file"); putc(c, faction); if (c == '\\') { c = getc(finput); if (c == EOF) fatal("unterminated string"); putc(c, faction); if (c == '\n') lineno++; } c = getc(finput); } putc(c, faction); break; case '/': putc(c, faction); c = getc(finput); if (c != '*' && c != '/') continue; cplus_comment = (c == '/'); putc(c, faction); c = getc(finput); ended = 0; while (!ended) { if (!cplus_comment && c == '*') { while (c == '*') { putc(c, faction); c = getc(finput); } if (c == '/') { putc(c, faction); ended = 1; } } else if (c == '\n') { lineno++; putc(c, faction); if (cplus_comment) ended = 1; else c = getc(finput); } else if (c == EOF) fatal("unterminated comment"); else { putc(c, faction); c = getc(finput); } } break; case '$': c = getc(finput); type_name = NULL; if (c == '<') { register char *cp = token_buffer; while ((c = getc(finput)) != '>' && c > 0) *cp++ = c; *cp = 0; type_name = token_buffer; value_components_used = 1; c = getc(finput); } if (c == '$') { fprintf(faction, "yyval"); if (!type_name) type_name = get_type_name(0, rule); if (type_name) fprintf(faction, ".%s", type_name); if(!type_name && typed) warns("$$ of `%s' has no declared type", rule->sym->tag); } else if (isdigit(c) || c == '-') { ungetc (c, finput); n = read_signed_integer(finput); c = getc(finput); if (!type_name && n > 0) type_name = get_type_name(n, rule); fprintf(faction, "yyvsp[%d]", n - stack_offset); if (type_name) fprintf(faction, ".%s", type_name); if(!type_name && typed) warnss("$%s of `%s' has no declared type", int_to_string(n), rule->sym->tag); continue; } else warni("$%s is invalid", printable_version(c)); break; case '@': c = getc(finput); if (isdigit(c) || c == '-') { ungetc (c, finput); n = read_signed_integer(finput); c = getc(finput); } else { warn("invalid @-construct"); n = 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -