📄 output.c
字号:
if (p->type[0] == '\0') fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n", n, p->name); else fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n", n, p->type, p->name); } fputs ("]])\n\n", out);}/*--------------------------------------.| Output the tokens definition to OUT. |`--------------------------------------*/static voidtoken_definitions_output (FILE *out){ int i; char const *sep = ""; fputs ("m4_define([b4_tokens], \n[", out); for (i = 0; i < ntokens; ++i) { symbol *sym = symbols[i]; int number = sym->user_token_number; /* At this stage, if there are literal aliases, they are part of SYMBOLS, so we should not find symbols which are the aliases here. */ if (number == USER_NUMBER_ALIAS) abort (); /* Skip error token. */ if (sym == errtoken) continue; /* If this string has an alias, then it is necessarily the alias which is to be output. */ if (sym->alias) sym = sym->alias; /* Don't output literal chars or strings (when defined only as a string). Note that must be done after the alias resolution: think about `%token 'f' "f"'. */ if (sym->tag[0] == '\'' || sym->tag[0] == '\"') continue; /* Don't #define nonliteral tokens whose names contain periods or '$' (as does the default value of the EOF token). */ if (strchr (sym->tag, '.') || strchr (sym->tag, '$')) continue; fprintf (out, "%s[[[%s]], [%d]]", sep, sym->tag, number); sep = ",\n"; } fputs ("])\n\n", out);}/*---------------------------------------.| Output the symbol destructors to OUT. |`---------------------------------------*/static voidsymbol_destructors_output (FILE *out){ int i; char const *sep = ""; fputs ("m4_define([b4_symbol_destructors], \n[", out); for (i = 0; i < nsyms; ++i) if (symbols[i]->destructor) { symbol *sym = symbols[i]; /* Filename, lineno, Symbol-name, Symbol-number, destructor, optional typename. */ fprintf (out, "%s[", sep); sep = ",\n"; escaped_file_name_output (out, sym->destructor_location.start.file); fprintf (out, ", [[%d]], [[%s]], [[%d]], [[%s]]", sym->destructor_location.start.line, sym->tag, sym->number, sym->destructor); if (sym->type_name) fprintf (out, ", [[%s]]", sym->type_name); fputc (']', out); } fputs ("])\n\n", out);}/*------------------------------------.| Output the symbol printers to OUT. |`------------------------------------*/static voidsymbol_printers_output (FILE *out){ int i; char const *sep = ""; fputs ("m4_define([b4_symbol_printers], \n[", out); for (i = 0; i < nsyms; ++i) if (symbols[i]->printer) { symbol *sym = symbols[i]; /* Filename, lineno, Symbol-name, Symbol-number, printer, optional typename. */ fprintf (out, "%s[", sep); sep = ",\n"; escaped_file_name_output (out, sym->printer_location.start.file); fprintf (out, ", [[%d]], [[%s]], [[%d]], [[%s]]", sym->printer_location.start.line, sym->tag, sym->number, sym->printer); if (sym->type_name) fprintf (out, ", [[%s]]", sym->type_name); fputc (']', out); } fputs ("])\n\n", out);}static voidprepare_actions (void){ /* Figure out the actions for the specified state, indexed by look-ahead token type. */ muscle_insert_rule_number_table ("defact", yydefact, yydefact[0], 1, nstates); /* Figure out what to do after reducing with each rule, depending on the saved state from before the beginning of parsing the data that matched this rule. */ muscle_insert_state_number_table ("defgoto", yydefgoto, yydefgoto[0], 1, nsyms - ntokens); /* Output PACT. */ muscle_insert_base_table ("pact", base, base[0], 1, nstates); MUSCLE_INSERT_INT ("pact_ninf", base_ninf); /* Output PGOTO. */ muscle_insert_base_table ("pgoto", base, base[nstates], nstates + 1, nvectors); muscle_insert_base_table ("table", table, table[0], 1, high + 1); MUSCLE_INSERT_INT ("table_ninf", table_ninf); muscle_insert_base_table ("check", check, check[0], 1, high + 1); /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus YYPACT) so that in states with unresolved conflicts, the default reduction is not used in the conflicted entries, so that there is a place to put a conflict pointer. This means that YYCONFLP and YYCONFL are nonsense for a non-GLR parser, so we could avoid accidents by not writing them out in that case. Nevertheless, it seems even better to be able to use the GLR skeletons even without the non-deterministic tables. */ muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table, conflict_table[0], 1, high + 1); muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list, 0, 1, conflict_list_cnt);}/*---------------------------.| Call the skeleton parser. |`---------------------------*/static voidoutput_skeleton (void){ FILE *in; FILE *out; int filter_fd[2]; char const *argv[6]; pid_t pid; /* Compute the names of the package data dir and skeleton file. Test whether m4sugar.m4 is readable, to check for proper installation. A faulty installation can cause deadlock, so a cheap sanity check is worthwhile. */ char const m4sugar[] = "m4sugar/m4sugar.m4"; char *full_m4sugar; char *full_cm4; char *full_skeleton; char const *p; char const *m4 = (p = getenv ("M4")) ? p : M4; char const *pkgdatadir = (p = getenv ("BISON_PKGDATADIR")) ? p : PKGDATADIR; size_t skeleton_size = strlen (skeleton) + 1; size_t pkgdatadirlen = strlen (pkgdatadir); while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/') pkgdatadirlen--; full_skeleton = xmalloc (pkgdatadirlen + 1 + (skeleton_size < sizeof m4sugar ? sizeof m4sugar : skeleton_size)); strcpy (full_skeleton, pkgdatadir); full_skeleton[pkgdatadirlen] = '/'; strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar); full_m4sugar = xstrdup (full_skeleton); strcpy (full_skeleton + pkgdatadirlen + 1, "c.m4"); full_cm4 = xstrdup (full_skeleton); strcpy (full_skeleton + pkgdatadirlen + 1, skeleton); xfclose (xfopen (full_m4sugar, "r")); /* Create an m4 subprocess connected to us via two pipes. */ if (trace_flag & trace_tools) fprintf (stderr, "running: %s %s - %s %s\n", m4, full_m4sugar, full_cm4, full_skeleton); argv[0] = m4; argv[1] = full_m4sugar; argv[2] = "-"; argv[3] = full_cm4; argv[4] = full_skeleton; argv[5] = NULL; init_subpipe (); pid = create_subpipe (argv, filter_fd); free (full_m4sugar); free (full_cm4); free (full_skeleton); out = fdopen (filter_fd[0], "w"); if (! out) error (EXIT_FAILURE, get_errno (), "fdopen"); /* Output the definitions of all the muscles. */ fputs ("m4_init()\n", out); user_actions_output (out); merger_output (out); token_definitions_output (out); symbol_destructors_output (out); symbol_printers_output (out); muscles_m4_output (out); fputs ("m4_wrap([m4_divert_pop(0)])\n", out); fputs ("m4_divert_push(0)dnl\n", out); xfclose (out); /* Read and process m4's output. */ timevar_push (TV_M4); in = fdopen (filter_fd[1], "r"); if (! in) error (EXIT_FAILURE, get_errno (), "fdopen"); scan_skel (in); xfclose (in); reap_subpipe (pid, m4); timevar_pop (TV_M4);}static voidprepare (void){ /* Flags. */ MUSCLE_INSERT_BOOL ("debug", debug_flag); MUSCLE_INSERT_BOOL ("defines_flag", defines_flag); MUSCLE_INSERT_BOOL ("error_verbose", error_verbose); MUSCLE_INSERT_BOOL ("locations_flag", locations_flag); MUSCLE_INSERT_BOOL ("pure", pure_parser); MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag); /* File names. */ MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy"); /* User Code. */ obstack_1grow (&pre_prologue_obstack, 0); obstack_1grow (&post_prologue_obstack, 0); muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack)); muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack)); /* Find the right skeleton file. */ if (!skeleton) { if (glr_parser || nondeterministic_parser) skeleton = "glr.c"; else skeleton = "yacc.c"; } /* Parse the skeleton file and output the needed parsers. */ MUSCLE_INSERT_C_STRING ("skeleton", skeleton);}/*----------------------------------------------------------.| Output the parsing tables and the parser code to ftable. |`----------------------------------------------------------*/voidoutput (void){ obstack_init (&format_obstack); prepare_symbols (); prepare_rules (); prepare_states (); prepare_actions (); prepare (); /* Process the selected skeleton file. */ output_skeleton (); obstack_free (&format_obstack, NULL); obstack_free (&pre_prologue_obstack, NULL); obstack_free (&post_prologue_obstack, NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -