static void set_nullable(void) { int i, j; int empty; int done_flag; nullable = TMALLOC(char, nsyms); NO_SPACE(nullable); for (i = 0; i < nsyms; ++i) nullable[i] = 0; done_flag = 0; while (!done_flag) { done_flag = 1; for (i = 1; i < nitems; i++) { empty = 1; while ((j = ritem[i]) >= 0) { if (!nullable[j]) empty = 0; ++i; } if (empty) { j = rlhs[-j]; if (!nullable[j]) { nullable[j] = 1; done_flag = 0; } } } } #ifdef DEBUG for (i = 0; i < nsyms; i++) { if (nullable[i]) printf("%s is nullable\n", symbol_name[i]); else printf("%s is not nullable\n", symbol_name[i]); } #endif }
void verbose (void) { int i; if (!vflag) return; null_rules = TMALLOC (Value_t, nrules); NO_SPACE (null_rules); fprintf (verbose_file, "\f\n"); for (i = 0; i < nstates; i++) print_state (i); FREE (null_rules); if (nunused) log_unused (); if (SRtotal || RRtotal) log_conflicts (); fprintf (verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens, nvars); fprintf (verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates); #if defined(YYBTYACC) { /* print out the grammar symbol # and parser internal symbol # for each symbol as an aide to writing the implementation for YYDESTRUCT_CALL() and YYSTYPE_TOSTRING() */ int maxtok = 0; fputs ("\ngrammar parser grammar\n", verbose_file); fputs ("symbol# value# symbol\n", verbose_file); for (i = 0; i < ntokens; ++i) { fprintf (verbose_file, " %5d %5d %s\n", i, symbol_value[i], symbol_name[i]); if (symbol_value[i] > maxtok) maxtok = symbol_value[i]; } for (i = ntokens; i < nsyms; ++i) fprintf (verbose_file, " %5d %5d %s\n", i, (maxtok + 1) + symbol_value[i] + 1, symbol_name[i]); } #endif }
static void output_accessing_symbols(void) { int i, j; int *translate; if (nstates != 0) { translate = TMALLOC(int, nstates); NO_SPACE(translate); for (i = 0; i < nstates; ++i) { int gsymb = accessing_symbol[i]; translate[i] = symbol_pval[gsymb]; } putl_code(output_file, "#if defined(YYDESTRUCT_CALL) || defined(YYSTYPE_TOSTRING)\n"); /* yystos[] may be unused, depending on compile-time defines */ start_int_table("stos", translate[0]); j = 10; for (i = 1; i < nstates; ++i) { if (j < 10) ++j; else { output_newline(); j = 1; } output_int(translate[i]); } end_table(); FREE(translate); putl_code(output_file, "#endif /* YYDESTRUCT_CALL || YYSTYPE_TOSTRING */\n"); }
static void output_accessing_symbols(void) { int i, j; int *translate; if (nstates != 0) { translate = TMALLOC(int, nstates); NO_SPACE(translate); for (i = 0; i < nstates; ++i) { int gsymb = accessing_symbol[i]; translate[i] = symbol_pval[gsymb]; } /* yystos[] may be unused, depending on compile-time defines */ start_int_table("stos", translate[0]); j = 10; for (i = 1; i < nstates; ++i) { if (j < 10) ++j; else { output_newline(); j = 1; } output_int(translate[i]); } end_table(); FREE(translate); }
static void initialize_states(void) { unsigned i; Value_t *start_derives; core *p; start_derives = derives[start_symbol]; for (i = 0; start_derives[i] >= 0; ++i) continue; p = (core *)MALLOC(sizeof(core) + i * sizeof(Value_t)); NO_SPACE(p); p->next = 0; p->link = 0; p->number = 0; p->accessing_symbol = 0; p->nitems = (Value_t) i; for (i = 0; start_derives[i] >= 0; ++i) p->items[i] = rrhs[start_derives[i]]; first_state = last_state = this_state = p; nstates = 1; }
static void output_debug(void) { int i, j, k, max; const char **symnam; const char *s; ++outline; fprintf(code_file, "#define YYFINAL %d\n", final_state); putl_code(code_file, "#ifndef YYDEBUG\n"); ++outline; fprintf(code_file, "#define YYDEBUG %d\n", tflag); putl_code(code_file, "#endif\n"); if (rflag) { fprintf(output_file, "#ifndef YYDEBUG\n"); fprintf(output_file, "#define YYDEBUG %d\n", tflag); fprintf(output_file, "#endif\n"); } max = 0; for (i = 2; i < ntokens; ++i) if (symbol_value[i] > max) max = symbol_value[i]; ++outline; fprintf(code_file, "#define YYMAXTOKEN %d\n", max); symnam = TMALLOC(const char *, max + 1); NO_SPACE(symnam); /* Note that it is not necessary to initialize the element */ /* symnam[max]. */ for (i = 0; i < max; ++i) symnam[i] = 0; for (i = ntokens - 1; i >= 2; --i) symnam[symbol_value[i]] = symbol_name[i]; symnam[0] = "end-of-file"; output_line("#if YYDEBUG"); start_str_table("name"); j = 80; for (i = 0; i <= max; ++i) { if ((s = symnam[i]) != 0) { if (s[0] == '"') { k = 7; while (*++s != '"') { ++k; if (*s == '\\') { k += 2; if (*++s == '\\') ++k; } } j += k; if (j > 80) { output_newline(); j = k; } fprintf(output_file, "\"\\\""); s = symnam[i]; while (*++s != '"') { if (*s == '\\') { fprintf(output_file, "\\\\"); if (*++s == '\\') fprintf(output_file, "\\\\"); else putc(*s, output_file); } else putc(*s, output_file); } fprintf(output_file, "\\\"\","); } else if (s[0] == '\'') { if (s[1] == '"') { j += 7; if (j > 80) { output_newline(); j = 7; } fprintf(output_file, "\"'\\\"'\","); } else { k = 5; while (*++s != '\'') { ++k; if (*s == '\\') { k += 2; if (*++s == '\\') ++k; } } j += k; if (j > 80) { output_newline(); j = k; } fprintf(output_file, "\"'"); s = symnam[i]; while (*++s != '\'') { if (*s == '\\') { fprintf(output_file, "\\\\"); if (*++s == '\\') fprintf(output_file, "\\\\"); else putc(*s, output_file); } else putc(*s, output_file); } fprintf(output_file, "'\","); } } else { k = (int)strlen(s) + 3; j += k; if (j > 80) { output_newline(); j = k; } putc('"', output_file); do { putc(*s, output_file); } while (*++s); fprintf(output_file, "\","); } } else { j += 2; if (j > 80) { output_newline(); j = 2; } fprintf(output_file, "0,"); } } end_table(); FREE(symnam); start_str_table("rule"); for (i = 2; i < nrules; ++i) { fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]); for (j = rrhs[i]; ritem[j] > 0; ++j) { s = symbol_name[ritem[j]]; if (s[0] == '"') { fprintf(output_file, " \\\""); while (*++s != '"') { if (*s == '\\') { if (s[1] == '\\') fprintf(output_file, "\\\\\\\\"); else fprintf(output_file, "\\\\%c", s[1]); ++s; } else putc(*s, output_file); } fprintf(output_file, "\\\""); } else if (s[0] == '\'') { if (s[1] == '"') fprintf(output_file, " '\\\"'"); else if (s[1] == '\\') { if (s[2] == '\\') fprintf(output_file, " '\\\\\\\\"); else fprintf(output_file, " '\\\\%c", s[2]); s += 2; while (*++s != '\'') putc(*s, output_file); putc('\'', output_file); } else fprintf(output_file, " '%c'", s[1]); } else fprintf(output_file, " %s", s); } fprintf(output_file, "\","); output_newline(); } end_table(); output_line("#endif"); }
static int pack_vector(int vector) { int i, j, k, l; int t; int loc; int ok; Value_t *from; Value_t *to; int newmax; i = order[vector]; t = tally[i]; assert(t); from = froms[i]; to = tos[i]; j = lowzero - from[0]; for (k = 1; k < t; ++k) if (lowzero - from[k] > j) j = lowzero - from[k]; for (;; ++j) { if (j == 0) continue; ok = 1; for (k = 0; ok && k < t; k++) { loc = j + from[k]; if (loc >= maxtable - 1) { if (loc >= MAXTABLE - 1) fatal("maximum table size exceeded"); newmax = maxtable; do { newmax += 200; } while (newmax <= loc); table = TREALLOC(Value_t, table, newmax); NO_SPACE(table); check = TREALLOC(Value_t, check, newmax); NO_SPACE(check); for (l = maxtable; l < newmax; ++l) { table[l] = 0; check[l] = -1; } maxtable = newmax; } if (check[loc] != -1) ok = 0; } for (k = 0; ok && k < vector; k++) { if (pos[k] == j) ok = 0; } if (ok) { for (k = 0; k < t; k++) { loc = j + from[k]; table[loc] = to[k]; check[loc] = from[k]; if (loc > high) high = loc; } while (check[lowzero] != -1) ++lowzero; return (j); } } }
/* * tmpfile() should be adequate, except that it may require special privileges * to use, e.g., MinGW and Windows 7 where it tries to use the root directory. */ static FILE * open_tmpfile(const char *label) { FILE *result; #if USE_MKSTEMP int fd; const char *tmpdir; char *name; const char *mark; if ((tmpdir = getenv("TMPDIR")) == 0 || access(tmpdir, W_OK) != 0) { #ifdef P_tmpdir tmpdir = P_tmpdir; #else tmpdir = "/tmp"; #endif if (access(tmpdir, W_OK) != 0) tmpdir = "."; } name = malloc(strlen(tmpdir) + 10 + strlen(label)); result = 0; if (name != 0) { if ((mark = strrchr(label, '_')) == 0) mark = label + strlen(label); sprintf(name, "%s/%.*sXXXXXX", tmpdir, (int)(mark - label), label); fd = mkstemp(name); if (fd >= 0) { result = fdopen(fd, "w+"); if (result != 0) { MY_TMPFILES *item; if (my_tmpfiles == 0) { atexit(close_tmpfiles); } item = NEW(MY_TMPFILES); NO_SPACE(item); item->name = name; NO_SPACE(item->name); item->next = my_tmpfiles; my_tmpfiles = item; } } } #else result = tmpfile(); #endif if (result == 0) open_error(label); return result; }
static void create_file_names(void) { size_t len; const char *defines_suffix; const char *externs_suffix; char *prefix; prefix = NULL; defines_suffix = DEFINES_SUFFIX; externs_suffix = EXTERNS_SUFFIX; /* compute the file_prefix from the user provided output_file_name */ if (output_file_name != 0) { if (!(prefix = strstr(output_file_name, ".tab.c")) && (prefix = strstr(output_file_name, ".c"))) { defines_suffix = ".h"; externs_suffix = ".i"; } } if (prefix != NULL) { len = (size_t) (prefix - output_file_name); file_prefix = MALLOC(len + 1); NO_SPACE(file_prefix); strncpy(file_prefix, output_file_name, len)[len] = 0; } else len = strlen(file_prefix); /* if "-o filename" was not given */ if (output_file_name == 0) { oflag = 1; CREATE_FILE_NAME(output_file_name, OUTPUT_SUFFIX); } if (rflag) { CREATE_FILE_NAME(code_file_name, CODE_SUFFIX); } else code_file_name = output_file_name; if (dflag) { if (explicit_file_name) { char *suffix; defines_file_name = strdup(output_file_name); if (defines_file_name == 0) no_space(); /* does the output_file_name have a known suffix */ suffix = strrchr(output_file_name, '.'); if (suffix != 0 && (!strcmp(suffix, ".c") || /* good, old-fashioned C */ !strcmp(suffix, ".C") || /* C++, or C on Windows */ !strcmp(suffix, ".cc") || /* C++ */ !strcmp(suffix, ".cxx") || /* C++ */ !strcmp(suffix, ".cpp"))) /* C++ (Windows) */ { strncpy(defines_file_name, output_file_name, suffix - output_file_name + 1); defines_file_name[suffix - output_file_name + 1] = 'h'; defines_file_name[suffix - output_file_name + 2] = 0; } else { fprintf(stderr,"%s: suffix of output file name %s" " not recognized, no -d file generated.\n", myname, output_file_name); dflag = 0; free(defines_file_name); defines_file_name = 0; } } else { CREATE_FILE_NAME(defines_file_name, defines_suffix); } } if (iflag) { CREATE_FILE_NAME(externs_file_name, externs_suffix); } if (vflag) { CREATE_FILE_NAME(verbose_file_name, VERBOSE_SUFFIX); } if (gflag) { CREATE_FILE_NAME(graph_file_name, GRAPH_SUFFIX); } if (prefix != NULL) { FREE(file_prefix); } }
static void create_file_names(void) { size_t len; const char *defines_suffix; const char *externs_suffix; char *prefix; prefix = NULL; defines_suffix = DEFINES_SUFFIX; externs_suffix = EXTERNS_SUFFIX; /* compute the file_prefix from the user provided output_file_name */ if (output_file_name != 0) { if (!(prefix = strstr(output_file_name, ".tab.c")) && (prefix = strstr(output_file_name, ".c"))) { defines_suffix = ".h"; externs_suffix = ".i"; } } if (prefix != NULL) { len = (size_t) (prefix - output_file_name); file_prefix = (char *)MALLOC(len + 1); NO_SPACE(file_prefix); strncpy(file_prefix, output_file_name, len)[len] = 0; } else len = strlen(file_prefix); /* if "-o filename" was not given */ if (output_file_name == 0) { oflag = 1; CREATE_FILE_NAME(output_file_name, OUTPUT_SUFFIX); } if (rflag) { CREATE_FILE_NAME(code_file_name, CODE_SUFFIX); } else code_file_name = output_file_name; if (dflag) { CREATE_FILE_NAME(defines_file_name, defines_suffix); } if (iflag) { CREATE_FILE_NAME(externs_file_name, externs_suffix); } if (vflag) { CREATE_FILE_NAME(verbose_file_name, VERBOSE_SUFFIX); } if (gflag) { CREATE_FILE_NAME(graph_file_name, GRAPH_SUFFIX); } if (prefix != NULL) { FREE(file_prefix); } }
static const char *xml_parse_attr_val(ACL_XML2 *xml, const char *data) { int ch; ACL_XML2_ATTR *attr = xml->curr_node->curr_attr; if (attr->value == xml->dummy && !attr->quote) { SKIP_SPACE(data); if (IS_QUOTE(*data)) attr->quote = *data++; } if (*data == 0) return data; if (attr->value == xml->dummy) attr->value = END(xml); while ((ch = *data) != 0) { if (attr->quote) { if (ch == attr->quote) { if (NO_SPACE(xml)) return data; data++; attr->value_size = END(xml) - attr->value; ADD(xml, '\0'); xml->curr_node->status = ACL_XML2_S_ATTR; xml->curr_node->last_ch = ch; break; } if (NO_SPACE(xml)) return data; ADD(xml, ch); xml->curr_node->last_ch = ch; } else if (ch == '>') { if (NO_SPACE(xml)) return data; data++; attr->value_size = END(xml) - attr->value; ADD(xml, '\0'); xml_parse_check_self_closed(xml); if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL) && xml->curr_node->last_ch == '/') { if (--attr->value_size >= 0) attr->value[attr->value_size] = 0; xml->curr_node->status = ACL_XML2_S_RGT; } else xml->curr_node->status = ACL_XML2_S_LGT; break; } else if (IS_SPACE(ch)) { if (NO_SPACE(xml)) return data; data++; attr->value_size = END(xml) - attr->value; ADD(xml, '\0'); xml->curr_node->status = ACL_XML2_S_ATTR; xml->curr_node->last_ch = ch; break; } else { if (NO_SPACE(xml)) return data; ADD(xml, ch); xml->curr_node->last_ch = ch; } data++; } /* 说明属性值还未解析完,需要继续解析 */ if (xml->curr_node->status == ACL_XML2_S_AVAL) return data; /* 当状态发生改变时,则说明属性值已经完毕 */ if ((xml->flag & ACL_XML2_FLAG_XML_DECODE) && attr->value_size > 1) { const char *val = attr->value; attr->value = END(xml); (void) acl_xml_decode(val, xml->vbuf); attr->value_size = END(xml) - attr->value; ADD(xml, '\0'); /* skip one byte */ } /* 将该标签ID号映射至哈希表中,以便于快速查询 */ if (IS_ID(attr->name) && *attr->value != 0) { const char *ptr = attr->value; /* 防止重复ID被插入现象 */ if (acl_htable_find(xml->id_table, ptr) == NULL) { acl_htable_enter(xml->id_table, ptr, attr); /* 当该属性被加入哈希表后才会赋于节点 id */ xml->curr_node->id = attr->value; } } /* 必须将该节点的当前属性对象置空,以便于继续解析时 * 可以创建新的属性对象 */ xml->curr_node->curr_attr = NULL; return data; }
static const char *xml_parse_attr(ACL_XML2 *xml, const char *data) { int ch; ACL_XML2_ATTR *attr = xml->curr_node->curr_attr; if (attr == NULL || attr->name == xml->dummy) { SKIP_SPACE(data); SKIP_WHILE(*data == '=', data); } if (*data == 0) return data; if (*data == '>') { xml_parse_check_self_closed(xml); if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL) && xml->curr_node->last_ch == '/') { xml->curr_node->status = ACL_XML2_S_RGT; } else xml->curr_node->status = ACL_XML2_S_LGT; xml->curr_node->curr_attr = NULL; if (NO_SPACE(xml)) return data; data++; ADD(xml, '\0'); return data; } xml->curr_node->last_ch = *data; if (*data == '/') { data++; /* 此处返回后会触发本函数再次被调用,当下一个字节为 '>' 时, * 上面通过调用 xml_parse_check_self_closed 检查是否为自封闭 * 标签: "/>" */ return data; } if (attr == NULL) { attr = acl_xml2_attr_alloc(xml->curr_node); xml->curr_node->curr_attr = attr; attr->name = END(xml); } while ((ch = *data) != 0) { xml->curr_node->last_ch = ch; if (ch == '=') { if (NO_SPACE(xml)) return data; data++; attr->name_size = END(xml) - attr->name; ADD(xml, '\0'); xml->curr_node->status = ACL_XML2_S_AVAL; break; } if (!IS_SPACE(ch)) { if (NO_SPACE(xml)) return data; ADD(xml, ch); } data++; } return data; }
static const char *xml_parse_meta_comment(ACL_XML2 *xml, const char *data) { int ch; if (xml->curr_node->text == xml->dummy) SKIP_SPACE(data); if (*data == 0) return data; if (xml->curr_node->text == xml->dummy) xml->curr_node->text = END(xml); while ((ch = *data) != 0) { if (xml->curr_node->quote) { if (NO_SPACE(xml)) return data; if (ch == xml->curr_node->quote) xml->curr_node->quote = 0; else ADD(xml, ch); } else if (IS_QUOTE(ch)) { if (NO_SPACE(xml)) return data; if (xml->curr_node->quote == 0) xml->curr_node->quote = ch; else ADD(xml, ch); } else if (ch == '<') { if (NO_SPACE(xml)) return data; xml->curr_node->nlt++; ADD(xml, ch); } else if (ch == '>') { if (xml->curr_node->nlt == 0 && xml->curr_node->meta[0] == '-' && xml->curr_node->meta[1] == '-') { if (NO_SPACE(xml)) return data; data++; xml->curr_node->text_size = END(xml) - xml->curr_node->text; ADD(xml, '\0'); xml->curr_node->status = ACL_XML2_S_MEND; break; } xml->curr_node->nlt--; if (NO_SPACE(xml)) return data; ADD(xml, ch); } else if (xml->curr_node->nlt > 0) { if (NO_SPACE(xml)) return data; ADD(xml, ch); } else if (ch == '-') { if (xml->curr_node->meta[0] != '-') xml->curr_node->meta[0] = '-'; else if (xml->curr_node->meta[1] != '-') xml->curr_node->meta[1] = '-'; } else { if (xml->curr_node->meta[0] == '-') { if (NO_SPACE(xml)) return data; ADD(xml, '-'); xml->curr_node->meta[0] = 0; } if (xml->curr_node->meta[1] == '-') { if (NO_SPACE(xml)) return data; ADD(xml, '-'); xml->curr_node->meta[1] = 0; } if (NO_SPACE(xml)) return data; ADD(xml, ch); } data++; } if (xml->curr_node->status == ACL_XML2_S_MEND && (xml->flag & ACL_XML2_FLAG_XML_DECODE) && xml->curr_node->text_size > 0 && !NO_SPACE(xml)) { const char *txt = xml->curr_node->text; xml->curr_node->text = END(xml); (void) acl_xml_decode(txt, xml->vbuf); xml->curr_node->text_size = END(xml) - xml->curr_node->text; ADD(xml, '\0'); /* skip one byte */ } return data; }
static const char *xml_parse_meta_text(ACL_XML2 *xml, const char *data) { int ch; if (xml->curr_node->text == xml->dummy) SKIP_SPACE(data); if (*data == 0) return data; if (xml->curr_node->text == xml->dummy) xml->curr_node->text = END(xml); while ((ch = *data) != 0) { if (xml->curr_node->quote) { if (NO_SPACE(xml)) return data; if (ch == xml->curr_node->quote) xml->curr_node->quote = 0; ADD(xml, ch); } else if (IS_QUOTE(ch)) { if (NO_SPACE(xml)) return data; if (xml->curr_node->quote == 0) xml->curr_node->quote = ch; ADD(xml, ch); } else if (ch == '<') { if (NO_SPACE(xml)) return data; xml->curr_node->nlt++; ADD(xml, ch); } else if (ch != '>') { if (NO_SPACE(xml)) return data; ADD(xml, ch); } else if (xml->curr_node->nlt == 0) { char *last; if (NO_SPACE(xml)) return data; xml->curr_node->text_size = END(xml) - xml->curr_node->text; xml->curr_node->status = ACL_XML2_S_MEND; ADD(xml, '\0'); data++; if ((xml->curr_node->flag & ACL_XML2_F_META_QM) == 0) break; last = END(xml) - 1; while (last > xml->curr_node->text) { if (*last == '?') { *last = 0; xml->curr_node->text_size = last - xml->curr_node->text; break; } last--; } if (last == xml->curr_node->text) break; xml_meta_attr(xml->curr_node); break; } else { if (NO_SPACE(xml)) return data; xml->curr_node->nlt--; ADD(xml, ch); } data++; } if (xml->curr_node->status == ACL_XML2_S_MEND && (xml->flag & ACL_XML2_FLAG_XML_DECODE) && xml->curr_node->text_size > 0 && !NO_SPACE(xml)) { const char *txt = xml->curr_node->text; xml->curr_node->text = END(xml); (void) acl_xml_decode(txt, xml->vbuf); xml->curr_node->text_size = END(xml) - xml->curr_node->text; ADD(xml, '\0'); /* skip one byte */ } return data; }