btyacc-3.0+dfsg/0002755000175000017500000000000007235344714013763 5ustar eribertoeribertobtyacc-3.0+dfsg/reader.c0000644000175000017500000012206706743372462015403 0ustar eribertoeriberto#include "defs.h" #include "mstring.h" /* The line size must be a positive integer. One hundred was chosen */ /* because few lines in Yacc input grammars exceed 100 characters. */ /* Note that if a line exceeds LINESIZE characters, the line buffer */ /* will be expanded to accomodate it. */ #define LINESIZE 100 /* the maximum nember of arguments (inherited attributes) to a non-terminal */ /* this is a hard limit, but seems more than adequate */ #define MAXARGS 20 char *cache; int cinc, cache_size; int ntags, tagmax, havetags=0; char **tag_table; char saw_eof, unionized; char *cptr, *line; int linesize; FILE *inc_file = NULL; char inc_file_name[LINESIZE]; int inc_save_lineno; int in_ifdef = 0; int ifdef_skip; #define MAX_DEFD_VARS 1000 char *defd_vars[MAX_DEFD_VARS] = {NULL}; bucket *goal; int prec; int gensym; char last_was_action; int maxitems; bucket **pitem; int maxrules; bucket **plhs; int name_pool_size; char *name_pool; char line_format[] = "#line %d \"%s\"\n"; int cachec(int c) { assert(cinc >= 0); if (cinc >= cache_size) { if (!(cache = REALLOC(cache, cache_size += 256))) no_space(); } return cache[cinc++] = c; } /* * Get line * Return: 1 - reg. line finished with '\n'. * 0 - EOF. */ char *get_line() { extern int Eflag; FILE *f; int c; int i; /* VM: input from main or include file */ NextLine:; f = inc_file ? inc_file : input_file; i = 0; if (saw_eof || (c = getc(f)) == EOF) { /* VM: end of include file */ if(inc_file) { fclose(inc_file); inc_file = NULL; lineno = inc_save_lineno; goto NextLine; } if (line) FREE(line); saw_eof = 1; return line = cptr = 0; } if (line == 0 || linesize != (LINESIZE + 1)) { if (line) FREE(line); linesize = LINESIZE + 1; if (!(line = MALLOC(linesize))) no_space(); } ++lineno; while ((line[i] = c) != '\n') { if (++i + 1 >= linesize) if (!(line = REALLOC(line, linesize += LINESIZE))) no_space(); if ((c = getc(f)) == EOF) { c = '\n'; saw_eof = 1; } } line[i+1] = 0; /* VM: process %ifdef line */ if(strncmp(&line[0], "%ifdef ", 7)==0) { char var_name[80]; int ii=0; char **ps; for(i=7; line[i]!='\n' && line[i]!=' '; i++, ii++) { var_name[ii] = line[i]; } var_name[ii] = 0; if(in_ifdef) { error(lineno, 0, 0, "Cannot have nested %%ifdef"); } /* Find the preprocessor variable */ for(ps=&defd_vars[0]; *ps; ps++) { if(strcmp(*ps,var_name)==0) { break; } } in_ifdef = 1; if(*ps) { ifdef_skip = 0; } else { ifdef_skip = 1; } goto NextLine; } /* VM: process %endif line */ if(strncmp(&line[0], "%endif", 6)==0) { if(!in_ifdef) { error(lineno, 0, 0, "There is no corresponding %%ifdef for %%endif"); } in_ifdef = 0; goto NextLine; } /* VM: skip ordinary lines if ordered by %endif */ if(in_ifdef && ifdef_skip) { goto NextLine; } /* VM: Process %include line */ if(strncmp(&line[0], "%include ", 9)==0) { int ii=0; for(i=9; line[i]!='\n' && line[i]!=' '; i++, ii++) { inc_file_name[ii] = line[i]; } inc_file_name[ii] = 0; if(inc_file) { error(lineno, 0, 0, "Nested include lines are not allowed"); } inc_file = fopen(inc_file_name, "r"); if(inc_file==NULL) { error(lineno, 0, 0, "Cannot open include file %s", inc_file_name); } inc_save_lineno = lineno; lineno = 0; goto NextLine; } /* VM: process %define line */ if(strncmp(&line[0], "%define ", 8)==0) { char var_name[80]; int ii=0; char **ps; for(i=8; line[i]!='\n' && line[i]!=' '; i++, ii++) { var_name[ii] = line[i]; } var_name[ii] = 0; /* Find the preprocessor variable */ for(ps=&defd_vars[0]; *ps; ps++) { if(strcmp(*ps,var_name)==0) { error(lineno, 0, 0, "Preprocessor variable %s already defined", var_name); } } *ps = MALLOC(strlen(var_name)+1); strcpy(*ps, var_name); *++ps = NULL; goto NextLine; } if(Eflag) { printf("YPP: %s", line); } return cptr = line; } char *dup_line() { register char *p, *s, *t; if (line == 0) return (0); s = line; while (*s != '\n') ++s; if (!(p = MALLOC(s - line + 1))) no_space(); s = line; t = p; while ((*t++ = *s++) != '\n'); return (p); } char *skip_comment() { register char *s; int st_lineno = lineno; char *st_line = dup_line(); char *st_cptr = st_line + (cptr - line); s = cptr + 2; while (s[0] != '*' || s[1] != '/') { if (*s == '\n') { if ((s = get_line()) == 0) unterminated_comment(st_lineno, st_line, st_cptr); } else ++s; } FREE(st_line); return cptr = s + 2; } int nextc() { register char *s; if (line == 0 && get_line() == 0) return (EOF); s = cptr; for (;;) { switch (*s) { case '\n': if ((s = get_line()) == 0) return EOF; break; case ' ': case '\t': case '\f': case '\r': case '\v': case ',': case ';': ++s; break; case '\\': cptr = s; return ('%'); case '/': if (s[1] == '*') { cptr = s; s = skip_comment(); break; } else if (s[1] == '/') { if ((s = get_line()) == 0) return EOF; break; } /* fall through */ default: cptr = s; return (*s); } } } static struct keyword { char name[12]; int token; } keywords[] = { { "binary", NONASSOC }, { "ident", IDENT }, { "left", LEFT }, { "nonassoc", NONASSOC }, { "right", RIGHT }, { "start", START }, { "term", TOKEN }, { "token", TOKEN }, { "type", TYPE }, { "union", UNION }, }; int keyword() { register int c; char *t_cptr = cptr; struct keyword *key; c = *++cptr; if (isalpha(c)) { cinc = 0; while (isalnum(c) || c == '_' || c == '.' || c == '$') { cachec(tolower(c)); c = *++cptr; } cachec(NUL); if ((key = bsearch(cache, keywords, sizeof(keywords)/sizeof(*key), sizeof(*key), strcmp))) return key->token; } else { ++cptr; if (c == '{') return (TEXT); if (c == '%' || c == '\\') return (MARK); if (c == '<') return (LEFT); if (c == '>') return (RIGHT); if (c == '0') return (TOKEN); if (c == '2') return (NONASSOC); } syntax_error(lineno, line, t_cptr); /*NOTREACHED*/ return 0; } void copy_ident() { register int c; register FILE *f = output_file; if ((c = nextc()) == EOF) unexpected_EOF(); if (c != '"') syntax_error(lineno, line, cptr); ++outline; fprintf(f, "#ident \""); for (;;) { c = *++cptr; if (c == '\n') { fprintf(f, "\"\n"); return; } putc(c, f); if (c == '"') { putc('\n', f); ++cptr; return; } } } #define OUTC(c) do { /* output a character on f1 and f2, if non-null */ \ int _c = (c); \ putc(_c, f1); \ if (f2) putc(_c, f2); \ } while(0) void copy_string(int quote, FILE *f1, FILE *f2) { register int c; int s_lineno = lineno; char *s_line = dup_line(); char *s_cptr = s_line + (cptr - line - 1); for (;;) { OUTC(c = *cptr++); if (c == quote) { FREE(s_line); return; } if (c == '\n') unterminated_string(s_lineno, s_line, s_cptr); if (c == '\\') { OUTC(c = *cptr++); if (c == '\n') { if (get_line() == 0) unterminated_string(s_lineno, s_line, s_cptr); } } } } void copy_comment(FILE *f1, FILE *f2) { register int c; if ((c = *cptr) == '/') { OUTC('*'); while ((c = *++cptr) != '\n') { OUTC(c); if (c == '*' && cptr[1] == '/') OUTC(' '); } OUTC('*'); OUTC('/'); } else if (c == '*') { int c_lineno = lineno; char *c_line = dup_line(); char *c_cptr = c_line + (cptr - line - 1); OUTC(c); while ((c = *++cptr) != '*' || cptr[1] != '/') { OUTC(c); if (c == '\n') { if (get_line() == 0) unterminated_comment(c_lineno, c_line, c_cptr); } } OUTC(c); OUTC('/'); FREE(c_line); cptr += 2; } } #undef OUTC void copy_text() { register int c; register FILE *f = text_file; int need_newline = 0; int t_lineno = lineno; char *t_line = dup_line(); char *t_cptr = t_line + (cptr - line - 2); if (*cptr == '\n') { if (get_line() == 0) unterminated_text(t_lineno, t_line, t_cptr); } if (!lflag) fprintf(f, line_format, lineno, (inc_file?inc_file_name:input_file_name)); loop: switch (c = *cptr++) { case '\n': putc('\n', f); need_newline = 0; if (get_line()) goto loop; unterminated_text(t_lineno, t_line, t_cptr); case '\'': case '"': putc(c, f); copy_string(c, f, 0); need_newline = 1; goto loop; case '/': putc(c, f); copy_comment(f, 0); need_newline = 1; goto loop; case '%': case '\\': if (*cptr == '}') { if (need_newline) putc('\n', f); ++cptr; FREE(t_line); return; } /* fall through */ default: putc(c, f); need_newline = 1; goto loop; } } void copy_union() { FILE *dc_file; register int c; int depth; int u_lineno = lineno; char *u_line = dup_line(); char *u_cptr = u_line + (cptr - line - 6); if (unionized) over_unionized(cptr - 6); unionized = 1; if (!lflag) fprintf(text_file, line_format, lineno, (inc_file?inc_file_name:input_file_name)); /* VM: Print to either code file or defines file but not to both */ dc_file = dflag ? union_file : text_file; fprintf(dc_file, "\ntypedef union"); depth = 0; loop: c = *cptr++; putc(c, dc_file); switch (c) { case '\n': get_line(); if (line == 0) unterminated_union(u_lineno, u_line, u_cptr); goto loop; case '{': ++depth; goto loop; case '}': if (--depth == 0) { fprintf(dc_file, " YYSTYPE;\n"); FREE(u_line); return; } goto loop; case '\'': case '"': copy_string(c, dc_file, 0); goto loop; case '/': copy_comment(dc_file, 0); goto loop; default: goto loop; } } int hexval(int c) { if (c >= '0' && c <= '9') return (c - '0'); if (c >= 'A' && c <= 'F') return (c - 'A' + 10); if (c >= 'a' && c <= 'f') return (c - 'a' + 10); return (-1); } bucket *get_literal() { register int c, quote; register int i; register int n; register char *s; register bucket *bp; int s_lineno = lineno; char *s_line = dup_line(); char *s_cptr = s_line + (cptr - line); quote = *cptr++; cinc = 0; for (;;) { c = *cptr++; if (c == quote) break; if (c == '\n') unterminated_string(s_lineno, s_line, s_cptr); if (c == '\\') { char *c_cptr = cptr - 1; c = *cptr++; switch (c) { case '\n': get_line(); if (line == 0) unterminated_string(s_lineno, s_line, s_cptr); continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': n = c - '0'; c = *cptr; if (IS_OCTAL(c)) { n = (n << 3) + (c - '0'); c = *++cptr; if (IS_OCTAL(c)) { n = (n << 3) + (c - '0'); ++cptr; } } 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); } 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); } bucket *get_name() { 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)); } int get_number() { register int c; register int n; n = 0; for (c = *cptr; isdigit(c); c = *++cptr) n = 10*n + (c - '0'); return (n); } // // Date: Mon, 29 Jun 1998 16:36:47 +0200 // From: Matthias Meixner // Organization: TH Darmstadt, Mikroelektronische Systeme // // While using your version of BTYacc (V2.1), I have found a bug. // It does not correctly // handle typenames, if one typename is a prefix of another one and // if this type is used after the longer one. In this case BTYacc // produces invalid code. // // e.g. in: // -------------------------------------------- // %{ // // #include // // struct List { // struct List *next; // int foo; // }; // // %} // %union { // struct List *fooList; // int foo; // } // // %type a // %type b // // %token A // // %% // // a: b {$$=malloc(sizeof(*$$));$$->next=NULL;$$->foo=$1;} // | a b {$$=malloc(sizeof(*$$));$$->next=$1;$$->foo=$2;} // // b: A {$$=$1;} // static char *cache_tag(char *tag, int len) { int i; char *s; for (i = 0; i < ntags; ++i) { if (strncmp(tag, tag_table[i], len) == 0 && // VM: this is bug fix proposed by Matthias Meixner tag_table[i][len]==0) return (tag_table[i]); } if (ntags >= tagmax) { tagmax += 16; tag_table = tag_table ? RENEW(tag_table, tagmax, char *) : NEW2(tagmax, char *); if (tag_table == 0) no_space(); } s = MALLOC(len + 1); if (s == 0) no_space(); strncpy(s, tag, len); s[len] = 0; tag_table[ntags++] = s; return s; } char *get_tag() { register int c; 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)); c = nextc(); if (c == EOF) unexpected_EOF(); if (c != '>') illegal_tag(t_lineno, t_line, t_cptr); ++cptr; FREE(t_line); havetags = 1; return cache_tag(cache, cinc); } static char *scan_id(void) { char *b = cptr; while (isalnum(*cptr) || *cptr == '_' || *cptr == '$') cptr++; return cache_tag(b, cptr-b); } 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(); } } } static void declare_argtypes(bucket *bp) { char *tags[MAXARGS]; int args = 0, c; if (bp->args >= 0) retyped_warning(bp->name); cptr++; /* skip open paren */ for (;;) { c = nextc(); if (c == EOF) unexpected_EOF(); if (c != '<') syntax_error(lineno, line, cptr); tags[args++] = get_tag(); c = nextc(); if (c == ')') break; if (c == EOF) unexpected_EOF(); } cptr++; /* skip close paren */ bp->args = args; if (!(bp->argnames = NEW2(args, char *))) no_space(); if (!(bp->argtags = NEW2(args, char *))) no_space(); while (--args >= 0) { bp->argtags[args] = tags[args]; bp->argnames[args] = 0; } } void declare_types() { register int c; register bucket *bp=0; char *tag=0; c = nextc(); if (c == '<') { tag = get_tag(); c = nextc(); } if (c == EOF) unexpected_EOF(); for (;;) { c = nextc(); if (isalpha(c) || c == '_' || c == '.' || c == '$') { bp = get_name(); if (nextc() == '(') declare_argtypes(bp); else bp->args = 0; } else if (c == '\'' || c == '"') { bp = get_literal(); bp->args = 0; } else return; if (tag) { if (bp->tag && tag != bp->tag) retyped_warning(bp->name); bp->tag = tag; } } } void declare_start() { 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; } void read_declarations() { 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 TYPE: declare_types(); break; case START: declare_start(); break; } } } void initialize_grammar() { nitems = 4; maxitems = 300; pitem = NEW2(maxitems, bucket *); if (pitem == 0) no_space(); pitem[0] = 0; pitem[1] = 0; pitem[2] = 0; pitem[3] = 0; nrules = 3; maxrules = 100; plhs = NEW2(maxrules, bucket *); if (plhs == 0) no_space(); plhs[0] = 0; plhs[1] = 0; plhs[2] = 0; rprec = NEW2(maxrules, Yshort); if (rprec == 0) no_space(); rprec[0] = 0; rprec[1] = 0; rprec[2] = 0; rassoc = NEW2(maxrules, char); if (rassoc == 0) no_space(); rassoc[0] = TOKEN; rassoc[1] = TOKEN; rassoc[2] = TOKEN; } void expand_items() { maxitems += 300; pitem = RENEW(pitem, maxitems, bucket *); if (pitem == 0) no_space(); } void expand_rules() { maxrules += 100; plhs = RENEW(plhs, maxrules, bucket *); if (plhs == 0) no_space(); rprec = RENEW(rprec, maxrules, Yshort); if (rprec == 0) no_space(); rassoc = RENEW(rassoc, maxrules, char); if (rassoc == 0) no_space(); } /* set in copy_args and incremented by the various routines that will rescan ** the argument list as appropriate */ static int rescan_lineno; static char *copy_args(int *alen) { struct mstring *s = msnew(); int depth = 0, len = 1, c; char quote = 0; int a_lineno = lineno; char *a_line = dup_line(); char *a_cptr = a_line + (cptr - line - 1); rescan_lineno = lineno; while ((c = *cptr++) != ')' || depth || quote) { if (c == ',' && !quote && !depth) { len++; mputc(s, 0); continue; } mputc(s, c); if (c == '\n') { get_line(); if (!line) { if (quote) unterminated_string(a_lineno, a_line, a_cptr); else unterminated_arglist(a_lineno, a_line, a_cptr); } } else if (quote) { if (c == quote) quote = 0; else if (c == '\\') { if (*cptr != '\n') mputc(s, *cptr++); } } else { if (c == '(') depth++; else if (c == ')') depth--; else if (c == '\"' || c == '\'') quote = c; } } if (alen) *alen = len; FREE(a_line); return msdone(s); } static char *parse_id(char *p, char **save) { char *b; while (isspace(*p)) if (*p++ == '\n') rescan_lineno++; if (!isalpha(*p) && *p != '_') return 0; b = p; while (isalnum(*p) || *p == '_' || *p == '$') p++; if (save) { *save = cache_tag(b, p-b); } return p; } static char *parse_int(char *p, int *save) { int neg=0, val=0; while (isspace(*p)) if (*p++ == '\n') rescan_lineno++; if (*p == '-') { neg=1; p++; } if (!isdigit(*p)) return 0; while (isdigit(*p)) val = val*10 + *p++ - '0'; if (neg) val = -val; if (save) *save = val; return p; } static void parse_arginfo(bucket *a, char *args, int argslen) { char *p=args, *tmp; int i, redec=0; if (a->args >= 0) { if (a->args != argslen) error(rescan_lineno, 0, 0, "number of arguments of %s does't " "agree with previous declaration", a->name); redec = 1; } else { if (!(a->args = argslen)) return; if (!(a->argnames = NEW2(argslen, char *)) || !(a->argtags = NEW2(argslen, char *))) no_space(); } if (!args) return; for (i=0; iargtags[i] != tmp) error(rescan_lineno, 0, 0, "type of argument %d to %s " "doesn't agree with previous declaration", i+1, a->name); } else a->argtags[i] = tmp; } else if (!redec) a->argtags[i] = 0; if (!(p = parse_id(p, &a->argnames[i]))) bad_formals(); while (isspace(*p)) if (*p++ == '\n') rescan_lineno++; if (*p++) bad_formals(); } free(args); } static char *compile_arg(char **theptr, char *yyvaltag) { char *p = *theptr; struct mstring *c = msnew(); int i, j, n; Yshort *offsets=0, maxoffset; bucket **rhs; 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++; iclass != ARGUMENT) offsets[++j] = i - nitems + 1; rhs = pitem + nitems - 1; if (yyvaltag) msprintf(c, "yyval.%s = ", yyvaltag); else msprintf(c, "yyval = "); while (*p) { if (*p == '$') { char *tag = 0; if (*++p == '<') if (!(p = parse_id(++p, &tag)) || *p++ != '>') illegal_tag(rescan_lineno, 0, 0); if (isdigit(*p) || *p == '-') { int val; if (!(p = parse_int(p, &val))) dollar_error(rescan_lineno, 0, 0); if (val <= 0) i = val - n; else if (val > maxoffset) { dollar_warning(rescan_lineno, val); i = val - maxoffset; } else { i = offsets[val]; if (!tag && !(tag = rhs[i]->tag) && havetags) untyped_rhs(val, rhs[i]->name); } msprintf(c, "yyvsp[%d]", i); if (tag) msprintf(c, ".%s", tag); else if (havetags) unknown_rhs(val); } else if (isalpha(*p) || *p == '_') { char *arg; if (!(p = parse_id(p, &arg))) dollar_error(rescan_lineno, 0, 0); for (i=plhs[nrules]->args-1; i>=0; i--) if (arg == plhs[nrules]->argnames[i]) break; if (i<0) error(rescan_lineno, 0, 0, "unknown argument $%s", arg); if (!tag) tag = plhs[nrules]->argtags[i]; msprintf(c, "yyvsp[%d]", i - plhs[nrules]->args + 1 - n); if (tag) msprintf(c, ".%s", tag); else if (havetags) error(rescan_lineno, 0, 0, "untyped argument $%s", arg); } else dollar_error(rescan_lineno, 0, 0); } else { if (*p == '\n') rescan_lineno++; mputc(c, *p++); } } *theptr = p; if (maxoffset > 0) FREE(offsets); return msdone(c); } #define ARG_CACHE_SIZE 1024 static struct arg_cache { struct arg_cache *next; char *code; int rule; } *arg_cache[ARG_CACHE_SIZE]; static int lookup_arg_cache(char *code) { struct arg_cache *entry; entry = arg_cache[strnshash(code) % ARG_CACHE_SIZE]; while (entry) { if (!strnscmp(entry->code, code)) return entry->rule; entry = entry->next; } return -1; } static void insert_arg_cache(char *code, int rule) { struct arg_cache *entry = NEW(struct arg_cache); int i; if (!entry) no_space(); i = strnshash(code) % ARG_CACHE_SIZE; entry->code = code; entry->rule = rule; entry->next = arg_cache[i]; arg_cache[i] = entry; } static void clean_arg_cache(void) { struct arg_cache *e, *t; int i; for (i=0; inext, FREE(t)) free(e->code); arg_cache[i] = 0; } } void advance_to_start() { register int c; register bucket *bp; char *s_cptr; int s_lineno; char *args = 0; int argslen = 0; 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 == '(') { ++cptr; args = copy_args(&argslen); if (args == 0) no_space(); c = nextc(); } if (c != ':') syntax_error(lineno, line, cptr); start_rule(bp, s_lineno); parse_arginfo(bp, args, argslen); ++cptr; } void start_rule(bucket *bp, int s_lineno) { if (bp->class == TERM) terminal_lhs(s_lineno); bp->class = NONTERM; if (!bp->index) bp->index = nrules; if (nrules >= maxrules) expand_rules(); plhs[nrules] = bp; rprec[nrules] = UNDEFINED; rassoc[nrules] = TOKEN; } void end_rule() { register int i; if (!last_was_action && plhs[nrules]->tag) { for (i = nitems - 1; 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; } void insert_empty_rule() { 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 = ACTION; bp->args = 0; if ((nitems += 2) > maxitems) expand_items(); bpp = pitem + nitems - 1; *bpp-- = bp; while ((bpp[0] = bpp[-1])) --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 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; iargtags[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++; iclass != 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(); } btyacc-3.0+dfsg/error.c0000644000175000017500000001073506557370503015265 0ustar eribertoeriberto/* * routines for printing error messages */ #include "defs.h" #include extern FILE *inc_file; extern char inc_file_name[]; void FileError(char *fmt, ...); /* * VM: print error message with file coordinates. * Do it in style acceptable to emacs. */ void FileError(char *fmt, ...) { va_list args; fprintf(stderr, "%s:%d: ", (inc_file?inc_file_name:input_file_name), lineno); va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); fprintf(stderr, "\n"); } void fatal(char *msg) { fprintf(stderr, "fatal - %s\n", msg); done(2); } void no_space() { fprintf(stderr, "fatal - out of space\n"); done(2); } void open_error(char *filename) { fprintf(stderr, "fatal - cannot open \"%s\"\n", filename); done(2); } void unexpected_EOF() { FileError("unexpected end-of-file"); done(1); } void print_pos(char *st_line, char *st_cptr) { register char *s; if (st_line == 0) return; for (s = st_line; *s != '\n'; ++s) { if (isprint(*s) || *s == '\t') putc(*s, stderr); else putc('?', stderr); } putc('\n', stderr); for (s = st_line; s < st_cptr; ++s) { if (*s == '\t') putc('\t', stderr); else putc(' ', stderr); } putc('^', stderr); putc('\n', stderr); } int read_errs = 0; void error(int lineno, char *line, char *cptr, char *msg, ...) { char sbuf[512]; va_list args; va_start(args, msg); vsprintf(sbuf, msg, args); va_end(args); FileError("%s", sbuf); read_errs++; } void syntax_error(int lineno, char *line, char *cptr) { error(lineno, line, cptr, "syntax error"); exit(1); } void unterminated_comment(int lineno, char *line, char *cptr) { error(lineno, line, cptr, "unmatched /*"); exit(1); } void unterminated_string(int lineno, char *line, char *cptr) { error(lineno, line, cptr, "unterminated string"); exit(1); } void unterminated_text(int lineno, char *line, char *cptr) { error(lineno, line, cptr, "unmatched %%{"); exit(1); } void unterminated_union(int lineno, char *line, char *cptr) { error(lineno, line, cptr, "unterminated %%union"); exit(1); } void over_unionized(char *cptr) { error(lineno, line, cptr, "too many %%union declarations"); exit(1); } void illegal_tag(int lineno, char *line, char *cptr) { error(lineno, line, cptr, "illegal tag"); } void illegal_character(char *cptr) { error(lineno, line, cptr, "illegal character"); } void used_reserved(char *s) { error(lineno, 0, 0, "illegal use of reserved symbol %s", s); } void tokenized_start(char *s) { error(lineno, 0, 0, "the start symbol %s cannot be declared to be a token", s); } void retyped_warning(char *s) { FileError("the type of %s has been redeclared", s); } void reprec_warning(char *s) { FileError("the precedence of %s has been redeclared", s); } void revalued_warning(char *s) { FileError("the value of %s has been redeclared", s); } void terminal_start(char *s) { error(lineno, 0, 0, "the start symbol %s is a token", s); } void restarted_warning() { FileError("the start symbol has been redeclared"); } void no_grammar() { error(lineno, 0, 0, "no grammar has been specified"); } void terminal_lhs(int lineno) { error(lineno, 0, 0, "a token appears on the lhs of a production"); } void prec_redeclared() { error(lineno, 0, 0, "conflicting %%prec specifiers"); } void unterminated_action(int lineno, char *line, char *cptr) { error(lineno, line, cptr, "unterminated action"); } void unterminated_arglist(int lineno, char *line, char *cptr) { error(lineno, line, cptr, "unterminated argument list"); } void bad_formals() { error(lineno, 0, 0, "bad formal argument list"); } void dollar_warning(int a_lineno, int i) { int slineno = lineno; lineno = a_lineno; FileError("$%d references beyond the end of the current rule", i); lineno = slineno; } void dollar_error(int lineno, char *line, char *cptr) { error(lineno, line, cptr, "illegal $-name"); } void untyped_lhs() { error(lineno, 0, 0, "$$ is untyped"); } void untyped_rhs(int i, char *s) { error(lineno, 0, 0, "$%d (%s) is untyped", i, s); } void unknown_rhs(int i) { error(lineno, 0, 0, "$%d is untyped (out of range)", i); } void default_action_warning() { FileError("the default action assigns an undefined value to $$"); } void undefined_goal(char *s) { error(lineno, 0, 0, "the start symbol %s is undefined", s); } void undefined_symbol_warning(char *s) { fprintf(stderr, "warning - the symbol %s is undefined\n", s); } btyacc-3.0+dfsg/symtab.c0000644000175000017500000000355306367232302015424 0ustar eribertoeriberto#include "defs.h" /* TABLE_SIZE is the number of entries in the symbol table. */ /* TABLE_SIZE must be a power of two. */ #define TABLE_SIZE 1024 bucket **symbol_table; bucket *first_symbol; bucket *last_symbol; int hash(char *name) { register char *s; register int c, k; assert(name && *name); s = name; k = *s; while ((c = *++s)) k = (31*k + c) & (TABLE_SIZE - 1); return (k); } bucket *make_bucket(char *name) { register bucket *bp; assert(name); bp = (bucket *) MALLOC(sizeof(bucket)); if (bp == 0) no_space(); bp->link = 0; bp->next = 0; bp->name = MALLOC(strlen(name) + 1); if (bp->name == 0) no_space(); bp->tag = 0; bp->value = UNDEFINED; bp->index = 0; bp->prec = 0; bp->class = UNKNOWN; bp->assoc = TOKEN; bp->args = -1; bp->argnames = 0; bp->argtags = 0; if (bp->name == 0) no_space(); strcpy(bp->name, name); return (bp); } bucket *lookup(char *name) { register bucket *bp, **bpp; bpp = symbol_table + hash(name); bp = *bpp; while (bp) { if (strcmp(name, bp->name) == 0) return (bp); bpp = &bp->link; bp = *bpp; } *bpp = bp = make_bucket(name); last_symbol->next = bp; last_symbol = bp; return (bp); } void create_symbol_table() { register int i; register bucket *bp; symbol_table = (bucket **) MALLOC(TABLE_SIZE*sizeof(bucket *)); if (symbol_table == 0) no_space(); for (i = 0; i < TABLE_SIZE; i++) symbol_table[i] = 0; bp = make_bucket("error"); bp->index = 1; bp->class = TERM; first_symbol = bp; last_symbol = bp; symbol_table[hash("error")] = bp; } void free_symbol_table() { FREE(symbol_table); symbol_table = 0; } void free_symbols() { register bucket *p, *q; for (p = first_symbol; p; p = q) { q = p->next; FREE(p); } } btyacc-3.0+dfsg/skel2c0000644000175000017500000000164106400463702015061 0ustar eribertoeribertoBEGIN { havesection = 0; nsec = 0; printf "/*\n** This file generated automatically from %s\n*/\n\n", FILENAME; printf "#include \"defs.h\"\n"; } /^%%/ { if (havesection) { printf " 0\n};\n\n"; } if (NF >= 2) { havesection = 1; section = $2; seclist[nsec] = section; nsec = nsec + 1; printf "char *%s[] =\n{\n", $2; printf " \"#line %d \\\"%s\\\"\",\n", FNR+1, FILENAME; } else { havesection = 0; } next; } { if (havesection) { gsub(/\\/, "\\\\"); gsub(/\t/, "\\t"); gsub(/\"/, "\\\""); printf " \"%s\",\n", $0; } else { print $0; } } END { if (havesection) { printf " 0\n};\n\n"; } if (nsec > 0) { printf "struct section section_list[] = {\n"; for (i=0; ierrflag) #define yyssp (yypstate->ssp) #define yyvsp (yypstate->vsp) #define yyval (yypstate->val) #define yyss (yypstate->ss) #define yyvs (yypstate->vs) #define yystacksize (yypstate->stacksize) static YYSTYPE *yylvals=0, *yylvp=0, *yylve=0, *yylvlim=0; static short *yylexemes=0, *yylexp=0; #define YYLEX (yylvpsave) #ifndef __cplusplus #define YYSCOPY(t, f, s) memcpy(t, f, (s)*sizeof(YYSTYPE)) #define YYMORESTACK do { int p = yyssp - yyss; \ yystacksize += 16; \ yyss = (short *)realloc(yyss, yystacksize * sizeof(short)); \ yyvs = (YYSTYPE *)realloc(yyvs, yystacksize * sizeof(YYSTYPE)); \ yyssp = yyss + p; \ yyvsp = yyvs + p; \ } while (0) #else /* C++ */ #define YYSCOPY(to, from, size) do { int _i; \ for (_i = (size)-1; _i >= 0; _i--) \ (to)[_i] = (from)[_i]; \ } while(0) #define YYMORESTACK do { int p = yyssp - yyss; \ short *tss = yyss; YYSTYPE *tvs = yyvs; \ yyss = new short[yystacksize + 16]; \ yyvs = new YYSTYPE[yystacksize + 16]; \ memcpy(yyss, tss, yystacksize * sizeof(short)); \ YYSCOPY(yyvs, tvs, yystacksize); \ yystacksize += 16; \ delete[] tss; \ delete[] tvs; \ yyssp = yyss + p; \ yyvsp = yyvs + p; \ } while (0) #endif /* C++ */ %% body #ifndef YYNEWSTATE #ifdef __oldc static struct yyparsestate *YYNEWSTATE(size) int size; #else static struct yyparsestate *YYNEWSTATE(int size) #endif /* __oldc */ { struct yyparsestate *p; #ifndef __cplusplus p = (struct yyparsestate *)malloc(sizeof(struct yyparsestate)); p->stacksize = size+4; p->ss = (short *)malloc((size+4)*sizeof(short)); p->vs = (YYSTYPE *)malloc((size+4)*sizeof(YYSTYPE)); #else /* C++ */ p = new yyparsestate; p->stacksize = size+4; p->ss = new short[size + 4]; p->vs = new YYSTYPE[size + 4]; #endif /* C++ */ return p; } #endif /* YYNEWSTATE */ #ifndef YYFREESTATE #ifndef __cplusplus #define YYFREESTATE(p) (free((p)->ss), free((p)->vs), free(p)) #else /* C++ */ #define YYFREESTATE(p) (delete[] (p)->ss, delete[] (p)->vs, delete (p)) #endif /* C++ */ #endif /* YYFREESTATE */ static int yyexpand() { int p = yylvp-yylvals; int s = yylvlim-yylvals; s += 16; #ifndef __cplusplus yylvals = (YYSTYPE *)realloc(yylvals, s*sizeof(YYSTYPE)); yylexemes = (short *)realloc(yylexemes, s*sizeof(short)); #else /* C++ */ { short *tl = yylexemes; YYSTYPE *tv = yylvals; yylvals = new YYSTYPE[s]; yylexemes = new short[s]; memcpy(yylexemes, tl, (s-16)*sizeof(short)); YYSCOPY(yylvals, tv, s-16); delete[] tl; delete[] tv; } #endif /* C++ */ yylvp = yylve = yylvals + p; yylvlim = yylvals + s; yylexp = yylexemes + p; return 0; } #define YYABORT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab #define YYVALID do { if (yytrial) goto yyvalid; } while(0) #ifdef __cplusplus extern "C" char *getenv(const char *); #else extern char *getenv(); #endif int yyparse(int yychar, YYSTYPE yylval) { int yym, yyn, yystate, yynewerrflag; #if YYDEBUG char *yys; #endif if (yychar < 0) yychar = 0; if (!yypstate) { /* initialize the parser state */ yypstate = YYNEWSTATE(12); yypath = 0; yytrial = 0; yyerrflag = 0; yylvp = yylve = yylvals; yylexp = yylexemes; yyssp = yyss; yyvsp = yyvs; *yyssp = yypstate->state = 0; } yystate = yypstate->state; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("yydebug: state %d, input %d (%s)", yystate, yychar, yys); #ifdef YYDBPR printf("<"); YYDBPR(yylval); printf(">"); #endif printf("\n"); } #endif if (yystate == YYFINAL && yychar == 0) goto yyaccept; if (yytrial) { if (yylvp == yylvlim) yyexpand(); *yylvp++ = yylval; yylve++; *yylexp++ = yychar; } yyloop: if ((yyn = yydefred[yystate])) goto yyreduce; if (yychar < 0) { if (yylvp < yylve) { yylval = *yylvp++; yychar = *yylexp++; } else { yypstate->state = yystate; return 0; } #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("yydebug: state %d, reading %d (%s)", yystate, yychar, yys); #ifdef YYDBPR printf("<"); YYDBPR(yylval); printf(">"); #endif printf("\n"); } #endif } if ((yyn = yycindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { int ctry; struct yyparsestate *save; #if YYDEBUG if (yydebug) printf("yydebug: state %d, conflict%s\n", yystate, yypath ? ", following successful trial parse" : yytrial ? "" : ", starting trial parse"); #endif if (yypath) { save = yypath; yypath = save->save; ctry = save->ctry; if (save->state != yystate) goto yyabort; YYFREESTATE(save); } else { save = YYNEWSTATE(yyssp - yyss); save->save = yypstate->save; save->state = yystate; save->errflag = yypstate->errflag; save->ssp = save->ss + (yyssp - yyss); save->vsp = save->vs + (yyvsp - yyvs); memcpy(save->ss, yyss, (yyssp - yyss + 1)*sizeof(short)); YYSCOPY(save->vs, yyvs, yyssp - yyss + 1); ctry = yytable[yyn]; if (yyctable[ctry] == -1) { #if YYDEBUG if (yydebug && yychar >= 0) printf("yydebug: backtracking 1 token\n"); #endif ctry++; } save->ctry = ctry; if (!yytrial) { if (!yylexemes) { #ifndef __cplusplus yylexemes = (short *)malloc(16*sizeof(short)); yylvals = (YYSTYPE *)malloc(16*sizeof(YYSTYPE)); #else /* C++ */ yylexemes = new short[16]; yylvals = new YYSTYPE[16]; #endif /* C++ */ yylvlim = yylvals + 16; } if (yylvp == yylve) { yylvp = yylve = yylvals; yylexp = yylexemes; if (yychar >= 0) { *yylve++ = yylval; *yylexp = yychar; yychar = -1; } } } if (yychar >= 0) { yylvp--, yylexp--; yychar = -1; } save->lexeme = yylvp - yylvals; yypstate->save = save; } if (yytable[yyn] == ctry) { #if YYDEBUG if (yydebug) printf("yydebug: state %d, shifting to state %d\n", yystate, yyctable[ctry]); #endif if (yychar < 0) yylvp++, yylexp++; yychar = -1; if (yyerrflag > 0) --yyerrflag; yystate = yyctable[ctry]; goto yyshift; } else { yyn = yyctable[ctry]; goto yyreduce; } } if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { #if YYDEBUG if (yydebug) printf("yydebug: state %d, shifting to state %d\n", yystate, yytable[yyn]); #endif yychar = (-1); if (yyerrflag > 0) --yyerrflag; yystate = yytable[yyn]; yyshift: if (yyssp >= yyss + yystacksize - 1) YYMORESTACK; *++yyssp = yystate; *++yyvsp = yylval; goto yyloop; } if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { yyn = yytable[yyn]; goto yyreduce; } if (yyerrflag) goto yyinrecovery; yynewerrflag = 1; goto yyerrhandler; yyerrlab: yynewerrflag = 0; yyerrhandler: while (yytrial) { int ctry; struct yyparsestate *save; #if YYDEBUG if (yydebug) printf("yydebug: error in state %d, %s state %d, %d tokens\n", yystate, "backtracking to", yypstate->save->state, (int)(yylvp - yylvals - yypstate->save->lexeme)); #endif save = yypstate->save; yylvp = yylvals + save->lexeme; yylexp = yylexemes + save->lexeme; yychar = -1; yyssp = yyss + (save->ssp - save->ss); yyvsp = yyvs + (save->vsp - save->vs); memcpy(yyss, save->ss, (yyssp - yyss + 1) * sizeof(short)); YYSCOPY(yyvs, save->vs, yyvsp - yyvs + 1); ctry = ++save->ctry; yystate = save->state; if ((yyn = yyctable[ctry]) >= 0) goto yyreduce; yypstate->save = save->save; YYFREESTATE(save); #if YYDEBUG if (yydebug && !yytrial) printf("yydebug: trial parse failed, entering error mode\n"); #endif yynewerrflag = 1; } if (yynewerrflag) yyerror("syntax error"); yyinrecovery: if (yyerrflag < 3) { yyerrflag = 3; for (;;) { if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) { #if YYDEBUG if (yydebug) printf("yydebug: state %d, error recovery %s state %d\n", *yyssp, "shifting to", yytable[yyn]); #endif yystate = yytable[yyn]; goto yyshift; } else { #if YYDEBUG if (yydebug) printf("yydebug: error recovery discarding state %d\n", *yyssp); #endif if (yyssp <= yyss) goto yyabort; --yyssp; --yyvsp; } } } else { if (yychar == 0) goto yyabort; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("yydebug: state %d, error recovery discards token %d (%s)\n", yystate, yychar, yys); } #endif yychar = (-1); goto yyloop; } yyreduce: yym = yylen[yyn]; #if YYDEBUG if (yydebug) { printf("yydebug: state %d, reducing by rule %d (%s)", yystate, yyn, yyrule[yyn]); #ifdef YYDBPR if (yym) { int i; printf("<"); for (i=yym; i>0; i--) { if (i!=yym) printf(", "); YYDBPR(yyvsp[1-i]); } printf(">"); } #endif printf("\n"); } #endif if (yyssp + 1 - yym >= yyss + yystacksize) YYMORESTACK; yyval = yyvsp[1-yym]; switch (yyn) { %% trailer } #if YYDEBUG && defined(YYDBPR) if (yydebug) { printf("yydebug: after reduction, result is "); YYDBPR(yyval); printf("\n"); } #endif yyssp -= yym; yystate = *yyssp; yyvsp -= yym; yym = yylhs[yyn]; if (yystate == 0 && yym == 0) { #if YYDEBUG if (yydebug) printf("yydebug: after reduction, %s from state 0 to state %d\n", "shifting", YYFINAL); #endif yystate = YYFINAL; *++yyssp = YYFINAL; *++yyvsp = yyval; if (yychar == 0) goto yyaccept; goto yyloop; } if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yystate) yystate = yytable[yyn]; else yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) printf("yydebug: after reduction, %s from state %d to state %d\n", "shifting", *yyssp, yystate); #endif if (yyssp >= yyss + yystacksize - 1) YYMORESTACK; *++yyssp = yystate; *++yyvsp = yyval; goto yyloop; yyvalid: if (yypath) goto yyabort; while (yypstate->save) { struct yyparsestate *save = yypstate->save; yypstate->save = save->save; save->save = yypath; yypath = save; } #if YYDEBUG if (yydebug) printf("yydebug: trial successful, %s state %d, %d tokens\n", "backtracking to", yypath->state, (int)(yylvp - yylvals - yypath->lexeme)); #endif yychar = -1; yyssp = yyss + (yypath->ssp - yypath->ss); yyvsp = yyvs + (yypath->vsp - yypath->vs); memcpy(yyss, yypath->ss, (yyssp - yyss + 1) * sizeof(short)); YYSCOPY(yyvs, yypath->vs, yyvsp - yyvs + 1); yylvp = yylvals + yypath->lexeme; yylexp = yylexemes + yypath->lexeme; yystate = yypath->state; goto yyloop; yyabort: while (yypstate) { struct yyparsestate *save = yypstate; yypstate = save->save; YYFREESTATE(save); } while (yypath) { struct yyparsestate *save = yypath; yypath = save->save; YYFREESTATE(save); } return -1; yyaccept: if (yytrial) goto yyvalid; while (yypstate) { struct yyparsestate *save = yypstate; yypstate = save->save; YYFREESTATE(save); } while (yypath) { struct yyparsestate *save = yypath; yypath = save->save; YYFREESTATE(save); } return 1; } btyacc-3.0+dfsg/lalr.c0000644000175000017500000002401606367232301015053 0ustar eribertoeriberto#include "defs.h" typedef struct shorts { struct shorts *next; Yshort value; } shorts; int tokensetsize; Yshort *lookaheads; Yshort *LAruleno; unsigned *LA; Yshort *accessing_symbol; core **state_table; shifts **shift_table; reductions **reduction_table; Yshort *goto_map; Yshort *from_state; Yshort *to_state; static int infinity; static int maxrhs; static int ngotos; static unsigned *F; static Yshort **includes; static shorts **lookback; static Yshort **R; static Yshort *INDEX; static Yshort *VERTICES; static int top; void lalr() { tokensetsize = WORDSIZE(ntokens); set_state_table(); set_accessing_symbol(); set_shift_table(); set_reduction_table(); set_maxrhs(); initialize_LA(); set_goto_map(); initialize_F(); build_relations(); compute_FOLLOWS(); compute_lookaheads(); } void set_state_table() { register core *sp; state_table = NEW2(nstates, core *); for (sp = first_state; sp; sp = sp->next) state_table[sp->number] = sp; } void set_accessing_symbol() { register core *sp; accessing_symbol = NEW2(nstates, Yshort); for (sp = first_state; sp; sp = sp->next) accessing_symbol[sp->number] = sp->accessing_symbol; } void set_shift_table() { register shifts *sp; shift_table = NEW2(nstates, shifts *); for (sp = first_shift; sp; sp = sp->next) shift_table[sp->number] = sp; } void set_reduction_table() { register reductions *rp; reduction_table = NEW2(nstates, reductions *); for (rp = first_reduction; rp; rp = rp->next) reduction_table[rp->number] = rp; } void set_maxrhs() { register Yshort *itemp; register Yshort *item_end; register int length; register int max; length = 0; max = 0; item_end = ritem + nitems; for (itemp = ritem; itemp < item_end; itemp++) { if (*itemp >= 0) { length++; } else { if (length > max) max = length; length = 0; } } maxrhs = max; } void initialize_LA() { register int i, j, k; register reductions *rp; lookaheads = NEW2(nstates + 1, Yshort); k = 0; for (i = 0; i < nstates; i++) { lookaheads[i] = k; rp = reduction_table[i]; if (rp) k += rp->nreds; } lookaheads[nstates] = k; LA = NEW2(k * tokensetsize, unsigned); LAruleno = NEW2(k, Yshort); lookback = NEW2(k, shorts *); k = 0; for (i = 0; i < nstates; i++) { rp = reduction_table[i]; if (rp) { for (j = 0; j < rp->nreds; j++) { LAruleno[k] = rp->rules[j]; k++; } } } } void set_goto_map() { register shifts *sp; register int i; register int symbol; register int k; register Yshort *temp_map; register int state2; register int state1; goto_map = NEW2(nvars + 1, Yshort) - ntokens; temp_map = NEW2(nvars + 1, Yshort) - ntokens; ngotos = 0; for (sp = first_shift; sp; sp = sp->next) { for (i = sp->nshifts - 1; i >= 0; i--) { symbol = accessing_symbol[sp->shift[i]]; if (ISTOKEN(symbol)) break; if (ngotos == MAXSHORT) fatal("too many gotos"); ngotos++; goto_map[symbol]++; } } k = 0; for (i = ntokens; i < nsyms; i++) { temp_map[i] = k; k += goto_map[i]; } for (i = ntokens; i < nsyms; i++) goto_map[i] = temp_map[i]; goto_map[nsyms] = ngotos; temp_map[nsyms] = ngotos; from_state = NEW2(ngotos, Yshort); to_state = NEW2(ngotos, Yshort); for (sp = first_shift; sp; sp = sp->next) { state1 = sp->number; for (i = sp->nshifts - 1; i >= 0; i--) { state2 = sp->shift[i]; symbol = accessing_symbol[state2]; if (ISTOKEN(symbol)) break; k = temp_map[symbol]++; from_state[k] = state1; to_state[k] = state2; } } FREE(temp_map + ntokens); } /* Map_goto maps a state/symbol pair into its numeric representation. */ int map_goto(int state, int symbol) { register int high; register int low; register int middle; register int s; low = goto_map[symbol]; high = goto_map[symbol + 1]; for (;;) { assert(low <= high); middle = (low + high) >> 1; s = from_state[middle]; if (s == state) return (middle); else if (s < state) low = middle + 1; else high = middle - 1; } } void initialize_F() { register int i; register int j; register int k; register shifts *sp; register Yshort *edge; register unsigned *rowp; register Yshort *rp; register Yshort **reads; register int nedges; register int stateno; register int symbol; register int nwords; nwords = ngotos * tokensetsize; F = NEW2(nwords, unsigned); reads = NEW2(ngotos, Yshort *); edge = NEW2(ngotos + 1, Yshort); nedges = 0; rowp = F; for (i = 0; i < ngotos; i++) { stateno = to_state[i]; sp = shift_table[stateno]; if (sp) { k = sp->nshifts; for (j = 0; j < k; j++) { symbol = accessing_symbol[sp->shift[j]]; if (ISVAR(symbol)) break; SETBIT(rowp, symbol); } for (; j < k; j++) { symbol = accessing_symbol[sp->shift[j]]; if (nullable[symbol]) edge[nedges++] = map_goto(stateno, symbol); } if (nedges) { reads[i] = rp = NEW2(nedges + 1, Yshort); for (j = 0; j < nedges; j++) rp[j] = edge[j]; rp[nedges] = -1; nedges = 0; } } rowp += tokensetsize; } SETBIT(F, 0); digraph(reads); for (i = 0; i < ngotos; i++) { if (reads[i]) FREE(reads[i]); } FREE(reads); FREE(edge); } void build_relations() { register int i; register int j; register int k; register Yshort *rulep; register Yshort *rp; register shifts *sp; register int length; register int nedges; register int done; register int state1; register int stateno; register int symbol1; register int symbol2; register Yshort *shortp; register Yshort *edge; register Yshort *states; register Yshort **new_includes; includes = NEW2(ngotos, Yshort *); edge = NEW2(ngotos + 1, Yshort); states = NEW2(maxrhs + 1, Yshort); for (i = 0; i < ngotos; i++) { nedges = 0; state1 = from_state[i]; symbol1 = accessing_symbol[to_state[i]]; for (rulep = derives[symbol1]; *rulep >= 0; rulep++) { length = 1; states[0] = state1; stateno = state1; for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++) { symbol2 = *rp; sp = shift_table[stateno]; k = sp->nshifts; for (j = 0; j < k; j++) { stateno = sp->shift[j]; if (accessing_symbol[stateno] == symbol2) break; } states[length++] = stateno; } add_lookback_edge(stateno, *rulep, i); length--; done = 0; while (!done) { done = 1; rp--; if (ISVAR(*rp)) { stateno = states[--length]; edge[nedges++] = map_goto(stateno, *rp); if (nullable[*rp] && length > 0) done = 0; } } } if (nedges) { includes[i] = shortp = NEW2(nedges + 1, Yshort); for (j = 0; j < nedges; j++) shortp[j] = edge[j]; shortp[nedges] = -1; } } new_includes = transpose(includes, ngotos); for (i = 0; i < ngotos; i++) if (includes[i]) FREE(includes[i]); FREE(includes); includes = new_includes; FREE(edge); FREE(states); } void add_lookback_edge(int stateno, int ruleno, int gotono) { register int i, k; register int found; register shorts *sp; i = lookaheads[stateno]; k = lookaheads[stateno + 1]; found = 0; while (!found && i < k) { if (LAruleno[i] == ruleno) found = 1; else ++i; } assert(found); sp = NEW(shorts); sp->next = lookback[i]; sp->value = gotono; lookback[i] = sp; } Yshort **transpose(Yshort **R, int n) { register Yshort **new_R; register Yshort **temp_R; register Yshort *nedges; register Yshort *sp; register int i; register int k; nedges = NEW2(n, Yshort); for (i = 0; i < n; i++) { sp = R[i]; if (sp) { while (*sp >= 0) nedges[*sp++]++; } } new_R = NEW2(n, Yshort *); temp_R = NEW2(n, Yshort *); for (i = 0; i < n; i++) { k = nedges[i]; if (k > 0) { sp = NEW2(k + 1, Yshort); new_R[i] = sp; temp_R[i] = sp; sp[k] = -1; } } FREE(nedges); for (i = 0; i < n; i++) { sp = R[i]; if (sp) { while (*sp >= 0) *temp_R[*sp++]++ = i; } } FREE(temp_R); return (new_R); } void compute_FOLLOWS() { digraph(includes); } void compute_lookaheads() { register int i, n; register unsigned *fp1, *fp2, *fp3; register shorts *sp, *next; register unsigned *rowp; rowp = LA; n = lookaheads[nstates]; for (i = 0; i < n; i++) { fp3 = rowp + tokensetsize; for (sp = lookback[i]; sp; sp = sp->next) { fp1 = rowp; fp2 = F + tokensetsize * sp->value; while (fp1 < fp3) *fp1++ |= *fp2++; } rowp = fp3; } for (i = 0; i < n; i++) for (sp = lookback[i]; sp; sp = next) { next = sp->next; FREE(sp); } FREE(lookback); FREE(F); } void digraph(Yshort **relation) { register int i; infinity = ngotos + 2; INDEX = NEW2(ngotos + 1, Yshort); VERTICES = NEW2(ngotos + 1, Yshort); top = 0; R = relation; for (i = 0; i < ngotos; i++) INDEX[i] = 0; for (i = 0; i < ngotos; i++) { if (INDEX[i] == 0 && R[i]) traverse(i); } FREE(INDEX); FREE(VERTICES); } void traverse(int i) { register unsigned *fp1; register unsigned *fp2; register unsigned *fp3; register int j; register Yshort *rp; int height; unsigned *base; VERTICES[++top] = i; INDEX[i] = height = top; base = F + i * tokensetsize; fp3 = base + tokensetsize; rp = R[i]; if (rp) { while ((j = *rp++) >= 0) { if (INDEX[j] == 0) traverse(j); if (INDEX[i] > INDEX[j]) INDEX[i] = INDEX[j]; fp1 = base; fp2 = F + j * tokensetsize; while (fp1 < fp3) *fp1++ |= *fp2++; } } if (INDEX[i] == height) { for (;;) { j = VERTICES[top--]; INDEX[j] = infinity; if (i == j) break; fp1 = base; fp2 = F + j * tokensetsize; while (fp1 < fp3) *fp2++ = *fp1++; } } } btyacc-3.0+dfsg/mstring.c0000644000175000017500000000413006367232301015577 0ustar eribertoeriberto#include #include #include #include #include "mstring.h" /* parameters about string length. START is the starting size and ** START+TAIL should be a power of two */ #define START 24 #define TAIL 8 void msprintf(struct mstring *s, const char *fmt, ...) { static char buf[4096]; /* a big static buffer */ va_list args; int len; if (!s || !s->base) return; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); len = strlen(buf); if (len > (s->end - s->ptr)) { int cp = s->ptr - s->base, cl = s->end - s->base, nl = cl; while (len > (nl - cp)) nl = nl + nl + TAIL; if ((s->base = realloc(s->base, nl))) { s->ptr = s->base + cp; s->end = s->base + nl; } else { s->ptr = s->end = 0; return; } } memcpy(s->ptr, buf, len); s->ptr += len; } int mputchar(struct mstring *s, int ch) { if (!s || !s->base) return ch; if (s->ptr == s->end) { int len = s->end - s->base; if ((s->base = realloc(s->base, len+len+TAIL))) { s->ptr = s->base + len; s->end = s->base + len+len+TAIL; } else { s->ptr = s->end = 0; return ch; } } *s->ptr++ = ch; return ch; } struct mstring *msnew(void) { struct mstring *n = malloc(sizeof(struct mstring)); if (n && (n->base = n->ptr = malloc(START))) n->end = n->base + START; else if (n) { free(n); n = 0; } return n; } char *msdone(struct mstring *s) { char *r = 0; if (s) { mputc(s, 0); r = s->base; free(s); } return r; } /* compare two strings, ignoring whitespace, except between two letters or ** digits (and treat all of these as equal) */ int strnscmp(const char *a, const char *b) { while(1) { while (isspace(*a)) a++; while (isspace(*b)) b++; while (*a && *a == *b) a++,b++; if (isspace(*a)) { if (isalnum(a[-1]) && isalnum(*b)) break; } else if (isspace(*b)) { if (isalnum(b[-1]) && isalnum(*a)) break; } else break; } return *a - *b; } unsigned int strnshash(const char *s) { unsigned int h = 0; while (*s) { if (!isspace(*s)) h = (h<<5) - h + *s; s++; } return h; } btyacc-3.0+dfsg/verbose.c0000644000175000017500000001430306367232302015565 0ustar eribertoeriberto #include "defs.h" static Yshort *null_rules; void verbose() { register int i; if (!vflag) return; null_rules = (Yshort *) MALLOC(nrules*sizeof(Yshort)); if (null_rules == 0) no_space(); 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); } void log_unused() { register int i; register Yshort *p; fprintf(verbose_file, "\n\nRules never reduced:\n"); for (i = 3; i < nrules; ++i) { if (!rules_used[i]) { fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]); for (p = ritem + rrhs[i]; *p >= 0; ++p) fprintf(verbose_file, " %s", symbol_name[*p]); fprintf(verbose_file, " (%d)\n", i - 2); } } } void log_conflicts() { register int i; fprintf(verbose_file, "\n\n"); for (i = 0; i < nstates; i++) { if (SRconflicts[i] || RRconflicts[i]) { fprintf(verbose_file, "State %d contains ", i); if (SRconflicts[i] == 1) fprintf(verbose_file, "1 shift/reduce conflict"); else if (SRconflicts[i] > 1) fprintf(verbose_file, "%d shift/reduce conflicts", SRconflicts[i]); if (SRconflicts[i] && RRconflicts[i]) fprintf(verbose_file, ", "); if (RRconflicts[i] == 1) fprintf(verbose_file, "1 reduce/reduce conflict"); else if (RRconflicts[i] > 1) fprintf(verbose_file, "%d reduce/reduce conflicts", RRconflicts[i]); fprintf(verbose_file, ".\n"); } } } void print_state(int state) { if (state) fprintf(verbose_file, "\n\n"); if (SRconflicts[state] || RRconflicts[state]) print_conflicts(state); fprintf(verbose_file, "state %d\n", state); print_core(state); print_nulls(state); print_actions(state); } void print_conflicts(int state) { register int symbol, act, number; register action *p; symbol = act = number = -1; for (p = parser[state]; p; p = p->next) { if (p->suppressed == 2) continue; if (p->symbol != symbol) { symbol = p->symbol; number = p->number; if (p->action_code == SHIFT) act = SHIFT; else act = REDUCE; } else if (p->suppressed == 1) { if (state == final_state && symbol == 0) { fprintf(verbose_file, "%d: shift/reduce conflict " "(accept, reduce %d) on $end\n", state, p->number - 2); } else { if (act == SHIFT) { fprintf(verbose_file, "%d: shift/reduce conflict " "(shift %d, reduce %d) on %s\n", state, number, p->number - 2, symbol_name[symbol]); } else { fprintf(verbose_file, "%d: reduce/reduce conflict " "(reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2, symbol_name[symbol]); } } } } } void print_core(int state) { register int i; register int k; register int rule; register core *statep; register Yshort *sp; register Yshort *sp1; statep = state_table[state]; k = statep->nitems; for (i = 0; i < k; i++) { sp1 = sp = ritem + statep->items[i]; while (*sp >= 0) ++sp; rule = -(*sp); fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]); for (sp = ritem + rrhs[rule]; sp < sp1; sp++) fprintf(verbose_file, "%s ", symbol_name[*sp]); putc('.', verbose_file); while (*sp >= 0) { fprintf(verbose_file, " %s", symbol_name[*sp]); sp++; } fprintf(verbose_file, " (%d)\n", -2 - *sp); } } void print_nulls(int state) { register action *p; register int i, j, k, nnulls; nnulls = 0; for (p = parser[state]; p; p = p->next) { if (p->action_code == REDUCE && (p->suppressed == 0 || p->suppressed == 1)) { i = p->number; if (rrhs[i] + 1 == rrhs[i+1]) { for (j = 0; j < nnulls && i > null_rules[j]; ++j) continue; if (j == nnulls) { ++nnulls; null_rules[j] = i; } else if (i != null_rules[j]) { ++nnulls; for (k = nnulls - 1; k > j; --k) null_rules[k] = null_rules[k-1]; null_rules[j] = i; } } } } for (i = 0; i < nnulls; ++i) { j = null_rules[i]; fprintf(verbose_file, "\t%s : . (%d)\n", symbol_name[rlhs[j]], j - 2); } fprintf(verbose_file, "\n"); } void print_actions(int stateno) { register action *p; register shifts *sp; register int as; if (stateno == final_state) fprintf(verbose_file, "\t$end accept\n"); p = parser[stateno]; if (p) { print_shifts(p); print_reductions(p, defred[stateno]); } sp = shift_table[stateno]; if (sp && sp->nshifts > 0) { as = accessing_symbol[sp->shift[sp->nshifts - 1]]; if (ISVAR(as)) print_gotos(stateno); } } void print_shifts(action *p) { register int count; register action *q; count = 0; for (q = p; q; q = q->next) { if (q->suppressed < 2 && q->action_code == SHIFT) ++count; } if (count > 0) { for (; p; p = p->next) { if (p->action_code == SHIFT && p->suppressed == 0) fprintf(verbose_file, "\t%s shift %d\n", symbol_name[p->symbol], p->number); } } } void print_reductions(action *p, int defred) { register int k, anyreds; register action *q; anyreds = 0; for (q = p; q ; q = q->next) { if (q->action_code == REDUCE && q->suppressed < 2) { anyreds = 1; break; } } if (anyreds == 0) fprintf(verbose_file, "\t. error\n"); else { for (; p; p = p->next) { if (p->action_code == REDUCE && p->number != defred) { k = p->number - 2; if (p->suppressed == 0) fprintf(verbose_file, "\t%s reduce %d\n", symbol_name[p->symbol], k); } } if (defred > 0) fprintf(verbose_file, "\t. reduce %d\n", defred - 2); } } void print_gotos(int stateno) { register int i, k; register int as; register Yshort *to_state; register shifts *sp; putc('\n', verbose_file); sp = shift_table[stateno]; to_state = sp->shift; for (i = 0; i < sp->nshifts; ++i) { k = to_state[i]; as = accessing_symbol[k]; if (ISVAR(as)) fprintf(verbose_file, "\t%s goto %d\n", symbol_name[as], k); } } btyacc-3.0+dfsg/mkpar.c0000644000175000017500000001433006367232301015231 0ustar eribertoeriberto #include "defs.h" action **parser; int SRtotal; int RRtotal; Yshort *SRconflicts; Yshort *RRconflicts; Yshort *defred; Yshort *rules_used; Yshort nunused; Yshort final_state; static int SRcount; static int RRcount; action *parse_actions(int stateno); action *get_shifts(int stateno); action *add_reductions(int stateno, action *actions); action *add_reduce(action *actions, int ruleno, int symbol); void make_parser() { register int i; parser = NEW2(nstates, action *); for (i = 0; i < nstates; i++) parser[i] = parse_actions(i); find_final_state(); remove_conflicts(); unused_rules(); if (SRtotal + RRtotal > 0) total_conflicts(); defreds(); } action *parse_actions(int stateno) { register action *actions; actions = get_shifts(stateno); actions = add_reductions(stateno, actions); return (actions); } action *get_shifts(int stateno) { register action *actions, *temp; register shifts *sp; register Yshort *to_state; register int i, k; register int symbol; actions = 0; sp = shift_table[stateno]; if (sp) { to_state = sp->shift; for (i = sp->nshifts - 1; i >= 0; i--) { k = to_state[i]; symbol = accessing_symbol[k]; if (ISTOKEN(symbol)) { temp = NEW(action); temp->next = actions; temp->symbol = symbol; temp->number = k; temp->prec = symbol_prec[symbol]; temp->action_code = SHIFT; temp->assoc = symbol_assoc[symbol]; actions = temp; } } } return (actions); } action *add_reductions(int stateno, action *actions) { register int i, j, m, n; register int ruleno, tokensetsize; register unsigned *rowp; tokensetsize = WORDSIZE(ntokens); m = lookaheads[stateno]; n = lookaheads[stateno + 1]; for (i = m; i < n; i++) { ruleno = LAruleno[i]; rowp = LA + i * tokensetsize; for (j = ntokens - 1; j >= 0; j--) { if (BIT(rowp, j)) actions = add_reduce(actions, ruleno, j); } } return (actions); } action *add_reduce(action *actions, int ruleno, int symbol) { register action *temp, *prev, *next; prev = 0; for (next = actions; next && next->symbol < symbol; next = next->next) prev = next; while (next && next->symbol == symbol && next->action_code == SHIFT) { prev = next; next = next->next; } while (next && next->symbol == symbol && next->action_code == REDUCE && next->number < ruleno) { prev = next; next = next->next; } temp = NEW(action); temp->next = next; temp->symbol = symbol; temp->number = ruleno; temp->prec = rprec[ruleno]; temp->action_code = REDUCE; temp->assoc = rassoc[ruleno]; if (prev) prev->next = temp; else actions = temp; return (actions); } void find_final_state() { register int goal, i; register Yshort *to_state; register shifts *p; p = shift_table[0]; to_state = p->shift; goal = ritem[1]; for (i = p->nshifts - 1; i >= 0; --i) { final_state = to_state[i]; if (accessing_symbol[final_state] == goal) break; } } void unused_rules() { register int i; register action *p; rules_used = (Yshort *) MALLOC(nrules*sizeof(Yshort)); if (rules_used == 0) no_space(); for (i = 0; i < nrules; ++i) rules_used[i] = 0; for (i = 0; i < nstates; ++i) { for (p = parser[i]; p; p = p->next) { if (p->action_code == REDUCE && p->suppressed <= 1) rules_used[p->number] = 1; } } nunused = 0; for (i = 3; i < nrules; ++i) if (!rules_used[i]) ++nunused; if (nunused) if (nunused == 1) fprintf(stderr, "%s: 1 rule never reduced\n", myname); else fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused); } void remove_conflicts() { register int i; register int symbol; register action *p, *pref; SRtotal = 0; RRtotal = 0; SRconflicts = NEW2(nstates, Yshort); RRconflicts = NEW2(nstates, Yshort); for (i = 0; i < nstates; i++) { SRcount = 0; RRcount = 0; symbol = -1; pref = 0; for (p = parser[i]; p; p = p->next) { if (p->symbol != symbol) { pref = p; symbol = p->symbol; } else if (i == final_state && symbol == 0) { SRcount++; p->suppressed = 1; if (!pref->suppressed) pref->suppressed = 1; } else if (pref->action_code == SHIFT) { if (pref->prec > 0 && p->prec > 0) { if (pref->prec < p->prec) { pref->suppressed = 2; pref = p; } else if (pref->prec > p->prec) { p->suppressed = 2; } else if (pref->assoc == LEFT) { pref->suppressed = 2; pref = p; } else if (pref->assoc == RIGHT) { p->suppressed = 2; } else { pref->suppressed = 2; p->suppressed = 2; } } else { SRcount++; p->suppressed = 1; if (!pref->suppressed) pref->suppressed = 1; } } else { RRcount++; p->suppressed = 1; if (!pref->suppressed) pref->suppressed = 1; } } SRtotal += SRcount; RRtotal += RRcount; SRconflicts[i] = SRcount; RRconflicts[i] = RRcount; } } void total_conflicts() { fprintf(stderr, "%s: ", myname); if (SRtotal == 1) fprintf(stderr, "1 shift/reduce conflict"); else if (SRtotal > 1) fprintf(stderr, "%d shift/reduce conflicts", SRtotal); if (SRtotal && RRtotal) fprintf(stderr, ", "); if (RRtotal == 1) fprintf(stderr, "1 reduce/reduce conflict"); else if (RRtotal > 1) fprintf(stderr, "%d reduce/reduce conflicts", RRtotal); fprintf(stderr, ".\n"); } int sole_reduction(int stateno) { register int count, ruleno; register action *p; count = 0; ruleno = 0; for (p = parser[stateno]; p; p = p->next) { if (p->action_code == SHIFT && p->suppressed <= 1) return (0); else if (p->action_code == REDUCE && p->suppressed <= 1) { if (ruleno > 0 && p->number != ruleno) return (0); if (p->symbol != 1) ++count; ruleno = p->number; } } if (count == 0) return (0); return (ruleno); } void defreds() { register int i; defred = NEW2(nstates, Yshort); for (i = 0; i < nstates; i++) defred[i] = sole_reduction(i); } void free_action_row(action *p) { register action *q; while (p) { q = p->next; FREE(p); p = q; } } void free_parser() { register int i; for (i = 0; i < nstates; i++) free_action_row(parser[i]); FREE(parser); } btyacc-3.0+dfsg/main.c0000644000175000017500000001721606440750465015061 0ustar eribertoeriberto#include "defs.h" #include #include #include char dflag; char lflag; char rflag; char tflag; char vflag; int Eflag = 0; char *file_prefix = "y"; char *myname = "yacc"; #ifdef __MSDOS__ #define DIR_CHAR '\\' #define DEFAULT_TMPDIR "." #else /* Unix */ #define DIR_CHAR '/' #define DEFAULT_TMPDIR "/tmp" #endif char *temp_form = "yacc_t_XXXXXX"; int lineno; int outline; char *action_file_name; char *code_file_name; char *defines_file_name; char *input_file_name = ""; char *output_file_name; char *text_file_name; char *union_file_name; char *verbose_file_name; FILE *action_file; /* a temp file, used to save actions associated */ /* with rules until the parser is written */ FILE *code_file; /* y.code.c (used when the -r option is specified) */ FILE *defines_file; /* y.tab.h */ FILE *input_file; /* the input file */ FILE *output_file; /* y.tab.c */ FILE *text_file; /* a temp file, used to save text until all */ /* symbols have been defined */ FILE *union_file; /* a temp file, used to save the union */ /* definition until all symbol have been */ /* defined */ FILE *verbose_file; /* y.output */ int nitems; int nrules; int nsyms; int ntokens; int nvars; int start_symbol; char **symbol_name; Yshort *symbol_value; Yshort *symbol_prec; char *symbol_assoc; Yshort *ritem; Yshort *rlhs; Yshort *rrhs; Yshort *rprec; char *rassoc; Yshort **derives; char *nullable; void done(int k) { if (action_file) { fclose(action_file); unlink(action_file_name); } if (text_file) { fclose(text_file); unlink(text_file_name); } if (union_file) { fclose(union_file); unlink(union_file_name); } exit(k); } void onintr() { done(1); } void set_signals() { #ifdef SIGINT if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, onintr); #endif #ifdef SIGTERM if (signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, onintr); #endif #ifdef SIGHUP if (signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, onintr); #endif } void usage() { fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-S skeleton file] " "filename\n", myname); exit(1); } void getargs(int argc, char **argv) { register int i; register char *s; if (argc > 0) myname = argv[0]; for (i = 1; i < argc; ++i) { s = argv[i]; if (*s != '-') break; switch (*++s) { case '\0': input_file = stdin; if (i + 1 < argc) usage(); return; case '-': ++i; goto no_more_options; case 'b': if (*++s) file_prefix = s; else if (++i < argc) file_prefix = argv[i]; else usage(); continue; case 'd': dflag = 1; break; case 'D': /* Find the preprocessor variable */ { char **ps; char *var_name = s + 1; extern char *defd_vars[]; for(ps=&defd_vars[0]; *ps; ps++) { if(strcmp(*ps,var_name)==0) { error(lineno, 0, 0, "Preprocessor variable %s already defined", var_name); } } *ps = MALLOC(strlen(var_name)+1); strcpy(*ps, var_name); *++ps = NULL; } continue; case 'E': Eflag = 1; break; case 'l': lflag = 1; break; case 'r': rflag = 1; break; case 't': tflag = 1; break; case 'v': vflag = 1; break; case 'S': if (*++s) read_skel(s); else if (++i < argc) read_skel(argv[i]); else usage(); continue; default: usage(); } for (;;) { switch (*++s) { case '\0': goto end_of_option; case 'd': dflag = 1; break; case 'l': lflag = 1; break; case 'r': rflag = 1; break; case 't': tflag = 1; break; case 'v': vflag = 1; break; default: usage(); } } end_of_option:; } no_more_options:; if (i + 1 != argc) usage(); input_file_name = argv[i]; if (!file_prefix) { if (input_file_name) { file_prefix = strdup(input_file_name); if ((s = strrchr(file_prefix, '.'))) *s = 0; } else { file_prefix = "y"; } } } char *allocate(unsigned n) { register char *p; p = NULL; if (n) { /* VM: add a few bytes here, cause * Linux calloc does not like sizes like 32768 */ p = CALLOC(1, n+10); if (!p) no_space(); } return (p); } void create_file_names() { int i, len; char *tmpdir; tmpdir = getenv("TMPDIR"); if (tmpdir == 0) tmpdir = DEFAULT_TMPDIR; len = strlen(tmpdir); i = len + 13; if (len && tmpdir[len-1] != DIR_CHAR) ++i; action_file_name = MALLOC(i); if (action_file_name == 0) no_space(); text_file_name = MALLOC(i); if (text_file_name == 0) no_space(); union_file_name = MALLOC(i); if (union_file_name == 0) no_space(); strcpy(action_file_name, tmpdir); strcpy(text_file_name, tmpdir); strcpy(union_file_name, tmpdir); if (len && tmpdir[len - 1] != DIR_CHAR) { action_file_name[len] = DIR_CHAR; text_file_name[len] = DIR_CHAR; union_file_name[len] = DIR_CHAR; ++len; } strcpy(action_file_name + len, temp_form); strcpy(text_file_name + len, temp_form); strcpy(union_file_name + len, temp_form); action_file_name[len + 5] = 'a'; text_file_name[len + 5] = 't'; union_file_name[len + 5] = 'u'; if(mktemp(action_file_name)==NULL) { fprintf(stderr, "btyacc: Cannot create temporary file\n"); exit(1); } if(mktemp(text_file_name)==NULL) { fprintf(stderr, "btyacc: Cannot create temporary file\n"); exit(1); } if(mktemp(union_file_name)==NULL) { fprintf(stderr, "btyacc: Cannot create temporary file\n"); exit(1); } len = strlen(file_prefix); output_file_name = MALLOC(len + 7); if (output_file_name == 0) no_space(); strcpy(output_file_name, file_prefix); strcpy(output_file_name + len, OUTPUT_SUFFIX); if (rflag) { code_file_name = MALLOC(len + 8); if (code_file_name == 0) no_space(); strcpy(code_file_name, file_prefix); strcpy(code_file_name + len, CODE_SUFFIX); } else code_file_name = output_file_name; if (dflag) { defines_file_name = MALLOC(len + 7); if (defines_file_name == 0) no_space(); strcpy(defines_file_name, file_prefix); strcpy(defines_file_name + len, DEFINES_SUFFIX); } if (vflag) { verbose_file_name = MALLOC(len + 8); if (verbose_file_name == 0) no_space(); strcpy(verbose_file_name, file_prefix); strcpy(verbose_file_name + len, VERBOSE_SUFFIX); } } void open_files() { create_file_names(); if (input_file == 0) { input_file = fopen(input_file_name, "r"); if (input_file == 0) open_error(input_file_name); } action_file = fopen(action_file_name, "w"); if (action_file == 0) open_error(action_file_name); text_file = fopen(text_file_name, "w"); if (text_file == 0) open_error(text_file_name); if (vflag) { verbose_file = fopen(verbose_file_name, "w"); if (verbose_file == 0) open_error(verbose_file_name); } if (dflag) { defines_file = fopen(defines_file_name, "w"); if (defines_file == 0) open_error(defines_file_name); union_file = fopen(union_file_name, "w"); if (union_file == 0) open_error(union_file_name); } output_file = fopen(output_file_name, "w"); if (output_file == 0) open_error(output_file_name); if (rflag) { code_file = fopen(code_file_name, "w"); if (code_file == 0) open_error(code_file_name); } else code_file = output_file; } int main(int argc, char **argv) { set_signals(); getargs(argc, argv); open_files(); reader(); lr0(); lalr(); make_parser(); verbose(); output(); done(0); return 0; } btyacc-3.0+dfsg/empty.y0000644000175000017500000000001506367232301015276 0ustar eribertoeriberto%% start: ; btyacc-3.0+dfsg/Makefile0000644000175000017500000000371006743416374015427 0ustar eribertoeriberto# # Makefile for BtYacc. # VERSION = 3-0 DEST = . HDRS = defs.h mstring.h CFLAGS = -g -Wall -Wstrict-prototypes -Wmissing-prototypes LDFLAGS = -static LIBS = CC = gcc LINKER = gcc # LINKER = cl # CC = cl MAKEFILE = Makefile OBJS = closure.o error.o lalr.o lr0.o main.o mkpar.o output.o \ mstring.o reader.o readskel.o skeleton.o symtab.o verbose.o warshall.o PRINT = pr -f -l88 PROGRAM = btyacc SRCS = closure.c error.c lalr.c lr0.c main.c mkpar.c output.c \ mstring.c reader.c readskel.c skeleton.c symtab.c verbose.c warshall.c OTHERS = README README.BYACC \ Makefile btyaccpa.ske push.skel empty.y skel2c manpage makefile.dos \ skeleton.c all: $(PROGRAM) $(PROGRAM): $(OBJS) $(LIBS) $(LINKER) $(LDFLAGS) -o $(PROGRAM) $(OBJS) $(LIBS) clean:; rm -f $(OBJS) clobber:; rm -f $(OBJS) $(PROGRAM) distclean:; rm -f $(OBJS) $(PROGRAM) skeleton.c *.zip *.gz depend:; mkmf -f $(MAKEFILE) PROGRAM=$(PROGRAM) DEST=$(DEST) index:; ctags -wx $(HDRS) $(SRCS) install: $(PROGRAM) cp $(PROGRAM).exe /bin oldinstall: $(PROGRAM) @echo Installing $(PROGRAM) in $(DEST) install -s $(PROGRAM) $(DEST) listing:; $(PRINT) Makefile $(HDRS) $(SRCS) | lpr lint:; lint $(SRCS) program: $(PROGRAM) tags: $(HDRS) $(SRCS) ctags $(HDRS) $(SRCS) dist: tar zip tar: rm -f btyacc.tar btyacc.tar.gz tar cvf btyacc.tar $(OTHERS) $(SRCS) $(HDRS) test/*.y gzip -9 btyacc.tar mv btyacc.tar.gz btyacc-$(VERSION).tar.gz zip: zip btyacc.zip $(OTHERS) $(SRCS) $(HDRS) test/*.y mv btyacc.zip btyacc-$(VERSION).zip skeleton.c: btyaccpa.ske skel2c awk -f skel2c btyaccpa.ske >skeleton.c etags TAGS: etags *.c *.h ### closure.o: defs.h error.o: defs.h lalr.o: defs.h lr0.o: defs.h main.o: defs.h mkpar.o: defs.h mstring.o: mstring.h output.o: defs.h reader.o: defs.h mstring.h skeleton.o: defs.h symtab.o: defs.h verbose.o: defs.h warshall.o: defs.h btyacc-3.0+dfsg/test/0002755000175000017500000000000013662527643014747 5ustar eribertoeribertobtyacc-3.0+dfsg/test/t2.y0000644000175000017500000000700606367232277015467 0ustar eribertoeriberto %union { Scope *scope; Expr *expr; Expr_List *elist; Type *type; Decl *decl; Decl_List *dlist; Code *code; char *id; }; %left '+' '-' %left '*' '/' '%' %nonassoc PREFIX %nonassoc POSTFIX '(' '[' '.' %token ID %token CONSTANT %token EXTERN REGISTER STATIC CONST VOLATILE IF THEN ELSE CLCL %type expr() %type decl() declarator_list(, ) decl_list() %type statement() statement_list() block_statement() %type declarator(, ) formal_arg() %type decl_specs() decl_spec() typename() cv_quals cv_qual %type opt_scope() %type formal_arg_list() nonempty_formal_arg_list() %start input %% opt_scope($e): [ $$ = $e; ] | CLCL [ $$ = global_scope; ] | opt_scope ID CLCL [ Decl *d = lookup($1, $2); if (!d || !d->scope) YERROR; $$ = d->scope; ] ; typename($e): opt_scope ID [ Decl *d = lookup($1, $2); if (!d || !d->istype()) YYERROR; $$ = d->type; ] ; input: decl_list(global_scope = new_scope(0)) ; decl_list($e): | decl_list decl($e) ; decl($e): decl_specs declarator_list($e,$1) ';' [YYVALID;] | decl_specs declarator($e,$1) block_statement(start_fn_def($e, $2)) { finish_fn_def($2, $3); } ; decl_specs($e): decl_spec [ $$ = $1; ] | decl_specs decl_spec($e) [ $$ = type_combine($1, $2); ] ; cv_quals: [ $$ = 0; ] | cv_quals cv_qual [ $$ = type_combine($1, $2); ] ; decl_spec($e): cv_qual [ $$ = $1; ] | typename [ $$ = $1; ] | EXTERN [ $$ = bare_extern(); ] | REGISTER [ $$ = bare_register(); ] | STATIC [ $$ = bare_static(); ] ; cv_qual: CONST [ $$ = bare_const(); ] | VOLATILE [ $$ = bare_volatile(); ] ; declarator_list($e, $t): declarator_list ',' declarator($e, $t) | declarator ; declarator($e, $t): /* empty */ [ if (!$t) YYERROR; ] { $$ = declare($e, 0, $t); } | ID { $$ = declare($e, $1, $t); } | '(' declarator($e, $t) ')' { $$ = $2; } | '*' cv_quals declarator($e, $t) %prec PREFIX { $$ = make_pointer($3, $2); } | declarator '[' expr($e) ']' { $$ = make_array($1->type, $3); } | declarator '(' formal_arg_list($e) ')' cv_quals { $$ = build_function($1, $3, $5); } ; formal_arg_list($e): { $$ = 0; } | nonempty_formal_arg_list { $$ = $1; } ; nonempty_formal_arg_list($e): nonempty_formal_arg_list ',' formal_arg($e) { $$ = append_dlist($1, $3); } | formal_arg { $$ = build_dlist($1); } ; formal_arg($e): decl_specs declarator($e,$1) { $$ = $2; } ; expr($e): expr '+' expr($e) { $$ = build_expr($1, ADD, $3); } | expr '-' expr($e) { $$ = build_expr($1, SUB, $3); } | expr '*' expr($e) { $$ = build_expr($1, MUL, $3); } | expr '%' expr($e) { $$ = build_expr($1, MOD, $3); } | expr '/' expr($e) { $$ = build_expr($1, DIV, $3); } | '*' expr($e) %prec PREFIX { $$ = build_expr(0, REF, $2); } | ID { $$ = var_expr($e, $1); } | CONSTANT { $$ = $1; } ; statement($e): decl { $$ = 0; } | expr($e) ';' [YYVALID;] { $$ = build_expr_code($1); } | IF '(' expr($e) ')' THEN statement($e) ELSE statement($e) [YYVALID;] { $$ = build_if($3, $6, $8); } | IF '(' expr($e) ')' THEN statement($e) [YYVALID;] { $$ = build_if($3, $6, 0); } | block_statement(new_scope($e)) [YYVALID;]{ $$ = $1; } ; statement_list($e): { $$ = 0; } | statement_list statement($e) { $$ = code_append($1, $2); } ; block_statement($e): '{' statement_list($e) '}' { $$ = $2; } ; btyacc-3.0+dfsg/test/ansiC.y0000644000175000017500000001766506373405431016202 0ustar eribertoeriberto%token AUTO REGISTER STATIC EXTERN TYPEDEF VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED CONST VOLATILE STRUCT UNION ENUM CASE DEFAULT IF SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN ELSE MULEQ DIVEQ MODEQ ADDEQ SUBEQ LSHEQ RSHEQ ANDEQ XOREQ OREQ AND OR EQU NEQ LEQ GEQ LSH RSH INC DEC ARROW IDENTIFIER STRING INTCONST CHARCONST FLOATCONST ELIPSIS SIZEOF %% translation.unit : external.declaration | translation.unit external.declaration ; external.declaration : function.definition | declaration ; function.definition : declaration.specifiers declarator declaration.list compound.statement | declarator declaration.list compound.statement | declaration.specifiers declarator compound.statement | declarator compound.statement ; declaration : declaration.specifiers init.declarator.list ';' | declaration.specifiers ';' ; declaration.list : declaration | declaration.list declaration ; declaration.specifiers : storage.class.specifier declaration.specifiers | storage.class.specifier | type.specifier declaration.specifiers | type.specifier | type.qualifier declaration.specifiers | type.qualifier ; storage.class.specifier : AUTO | REGISTER | STATIC | EXTERN | TYPEDEF ; type.specifier : VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | struct.or.union.specifier | enum.specifier | typedef.name ; type.qualifier : CONST | VOLATILE ; struct.or.union.specifier : struct.or.union IDENTIFIER '{' struct.declaration.list '}' | struct.or.union '{' struct.declaration.list '}' | struct.or.union IDENTIFIER ; struct.or.union : STRUCT | UNION ; struct.declaration.list : struct.declaration | struct.declaration.list struct.declaration ; init.declarator.list : init.declarator | init.declarator.list ',' init.declarator ; init.declarator : declarator | declarator '=' initializer ; struct.declaration : specifier.qualifier.list struct.declarator.list ';' ; specifier.qualifier.list : type.specifier specifier.qualifier.list | type.specifier | type.qualifier specifier.qualifier.list | type.qualifier ; struct.declarator.list : struct.declarator | struct.declarator.list ',' struct.declarator ; struct.declarator : declarator | declarator ':' constant.expression | ':' constant.expression ; enum.specifier : ENUM IDENTIFIER '{' enumerator.list '}' | ENUM '{' enumerator.list '}' | ENUM IDENTIFIER ; enumerator.list : enumerator | enumerator.list ',' enumerator ; enumerator : IDENTIFIER | IDENTIFIER '=' constant.expression ; declarator : pointer direct.declarator | direct.declarator ; direct.declarator : IDENTIFIER | '(' declarator ')' | direct.declarator '[' constant.expression ']' | direct.declarator '[' ']' | direct.declarator '(' parameter.type.list ')' | direct.declarator '(' identifier.list ')' | direct.declarator '(' ')' ; pointer : '*' type.qualifier.list | '*' | '*' type.qualifier.list pointer | '*' pointer ; type.qualifier.list : type.qualifier | type.qualifier.list type.qualifier ; parameter.type.list : parameter.list | parameter.list ',' ELIPSIS ; parameter.list : parameter.declaration | parameter.list ',' parameter.declaration ; parameter.declaration : declaration.specifiers declarator | declaration.specifiers abstract.declarator | declaration.specifiers ; identifier.list : IDENTIFIER | identifier.list ',' IDENTIFIER ; initializer : assignment.expression | '{' initializer.list '}' | '{' initializer.list ',' '}' ; initializer.list : initializer | initializer.list ',' initializer ; type.name : specifier.qualifier.list abstract.declarator | specifier.qualifier.list ; abstract.declarator : pointer | pointer direct.abstract.declarator | direct.abstract.declarator ; direct.abstract.declarator : '(' abstract.declarator ')' | direct.abstract.declarator '[' constant.expression ']' | '[' constant.expression ']' | direct.abstract.declarator '[' ']' | '[' ']' | direct.abstract.declarator '(' parameter.type.list ')' | '(' parameter.type.list ')' | direct.abstract.declarator '(' ')' | '(' ')' ; typedef.name : IDENTIFIER ; statement : labeled.statement | expression.statement | compound.statement | selection.statement | iteration.statement | jump.statement ; labeled.statement : IDENTIFIER ':' statement | CASE constant.expression ':' statement | DEFAULT ':' statement ; expression.statement : expression ';' | ';' ; compound.statement : '{' declaration.list statement.list '}' | '{' declaration.list '}' | '{' statement.list '}' | '{' '}' ; statement.list : statement | statement.list statement ; selection.statement : IF '(' expression ')' statement | IF '(' expression ')' statement ELSE statement | SWITCH '(' expression ')' statement ; iteration.statement : WHILE '(' expression ')' statement | DO statement WHILE '(' expression ')' ';' | FOR '(' expression ';' expression ';' expression ')' statement | FOR '(' expression ';' expression ';' ')' statement | FOR '(' expression ';' ';' expression ')' statement | FOR '(' expression ';' ';' ')' statement | FOR '(' ';' expression ';' expression ')' statement | FOR '(' ';' expression ';' ')' statement | FOR '(' ';' ';' expression ')' statement | FOR '(' ';' ';' ')' statement ; jump.statement : GOTO IDENTIFIER ';' | CONTINUE ';' | BREAK ';' | RETURN expression ';' | RETURN ';' ; constant.expression : assignment.expression ; expression : assignment.expression | expression ',' assignment.expression ; assignment.expression : conditional.expression | unary.expression assignment.operator assignment.expression ; assignment.operator : '=' | MULEQ | DIVEQ | MODEQ | ADDEQ | SUBEQ | LSHEQ | RSHEQ | ANDEQ | XOREQ | OREQ ; conditional.expression : logical.OR.expression | logical.OR.expression '?' expression ':' conditional.expression ; logical.OR.expression : logical.AND.expression | logical.OR.expression OR logical.AND.expression ; logical.AND.expression : inclusive.OR.expression | logical.AND.expression AND inclusive.OR.expression ; inclusive.OR.expression : exclusive.OR.expression | inclusive.OR.expression '|' exclusive.OR.expression ; exclusive.OR.expression : AND.expression | exclusive.OR.expression '^' AND.expression ; AND.expression : equality.expression | AND.expression '&' equality.expression ; equality.expression : relational.expression | equality.expression EQU relational.expression | equality.expression NEQ relational.expression ; relational.expression : shift.expression | relational.expression '<' shift.expression | relational.expression '>' shift.expression | relational.expression LEQ shift.expression | relational.expression GEQ shift.expression ; shift.expression : additive.expression | shift.expression LSH additive.expression | shift.expression RSH additive.expression ; additive.expression : multiplicative.expression | additive.expression '+' multiplicative.expression | additive.expression '-' multiplicative.expression ; multiplicative.expression : cast.expression | multiplicative.expression '*' cast.expression | multiplicative.expression '/' cast.expression | multiplicative.expression '%' cast.expression ; cast.expression : unary.expression | '(' type.name ')' cast.expression ; unary.expression : postfix.expression | INC unary.expression | DEC unary.expression | unary.operator cast.expression | SIZEOF unary.expression | SIZEOF '(' type.name ')' ; unary.operator : '&' | '*' | '+' | '-' | '~' | '!' ; postfix.expression : primary.expression | postfix.expression '[' expression ']' | postfix.expression '(' argument.expression.list ')' | postfix.expression '(' ')' | postfix.expression '.' IDENTIFIER | postfix.expression ARROW IDENTIFIER | postfix.expression INC | postfix.expression DEC ; primary.expression : IDENTIFIER | constant | STRING | '(' expression ')' ; argument.expression.list : assignment.expression | argument.expression.list ',' assignment.expression ; constant : INTCONST | CHARCONST | FLOATCONST ; btyacc-3.0+dfsg/test/test.y0000644000175000017500000000077006440750536016115 0ustar eribertoeriberto%{ /* first section */ %} %% %{ /* second section */ %} S : /* empty */ { printf("S -> epsilon\n"); } | '(' S ')' S { printf("S -> ( S ) S\n"); } %ifdef ABC /* see how preprocessor can be used */ | '*' { printf("S -> *\n"); } %endif ; %% #include main() { printf("yyparse() = %d\n",yyparse()); } yylex() { int ch; do { ch = getchar(); } while (ch == ' ' || ch == '\n' || ch == '\t'); if (ch == EOF) return 0; return ch; } yyerror(s) char*s; { printf("%s\n",s); } btyacc-3.0+dfsg/test/error.y0000644000175000017500000000016506367232277016272 0ustar eribertoeriberto%% S: error %% main(){printf("yyparse() = %d\n",yyparse());} yylex(){return-1;} yyerror(s)char*s;{printf("%s\n",s);} btyacc-3.0+dfsg/test/t1.y0000644000175000017500000000037206367232277015465 0ustar eribertoeriberto%left LO '+' '-' %left HI '*' '/' '%' %nonassoc UNARY %% expr: expr op1 expr %prec LO | expr op2 expr %prec HI | unary expr %prec UNARY ; op1 : '+' | '-' ; op2 : '*' | '/' | '%' ; unary : '+' | '-' | '*' | '&' ; btyacc-3.0+dfsg/test/ansiC2.y0000644000175000017500000001741706367232277016270 0ustar eribertoeriberto%token AUTO REGISTER STATIC EXTERN TYPEDEF VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED CONST VOLATILE STRUCT UNION ENUM CASE DEFAULT IF SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN ELSE MULEQ DIVEQ MODEQ ADDEQ SUBEQ LSHEQ RSHEQ ANDEQ XOREQ OREQ AND OR EQU NEQ LEQ GEQ LSH RSH INC DEC ARROW IDENTIFIER STRING INTCONST CHARCONST FLOATCONST ELIPSIS SIZEOF %% translation.unit : external.declaration | translation.unit external.declaration ; external.declaration : function.definition | declaration ; function.definition : declaration.specifiers declarator declaration.list.opt compound.statement | declarator declaration.list.opt compound.statement ; declaration.specifiers.opt : | declaration.specifiers ; declaration.list.opt : | declaration.list ; declaration : declaration.specifiers init.declarator.list.opt ';' ; declaration.list : declaration | declaration.list declaration ; declaration.specifiers : storage.class.specifier declaration.specifiers.opt | type.specifier declaration.specifiers.opt | type.qualifier declaration.specifiers.opt ; storage.class.specifier : AUTO | REGISTER | STATIC | EXTERN | TYPEDEF ; type.specifier : VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | struct.or.union.specifier | enum.specifier | typedef.name ; type.qualifier : CONST | VOLATILE ; struct.or.union.specifier : struct.or.union identifier.opt '{' struct.declaration.list '}' | struct.or.union IDENTIFIER ; struct.or.union : STRUCT | UNION ; struct.declaration.list : struct.declaration | struct.declaration.list struct.declaration ; init.declarator.list.opt : | init.declarator.list ; init.declarator.list : init.declarator | init.declarator.list ',' init.declarator ; init.declarator : declarator | declarator '=' initializer ; struct.declaration : specifier.qualifier.list struct.declarator.list ';' ; specifier.qualifier.list.opt : | specifier.qualifier.list ; specifier.qualifier.list : type.specifier specifier.qualifier.list.opt | type.qualifier specifier.qualifier.list.opt ; struct.declarator.list : struct.declarator | struct.declarator.list ',' struct.declarator ; struct.declarator : declarator | declarator.opt ':' constant.expression ; enum.specifier : ENUM identifier.opt '{' enumerator.list '}' | ENUM IDENTIFIER ; enumerator.list : enumerator | enumerator.list ',' enumerator ; enumerator : IDENTIFIER | IDENTIFIER '=' constant.expression ; declarator.opt : | declarator ; declarator : pointer.opt direct.declarator ; direct.declarator : IDENTIFIER | '(' declarator ')' | direct.declarator '[' constant.expression ']' | direct.declarator '(' parameter.type.list ')' | direct.declarator '(' identifier.list.opt ')' ; pointer.opt : | pointer ; pointer : '*' type.qualifier.list.opt | '*' type.qualifier.list.opt pointer ; type.qualifier.list.opt : | type.qualifier.list ; type.qualifier.list : type.qualifier | type.qualifier.list type.qualifier ; parameter.type.list.opt : | parameter.type.list ; parameter.type.list : parameter.list | parameter.list ',' ELIPSIS ; parameter.list : parameter.declaration | parameter.list ',' parameter.declaration ; parameter.declaration : declaration.specifiers declarator | declaration.specifiers abstract.declarator.opt ; identifier.list.opt : | identifier.list ; identifier.list : IDENTIFIER | identifier.list ',' IDENTIFIER ; initializer : assignment.expression | '{' initializer.list '}' | '{' initializer.list ',' '}' ; initializer.list : initializer | initializer.list ',' initializer ; type.name : specifier.qualifier.list abstract.declarator.opt ; abstract.declarator.opt : | abstract.declarator ; abstract.declarator : pointer | pointer.opt direct.abstract.declarator ; direct.abstract.declarator.opt : | direct.abstract.declarator ; direct.abstract.declarator : '(' abstract.declarator ')' | direct.abstract.declarator.opt '[' constant.expression.opt ']' | direct.abstract.declarator '(' parameter.type.list.opt ')' | '(' parameter.type.list.opt ')' ; typedef.name : IDENTIFIER ; identifier.opt : | IDENTIFIER ; statement : labeled.statement | expression.statement | compound.statement | selection.statement | iteration.statement | jump.statement ; labeled.statement : IDENTIFIER ':' statement | CASE constant.expression ':' statement | DEFAULT ':' statement ; expression.statement : expression.opt ';' ; compound.statement : '{' declaration.list.opt statement.list.opt '}' ; statement.list.opt : | statement.list ; statement.list : statement | statement.list statement ; selection.statement : IF '(' expression ')' statement | IF '(' expression ')' statement ELSE statement | SWITCH '(' expression ')' statement ; iteration.statement : WHILE '(' expression ')' statement | DO statement WHILE '(' expression ')' ';' | FOR '(' expression.opt ';' expression.opt ';' expression.opt ')' statement ; jump.statement : GOTO IDENTIFIER ';' | CONTINUE ';' | BREAK ';' | RETURN expression.opt ';' ; expression.opt : | expression ; constant.expression.opt : | constant.expression ; constant.expression : assignment.expression ; expression : assignment.expression | expression ',' assignment.expression ; assignment.expression : conditional.expression | unary.expression assignment.operator assignment.expression ; assignment.operator : '=' | MULEQ | DIVEQ | MODEQ | ADDEQ | SUBEQ | LSHEQ | RSHEQ | ANDEQ | XOREQ | OREQ ; conditional.expression : logical.OR.expression | logical.OR.expression '?' expression ':' conditional.expression ; logical.OR.expression : logical.AND.expression | logical.OR.expression OR logical.AND.expression ; logical.AND.expression : inclusive.OR.expression | logical.AND.expression AND inclusive.OR.expression ; inclusive.OR.expression : exclusive.OR.expression | inclusive.OR.expression '|' exclusive.OR.expression ; exclusive.OR.expression : AND.expression | exclusive.OR.expression '^' AND.expression ; AND.expression : equality.expression | AND.expression '&' equality.expression ; equality.expression : relational.expression | equality.expression EQU relational.expression | equality.expression NEQ relational.expression ; relational.expression : shift.expression | relational.expression '<' shift.expression | relational.expression '>' shift.expression | relational.expression LEQ shift.expression | relational.expression GEQ shift.expression ; shift.expression : additive.expression | shift.expression LSH additive.expression | shift.expression RSH additive.expression ; additive.expression : multiplicative.expression | additive.expression '+' multiplicative.expression | additive.expression '-' multiplicative.expression ; multiplicative.expression : cast.expression | multiplicative.expression '*' cast.expression | multiplicative.expression '/' cast.expression | multiplicative.expression '%' cast.expression ; cast.expression : unary.expression | '(' type.name ')' cast.expression ; unary.expression : postfix.expression | INC unary.expression | DEC unary.expression | unary.operator cast.expression | SIZEOF unary.expression | SIZEOF '(' type.name ')' ; unary.operator : '&' | '*' | '+' | '-' | '~' | '!' ; postfix.expression : primary.expression | postfix.expression '[' expression ']' | postfix.expression '(' argument.expression.list.opt ')' | postfix.expression '.' IDENTIFIER | postfix.expression ARROW IDENTIFIER | postfix.expression INC | postfix.expression DEC ; primary.expression : IDENTIFIER | constant | STRING | '(' expression ')' ; argument.expression.list.opt : | argument.expression.list ; argument.expression.list : assignment.expression | argument.expression.list ',' assignment.expression ; constant : INTCONST | CHARCONST | FLOATCONST ; btyacc-3.0+dfsg/README0000644000175000017500000005222406743423003014636 0ustar eribertoeriberto BTYACC -- backtracking yacc =========================== BTYACC was created by Chris Dodd using ideas from many places and lots of code from the Berkeley Yacc distribution, which is a public domain yacc clone put together by the good folks at Berkeley. This code is distributed with NO WARRANTEE and is public domain. It is certain to contain bugs, which you should report to: chrisd@collins.com. Vadim Maslov of Siber Systems considerably modified BTYACC to make it suitable for production environment. Several people have suggested bug fixes that were incorporated into BtYacc. See the README.BYACC files for more about Berkeley Yacc and other sources of info. http://www.siber.com/btyacc/ is the current home of BtYacc. It is provided courtesy of Siber Systems http://www.siber.com/. Version 3.0 changes ------------------- by Vadim Maslov Changes mostly occurred in btyaccpa.ske file that contains the parsing shift/reduce/backtrack algorithm. Version 3.0 innovations focus on: - text position computation and propagation, - industrial-strength error processing and recovery. ** Added mechanism for computing and propagating text position of tokens and non-terminals. Compilers often need to build AST trees such that every node in a tree can relate to the parsed program source it came from. The following applications are very likely to need this: - debuggers that show actual source of the debugged program, - source-to-source translators that want unchanged parts of the tree to generate the unchanged code. The new YYPOSN mechanism added in this version of BtYacc helps you in automating the text position computation and in assigning the computed text positions to the AST. This mechanism is successfully used in commercial parsers and source-to-source translators. In standard Yaccs every token and every non-terminal has an YYSTYPE semantic value attached to it. In this new version every token and every non-terminal also has an YYPOSN text position attached to it. YYPOSN is a user-defined type that can be anything and that has a meaning of text position attached to token or non-terminal. In addition to semantic value stack BtYacc now maintains text position stack. Behavior of the text position stack is similar to the behavior of the semantic value stack. If using text position mechanism, you need to define the following: YYPOSN Preprocessor variable that contains C/C++ type of the text position attached to every token and non-terminal. yyposn Global variable of type YYPOSN. The lexer must assign text position of the returned token to yyposn, just like it assigns semantic value of the returned token to yylval. YYREDUCEPOSNFUNC Preprocessor variable that points to unction that is called after the grammar rule reduction to reduce text positions located on the stack. This function is called by BtYacc to reduce text positions. The function is called immediately after the regular rule reduction occurs. The function has the following prototype: void ReducePosn(YYPOSN &ret, YYPOSN *terms, YYSTYPE *term_vals, int term_no, int stk_pos, int yychar, YYPOSN &yyposn, UserType extra); The function arguments are: - ret Reference to the text position returned by the rule. The function must write the computed text position returned by the rule to ret. This is analogue of the $$ semantic value. - term_posns Array of the right-hand side rule components YYPOSN text positions. These are analogues of $1, $2, ..., $N in the text position world. - term_vals Array of the right-hand side (RHS) rule components YYSTYPE values. These are the $1,...,$N themselves. - term_no Number of the components in RHS of the reduced rule. Equal to size of arrays term_posns and term_vals. Also equal to N in $1,...,$N in the reduced rule. - stk_pos YYSTYPE/YYPOSN stack position before the reduction. - yychar Lookahead token that immediately follows the reduced RHS components. - yyposn YYPOSN of the token that immediately follows the reduced RHS components. - extra User-defined extra argument passed to ReducePosn. Typically this function extracts text positions from the right-hand side rule components and either assigns them to the returned $$ structure/tree or if no $$ value is returned, puts them into the ret text position from where it will be picked up by the later reduced rules. YYREDUCEPOSNFUNCARG Extra user-defined argument passed to the ReducePosn function. This argument can use any variables defined in btyaccpa.ske. ** Added code to btyaccpa.ske that automatically cleans up semantic semantic values and text positions of tokens and non-terminals that are discarded and deleted as a result of error processing. In the previous versions the discarded token and non-terminal semantic values were not cleaned that caused quite severe leaks. The only way to fix it was to add garbage collection to YYSTYPE class. Now BtYacc skeleton calls delete functions for semantic values and positions of the discarded tokens and non-terminals. You need to define the following functions that BtYacc calls when it needs to delete semantic value or text position. YYDELETEVAL User-defined function that is called by BtYacc to delete semantic value of the token or non-terminal. The user-defined function must have the prototype: void DeleteYYval(YYSTYPE v, int type); v is semantic value to delete, type is one of the following: 0 discarding token 1 discarding state 2 cleaning up stack when aborting YYDELETEPOSN User-defined function that is called by BtYacc to delete text position of the token or non-terminal. The user-defined function must have the prototype: void DeleteYYposn(YYPOSN p, int type); v is semantic value to delete, type is one of the following: 0 discarding token 1 discarding state 2 cleaning up stack when aborting ** User can define "detailed" syntax error processing function that reports an *exact* position of the token that caused the error. If you define preprocessor variable YYERROR_DETAILED in your grammar then you need define the following error processing function: void yyerror_detailed(char *text, int errt, YYSTYPE &errt_value, YYPOSN &errt_posn); It receives the following arguments: text Error message. errt Code of the token that caused the error. errt_value Value of the token that caused the error. errt_posn Text position of token that caused error. ** Dropped compatibility with C. Compatibility with C became increasingly difficult to maintain as new features were added to btyaccpa.ske. So we dropped it. If anybody wants to make the new version compatible with C, we would gladly accept the changes. Meanwhile we expect that you use C++ to write grammar actions and everything else in grammar files. Since C is (in a sense) subset of C++, your C-based grammar may work if you use C++ compiler to compile it. Version 3.0 bugs fixed ---------------------- Matthias Meixner fixed a bug: BtYacc does not correctly handle typenames, if one typename is a prefix of another one and if this type is used after the longer one. In this case BTYacc produces invalid code. Version 2.1 changes ------------------- by Vadim Maslov ** Added preprocessor statements to BtYacc that are similar in function and behavior to C/C++ preprocessor statements. These statements are used to: - Introduce modularity into a grammar by breaking it into several *.y files and assembling different grammars from the *.y modules using %include and %ifdef. - Have several versions of the same grammar by using %ifdef and $endif. - To include automatically generated grammar fragment. For instance, we use %include to include automatically generated list of tokens. Preprocessor statements are: %define Define preprocessor variable named . %ifdef If preprocessor variable named is defined by %define, then process the text from this %ifdef to the closing %endif. %endif Closing bracket for %ifdef preprocessor statement. Only one nesting level of %ifdef-%endif is allowed. %include Process contents of the file named . If is a relative name, it is looked up in a directory in which btyacc was started. Only one nesting level of %include is allowed. Version 2.0 changes ------------------- by Vadim Maslov ** Changed 16-bit short numbers to 32-bit int numbers in grammar tables, so that huge grammar tables (tables that are larger than 32768 elements) resulting from huge grammars (Cobol grammar, for instance) can work correctly. You need to have 32-bit integer to index table bigger than 32768 elements, 16-bit integer is not enough. The original BtYacc just generated non-working tables larger than 32768 elements without even notifying about the table overflow. ** Make error recovery work correctly when error happens while processing nested conflicts. Original BtYacc could infinitely cycle in certain situations that involved error recovery while in nested conflict. More detailed explanation: when we have nested conflicts (conflict that happens while trial-processing another conflict), it leads btyacc into NP-complete searching of conflict tree. The ultimate goal is YYVALID operator that selects a particular branch of that tree as a valid one. If no YYVALID is found on the tree, then error recovery takes over. The problem with this is that error recovery is started in the same state context that exists on the last surveyed branch of the conflict tree. Sometimes this last branch may be of zero length and it results in recovering to exactly the same state as existed before entering the conflict. BtYacc cycles then. We solved this problem by memorizing the longest path in the conflict tree while browsing it. If we ever get into error recovery, we restore state that existed on the longest path. Effectively we say: if we have an error, let us move forward as far as we possibly could while we were browsing the conflict tree. ** Introduce YYVALID_NESTED operation in addition to simply YYVALID. When we have a nested conflict (conflict while processing in trial mode for another conflict), we want to relate YYVALID to a particular level of conflict being in trial. Since we mostly anticipate only 2-level nested conflicts YYVALID_NESTED tells the parser to satisfy only the internal conflict. Therefore, in 1-level conflict situation YYVALID_NESTED acts like a regular YYVALID, but in 2-level conflict it is a no-op and the other YYVALID for outer conflict will be searched for. ** Improved handling of situation where /tmp directory is missing. Original btyacc just died quietly when /tmp directory was missing. We added code that states the problem explicitly. While on UNIX /tmp directory is always present, it may be missing on WIN32 systems, therefore diagnosing this situation is important. Version 1.0 changes: BackTracking ================================= by Chris Dodd BTYACC is a modified version of yacc that supports automatic backtracking and semantic disambiguation to parse ambiguous grammars, as well as syntactic sugar for inherited attributes (which tend to introduce conflicts). Whenever a btyacc generated parser runs into a shift-reduce or reduce-reduce error in the parse table, it remembers the current parse point (yacc stack and input stream state), and goes into trial parse mode. It then continues parsing, ignoring most rule actions. If it runs into an error (either through the parse table or through an action calling YYERROR), it backtracks to the most recent conflict point and tries a different alternative. If it finds a successful parse (reaches the end of the input or an action calls YYVALID), it backtracks to the point where it first entered trial parse mode, and continues with a full parse (executing all actions), following the path of the successful trial. Actions in btyacc come in two flavors -- {}-actions, which are only executed when not in trial mode, and []-actions which are executed regardless of mode. There are also inherited attributes, which look like arguments (they are enclosed in "()") and act like []-actions. What this buys you: * No more lexer feedback hack. In yacc grammars for C, a standard hack, know as the "lexer feedback hack" is used to find typedef names. The lexer uses semantic information to decide if any given identifier is a typedef-name or not and returns a special token. With btyacc, you no longer need to do this; the lexer should just always return an identifier. The btyacc grammar then needs a rule of the form: typename: ID [ if (!IsTypeName(LookupId($1))) YYERROR; ] While the hack works adequately well for parsing C, it becomes a nightmare when you try to parse something like C++, where treating an ID as a typedef becomes heavily dependent on context. * Easy disambiguation via simple ordering. Btyacc runs its trials via the rule "try shifting first, then try reducing by the order that the conflicting rules appear in the input file". This means you can deal with semantic a disambiguation rule like: [1] If it looks like a declaration it is, otherwise [2] If it looks like an expression it is, otherwise [3] it is a syntax error [Ellis&Stroustrup, Annotated C++ Reference Manual, p93] To deal with this, you need only put all the rules for declarations before the rules for expressions in the grammar file. * No extra cost if you do not use it. Backtracking is only triggered when the parse hits a shift/reduce or reduce/reduce conflict in the table. If you have no conflicts in your grammar, there is no extra cost, other than some extra code which will never be invoked. * C++ and ANSI C compatible parsers. The parsers produced by btyacc can be compiled with C++ correctly. If you "#define" YYSTYPE to be some C++ type with constructor and destructor, everything will work fine. My favorite is "#define YYSTYPE SmartPointer", where SmartPointer is a smart pointer type that does garbage collection on the pointed to objects. BTYACC was originally written to make it easy to write a C++ parser (my goal was to be able to use the grammar out of the back of the ARM with as few modifications as possible). Anyone who has ever looked at Jim Roskind public domain C++ yacc grammar, or the yacc-based grammar used in g++ knows how difficult this is. BTYACC is very useful for parsing any ambiguous grammar, particularly ones that come from trying to merge two (or more) complete grammars. Limitations of the backtracking: Currently, the generated parser does NO pruning of alternate parsing paths. To avoid an exponential explosion of possible paths (and parsing time), you need to manually tell the parser when it can throw away saved paths using YYVALID. In practice, this turns out to be fairly easy to do. A C++ parser (for example) can just put a [YYVALID;] after every complete declaration and statement rule, corresponding to pruning the backtracking state after seeing a ';' or '}' -- there will never be a situation in which it is useful to backtrack past either of these. Inherited attributes in btyacc: Inherited attributes look a lot like function arguments to non-terminals, which is what they end up being in a recursive descent parser, but NOT how they are implemented in btyacc. Basically they are just syntactic sugar for embedded semantic actions and $0, $-1, ... in normal yacc. btyacc gives you two big advantages besides just the syntax: 1. it does type checking on the inherited attributes, so you do not have to specify $0 and makes sure you give the correct number of arguments (inherited attributes) to every use of a non-terminal. 2. It "collapses" identical actions from that are produced from inherited attributes. This eliminates many potential reduce-reduce conflicts arising from the inherited attributes. You use inherited attributes by declaring the types of the attributes in the preamble with a type declaration and declaring names of the attributes on the lhs of the yacc rule. You can of course have more than one rule with the same lhs, and you can even give them different names in each, but the type and number must be the same. Here is a small example: /* lhs takes 2 inherited attributes */ %type lhs(, ) stuff(, ) %% lhs($i1, $i2) : { $$ = $i1 } | lhs($i1, $i2) stuff($1,$i2) { $$ = $2; } This is roughly equivalent to the following yacc code: lhs : { $$ = $-1; } | lhs [ $$ = $-1; ] [ $$ = $0; ] stuff { $$ = $4; } ; See the file "test/t2.y" for a longer and more complete example. At the current time, the start symbol cannot have any arguments. Variant parsers: Btyacc supports the -S flag to use a different parser skeleton, changing the way that the parser is called and used. The skeleton "push.skel" is included to produce a "passive" parser that you feed tokens to (rather than having the parser call a separate yylex routine). With push.skel, yyparse is defined as follows: int yyparse(int token, YYSTYPE yylval) You should call yyparse repeatedly with successive tokens of input. It returns 0 if more input is needed, 1 for a successful parse, and -1 for an unrecoverable parse error. Miscellaneous Features in ver. 1.0 ---------------------------------- by Chris Dodd The -r option has been implemented. The -r option tells Yacc to put the read-only tables in y.tab.c and the code and variables in y.code.c. Keith Bostic asked for this option so that :yyfix could be eliminated. The -l and -t options have been implemented. The -l option tells Yacc not to include #line directives in the code it produces. The -t option causes debugging code to be included in the compiled parser. The code for error recovery has been changed to implement the same algorithm as AT&T Yacc. There will still be differences in the way error recovery works because AT&T Yacc uses more default reductions than Berkeley Yacc. The environment variable TMPDIR determines the directory where temporary files will be created. If TMPDIR is defined, temporary files will be created in the directory whose pathname is the value of TMPDIR. By default, temporary files are created in /tmp. The keywords are now case-insensitive. For example, %nonassoc, %NONASSOC, %NonAssoc, and %nOnAsSoC are all equivalent. Commas and semicolons that are not part of C code are treated as commentary. Line-end comments, as in BCPL, are permitted. Line-end comments begin with // and end at the next end-of-line. Line-end comments are permitted in C code; they are converted to C comments on output. The form of y.output files has been changed to look more like those produced by AT&T Yacc. A new kind of declaration has been added. The form of the declaration is %ident string where string is a sequence of characters beginning with a double quote and ending with either a double quote or the next end-of-line, whichever comes first. The declaration will cause a #ident directive to be written near the start of the output file. If a parser has been compiled with debugging code, that code can be enabled by setting an environment variable. If the environment variable YYDEBUG is set to 0, debugging output is suppressed. If it is set to 1, debugging output is written to standard output. Building BtYacc --------------- by Chris Dodd and Vadim Maslov We used GCC and GNU make to compile BtYacc both on UNIX and WIN32 paltforms. You are welcome to try different combinations of makes and compilers. Most likely it will work, but it may require Makefile changes. There is no config script. Just type "make" and it should compile. AWK. If you want to change file btyaccpa.ske (backtracking parser skeleton), you will need awk to compile it into skeleton.c file. We used GNU AWK (gawk) version 3.0. It is known that using older versions of gawk may create problems in compilation, because older awks have problems with backslashes at the end of a line. For MSDOS, there a "makefile.dos" that should do the trick. Note: makefile.dos was not tested for a long time. The result of compilation should be a single executable called "btyacc" which you can install anywhere you like; it does not require any other files in the distribution to run. Legal Stuff ----------- by Chris Dodd and Vadim Maslov In English: BtYacc is freeware. BtYacc is distributed with no warranty whatsoever. The author and any other contributors take no responsibility for any and all consequences of its use. In Legalese: LIMITATION OF LIABILITY. NEITHER SIBER SYSTEMS NOR ANY OF ITS LICENSORS NOR ANY BTYACC CONTRIBUTOR SHALL BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE, DATA OR DATA USE, CAUSED BY BTYACC AND INCURRED BY CUSTOMER OR ANY THIRD PARTY, WHETHER IN AN ACTION IN CONTRACT OR TORT, EVEN IF SIBER SYSTEMS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. btyacc-3.0+dfsg/lr0.c0000644000175000017500000002270606367232301014622 0ustar eribertoeriberto #include "defs.h" extern Yshort *itemset; extern Yshort *itemsetend; extern unsigned *ruleset; int nstates; core *first_state; shifts *first_shift; reductions *first_reduction; static core **state_set; static core *this_state; static core *last_state; static shifts *last_shift; static reductions *last_reduction; static int nshifts; static Yshort *shift_symbol; static Yshort *redset; static Yshort *shiftset; static Yshort **kernel_base; static Yshort **kernel_end; static Yshort *kernel_items; void allocate_itemsets() { register Yshort *itemp; register Yshort *item_end; register int symbol; register int i; register int count; register int max; register Yshort *symbol_count; count = 0; symbol_count = NEW2(nsyms, Yshort); item_end = ritem + nitems; for (itemp = ritem; itemp < item_end; itemp++) { symbol = *itemp; if (symbol >= 0) { count++; symbol_count[symbol]++; } } kernel_base = NEW2(nsyms, Yshort *); kernel_items = NEW2(count, Yshort); count = 0; max = 0; for (i = 0; i < nsyms; i++) { kernel_base[i] = kernel_items + count; count += symbol_count[i]; if (max < symbol_count[i]) max = symbol_count[i]; } shift_symbol = symbol_count; kernel_end = NEW2(nsyms, Yshort *); } void allocate_storage() { allocate_itemsets(); shiftset = NEW2(nsyms, Yshort); redset = NEW2(nrules + 1, Yshort); state_set = NEW2(nitems, core *); } void append_states() { register int i; register int j; register int symbol; #ifdef TRACE fprintf(stderr, "Entering append_states()\n"); #endif for (i = 1; i < nshifts; i++) { symbol = shift_symbol[i]; j = i; while (j > 0 && shift_symbol[j - 1] > symbol) { shift_symbol[j] = shift_symbol[j - 1]; j--; } shift_symbol[j] = symbol; } for (i = 0; i < nshifts; i++) { symbol = shift_symbol[i]; shiftset[i] = get_state(symbol); } } void free_storage() { FREE(shift_symbol); FREE(redset); FREE(shiftset); FREE(kernel_base); FREE(kernel_end); FREE(kernel_items); FREE(state_set); } void generate_states() { allocate_storage(); itemset = NEW2(nitems, Yshort); ruleset = NEW2(WORDSIZE(nrules), unsigned); set_first_derives(); initialize_states(); while (this_state) { closure(this_state->items, this_state->nitems); save_reductions(); new_itemsets(); append_states(); if (nshifts > 0) save_shifts(); this_state = this_state->next; } finalize_closure(); free_storage(); } int get_state(int symbol) { register int key; register Yshort *isp1; register Yshort *isp2; register Yshort *iend; register core *sp; register int found; register int n; #ifdef TRACE fprintf(stderr, "Entering get_state(%d)\n", symbol); #endif isp1 = kernel_base[symbol]; iend = kernel_end[symbol]; n = iend - isp1; key = *isp1; assert(0 <= key && key < nitems); sp = state_set[key]; if (sp) { found = 0; while (!found) { if (sp->nitems == n) { found = 1; isp1 = kernel_base[symbol]; isp2 = sp->items; while (found && isp1 < iend) { if (*isp1++ != *isp2++) found = 0; } } if (!found) { if (sp->link) { sp = sp->link; } else { sp = sp->link = new_state(symbol); found = 1; } } } } else { state_set[key] = sp = new_state(symbol); } return (sp->number); } void initialize_states() { register int i; register Yshort *start_derives; register core *p; start_derives = derives[start_symbol]; for (i = 0; start_derives[i] >= 0; ++i) continue; p = (core *) MALLOC(sizeof(core) + i*sizeof(Yshort)); if (p == 0) no_space(); p->next = 0; p->link = 0; p->number = 0; p->accessing_symbol = 0; p->nitems = 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; } void new_itemsets() { register int i; register int shiftcount; register Yshort *isp; register Yshort *ksp; register int symbol; for (i = 0; i < nsyms; i++) kernel_end[i] = 0; shiftcount = 0; isp = itemset; while (isp < itemsetend) { i = *isp++; symbol = ritem[i]; if (symbol > 0) { ksp = kernel_end[symbol]; if (!ksp) { shift_symbol[shiftcount++] = symbol; ksp = kernel_base[symbol]; } *ksp++ = i + 1; kernel_end[symbol] = ksp; } } nshifts = shiftcount; } core *new_state(int symbol) { register int n; register core *p; register Yshort *isp1; register Yshort *isp2; register Yshort *iend; #ifdef TRACE fprintf(stderr, "Entering new_state(%d)\n", symbol); #endif if (nstates >= MAXSHORT) fatal("too many states"); isp1 = kernel_base[symbol]; iend = kernel_end[symbol]; n = iend - isp1; p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(Yshort))); p->accessing_symbol = symbol; p->number = nstates; p->nitems = n; isp2 = p->items; while (isp1 < iend) *isp2++ = *isp1++; last_state->next = p; last_state = p; nstates++; return (p); } /* show_cores is used for debugging */ void show_cores() { core *p; int i, j, k, n; int itemno; k = 0; for (p = first_state; p; ++k, p = p->next) { if (k) printf("\n"); printf("state %d, number = %d, accessing symbol = %s\n", k, p->number, symbol_name[p->accessing_symbol]); n = p->nitems; for (i = 0; i < n; ++i) { itemno = p->items[i]; printf("%4d ", itemno); j = itemno; while (ritem[j] >= 0) ++j; printf("%s :", symbol_name[rlhs[-ritem[j]]]); j = rrhs[-ritem[j]]; while (j < itemno) printf(" %s", symbol_name[ritem[j++]]); printf(" ."); while (ritem[j] >= 0) printf(" %s", symbol_name[ritem[j++]]); printf("\n"); fflush(stdout); } } } /* show_ritems is used for debugging */ void show_ritems() { int i; for (i = 0; i < nitems; ++i) printf("ritem[%d] = %d\n", i, ritem[i]); } /* show_rrhs is used for debugging */ void show_rrhs() { int i; for (i = 0; i < nrules; ++i) printf("rrhs[%d] = %d\n", i, rrhs[i]); } /* show_shifts is used for debugging */ void show_shifts() { shifts *p; int i, j, k; k = 0; for (p = first_shift; p; ++k, p = p->next) { if (k) printf("\n"); printf("shift %d, number = %d, nshifts = %d\n", k, p->number, p->nshifts); j = p->nshifts; for (i = 0; i < j; ++i) printf("\t%d\n", p->shift[i]); } } void save_shifts() { register shifts *p; register Yshort *sp1; register Yshort *sp2; register Yshort *send; p = (shifts *) allocate((unsigned) (sizeof(shifts) + (nshifts - 1) * sizeof(Yshort))); p->number = this_state->number; p->nshifts = nshifts; sp1 = shiftset; sp2 = p->shift; send = shiftset + nshifts; while (sp1 < send) *sp2++ = *sp1++; if (last_shift) { last_shift->next = p; last_shift = p; } else { first_shift = p; last_shift = p; } } void save_reductions() { register Yshort *isp; register Yshort *rp1; register Yshort *rp2; register int item; register int count; register reductions *p; register Yshort *rend; count = 0; for (isp = itemset; isp < itemsetend; isp++) { item = ritem[*isp]; if (item < 0) { redset[count++] = -item; } } if (count) { p = (reductions *) allocate((unsigned) (sizeof(reductions) + (count - 1) * sizeof(Yshort))); p->number = this_state->number; p->nreds = count; rp1 = redset; rp2 = p->rules; rend = rp1 + count; while (rp1 < rend) *rp2++ = *rp1++; if (last_reduction) { last_reduction->next = p; last_reduction = p; } else { first_reduction = p; last_reduction = p; } } } void set_derives() { register int i, k; register int lhs; register Yshort *rules; derives = NEW2(nsyms, Yshort *); rules = NEW2(nvars + nrules, Yshort); k = 0; for (lhs = start_symbol; lhs < nsyms; lhs++) { derives[lhs] = rules + k; for (i = 0; i < nrules; i++) { if (rlhs[i] == lhs) { rules[k] = i; k++; } } rules[k] = -1; k++; } #ifdef DEBUG print_derives(); #endif } void free_derives() { FREE(derives[start_symbol]); FREE(derives); } #ifdef DEBUG void print_derives() { register int i; register Yshort *sp; printf("\nDERIVES\n\n"); for (i = start_symbol; i < nsyms; i++) { printf("%s derives ", symbol_name[i]); for (sp = derives[i]; *sp >= 0; sp++) { printf(" %d", *sp); } putchar('\n'); } putchar('\n'); } #endif void set_nullable() { register int i, j; register int empty; int done; nullable = MALLOC(nsyms); if (nullable == 0) no_space(); for (i = 0; i < nsyms; ++i) nullable[i] = 0; done = 0; while (!done) { done = 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 = 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 free_nullable() { FREE(nullable); } void lr0() { set_derives(); set_nullable(); generate_states(); } btyacc-3.0+dfsg/makefile.dos0000644000175000017500000000302506743423041016237 0ustar eribertoeriberto# Makefile for MS-DOS using Borland C (by P. Foggia) # DEST = . HDRS = defs.h mstring.h CFLAGS = -ml -c LDFLAGS = /c # Change LIBDIR to your compiler's library path LIBDIR = L:\bc\lib C0 = $(LIBDIR)\c0l.obj CLIB = $(LIBDIR)\cl.lib LIBS = LINKER = tlink CC = bcc MAKEFILE = Makefile.dos OBJS1 = closure.obj error.obj lalr.obj lr0.obj main.obj mkpar.obj output.obj OBJS2 = mstring.obj reader.obj skeleton.obj symtab.obj verbose.obj warshall.obj OBJS = $(OBJS1) $(OBJS2) PROGRAM = btyacc.exe SRCS = closure.c error.c lalr.c lr0.c main.c mkpar.c output.c \ mstring.c reader.c skeleton.c symtab.c verbose.c warshall.c OTHERS = README README.BYACC \ Makefile btyaccpa.ske empty.y skel2c manpage all: $(PROGRAM) $(PROGRAM): $(OBJS) $(LIBS) @echo Linking $(PROGRAM) ... @echo $(LDFLAGS) $(C0) + > link.lst @echo $(OBJS1) + >> link.lst @echo $(OBJS2) >> link.lst @echo $(PROGRAM) >>link.lst @echo nul >> link.lst @echo $(CLIB) >> link.lst @$(LINKER) @link.lst @echo ... done program: $(PROGRAM) skeleton.c: btyaccpa.ske awk -f skel2c btyaccpa.ske >skeleton.c ### closure.o: defs.h error.o: defs.h lalr.o: defs.h lr0.o: defs.h main.o: defs.h mkpar.o: defs.h mstring.o: mstring.h output.o: defs.h reader.o: defs.h mstring.h skeleton.o: defs.h symtab.o: defs.h verbose.o: defs.h warshall.o: defs.h btyacc-3.0+dfsg/manpage0000644000175000017500000000452306373405303015312 0ustar eribertoeriberto.\" %W% %R% (Berkeley) %E% .\" .TH YACC 1 "July\ 15,\ 1990" .UC 6 .SH NAME Yacc \- an LALR(1) parser generator .SH SYNOPSIS .B yacc [ -dlrtv ] [ -b .I prefix .B ] [ -S .I skeleton file .B ] .I filename .SH DESCRIPTION .I Yacc reads the grammar specification in the file .I filename and generates an LR(1) parser for it. The parsers consist of a set of LALR(1) parsing tables and a driver routine written in the C programming language. .I Yacc normally writes the parse tables and the driver routine to the file .IR y.tab.c. .PP The following options are available: .RS .TP \fB-b \fIprefix\fR The .B -b option changes the prefix prepended to the output file names to the string denoted by .IR prefix. The default prefix is derived from the input filename. .TP .B -d The \fB-d\fR option causes the header file .IR y.tab.h to be written. .TP .B -l If the .B -l option is not specified, .I yacc will insert \fB#line\fR directives in the generated code. The \fB#line\fR directives let the C compiler relate errors in the generated code to the user's original code. If the \fB-l\fR option is specified, .I yacc will not insert the \fB#line\fR directives. \fB#line\fR directives specified by the user will be retained. .TP .B -r The .B -r option causes .I yacc to produce separate files for code and tables. The code file is named .IR y.code.c, and the tables file is named .IR y.tab.c. .TP .B -t The .B -t option changes the preprocessor directives generated by .I yacc so that debugging statements will be incorporated in the compiled code. .TP .B -v The .B -v option causes a human-readable description of the generated parser to be written to the file .IR y.output. .TP \fB-S \fIskeleton file\fR The \fB-S\fR option causes a different skeleton file to be used. The default skeleton file is built in to \fIyacc\fR when it is built. .RE .PP If the environment variable TMPDIR is set, the string denoted by TMPDIR will be used as the name of the directory where the temporary files are created. .SH FILES .IR filename\fB.code.c .br .IR filename\fB.tab.c .br .IR filename\fB.tab.h .br .IR filename\fB.output .br .BR /tmp/yacc.aXXXXXX .br .BR /tmp/yacc.tXXXXXX .br .BR /tmp/yacc.uXXXXXX .SH DIAGNOSTICS If there are rules that are never reduced, the number of such rules is reported on standard error. If there are any LALR(1) conflicts, the number of conflicts is reported on standard error. btyacc-3.0+dfsg/warshall.c0000644000175000017500000000226306367232302015737 0ustar eribertoeriberto#include "defs.h" void transitive_closure(unsigned *R, int n) { register int rowsize; register unsigned mask; register unsigned *rowj; register unsigned *rp; register unsigned *rend; register unsigned *ccol; register unsigned *relend; register unsigned *cword; register unsigned *rowi; rowsize = WORDSIZE(n); relend = R + n*rowsize; cword = R; mask = 1; rowi = R; while (rowi < relend) { ccol = cword; rowj = R; while (rowj < relend) { if (*ccol & mask) { rp = rowi; rend = rowj + rowsize; while (rowj < rend) *rowj++ |= *rp++; } else { rowj += rowsize; } ccol += rowsize; } mask <<= 1; if (mask == 0) { mask = 1; cword++; } rowi += rowsize; } } void reflexive_transitive_closure(unsigned *R, int n) { register int rowsize; register unsigned mask; register unsigned *rp; register unsigned *relend; transitive_closure(R, n); rowsize = WORDSIZE(n); relend = R + n*rowsize; mask = 1; rp = R; while (rp < relend) { *rp |= mask; mask <<= 1; if (mask == 0) { mask = 1; rp++; } rp += rowsize; } } btyacc-3.0+dfsg/README.BYACC0000644000175000017500000000465406743415416015473 0ustar eribertoeriberto Berkeley Yacc is an LALR(1) parser generator. Berkeley Yacc has been made as compatible as possible with AT&T Yacc. Berkeley Yacc can accept any input specification that conforms to the AT&T Yacc documentation. Specifications that take advantage of undocumented features of AT&T Yacc will probably be rejected. Berkeley Yacc is distributed with no warranty whatever. The code is certain to contain errors. Neither the author nor any contributor takes responsibility for any consequences of its use. Berkeley Yacc is in the public domain. The data structures and algorithms used in Berkeley Yacc are all either taken from documents available to the general public or are inventions of the author. Anyone may freely distribute source or binary forms of Berkeley Yacc whether unchanged or modified. Distributers may charge whatever fees they can obtain for Berkeley Yacc. Programs generated by Berkeley Yacc may be distributed freely. Please report bugs to corbett@berkeley.edu Include a small example if possible. Please include the banner string from skeleton.c with the bug report. Do not expect rapid responses. ------------------------------------------------------------------------------ ACKNOWLEDGEMENTS ================ Berkeley Yacc owes much to the unflagging efforts of Keith Bostic. His badgering kept me working on it long after I was ready to quit. Berkeley Yacc is based on the excellent algorithm for computing LALR(1) lookaheads developed by Tom Pennello and Frank DeRemer. The algorithm is described in their almost impenetrable article in TOPLAS 4,4. Finally, much of the credit for the latest version must go to those who pointed out deficiencies of my earlier releases. Among the most prolific contributors were Benson I. Margulies Dave Gentzel Antoine Verheijen Peter S. Housel Dale Smith Ozan Yigit John Campbell Bill Sommerfeld Paul Hilfinger Gary Bridgewater Dave Bakken Dan Lanciani Richard Sargent Parag Patel ------------------------------------------------------------------------------ The initial idea for BTYACC came to me after reading the paper "Parsing Non-LR(k) Grammars with Yacc" Gary H. Merrill _Software Prctice and Experience_ Vol. 23(8), 829-850 (August 1993) this paper talks about the basic idea of using a trial parse to resolve conflicts in the grammar. Patches to make things work on MSDOS are courtesy of Pasquale Foggia btyacc-3.0+dfsg/output.c0000644000175000017500000006174306526333055015476 0ustar eribertoeriberto#include "defs.h" static int nvectors; static int nentries; static Yshort **froms; static Yshort **tos; static Yshort *conflicts, nconflicts; static Yshort *tally; static Yshort *width; static Yshort *state_count; static Yshort *order; static Yshort *base; static Yshort *pos; static int maxtable; static Yshort *table; static Yshort *check; static int lowzero; static int high; void output() { free_itemsets(); free_shifts(); free_reductions(); output_stored_text(); output_defines(); output_rule_data(); output_yydefred(); output_actions(); free_parser(); output_debug(); output_stype(); if (rflag) write_section("tables"); write_section("header"); output_trailing_text(); write_section("body"); output_semantic_actions(); write_section("trailer"); } void output_rule_data() { register int i; register int j; if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "int yylhs[] = {%42d,", symbol_value[start_symbol]); j = 10; for (i = 3; i < nrules; i++) { if (j >= 10) { if (!rflag) ++outline; putc('\n', output_file); j = 1; } else ++j; fprintf(output_file, "%5d,", symbol_value[rlhs[i]]); } if (!rflag) outline += 2; fprintf(output_file, "\n};\n"); if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "int yylen[] = {%42d,", 2); j = 10; for (i = 3; i < nrules; i++) { if (j >= 10) { if (!rflag) ++outline; putc('\n', output_file); j = 1; } else j++; fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1); } if (!rflag) outline += 2; fprintf(output_file, "\n};\n"); } void output_yydefred() { register int i, j; if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "int yydefred[] = {%39d,", (defred[0] ? defred[0] - 2 : 0)); j = 10; for (i = 1; i < nstates; i++) { if (j < 10) ++j; else { if (!rflag) ++outline; putc('\n', output_file); j = 1; } fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0)); } if (!rflag) outline += 2; fprintf(output_file, "\n};\n"); } void output_actions() { nvectors = 3*nstates + nvars; froms = NEW2(nvectors, Yshort *); tos = NEW2(nvectors, Yshort *); tally = NEW2(nvectors, Yshort); width = NEW2(nvectors, Yshort); if (SRtotal+RRtotal) conflicts = NEW2(4*(SRtotal+RRtotal), Yshort); else conflicts = 0; nconflicts = 0; token_actions(); FREE(lookaheads); FREE(LA); FREE(LAruleno); FREE(accessing_symbol); goto_actions(); FREE(goto_map + ntokens); FREE(from_state); FREE(to_state); sort_actions(); pack_table(); output_base(); output_table(); output_check(); output_ctable(); } int find_conflict_base(int cbase) { int i,j; for (i=0; i= nconflicts) return i; } return cbase; } void token_actions() { register int i, j; register int shiftcount, reducecount, conflictcount, csym, cbase; register int max, min; register Yshort *actionrow, *r, *s; register action *p; actionrow = NEW2(3*ntokens, Yshort); for (i = 0; i < nstates; ++i) { if (parser[i]) { for (j = 0; j < 3*ntokens; ++j) actionrow[j] = 0; shiftcount = 0; reducecount = 0; conflictcount = 0; csym = -1; cbase = nconflicts; for (p = parser[i]; p; p = p->next) { if (csym != -1 && csym != p->symbol) { conflictcount++; conflicts[nconflicts++] = -1; j = find_conflict_base(cbase); actionrow[csym + 2*ntokens] = j + 1; if (j == cbase) { cbase = nconflicts; } else { if (conflicts[cbase] == -1) cbase++; nconflicts = cbase; } csym = -1; } if (p->suppressed == 0) { if (p->action_code == SHIFT) { ++shiftcount; actionrow[p->symbol] = p->number; } else if (p->action_code == REDUCE && p->number != defred[i]) { ++reducecount; actionrow[p->symbol + ntokens] = p->number; } } else if (p->suppressed == 1) { csym = p->symbol; if (p->action_code == SHIFT) { conflicts[nconflicts++] = p->number; } else if (p->action_code == REDUCE && p->number != defred[i]) { if (cbase == nconflicts) { if (cbase) cbase--; else conflicts[nconflicts++] = -1; } conflicts[nconflicts++] = p->number - 2; } } } if (csym != -1) { conflictcount++; conflicts[nconflicts++] = -1; j = find_conflict_base(cbase); actionrow[csym + 2*ntokens] = j + 1; if (j == cbase) { cbase = nconflicts; } else { if (conflicts[cbase] == -1) cbase++; nconflicts = cbase; } } tally[i] = shiftcount; tally[nstates+i] = reducecount; tally[2*nstates+i] = conflictcount; width[i] = 0; width[nstates+i] = 0; width[2*nstates+i] = 0; if (shiftcount > 0) { froms[i] = r = NEW2(shiftcount, Yshort); tos[i] = s = NEW2(shiftcount, Yshort); min = MAXSHORT; max = 0; for (j = 0; j < ntokens; ++j) { if (actionrow[j]) { if (min > symbol_value[j]) min = symbol_value[j]; if (max < symbol_value[j]) max = symbol_value[j]; *r++ = symbol_value[j]; *s++ = actionrow[j]; } } width[i] = max - min + 1; } if (reducecount > 0) { froms[nstates+i] = r = NEW2(reducecount, Yshort); tos[nstates+i] = s = NEW2(reducecount, Yshort); min = MAXSHORT; max = 0; for (j = 0; j < ntokens; ++j) { if (actionrow[ntokens+j]) { if (min > symbol_value[j]) min = symbol_value[j]; if (max < symbol_value[j]) max = symbol_value[j]; *r++ = symbol_value[j]; *s++ = actionrow[ntokens+j] - 2; } } width[nstates+i] = max - min + 1; } if (conflictcount > 0) { froms[2*nstates+i] = r = NEW2(conflictcount, Yshort); tos[2*nstates+i] = s = NEW2(conflictcount, Yshort); min = MAXSHORT; max = 0; for (j = 0; j < ntokens; ++j) { if (actionrow[2*ntokens+j]) { if (min > symbol_value[j]) min = symbol_value[j]; if (max < symbol_value[j]) max = symbol_value[j]; *r++ = symbol_value[j]; *s++ = actionrow[2*ntokens+j] - 1; } } width[2*nstates+i] = max - min + 1; } } } FREE(actionrow); } void goto_actions() { register int i, j, k; state_count = NEW2(nstates, Yshort); k = default_goto(start_symbol + 1); if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "int yydgoto[] = {%40d,", k); save_column(start_symbol + 1, k); j = 10; for (i = start_symbol + 2; i < nsyms; i++) { if (j >= 10) { if (!rflag) ++outline; putc('\n', output_file); j = 1; } else ++j; k = default_goto(i); fprintf(output_file, "%5d,", k); save_column(i, k); } if (!rflag) outline += 2; fprintf(output_file, "\n};\n"); FREE(state_count); } int default_goto(int symbol) { register int i; register int m; register int n; register int default_state; register int max; m = goto_map[symbol]; n = goto_map[symbol + 1]; if (m == n) return (0); for (i = 0; i < nstates; i++) state_count[i] = 0; for (i = m; i < n; i++) state_count[to_state[i]]++; max = 0; default_state = 0; for (i = 0; i < nstates; i++) { if (state_count[i] > max) { max = state_count[i]; default_state = i; } } return (default_state); } void save_column(int symbol, int default_state) { register int i; register int m; register int n; register Yshort *sp; register Yshort *sp1; register Yshort *sp2; register int count; register int symno; m = goto_map[symbol]; n = goto_map[symbol + 1]; count = 0; for (i = m; i < n; i++) { if (to_state[i] != default_state) ++count; } if (count == 0) return; symno = symbol_value[symbol] + 3*nstates; froms[symno] = sp1 = sp = NEW2(count, Yshort); tos[symno] = sp2 = NEW2(count, Yshort); for (i = m; i < n; i++) { if (to_state[i] != default_state) { *sp1++ = from_state[i]; *sp2++ = to_state[i]; } } tally[symno] = count; width[symno] = sp1[-1] - sp[0] + 1; } void sort_actions() { register int i; register int j; register int k; register int t; register int w; order = NEW2(nvectors, Yshort); nentries = 0; for (i = 0; i < nvectors; i++) { if (tally[i] > 0) { t = tally[i]; w = width[i]; j = nentries - 1; while (j >= 0 && (width[order[j]] < w)) j--; while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t)) j--; for (k = nentries - 1; k > j; k--) order[k + 1] = order[k]; order[j + 1] = i; nentries++; } } } void pack_table() { register int i; register int place; register int state; base = NEW2(nvectors, Yshort); pos = NEW2(nentries, Yshort); maxtable = 1000; table = NEW2(maxtable, Yshort); check = NEW2(maxtable, Yshort); lowzero = 0; high = 0; for (i = 0; i < maxtable; i++) check[i] = -1; for (i = 0; i < nentries; i++) { state = matching_vector(i); if (state < 0) place = pack_vector(i); else place = base[state]; pos[i] = place; base[order[i]] = place; } for (i = 0; i < nvectors; i++) { if (froms[i]) FREE(froms[i]); if (tos[i]) FREE(tos[i]); } FREE(froms); FREE(tos); FREE(tally); FREE(width); FREE(pos); } /* The function matching_vector determines if the vector specified by */ /* the input parameter matches a previously considered vector. The */ /* test at the start of the function checks if the vector represents */ /* a row of shifts over terminal symbols or a row of reductions, or a */ /* column of shifts over a nonterminal symbol. Berkeley Yacc does not */ /* check if a column of shifts over a nonterminal symbols matches a */ /* previously considered vector. Because of the nature of LR parsing */ /* tables, no two columns can match. Therefore, the only possible */ /* match would be between a row and a column. Such matches are */ /* unlikely. Therefore, to save time, no attempt is made to see if a */ /* column matches a previously considered vector. */ /* */ /* Matching_vector is poorly designed. The test could easily be made */ /* faster. Also, it depends on the vectors being in a specific */ /* order. */ /* Not really any point in checking for matching conflicts -- it is */ /* extremely unlikely to occur, and conflicts are (hopefully) rare. */ int matching_vector(int vector) { register int i; register int j; register int k; register int t; register int w; register int match; register int prev; i = order[vector]; if (i >= 2*nstates) return (-1); t = tally[i]; w = width[i]; for (prev = vector - 1; prev >= 0; prev--) { j = order[prev]; if (width[j] != w || tally[j] != t) return (-1); match = 1; for (k = 0; match && k < t; k++) { if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k]) match = 0; } if (match) return (j); } return (-1); } int pack_vector(int vector) { register int i, j, k, l; register int t; register int loc; register int ok; register Yshort *from; register Yshort *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) { if (loc >= MAXTABLE) fatal("maximum table size exceeded"); newmax = maxtable; do { newmax += 200; } while (newmax <= loc); table = (Yshort *) REALLOC(table, newmax*sizeof(Yshort)); if (table == 0) no_space(); check = (Yshort *) REALLOC(check, newmax*sizeof(Yshort)); if (check == 0) no_space(); 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); } } } void output_base() { register int i, j; if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "int yysindex[] = {%39d,", base[0]); j = 10; for (i = 1; i < nstates; i++) { if (j >= 10) { if (!rflag) ++outline; putc('\n', output_file); j = 1; } else ++j; fprintf(output_file, "%5d,", base[i]); } if (!rflag) outline += 2; fprintf(output_file, "\n};\n"); if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "int yyrindex[] = {%39d,", base[nstates]); j = 10; for (i = nstates + 1; i < 2*nstates; i++) { if (j >= 10) { if (!rflag) ++outline; putc('\n', output_file); j = 1; } else ++j; fprintf(output_file, "%5d,", base[i]); } if (!rflag) outline += 2; fprintf(output_file, "\n};\n"); if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "int yycindex[] = {%39d,", base[2*nstates]); j = 10; for (i = 2*nstates + 1; i < 3*nstates; i++) { if (j >= 10) { if (!rflag) ++outline; putc('\n', output_file); j = 1; } else ++j; fprintf(output_file, "%5d,", base[i]); } if (!rflag) outline += 2; fprintf(output_file, "\n};\n"); if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "int yygindex[] = {%39d,", base[3*nstates]); j = 10; for (i = 3*nstates + 1; i < nvectors - 1; i++) { if (j >= 10) { if (!rflag) ++outline; putc('\n', output_file); j = 1; } else ++j; fprintf(output_file, "%5d,", base[i]); } if (!rflag) outline += 2; fprintf(output_file, "\n};\n"); FREE(base); } void output_table() { register int i; register int j; ++outline; fprintf(stderr, "YYTABLESIZE: %d\n", high); if(high >= MAXSHORT) { fprintf(stderr, "Table is longer than %d elements. It's not gonna fly.\n", MAXSHORT); exit(1); } fprintf(code_file, "#define YYTABLESIZE %d\n", high); if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "int yytable[] = {%40d,", table[0]); j = 10; for (i = 1; i <= high; i++) { if (j >= 10) { if (!rflag) ++outline; putc('\n', output_file); j = 1; } else ++j; fprintf(output_file, "%5d,", table[i]); } if (!rflag) outline += 2; fprintf(output_file, "\n};\n"); FREE(table); } void output_check() { register int i; register int j; if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "int yycheck[] = {%40d,", check[0]); j = 10; for (i = 1; i <= high; i++) { if (j >= 10) { if (!rflag) ++outline; putc('\n', output_file); j = 1; } else ++j; fprintf(output_file, "%5d,", check[i]); } if (!rflag) outline += 2; fprintf(output_file, "\n};\n"); FREE(check); } void output_ctable() { register int i; register int j; if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "int yyctable[] = {%39d,", conflicts ? conflicts[0] : 0); j = 10; for (i = 1; i < nconflicts; i++) { if (j >= 10) { if (!rflag) ++outline; putc('\n', output_file); j = 1; } else ++j; fprintf(output_file, "%5d,", conflicts[i]); } if (!rflag) outline += 2; fprintf(output_file, "\n};\n"); if (conflicts) FREE(conflicts); } int is_C_identifier(char *name) { register char *s; register int c; s = name; c = *s; if (c == '"') { c = *++s; if (!isalpha(c) && c != '_' && c != '$') return (0); while ((c = *++s) != '"') { if (!isalnum(c) && c != '_' && c != '$') return (0); } return (1); } if (!isalpha(c) && c != '_' && c != '$') return (0); while ((c = *++s)) { if (!isalnum(c) && c != '_' && c != '$') return (0); } return (1); } void output_defines() { register int c, i; register char *s; FILE *dc_file; if(dflag) { fprintf(defines_file, "#ifndef _yacc_defines_h_\n"); fprintf(defines_file, "#define _yacc_defines_h_\n\n"); } /* VM: Print to either code file or defines file but not to both */ dc_file = dflag ? defines_file : code_file; for (i = 2; i < ntokens; ++i) { s = symbol_name[i]; if (is_C_identifier(s)) { fprintf(dc_file, "#define "); c = *s; if (c == '"') { while ((c = *++s) != '"') { putc(c, dc_file); } } else { do { putc(c, dc_file); } while ((c = *++s)); } ++outline; fprintf(dc_file, " %d\n", symbol_value[i]); } } ++outline; fprintf(dc_file, "#define YYERRCODE %d\n", symbol_value[1]); if (dflag && unionized) { fclose(union_file); union_file = fopen(union_file_name, "r"); if (union_file == NULL) open_error(union_file_name); while ((c = getc(union_file)) != EOF) { putc(c, defines_file); } fprintf(defines_file, "extern YYSTYPE yylval;\n"); } if(dflag) { fprintf(defines_file, "\n#endif\n"); } } void output_stored_text() { register int c; register FILE *in, *out; register int state; /* 0=middle of line, 1=start of line, 2=seen '#' */ state = 1; fclose(text_file); text_file = fopen(text_file_name, "r"); if (text_file == NULL) open_error(text_file_name); in = text_file; if ((c = getc(in)) == EOF) return; out = code_file; do { if (c == '\n') { ++outline; if (state == 2) { fprintf(out, line_format+1, outline + 1, code_file_name); state = 1; continue; } state = 1; } else if (state == 1 && c == '#') state = 2; else state = 0; putc(c, out); } while ((c = getc(in)) != EOF); if (!lflag) fprintf(out, line_format, ++outline + 1, code_file_name); } void output_debug() { register int i, j, k, max; char **symnam, *s; ++outline; fprintf(code_file, "#define YYFINAL %d\n", final_state); outline += 3; fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n", tflag); if (rflag) fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n", tflag); 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 = (char **) MALLOC((max+1)*sizeof(char *)); if (symnam == 0) no_space(); /* 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"; if (!rflag) ++outline; fprintf(output_file, "#if YYDEBUG\n"); if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "char *yyname[] = {"); j = 80; for (i = 0; i <= max; ++i) { if ((s = symnam[i])) { if (s[0] == '"') { k = 7; while (*++s != '"') { ++k; if (*s == '\\') { k += 2; if (*++s == '\\') ++k; } } j += k; if (j > 80) { if (!rflag) ++outline; putc('\n', output_file); 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) { if (!rflag) ++outline; putc('\n', output_file); j = 7; } fprintf(output_file, "\"'\\\"'\","); } else { k = 5; while (*++s != '\'') { ++k; if (*s == '\\') { k += 2; if (*++s == '\\') ++k; } } j += k; if (j > 80) { if (!rflag) ++outline; putc('\n', output_file); 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 = strlen(s) + 3; j += k; if (j > 80) { if (!rflag) ++outline; putc('\n', output_file); j = k; } putc('"', output_file); do { putc(*s, output_file); } while (*++s); fprintf(output_file, "\","); } } else { j += 2; if (j > 80) { if (!rflag) ++outline; putc('\n', output_file); j = 2; } fprintf(output_file, "0,"); } } if (!rflag) outline += 2; fprintf(output_file, "\n};\n"); FREE(symnam); if (!rflag) ++outline; if (!rflag) fprintf(output_file, "static "); fprintf(output_file, "char *yyrule[] = {\n"); 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); } if (!rflag) ++outline; fprintf(output_file, "\",\n"); } if (!rflag) outline += 2; fprintf(output_file, "};\n#endif\n"); } void output_stype() { if (!unionized && ntags == 0) { outline += 3; fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n"); } } void output_trailing_text() { register int c, last; register FILE *in, *out; if (line == 0) return; in = input_file; out = code_file; c = *cptr; if (c == '\n') { ++lineno; if ((c = getc(in)) == EOF) return; if (!lflag) { ++outline; fprintf(out, line_format, lineno, (inc_file?inc_file_name:input_file_name)); } if (c == '\n') ++outline; putc(c, out); last = c; } else { if (!lflag) { ++outline; fprintf(out, line_format, lineno, (inc_file?inc_file_name:input_file_name)); } do { putc(c, out); } while ((c = *++cptr) != '\n'); ++outline; putc('\n', out); last = '\n'; } while ((c = getc(in)) != EOF) { if (c == '\n') ++outline; putc(c, out); last = c; } if (last != '\n') { ++outline; putc('\n', out); } if (!lflag) fprintf(out, line_format, ++outline + 1, code_file_name); } void output_semantic_actions() { register int c, last; register FILE *out; register int state; /* 0=middle of line, 1=start of line, 2=seen '#' */ state = 1; fclose(action_file); action_file = fopen(action_file_name, "r"); if (action_file == NULL) open_error(action_file_name); if ((c = getc(action_file)) == EOF) return; out = code_file; do { last = c; if (c == '\n') { ++outline; if (state == 2) { fprintf(out, line_format+1, outline + 1, code_file_name); state = 1; continue; } state = 1; } else if (state == 1 && c == '#') state = 2; else state = 0; putc(c, out); } while ((c = getc(action_file)) != EOF); if (last != '\n') { ++outline; putc('\n', out); } if (!lflag) fprintf(out, line_format, ++outline + 1, code_file_name); } void free_itemsets() { register core *cp, *next; FREE(state_table); for (cp = first_state; cp; cp = next) { next = cp->next; FREE(cp); } } void free_shifts() { register shifts *sp, *next; FREE(shift_table); for (sp = first_shift; sp; sp = next) { next = sp->next; FREE(sp); } } void free_reductions() { register reductions *rp, *next; FREE(reduction_table); for (rp = first_reduction; rp; rp = next) { next = rp->next; FREE(rp); } } void write_section(char *section_name) { char **section; FILE *fp; int i; struct section *sl; for(sl=§ion_list[0]; sl->name; sl++) { if(strcmp(sl->name,section_name)==0) { break; } } if(sl->name==0) { fprintf(stderr, "Cannot find section '%s' in your skeleton file\n", section_name); exit(1); } section = sl->ptr; fp = code_file; for (i = lflag ? 1 : 0; section[i]; ++i) { ++outline; fprintf(fp, "%s\n", section[i]); } } btyacc-3.0+dfsg/defs.h0000644000175000017500000002700306462035400015043 0ustar eribertoeriberto#include #include #include #include #include /* machine-dependent definitions */ /* the following definitions are for the Tahoe */ /* they might have to be changed for other machines */ /* MAXCHAR is the largest unsigned character value */ /* MAXSHORT is the largest value of a C short */ /* MINSHORT is the most negative value of a C short */ /* MAXTABLE is the maximum table size */ /* BITS_PER_WORD is the number of bits in a C unsigned */ /* WORDSIZE computes the number of words needed to */ /* store n bits */ /* BIT returns the value of the n-th bit starting */ /* from r (0-indexed) */ /* SETBIT sets the n-th bit starting from r */ #define MAXCHAR 255 #define MAXSHORT ((int)0x7FFFFFFF) #define MINSHORT ((int)0x80000000) #define MAXTABLE 120000 #ifdef __MSDOS__ #define BITS_PER_WORD 16 #define LOG2_BPW 4 #else /* Real computers... */ #define BITS_PER_WORD 32 #define LOG2_BPW 5 #endif #define BITS_PER_WORD_1 (BITS_PER_WORD-1) #define WORDSIZE(n) (((n)+(BITS_PER_WORD_1))/BITS_PER_WORD) #define BIT(r, n) ((((r)[(n)>>LOG2_BPW])>>((n)&BITS_PER_WORD_1))&1) #define SETBIT(r, n) ((r)[(n)>>LOG2_BPW]|=((unsigned)1<<((n)&BITS_PER_WORD_1))) /* VM: this is a 32-bit replacement for original 16-bit short */ typedef int Yshort; /* character names */ #define NUL '\0' /* the null character */ #define NEWLINE '\n' /* line feed */ #define SP ' ' /* space */ #define BS '\b' /* backspace */ #define HT '\t' /* horizontal tab */ #define VT '\013' /* vertical tab */ #define CR '\r' /* carriage return */ #define FF '\f' /* form feed */ #define QUOTE '\'' /* single quote */ #define DOUBLE_QUOTE '\"' /* double quote */ #define BACKSLASH '\\' /* backslash */ /* defines for constructing filenames */ #define DEFINES_SUFFIX "_tab.h" #define OUTPUT_SUFFIX "_tab.c" #define CODE_SUFFIX "_code.c" #define VERBOSE_SUFFIX ".output" /* keyword codes */ #define TOKEN 0 #define LEFT 1 #define RIGHT 2 #define NONASSOC 3 #define MARK 4 #define TEXT 5 #define TYPE 6 #define START 7 #define UNION 8 #define IDENT 9 /* symbol classes */ #define UNKNOWN 0 #define TERM 1 #define NONTERM 2 #define ACTION 3 #define ARGUMENT 4 /* the undefined value */ #define UNDEFINED (-1) /* action codes */ #define SHIFT 1 #define REDUCE 2 /* character macros */ #define IS_IDENT(c) (isalnum(c) || (c) == '_' || (c) == '.' || (c) == '$') #define IS_OCTAL(c) ((c) >= '0' && (c) <= '7') #define NUMERIC_VALUE(c) ((c) - '0') /* symbol macros */ #define ISTOKEN(s) ((s) < start_symbol) #define ISVAR(s) ((s) >= start_symbol) /* storage allocation macros */ #define CALLOC(k,n) (calloc((unsigned)(k),(unsigned)(n))) #define FREE(x) (free((char*)(x))) #define MALLOC(n) (malloc((unsigned)(n))) #define NEW(t) ((t*)allocate(sizeof(t))) #define NEW2(n,t) ((t*)allocate((unsigned)((n)*sizeof(t)))) #define REALLOC(p,n) (realloc((char*)(p),(unsigned)(n))) #define RENEW(p,n,t) ((t*)realloc((char*)(p),(unsigned)((n)*sizeof(t)))) /* the structure of a symbol table entry */ typedef struct bucket bucket; struct bucket { struct bucket *link; struct bucket *next; char *name; char *tag; char **argnames; char **argtags; Yshort args; Yshort value; Yshort index; Yshort prec; char class; char assoc; }; /* the structure of the LR(0) state machine */ typedef struct core core; struct core { struct core *next; struct core *link; Yshort number; Yshort accessing_symbol; Yshort nitems; Yshort items[1]; }; /* the structure used to record shifts */ typedef struct shifts shifts; struct shifts { struct shifts *next; Yshort number; Yshort nshifts; Yshort shift[1]; }; /* the structure used to store reductions */ typedef struct reductions reductions; struct reductions { struct reductions *next; Yshort number; Yshort nreds; Yshort rules[1]; }; /* the structure used to represent parser actions */ typedef struct action action; struct action { struct action *next; Yshort symbol; Yshort number; Yshort prec; char action_code; char assoc; char suppressed; }; struct section { char *name; char **ptr; }; extern struct section section_list[]; /* global variables */ extern char dflag; extern char lflag; extern char rflag; extern char tflag; extern char vflag; extern char *myname; extern char *cptr; extern char *line; extern int lineno; extern int outline; extern char *banner[]; extern char *tables[]; extern char *header[]; extern char *body[]; extern char *trailer[]; extern char *action_file_name; extern char *code_file_name; extern char *defines_file_name; extern char *input_file_name; extern char *output_file_name; extern char *text_file_name; extern char *union_file_name; extern char *verbose_file_name; extern FILE *inc_file; extern char inc_file_name[]; extern FILE *action_file; extern FILE *code_file; extern FILE *defines_file; extern FILE *input_file; extern FILE *output_file; extern FILE *text_file; extern FILE *union_file; extern FILE *verbose_file; extern int nitems; extern int nrules; extern int nsyms; extern int ntokens; extern int nvars; extern int ntags; extern char unionized; extern char line_format[]; extern int start_symbol; extern char **symbol_name; extern Yshort *symbol_value; extern Yshort *symbol_prec; extern char *symbol_assoc; extern Yshort *ritem; extern Yshort *rlhs; extern Yshort *rrhs; extern Yshort *rprec; extern char *rassoc; extern Yshort **derives; extern char *nullable; extern bucket *first_symbol; extern bucket *last_symbol; extern int nstates; extern core *first_state; extern shifts *first_shift; extern reductions *first_reduction; extern Yshort *accessing_symbol; extern core **state_table; extern shifts **shift_table; extern reductions **reduction_table; extern unsigned *LA; extern Yshort *LAruleno; extern Yshort *lookaheads; extern Yshort *goto_map; extern Yshort *from_state; extern Yshort *to_state; extern action **parser; extern int SRtotal; extern int RRtotal; extern Yshort *SRconflicts; extern Yshort *RRconflicts; extern Yshort *defred; extern Yshort *rules_used; extern Yshort nunused; extern Yshort final_state; /* system variable */ extern int errno; /* global functions */ /* closure.c */ void set_EFF(void); void set_first_derives(void); void closure(Yshort *, int); void finalize_closure(void); void print_closure(int); void print_EFF(void); void print_first_derives(void); /* error.c */ void fatal(char *); void no_space(void); void open_error(char *); void unexpected_EOF(void); void print_pos(char *, char *); void error(int, char *, char *, char *, ...); void syntax_error(int, char *, char *); void unterminated_comment(int, char *, char *); void unterminated_string(int, char *, char *); void unterminated_text(int, char *, char *); void unterminated_union(int, char *, char *); void over_unionized(char *); void illegal_tag(int, char *, char *); void illegal_character(char *); void used_reserved(char *); void tokenized_start(char *); void retyped_warning(char *); void reprec_warning(char *); void revalued_warning(char *); void terminal_start(char *); void restarted_warning(void); void no_grammar(void); void terminal_lhs(int); void prec_redeclared(void); void unterminated_action(int, char *, char *); void unterminated_arglist(int, char *, char *); void bad_formals(void); void dollar_warning(int, int); void dollar_error(int, char *, char *); void untyped_lhs(void); void untyped_rhs(int, char *); void unknown_rhs(int); void default_action_warning(void); void undefined_goal(char *); void undefined_symbol_warning(char *); /* lalr.c */ void lalr(void); void set_state_table(void); void set_accessing_symbol(void); void set_shift_table(void); void set_reduction_table(void); void set_maxrhs(void); void initialize_LA(void); void set_goto_map(void); int map_goto(int, int); void initialize_F(void); void build_relations(void); void add_lookback_edge(int, int, int); Yshort **transpose(Yshort **, int); void compute_FOLLOWS(void); void compute_lookaheads(void); void digraph(Yshort **); void traverse(int); /* lr0.c */ void allocate_itemsets(void); void allocate_storage(void); void append_states(void); void free_storage(void); void generate_states(void); int get_state(int); void initialize_states(void); void new_itemsets(void); core *new_state(int); void show_cores(void); void show_ritems(void); void show_rrhs(void); void show_shifts(void); void save_shifts(void); void save_reductions(void); void set_derives(void); void free_derives(void); void print_derives(void); void set_nullable(void); void free_nullable(void); void lr0(void); /* main.c */ void done(int); void onintr(void); void set_signals(void); void usage(void); void getargs(int, char **); char *allocate(unsigned); void create_file_names(void); void open_files(void); int main(int, char **); /* mkpar.c */ void make_parser(void); action *parse_actions(int); action *get_shifts(int); action *add_reductions(int, action *); action *add_reduce(action *, int, int); void find_final_state(void); void unused_rules(void); void remove_conflicts(void); void total_conflicts(void); int sole_reduction(int); void defreds(void); void free_action_row(action *); void free_parser(void); /* output.c */ void output(void); void output_rule_data(void); void output_yydefred(void); void output_actions(void); int find_conflict_base(int); void token_actions(void); void goto_actions(void); int default_goto(int); void save_column(int, int); void sort_actions(void); void pack_table(void); int matching_vector(int); int pack_vector(int); void output_base(void); void output_table(void); void output_check(void); void output_ctable(void); int is_C_identifier(char *); void output_defines(void); void output_stored_text(void); void output_debug(void); void output_stype(void); void output_trailing_text(void); void output_semantic_actions(void); void free_itemsets(void); void free_shifts(void); void free_reductions(void); void write_section(char *section_name); /* reader.c */ int cachec(int); char *get_line(void); char *dup_line(void); char *skip_comment(void); int nextc(void); int keyword(void); void copy_ident(void); void copy_string(int, FILE *, FILE *); void copy_comment(FILE *, FILE *); void copy_text(void); void copy_union(void); int hexval(int); bucket *get_literal(void); int is_reserved(char *); bucket *get_name(void); int get_number(void); char *get_tag(void); void declare_tokens(int); void declare_types(void); void declare_start(void); void read_declarations(void); void initialize_grammar(void); void expand_items(void); void expand_rules(void); void advance_to_start(void); void start_rule(bucket *, int); void end_rule(void); void insert_empty_rule(void); void add_symbol(void); void copy_action(void); int mark_symbol(void); void read_grammar(void); void free_tags(void); void pack_names(void); void check_symbols(void); void pack_symbols(void); void pack_grammar(void); void print_grammar(void); void reader(void); /* readskel.c */ void read_skel(char *); /* symtab.c */ int hash(char *); bucket *make_bucket(char *); bucket *lookup(char *); void create_symbol_table(void); void free_symbol_table(void); void free_symbols(void); /* verbose.c */ void verbose(void); void log_unused(void); void log_conflicts(void); void print_state(int); void print_conflicts(int); void print_core(int); void print_nulls(int); void print_actions(int); void print_shifts(action *); void print_reductions(action *, int); void print_gotos(int); /* warshall.c */ void transitive_closure(unsigned *, int); void reflexive_transitive_closure(unsigned *, int); btyacc-3.0+dfsg/closure.c0000644000175000017500000001043706367232300015576 0ustar eribertoeriberto#include "defs.h" Yshort *itemset; Yshort *itemsetend; unsigned *ruleset; static unsigned *first_derives; static unsigned *EFF; void set_EFF() { register unsigned *row; register int symbol; register Yshort *sp; register int rowsize; register int i; register int rule; rowsize = WORDSIZE(nvars); EFF = NEW2(nvars * rowsize, unsigned); row = EFF; for (i = start_symbol; i < nsyms; i++) { sp = derives[i]; for (rule = *sp; rule > 0; rule = *++sp) { symbol = ritem[rrhs[rule]]; if (ISVAR(symbol)) { symbol -= start_symbol; SETBIT(row, symbol); } } row += rowsize; } reflexive_transitive_closure(EFF, nvars); #ifdef DEBUG print_EFF(); #endif } void set_first_derives() { register unsigned *rrow; register unsigned *vrow; register int j; register unsigned mask; register unsigned cword; register Yshort *rp; int rule; int i; int rulesetsize; int varsetsize; rulesetsize = WORDSIZE(nrules); varsetsize = WORDSIZE(nvars); first_derives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize; set_EFF(); rrow = first_derives + ntokens * rulesetsize; for (i = start_symbol; i < nsyms; i++) { vrow = EFF + ((i - ntokens) * varsetsize); cword = *vrow++; mask = 1; for (j = start_symbol; j < nsyms; j++) { if (cword & mask) { rp = derives[j]; while ((rule = *rp++) >= 0) { SETBIT(rrow, rule); } } mask <<= 1; if (mask == 0) { cword = *vrow++; mask = 1; } } vrow += varsetsize; rrow += rulesetsize; } #ifdef DEBUG print_first_derives(); #endif FREE(EFF); } void closure(Yshort *nucleus, int n) { register int ruleno; register unsigned word; register unsigned mask; register Yshort *csp; register unsigned *dsp; register unsigned *rsp; register int rulesetsize; Yshort *csend; unsigned *rsend; int symbol; int itemno; rulesetsize = WORDSIZE(nrules); rsp = ruleset; rsend = ruleset + rulesetsize; for (rsp = ruleset; rsp < rsend; rsp++) *rsp = 0; csend = nucleus + n; for (csp = nucleus; csp < csend; ++csp) { symbol = ritem[*csp]; if (ISVAR(symbol)) { dsp = first_derives + symbol * rulesetsize; rsp = ruleset; while (rsp < rsend) *rsp++ |= *dsp++; } } ruleno = 0; itemsetend = itemset; csp = nucleus; for (rsp = ruleset; rsp < rsend; ++rsp) { word = *rsp; if (word == 0) ruleno += BITS_PER_WORD; else { mask = 1; while (mask) { if (word & mask) { itemno = rrhs[ruleno]; while (csp < csend && *csp < itemno) *itemsetend++ = *csp++; *itemsetend++ = itemno; while (csp < csend && *csp == itemno) ++csp; } mask <<= 1; ++ruleno; } } } while (csp < csend) *itemsetend++ = *csp++; #ifdef DEBUG print_closure(n); #endif } void finalize_closure() { FREE(itemset); FREE(ruleset); FREE(first_derives + ntokens * WORDSIZE(nrules)); } #ifdef DEBUG void print_closure(int n) { register Yshort *isp; printf("\n\nn = %d\n\n", n); for (isp = itemset; isp < itemsetend; isp++) printf(" %d\n", *isp); } void print_EFF() { register int i, j; register unsigned *rowp; register unsigned word; register unsigned mask; printf("\n\nEpsilon Free Firsts\n"); for (i = start_symbol; i < nsyms; i++) { printf("\n%s", symbol_name[i]); rowp = EFF + ((i - start_symbol) * WORDSIZE(nvars)); word = *rowp++; mask = 1; for (j = 0; j < nvars; j++) { if (word & mask) printf(" %s", symbol_name[start_symbol + j]); mask <<= 1; if (mask == 0) { word = *rowp++; mask = 1; } } } } void print_first_derives() { register int i; register int j; register unsigned *rp; register unsigned cword; register unsigned mask; printf("\n\n\nFirst Derives\n"); for (i = start_symbol; i < nsyms; i++) { printf("\n%s derives\n", symbol_name[i]); rp = first_derives + i * WORDSIZE(nrules); cword = *rp++; mask = 1; for (j = 0; j <= nrules; j++) { if (cword & mask) printf(" %d\n", j); mask <<= 1; if (mask == 0) { cword = *rp++; mask = 1; } } } fflush(stdout); } #endif btyacc-3.0+dfsg/btyaccpa.ske0000644000175000017500000005144306740551111016251 0ustar eribertoeriberto/* The banner used here should be replaced with an #ident directive */ /* if the target C compiler supports #ident directives. */ /* */ /* If the skeleton is changed, the banner should be changed so that */ /* the altered version can easily be distinguished from the original. */ %% banner // // @(#)btyaccpar, based on byacc 1.8 (Berkeley) // #define YYBTYACC 1 #include #include #include typedef int Yshort; %% tables #define _C_ "C" extern _C_ Yshort yylhs[]; extern _C_ Yshort yylen[]; extern _C_ Yshort yydefred[]; extern _C_ Yshort yydgoto[]; extern _C_ Yshort yysindex[]; extern _C_ Yshort yyrindex[]; extern _C_ Yshort yycindex[]; extern _C_ Yshort yygindex[]; extern _C_ Yshort yytable[]; extern _C_ Yshort yycheck[]; extern _C_ Yshort yyctable[]; #if YYDEBUG extern _C_ char *yyname[]; extern _C_ char *yyrule[]; #endif %% header // // YYPOSN is user-defined text position type. // #ifndef YYPOSN #define YYPOSN int #endif #ifdef YYREDUCEPOSNFUNC #define YYCALLREDUCEPOSN(e) \ if(reduce_posn) { \ YYREDUCEPOSNFUNC(yyps->pos, &(yyps->psp)[1-yym], &(yyps->vsp)[1-yym], \ yym, yyps->psp - yyps->ps, yychar, yyposn, e); \ reduce_posn = 0; \ } #ifndef YYCALLREDUCEPOSNARG #define YYCALLREDUCEPOSNARG yyps->val #endif #define YYPOSNARG(n) ((yyps->psp)[1-yym+(n)-1]) #define YYPOSNOUT (yyps->pos) #endif // If delete function is not defined by the user, do not deletions. #ifndef YYDELETEVAL #define YYDELETEVAL(v) #endif // If delete function is not defined by the user, do not deletions. #ifndef YYDELETEPOSN #define YYDELETEPOSN(v) #endif #define yyclearin (yychar=(-1)) #define yyerrok (yyps->errflag=0) #ifndef YYSTACKGROWTH #define YYSTACKGROWTH 16 #endif #ifndef YYDEFSTACKSIZE #define YYDEFSTACKSIZE 12 #endif #ifdef YYDEBUG int yydebug; #endif int yynerrs; /* These value/posn are taken from the lexer */ YYSTYPE yylval; YYPOSN yyposn; /* These value/posn of the root non-terminal are returned to the caller */ YYSTYPE yyretlval; YYPOSN yyretposn; #define YYABORT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab #define YYVALID do { if (yyps->save) goto yyvalid; } while(0) #define YYVALID_NESTED do { if (yyps->save && \ yyps->save->save==0) goto yyvalid; } while(0) struct yyparsestate { yyparsestate *save; // Previously saved parser state int state; int errflag; Yshort *ssp; // state stack pointer YYSTYPE *vsp; // value stack pointer YYPOSN *psp; // position stack pointer YYSTYPE val; // value as returned by actions YYPOSN pos; // position as returned by universal action Yshort *ss; // state stack base YYSTYPE *vs; // values stack base YYPOSN *ps; // position stack base int lexeme; // index of the conflict lexeme in the lexical queue unsigned int stacksize; // current maximum stack size Yshort ctry; // index in yyctable[] for this conflict }; // Current parser state static yyparsestate *yyps=0; // yypath!=NULL: do the full parse, starting at *yypath parser state. static yyparsestate *yypath=0; // Base of the lexical value queue static YYSTYPE *yylvals=0; // Current posistion at lexical value queue static YYSTYPE *yylvp=0; // End position of lexical value queue static YYSTYPE *yylve=0; // The last allocated position at the lexical value queue static YYSTYPE *yylvlim=0; // Base of the lexical position queue static YYPOSN *yylpsns=0; // Current posistion at lexical position queue static YYPOSN *yylpp=0; // End position of lexical position queue static YYPOSN *yylpe=0; // The last allocated position at the lexical position queue static YYPOSN *yylplim=0; // Current position at lexical token queue static Yshort *yylexp=0; static Yshort *yylexemes=0; // // For use in generated program // #define yytrial (yyps->save) #define yyvsp (yyps->vsp) #define yyval (yyps->val) #define yydepth (yyps->ssp - yyps->ss) // // Local prototypes. // int yyparse(void); int YYLex1(); int yyexpand(); void YYSCopy(YYSTYPE *to, YYSTYPE *from, int size); void YYPCopy(YYPOSN *to, YYPOSN *from, int size); void YYMoreStack(yyparsestate *yyps); yyparsestate *YYNewState(int size); void YYFreeState(yyparsestate *p); %% body // // Parser function // int yyparse() { int yym, yyn, yystate, yychar, yynewerrflag; yyparsestate *yyerrctx = NULL; int reduce_posn; #if YYDEBUG char *yys; if ((yys = getenv("YYDEBUG"))) { yyn = *yys; if (yyn >= '0' && yyn <= '9') yydebug = yyn - '0'; } #endif yyps = YYNewState(YYDEFSTACKSIZE); yyps->save = 0; yynerrs = 0; yyps->errflag = 0; yychar = (-1); yyps->ssp = yyps->ss; yyps->vsp = yyps->vs; yyps->psp = yyps->ps; *(yyps->ssp) = yystate = 0; // // Main parsing loop // yyloop: if ((yyn = yydefred[yystate])) { goto yyreduce; } // // Read one token // if (yychar < 0) { if ((yychar = YYLex1()) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("yydebug[%d,%d]: state %d, reading %d (%s)", yydepth, (int)yytrial, yystate, yychar, yys); #ifdef YYDBPR printf("<"); YYDBPR(yylval); printf(">"); #endif printf("\n"); } #endif } // // Do we have a conflict? // if ((yyn = yycindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { int ctry; if (yypath) { #if YYDEBUG if (yydebug) { printf("yydebug[%d,%d]: CONFLICT in state %d: following successful trial parse\n", yydepth, (int)yytrial, yystate); } #endif // Switch to the next conflict context yyparsestate *save = yypath; yypath = save->save; ctry = save->ctry; if (save->state != yystate) goto yyabort; YYFreeState(save); } else { #if YYDEBUG if (yydebug) { printf("yydebug[%d,%d]: CONFLICT in state %d. ", yydepth, (int)yytrial, yystate); if(yyps->save) { printf("ALREADY in conflict. Continue trial parse."); } else { printf("Start trial parse."); } printf("\n"); } #endif yyparsestate *save = YYNewState(yyps->ssp - yyps->ss); save->save = yyps->save; save->state = yystate; save->errflag = yyps->errflag; save->ssp = save->ss + (yyps->ssp - yyps->ss); save->vsp = save->vs + (yyps->vsp - yyps->vs); save->psp = save->ps + (yyps->psp - yyps->ps); memcpy (save->ss, yyps->ss, (yyps->ssp - yyps->ss + 1)*sizeof(Yshort)); YYSCopy(save->vs, yyps->vs, (yyps->ssp - yyps->ss + 1)); YYPCopy(save->ps, yyps->ps, (yyps->ssp - yyps->ss + 1)); ctry = yytable[yyn]; if (yyctable[ctry] == -1) { #if YYDEBUG if (yydebug && yychar >= 0) printf("yydebug[%d]: backtracking 1 token\n", (int)yytrial); #endif ctry++; } save->ctry = ctry; if (!yyps->save) { // If this is a first conflict in the stack, start saving lexemes if (!yylexemes) { yylexemes = new Yshort[YYSTACKGROWTH]; yylvals = new YYSTYPE[YYSTACKGROWTH]; yylvlim = yylvals + YYSTACKGROWTH; yylpsns = new YYPOSN[YYSTACKGROWTH]; yylplim = yylpsns + YYSTACKGROWTH; } if (yylvp == yylve) { yylvp = yylve = yylvals; yylpp = yylpe = yylpsns; yylexp = yylexemes; if (yychar >= 0) { *yylve++ = yylval; *yylpe++ = yyposn; *yylexp = yychar; yychar = -1; } } } if (yychar >= 0) { yylvp--, yylpp--, yylexp--; yychar = -1; } save->lexeme = yylvp - yylvals; yyps->save = save; } if (yytable[yyn] == ctry) { #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: state %d, shifting to state %d\n", yydepth, (int)yytrial, yystate, yyctable[ctry]); #endif if (yychar < 0) yylvp++, yylpp++, yylexp++; yychar = -1; if (yyps->errflag > 0) --yyps->errflag; yystate = yyctable[ctry]; goto yyshift; } else { yyn = yyctable[ctry]; goto yyreduce; } } // // Is action a shift? // if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: state %d, shifting to state %d\n", yydepth, (int)yytrial, yystate, yytable[yyn]); #endif yychar = (-1); if (yyps->errflag > 0) --yyps->errflag; yystate = yytable[yyn]; yyshift: if (yyps->ssp >= yyps->ss + yyps->stacksize - 1) { YYMoreStack(yyps); } *++(yyps->ssp) = yystate; *++(yyps->vsp) = yylval; *++(yyps->psp) = yyposn; goto yyloop; } if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { yyn = yytable[yyn]; goto yyreduce; } // // Action: error // if (yyps->errflag) goto yyinrecovery; yynewerrflag = 1; goto yyerrhandler; yyerrlab: yynewerrflag = 0; yyerrhandler: while (yyps->save) { int ctry; yyparsestate *save = yyps->save; #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: ERROR in state %d, CONFLICT BACKTRACKING to state %d, %d tokens\n", yydepth, (int)yytrial, yystate, yyps->save->state, yylvp - yylvals - yyps->save->lexeme); #endif // Memorize most forward-looking error state in case // it's really an error. if(yyerrctx==NULL || yyerrctx->lexemessp - yyps->ss); yyerrctx->save = yyps->save; yyerrctx->state = yystate; yyerrctx->errflag = yyps->errflag; yyerrctx->ssp = yyerrctx->ss + (yyps->ssp - yyps->ss); yyerrctx->vsp = yyerrctx->vs + (yyps->vsp - yyps->vs); yyerrctx->psp = yyerrctx->ps + (yyps->psp - yyps->ps); memcpy (yyerrctx->ss, yyps->ss, (yyps->ssp - yyps->ss + 1)*sizeof(Yshort)); YYSCopy(yyerrctx->vs, yyps->vs, (yyps->ssp - yyps->ss + 1)); YYPCopy(yyerrctx->ps, yyps->ps, (yyps->ssp - yyps->ss + 1)); yyerrctx->lexeme = yylvp - yylvals; } yylvp = yylvals + save->lexeme; yylpp = yylpsns + save->lexeme; yylexp = yylexemes + save->lexeme; yychar = -1; yyps->ssp = yyps->ss + (save->ssp - save->ss); yyps->vsp = yyps->vs + (save->vsp - save->vs); yyps->psp = yyps->ps + (save->psp - save->ps); memcpy (yyps->ss, save->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort)); YYSCopy(yyps->vs, save->vs, yyps->vsp - yyps->vs + 1); YYPCopy(yyps->ps, save->ps, yyps->psp - yyps->ps + 1); ctry = ++save->ctry; yystate = save->state; // We tried shift, try reduce now if ((yyn = yyctable[ctry]) >= 0) { goto yyreduce; } yyps->save = save->save; YYFreeState(save); // // Nothing left on the stack -- error // if (!yyps->save) { #if YYDEBUG if (yydebug) { printf("yydebug[%d]: trial parse FAILED, entering ERROR mode\n", (int)yytrial); } #endif // Restore state as it was in the most forward-advanced error yylvp = yylvals + yyerrctx->lexeme; yylpp = yylpsns + yyerrctx->lexeme; yylexp = yylexemes + yyerrctx->lexeme; yychar = yylexp[-1]; yylval = yylvp[-1]; yyposn = yylpp[-1]; yyps->ssp = yyps->ss + (yyerrctx->ssp - yyerrctx->ss); yyps->vsp = yyps->vs + (yyerrctx->vsp - yyerrctx->vs); yyps->psp = yyps->ps + (yyerrctx->psp - yyerrctx->ps); memcpy (yyps->ss, yyerrctx->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort)); YYSCopy(yyps->vs, yyerrctx->vs, yyps->vsp - yyps->vs + 1); YYPCopy(yyps->ps, yyerrctx->ps, yyps->psp - yyps->ps + 1); yystate = yyerrctx->state; YYFreeState(yyerrctx); yyerrctx = NULL; } yynewerrflag = 1; } if (yynewerrflag) { #ifdef YYERROR_DETAILED yyerror_detailed("syntax error", yychar, yylval, yyposn); #else yyerror("syntax error"); #endif } ++yynerrs; yyinrecovery: if (yyps->errflag < 3) { yyps->errflag = 3; for (;;) { if ((yyn = yysindex[*(yyps->ssp)]) && (yyn += YYERRCODE) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) { #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: state %d, ERROR recovery shifts to state %d\n", yydepth, (int)yytrial, *(yyps->ssp), yytable[yyn]); #endif /* Use label yyerrlab, so that compiler does not warn */ if(yyps->errflag != yyps->errflag) goto yyerrlab; yystate = yytable[yyn]; goto yyshift; } else { #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: ERROR recovery discards state %d\n", yydepth, (int)yytrial, *(yyps->ssp)); #endif if (yyps->ssp <= yyps->ss) { goto yyabort; } if(!yytrial) { YYDELETEVAL(yyps->vsp[0],1); YYDELETEPOSN(yyps->psp[0],1); } --(yyps->ssp); --(yyps->vsp); --(yyps->psp); } } } else { if (yychar == 0) goto yyabort; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("yydebug[%d,%d]: state %d, ERROR recovery discards token %d (%s)\n", yydepth, (int)yytrial, yystate, yychar, yys); } #endif if(!yytrial) { YYDELETEVAL(yylval,0); YYDELETEPOSN(yyposn,0); } yychar = (-1); goto yyloop; } // // Reduce the rule // yyreduce: yym = yylen[yyn]; #if YYDEBUG if (yydebug) { printf("yydebug[%d,%d]: state %d, reducing by rule %d (%s)", yydepth, (int)yytrial, yystate, yyn, yyrule[yyn]); #ifdef YYDBPR if (yym) { int i; printf("<"); for (i=yym; i>0; i--) { if (i!=yym) printf(", "); YYDBPR((yyps->vsp)[1-i]); } printf(">"); } #endif printf("\n"); } #endif if (yyps->ssp + 1 - yym >= yyps->ss + yyps->stacksize) { YYMoreStack(yyps); } /* "$$ = NULL" default action */ memset(&yyps->val, 0, sizeof(yyps->val)); /* default reduced position is NULL -- no position at all. no position will be assigned at trial time and if no position handling is present */ memset(&yyps->pos, 0, sizeof(yyps->pos)); reduce_posn = TRUE; switch (yyn) { %% trailer default: break; } #if YYDEBUG && defined(YYDBPR) if (yydebug) { printf("yydebug[%d]: after reduction, result is ", yytrial); YYDBPR(yyps->val); printf("\n"); } #endif // Perform user-defined position reduction #ifdef YYREDUCEPOSNFUNC if(!yytrial) { YYCALLREDUCEPOSN(YYREDUCEPOSNFUNCARG); } #endif yyps->ssp -= yym; yystate = *(yyps->ssp); yyps->vsp -= yym; yyps->psp -= yym; yym = yylhs[yyn]; if (yystate == 0 && yym == 0) { #if YYDEBUG if (yydebug) { printf("yydebug[%d,%d]: after reduction, shifting from state 0 to state %d\n", yydepth, (int)yytrial, YYFINAL); } #endif yystate = YYFINAL; *++(yyps->ssp) = YYFINAL; *++(yyps->vsp) = yyps->val; yyretlval = yyps->val; // return value of root non-terminal to yylval *++(yyps->psp) = yyps->pos; yyretposn = yyps->pos; // return value of root position to yyposn if (yychar < 0) { if ((yychar = YYLex1()) < 0) { yychar = 0; } #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("yydebug[%d,%d]: state %d, reading %d (%s)\n", yydepth, (int)yytrial, YYFINAL, yychar, yys); } #endif } if (yychar == 0) goto yyaccept; goto yyloop; } if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yystate) { yystate = yytable[yyn]; } else { yystate = yydgoto[yym]; } #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: after reduction, shifting from state %d to state %d\n", yydepth, (int)yytrial, *(yyps->ssp), yystate); #endif if (yyps->ssp >= yyps->ss + yyps->stacksize - 1) { YYMoreStack(yyps); } *++(yyps->ssp) = yystate; *++(yyps->vsp) = yyps->val; *++(yyps->psp) = yyps->pos; goto yyloop; // // Reduction declares that this path is valid. // Set yypath and do a full parse // yyvalid: if (yypath) { goto yyabort; } while (yyps->save) { yyparsestate *save = yyps->save; yyps->save = save->save; save->save = yypath; yypath = save; } #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: CONFLICT trial successful, backtracking to state %d, %d tokens\n", yydepth, (int)yytrial, yypath->state, yylvp - yylvals - yypath->lexeme); #endif if(yyerrctx) { YYFreeState(yyerrctx); yyerrctx = NULL; } yychar = -1; yyps->ssp = yyps->ss + (yypath->ssp - yypath->ss); yyps->vsp = yyps->vs + (yypath->vsp - yypath->vs); yyps->psp = yyps->ps + (yypath->psp - yypath->ps); memcpy (yyps->ss, yypath->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort)); YYSCopy(yyps->vs, yypath->vs, yyps->vsp - yyps->vs + 1); YYPCopy(yyps->ps, yypath->ps, yyps->psp - yyps->ps + 1); yylvp = yylvals + yypath->lexeme; yylpp = yylpsns + yypath->lexeme; yylexp = yylexemes + yypath->lexeme; yystate = yypath->state; goto yyloop; yyabort: if(yyerrctx) { YYFreeState(yyerrctx); yyerrctx = NULL; } YYSTYPE *pv; for(pv=yyps->vs; pvvsp; pv++) { YYDELETEVAL(*pv,2); } YYPOSN *pp; for(pp=yyps->ps; pppsp; pp++) { YYDELETEPOSN(*pp,2); } while (yyps) { yyparsestate *save = yyps; yyps = save->save; YYFreeState(save); } while (yypath) { yyparsestate *save = yypath; yypath = save->save; YYFreeState(save); } return (1); yyaccept: if (yyps->save) goto yyvalid; if(yyerrctx) { YYFreeState(yyerrctx); yyerrctx = NULL; } while (yyps) { yyparsestate *save = yyps; yyps = save->save; YYFreeState(save); } while (yypath) { yyparsestate *save = yypath; yypath = save->save; YYFreeState(save); } return (0); } int YYLex1() { if(yylvpsave) { if(yylvp==yylvlim) { yyexpand(); } *yylexp = yylex(); *yylvp++ = yylval; yylve++; *yylpp++ = yyposn; yylpe++; return *yylexp++; } else { return yylex(); } } } int yyexpand() { int p = yylvp-yylvals; int s = yylvlim-yylvals; s += YYSTACKGROWTH; { Yshort *tl = yylexemes; YYSTYPE *tv = yylvals; YYPOSN *tp = yylpsns; yylvals = new YYSTYPE[s]; yylpsns = new YYPOSN[s]; yylexemes = new Yshort[s]; memcpy(yylexemes, tl, (s-YYSTACKGROWTH)*sizeof(Yshort)); YYSCopy(yylvals, tv, s-YYSTACKGROWTH); YYPCopy(yylpsns, tp, s-YYSTACKGROWTH); delete[] tl; delete[] tv; delete[] tp; } yylvp = yylve = yylvals + p; yylvlim = yylvals + s; yylpp = yylpe = yylpsns + p; yylplim = yylpsns + s; yylexp = yylexemes + p; return 0; } void YYSCopy(YYSTYPE *to, YYSTYPE *from, int size) { int i; for (i = size-1; i >= 0; i--) { to[i] = from[i]; } } void YYPCopy(YYPOSN *to, YYPOSN *from, int size) { int i; for (i = size-1; i >= 0; i--) { to[i] = from[i]; } } void YYMoreStack(yyparsestate *yyps) { int p = yyps->ssp - yyps->ss; Yshort *tss = yyps->ss; YYSTYPE *tvs = yyps->vs; YYPOSN *tps = yyps->ps; yyps->ss = new Yshort [yyps->stacksize + YYSTACKGROWTH]; yyps->vs = new YYSTYPE[yyps->stacksize + YYSTACKGROWTH]; yyps->ps = new YYPOSN [yyps->stacksize + YYSTACKGROWTH]; memcpy(yyps->ss, tss, yyps->stacksize * sizeof(Yshort)); YYSCopy(yyps->vs, tvs, yyps->stacksize); YYPCopy(yyps->ps, tps, yyps->stacksize); yyps->stacksize += YYSTACKGROWTH; delete[] tss; delete[] tvs; delete[] tps; yyps->ssp = yyps->ss + p; yyps->vsp = yyps->vs + p; yyps->psp = yyps->ps + p; } yyparsestate *YYNewState(int size) { yyparsestate *p = new yyparsestate; p->stacksize = size+4; p->ss = new Yshort [size + 4]; p->vs = new YYSTYPE[size + 4]; p->ps = new YYPOSN [size + 4]; memset(&p->vs[0], 0, (size+4)*sizeof(YYSTYPE)); memset(&p->ps[0], 0, (size+4)*sizeof(YYPOSN)); return p; } void YYFreeState(yyparsestate *p) { delete[] p->ss; delete[] p->vs; delete[] p->ps; delete p; } btyacc-3.0+dfsg/skeleton.c0000644000175000017500000006572506743372503015770 0ustar eribertoeriberto/* ** This file generated automatically from */ #include "defs.h" /* The banner used here should be replaced with an #ident directive */ /* if the target C compiler supports #ident directives. */ /* */ /* If the skeleton is changed, the banner should be changed so that */ /* the altered version can easily be distinguished from the original. */ char *banner[] = { "#line 8 \"btyaccpa.ske\"", "", "//", "// @(#)btyaccpar, based on byacc 1.8 (Berkeley)", "//", "#define YYBTYACC 1", "", "#include ", "#include ", "#include ", "", "typedef int Yshort;", "", 0 }; char *tables[] = { "#line 21 \"btyaccpa.ske\"", "", "#define _C_ \"C\"", "", "extern _C_ Yshort yylhs[];", "extern _C_ Yshort yylen[];", "extern _C_ Yshort yydefred[];", "extern _C_ Yshort yydgoto[];", "extern _C_ Yshort yysindex[];", "extern _C_ Yshort yyrindex[];", "extern _C_ Yshort yycindex[];", "extern _C_ Yshort yygindex[];", "extern _C_ Yshort yytable[];", "extern _C_ Yshort yycheck[];", "extern _C_ Yshort yyctable[];", "", "#if YYDEBUG", "extern _C_ char *yyname[];", "extern _C_ char *yyrule[];", "#endif", "", 0 }; char *header[] = { "#line 42 \"btyaccpa.ske\"", "", "//", "// YYPOSN is user-defined text position type.", "//", "#ifndef YYPOSN", "#define YYPOSN int", "#endif", "", "#ifdef YYREDUCEPOSNFUNC", "#define YYCALLREDUCEPOSN(e) \\", "\tif(reduce_posn) { \\", "\t YYREDUCEPOSNFUNC(yyps->pos, &(yyps->psp)[1-yym], &(yyps->vsp)[1-yym], \\", "\t\t\t yym, yyps->psp - yyps->ps, yychar, yyposn, e); \\", "\t reduce_posn = 0; \\", "\t}", "", "#ifndef YYCALLREDUCEPOSNARG", "#define YYCALLREDUCEPOSNARG yyps->val", "#endif", "", "", "#define YYPOSNARG(n) ((yyps->psp)[1-yym+(n)-1])", "#define YYPOSNOUT (yyps->pos)", "#endif", "", "// If delete function is not defined by the user, do not deletions.", "#ifndef YYDELETEVAL", "#define YYDELETEVAL(v) ", "#endif", "", "// If delete function is not defined by the user, do not deletions.", "#ifndef YYDELETEPOSN", "#define YYDELETEPOSN(v) ", "#endif", "", "#define yyclearin (yychar=(-1))", "", "#define yyerrok (yyps->errflag=0)", "", "#ifndef YYSTACKGROWTH", "#define YYSTACKGROWTH 16", "#endif", "", "#ifndef YYDEFSTACKSIZE", "#define YYDEFSTACKSIZE 12", "#endif", "", "#ifdef YYDEBUG", "int yydebug;", "#endif", "", "int yynerrs;", "", "/* These value/posn are taken from the lexer */", "YYSTYPE yylval;", "YYPOSN yyposn;", "", "/* These value/posn of the root non-terminal are returned to the caller */", "YYSTYPE yyretlval;", "YYPOSN yyretposn;", "", "#define YYABORT goto yyabort", "#define YYACCEPT goto yyaccept", "#define YYERROR goto yyerrlab", "#define YYVALID do { if (yyps->save) goto yyvalid; } while(0)", "#define YYVALID_NESTED do { if (yyps->save && \\", " yyps->save->save==0) goto yyvalid; } while(0)", "", "struct yyparsestate {", " yyparsestate *save; // Previously saved parser state", " int state;", " int errflag;", " Yshort *ssp; // state stack pointer", " YYSTYPE *vsp; // value stack pointer", " YYPOSN *psp; // position stack pointer", " YYSTYPE val; // value as returned by actions", " YYPOSN pos; // position as returned by universal action", " Yshort *ss; // state stack base", " YYSTYPE *vs; // values stack base", " YYPOSN *ps; // position stack base", " int lexeme; // index of the conflict lexeme in the lexical queue", " unsigned int stacksize; // current maximum stack size", " Yshort ctry; // index in yyctable[] for this conflict", "};", "", "// Current parser state", "static yyparsestate *yyps=0;", "", "// yypath!=NULL: do the full parse, starting at *yypath parser state.", "static yyparsestate *yypath=0;", "", "// Base of the lexical value queue", "static YYSTYPE *yylvals=0;", "", "// Current posistion at lexical value queue", "static YYSTYPE *yylvp=0;", "", "// End position of lexical value queue", "static YYSTYPE *yylve=0;", "", "// The last allocated position at the lexical value queue", "static YYSTYPE *yylvlim=0;", "", "// Base of the lexical position queue", "static YYPOSN *yylpsns=0;", "", "// Current posistion at lexical position queue", "static YYPOSN *yylpp=0;", "", "// End position of lexical position queue", "static YYPOSN *yylpe=0;", "", "// The last allocated position at the lexical position queue", "static YYPOSN *yylplim=0;", "", "// Current position at lexical token queue", "static Yshort *yylexp=0;", "", "static Yshort *yylexemes=0;", "", "//", "// For use in generated program", "//", "#define yytrial (yyps->save)", "#define yyvsp (yyps->vsp)", "#define yyval (yyps->val)", "#define yydepth (yyps->ssp - yyps->ss)", "", "", "//", "// Local prototypes.", "//", "int yyparse(void);", "", "int YYLex1();", "int yyexpand();", "void YYSCopy(YYSTYPE *to, YYSTYPE *from, int size);", "void YYPCopy(YYPOSN *to, YYPOSN *from, int size);", "void YYMoreStack(yyparsestate *yyps);", "yyparsestate *YYNewState(int size);", "void YYFreeState(yyparsestate *p);", "", "", 0 }; char *body[] = { "#line 186 \"btyaccpa.ske\"", "", "", "//", "// Parser function", "//", "int yyparse() {", " int yym, yyn, yystate, yychar, yynewerrflag;", " yyparsestate *yyerrctx = NULL;", " int reduce_posn;", "", "#if YYDEBUG", " char *yys;", " ", " if ((yys = getenv(\"YYDEBUG\"))) {", " yyn = *yys;", " if (yyn >= '0' && yyn <= '9')", " yydebug = yyn - '0'; ", " }", "#endif", " ", " yyps = YYNewState(YYDEFSTACKSIZE);", " yyps->save = 0;", " yynerrs = 0;", " yyps->errflag = 0;", " yychar = (-1);", " ", " yyps->ssp = yyps->ss;", " yyps->vsp = yyps->vs;", " yyps->psp = yyps->ps;", " *(yyps->ssp) = yystate = 0;", " ", "", " //", " // Main parsing loop", " //", " yyloop:", " if ((yyn = yydefred[yystate])) {", " goto yyreduce;", " }", "", " //", " // Read one token", " //", " if (yychar < 0) {", " if ((yychar = YYLex1()) < 0) yychar = 0;", "#if YYDEBUG", " if (yydebug) {", " yys = 0;", " if (yychar <= YYMAXTOKEN) yys = yyname[yychar];", " if (!yys) yys = \"illegal-symbol\";", " printf(\"yydebug[%d,%d]: state %d, reading %d (%s)\", ", "\t yydepth, (int)yytrial, yystate, yychar, yys);", "#ifdef YYDBPR", " printf(\"<\");", " YYDBPR(yylval);", " printf(\">\");", "#endif", " printf(\"\\n\"); ", " }", "#endif", " }", "", " //", " // Do we have a conflict?", " //", " if ((yyn = yycindex[yystate]) &&", " (yyn += yychar) >= 0 &&", " yyn <= YYTABLESIZE &&", " yycheck[yyn] == yychar) {", " int ctry;", "", " if (yypath) {", "#if YYDEBUG", " if (yydebug) {", " printf(\"yydebug[%d,%d]: CONFLICT in state %d: following successful trial parse\\n\", ", "\t yydepth, (int)yytrial, yystate);", " }", "#endif", " // Switch to the next conflict context", " yyparsestate *save = yypath;", " yypath = save->save;", " ctry = save->ctry;", " if (save->state != yystate) ", " goto yyabort;", " YYFreeState(save); ", "", " } else {", "", "#if YYDEBUG", " if (yydebug) {", " printf(\"yydebug[%d,%d]: CONFLICT in state %d. \", ", "\t yydepth, (int)yytrial, yystate);", " if(yyps->save) {", " printf(\"ALREADY in conflict. Continue trial parse.\");", " } else {", " printf(\"Start trial parse.\");", " }", " printf(\"\\n\");", " }", "#endif", " yyparsestate *save = YYNewState(yyps->ssp - yyps->ss);", " save->save = yyps->save;", " save->state = yystate;", " save->errflag = yyps->errflag;", " save->ssp = save->ss + (yyps->ssp - yyps->ss);", " save->vsp = save->vs + (yyps->vsp - yyps->vs);", " save->psp = save->ps + (yyps->psp - yyps->ps);", " memcpy (save->ss, yyps->ss, (yyps->ssp - yyps->ss + 1)*sizeof(Yshort));", " YYSCopy(save->vs, yyps->vs, (yyps->ssp - yyps->ss + 1));", " YYPCopy(save->ps, yyps->ps, (yyps->ssp - yyps->ss + 1));", " ctry = yytable[yyn];", " if (yyctable[ctry] == -1) {", "#if YYDEBUG", " if (yydebug && yychar >= 0)", " printf(\"yydebug[%d]: backtracking 1 token\\n\", ", "\t\t (int)yytrial);", "#endif", " ctry++; ", " }", " save->ctry = ctry;", " if (!yyps->save) {", " // If this is a first conflict in the stack, start saving lexemes", " if (!yylexemes) {", " yylexemes = new Yshort[YYSTACKGROWTH];", " yylvals = new YYSTYPE[YYSTACKGROWTH];", " yylvlim = yylvals + YYSTACKGROWTH; ", " yylpsns = new YYPOSN[YYSTACKGROWTH];", " yylplim = yylpsns + YYSTACKGROWTH; ", " }", " if (yylvp == yylve) {", " yylvp = yylve = yylvals;", "\t yylpp = yylpe = yylpsns;", " yylexp = yylexemes;", " if (yychar >= 0) {", " *yylve++ = yylval;", " *yylpe++ = yyposn;", " *yylexp = yychar;", " yychar = -1; ", " } ", " } ", " }", " if (yychar >= 0) {", " yylvp--, yylpp--, yylexp--;", " yychar = -1; ", " }", " save->lexeme = yylvp - yylvals;", " yyps->save = save; ", " }", " if (yytable[yyn] == ctry) {", "#if YYDEBUG", " if (yydebug)", " printf(\"yydebug[%d,%d]: state %d, shifting to state %d\\n\",", " yydepth, (int)yytrial, yystate, yyctable[ctry]);", "#endif", " if (yychar < 0)", " yylvp++, yylpp++, yylexp++;", " yychar = -1;", " if (yyps->errflag > 0) --yyps->errflag;", " yystate = yyctable[ctry];", " goto yyshift; ", " } else {", " yyn = yyctable[ctry];", " goto yyreduce; ", " } ", " }", "", " //", " // Is action a shift?", " //", " if ((yyn = yysindex[yystate]) &&", " (yyn += yychar) >= 0 &&", " yyn <= YYTABLESIZE &&", " yycheck[yyn] == yychar) {", "#if YYDEBUG", " if (yydebug)", " printf(\"yydebug[%d,%d]: state %d, shifting to state %d\\n\",", " yydepth, (int)yytrial, yystate, yytable[yyn]);", "#endif", " yychar = (-1);", " if (yyps->errflag > 0) --yyps->errflag;", " yystate = yytable[yyn];", " yyshift:", " if (yyps->ssp >= yyps->ss + yyps->stacksize - 1) {", " YYMoreStack(yyps);", " }", " *++(yyps->ssp) = yystate;", " *++(yyps->vsp) = yylval;", " *++(yyps->psp) = yyposn;", " goto yyloop;", " }", " if ((yyn = yyrindex[yystate]) &&", " (yyn += yychar) >= 0 &&", " yyn <= YYTABLESIZE &&", " yycheck[yyn] == yychar) {", " yyn = yytable[yyn];", " goto yyreduce;", " }", "", " //", " // Action: error", " //", " if (yyps->errflag) goto yyinrecovery;", " yynewerrflag = 1;", " goto yyerrhandler;", "yyerrlab:", " yynewerrflag = 0;", "yyerrhandler:", " while (yyps->save) { ", " int ctry; ", " yyparsestate *save = yyps->save;", "#if YYDEBUG", " if (yydebug)", " printf(\"yydebug[%d,%d]: ERROR in state %d, CONFLICT BACKTRACKING to state %d, %d tokens\\n\",", " yydepth, (int)yytrial, yystate, yyps->save->state, yylvp - yylvals - yyps->save->lexeme);", "#endif", " // Memorize most forward-looking error state in case", " // it's really an error.", " if(yyerrctx==NULL || yyerrctx->lexemessp - yyps->ss);", " yyerrctx->save = yyps->save;", " yyerrctx->state = yystate;", " yyerrctx->errflag = yyps->errflag;", " yyerrctx->ssp = yyerrctx->ss + (yyps->ssp - yyps->ss);", " yyerrctx->vsp = yyerrctx->vs + (yyps->vsp - yyps->vs);", " yyerrctx->psp = yyerrctx->ps + (yyps->psp - yyps->ps);", " memcpy (yyerrctx->ss, yyps->ss, (yyps->ssp - yyps->ss + 1)*sizeof(Yshort));", " YYSCopy(yyerrctx->vs, yyps->vs, (yyps->ssp - yyps->ss + 1));", " YYPCopy(yyerrctx->ps, yyps->ps, (yyps->ssp - yyps->ss + 1));", " yyerrctx->lexeme = yylvp - yylvals;", " }", " yylvp = yylvals + save->lexeme;", " yylpp = yylpsns + save->lexeme;", " yylexp = yylexemes + save->lexeme;", " yychar = -1;", " yyps->ssp = yyps->ss + (save->ssp - save->ss);", " yyps->vsp = yyps->vs + (save->vsp - save->vs);", " yyps->psp = yyps->ps + (save->psp - save->ps);", " memcpy (yyps->ss, save->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort));", " YYSCopy(yyps->vs, save->vs, yyps->vsp - yyps->vs + 1);", " YYPCopy(yyps->ps, save->ps, yyps->psp - yyps->ps + 1);", " ctry = ++save->ctry;", " yystate = save->state;", " // We tried shift, try reduce now", " if ((yyn = yyctable[ctry]) >= 0) {", " goto yyreduce;", " }", " yyps->save = save->save;", " YYFreeState(save);", " //", " // Nothing left on the stack -- error", " //", " if (!yyps->save) {", "#if YYDEBUG", " if (yydebug) {", " printf(\"yydebug[%d]: trial parse FAILED, entering ERROR mode\\n\", ", "\t (int)yytrial);", " }", "#endif", " // Restore state as it was in the most forward-advanced error", " yylvp = yylvals + yyerrctx->lexeme;", " yylpp = yylpsns + yyerrctx->lexeme;", " yylexp = yylexemes + yyerrctx->lexeme;", " yychar = yylexp[-1];", " yylval = yylvp[-1];", " yyposn = yylpp[-1];", " yyps->ssp = yyps->ss + (yyerrctx->ssp - yyerrctx->ss);", " yyps->vsp = yyps->vs + (yyerrctx->vsp - yyerrctx->vs);", " yyps->psp = yyps->ps + (yyerrctx->psp - yyerrctx->ps);", " memcpy (yyps->ss, yyerrctx->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort));", " YYSCopy(yyps->vs, yyerrctx->vs, yyps->vsp - yyps->vs + 1);", " YYPCopy(yyps->ps, yyerrctx->ps, yyps->psp - yyps->ps + 1);", " yystate = yyerrctx->state;", " YYFreeState(yyerrctx);", " yyerrctx = NULL;", " }", " yynewerrflag = 1; ", " }", " if (yynewerrflag) {", "#ifdef YYERROR_DETAILED", " yyerror_detailed(\"syntax error\", yychar, yylval, yyposn);", "#else", " yyerror(\"syntax error\");", "#endif", " }", " ++yynerrs;", " yyinrecovery:", " if (yyps->errflag < 3) {", " yyps->errflag = 3;", " for (;;) {", " if ((yyn = yysindex[*(yyps->ssp)]) && ", "\t (yyn += YYERRCODE) >= 0 &&", " yyn <= YYTABLESIZE && ", "\t yycheck[yyn] == YYERRCODE) {", "#if YYDEBUG", " if (yydebug)", " printf(\"yydebug[%d,%d]: state %d, ERROR recovery shifts to state %d\\n\",", " yydepth, (int)yytrial, *(yyps->ssp), yytable[yyn]);", "#endif", " /* Use label yyerrlab, so that compiler does not warn */", " if(yyps->errflag != yyps->errflag) goto yyerrlab;", " yystate = yytable[yyn];", " goto yyshift; ", " } else {", "#if YYDEBUG", " if (yydebug)", " printf(\"yydebug[%d,%d]: ERROR recovery discards state %d\\n\",", " yydepth, (int)yytrial, *(yyps->ssp));", "#endif", " if (yyps->ssp <= yyps->ss) {", "\t goto yyabort;", "\t}", "\tif(!yytrial) {", "\t YYDELETEVAL(yyps->vsp[0],1);", "\t YYDELETEPOSN(yyps->psp[0],1);", "\t}", " --(yyps->ssp);", " --(yyps->vsp);", " --(yyps->psp);", " }", " }", " } else {", " if (yychar == 0) goto yyabort;", "#if YYDEBUG", " if (yydebug) {", " yys = 0;", " if (yychar <= YYMAXTOKEN) yys = yyname[yychar];", " if (!yys) yys = \"illegal-symbol\";", " printf(\"yydebug[%d,%d]: state %d, ERROR recovery discards token %d (%s)\\n\",", " yydepth, (int)yytrial, yystate, yychar, yys); ", " }", "#endif", " if(!yytrial) {", " YYDELETEVAL(yylval,0);", " YYDELETEPOSN(yyposn,0);", " }", " yychar = (-1);", " goto yyloop;", " }", "", " //", " // Reduce the rule", " //", "yyreduce:", " yym = yylen[yyn];", "#if YYDEBUG", " if (yydebug) {", " printf(\"yydebug[%d,%d]: state %d, reducing by rule %d (%s)\",", " yydepth, (int)yytrial, yystate, yyn, yyrule[yyn]);", "#ifdef YYDBPR", " if (yym) {", " int i;", " printf(\"<\");", " for (i=yym; i>0; i--) {", " if (i!=yym) printf(\", \");", " YYDBPR((yyps->vsp)[1-i]);", " }", " printf(\">\");", " }", "#endif", " printf(\"\\n\");", " }", "#endif", " if (yyps->ssp + 1 - yym >= yyps->ss + yyps->stacksize) {", " YYMoreStack(yyps);", " }", "", " /* \"$$ = NULL\" default action */", " memset(&yyps->val, 0, sizeof(yyps->val));", "", " /* default reduced position is NULL -- no position at all.", " no position will be assigned at trial time and if no position handling is present */", " memset(&yyps->pos, 0, sizeof(yyps->pos));", "", " reduce_posn = TRUE;", "", " switch (yyn) {", "", 0 }; char *trailer[] = { "#line 567 \"btyaccpa.ske\"", "", " default:", " break;", " }", "", "#if YYDEBUG && defined(YYDBPR)", " if (yydebug) {", " printf(\"yydebug[%d]: after reduction, result is \", yytrial);", " YYDBPR(yyps->val);", " printf(\"\\n\");", " }", "#endif", "", " // Perform user-defined position reduction", "#ifdef YYREDUCEPOSNFUNC", " if(!yytrial) {", " YYCALLREDUCEPOSN(YYREDUCEPOSNFUNCARG);", " }", "#endif", "", " yyps->ssp -= yym;", " yystate = *(yyps->ssp);", " yyps->vsp -= yym;", " yyps->psp -= yym;", "", " yym = yylhs[yyn];", " if (yystate == 0 && yym == 0) {", "#if YYDEBUG", " if (yydebug) {", " printf(\"yydebug[%d,%d]: after reduction, shifting from state 0 to state %d\\n\", ", "\t yydepth, (int)yytrial, YYFINAL);", " }", "#endif", " yystate = YYFINAL;", " *++(yyps->ssp) = YYFINAL;", " *++(yyps->vsp) = yyps->val;", " yyretlval = yyps->val;\t// return value of root non-terminal to yylval", " *++(yyps->psp) = yyps->pos;", " yyretposn = yyps->pos;\t// return value of root position to yyposn", " if (yychar < 0) {", " if ((yychar = YYLex1()) < 0) {", " yychar = 0;", " }", "#if YYDEBUG", " if (yydebug) {", " yys = 0;", " if (yychar <= YYMAXTOKEN) yys = yyname[yychar];", " if (!yys) yys = \"illegal-symbol\";", " printf(\"yydebug[%d,%d]: state %d, reading %d (%s)\\n\", ", "\t yydepth, (int)yytrial, YYFINAL, yychar, yys); ", " }", "#endif", " }", " if (yychar == 0) goto yyaccept;", " goto yyloop;", " }", "", " if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&", " yyn <= YYTABLESIZE && yycheck[yyn] == yystate) {", " yystate = yytable[yyn];", " } else {", " yystate = yydgoto[yym];", " }", "#if YYDEBUG", " if (yydebug)", " printf(\"yydebug[%d,%d]: after reduction, shifting from state %d to state %d\\n\",", " yydepth, (int)yytrial, *(yyps->ssp), yystate);", "#endif", " if (yyps->ssp >= yyps->ss + yyps->stacksize - 1) {", " YYMoreStack(yyps);", " }", " *++(yyps->ssp) = yystate;", " *++(yyps->vsp) = yyps->val;", " *++(yyps->psp) = yyps->pos;", " goto yyloop;", "", "", " //", " // Reduction declares that this path is valid.", " // Set yypath and do a full parse", " //", "yyvalid:", " if (yypath) {", " goto yyabort;", " }", " while (yyps->save) {", " yyparsestate *save = yyps->save;", " yyps->save = save->save;", " save->save = yypath;", " yypath = save;", " }", "#if YYDEBUG", " if (yydebug)", " printf(\"yydebug[%d,%d]: CONFLICT trial successful, backtracking to state %d, %d tokens\\n\",", " yydepth, (int)yytrial, yypath->state, yylvp - yylvals - yypath->lexeme);", "#endif", " if(yyerrctx) {", " YYFreeState(yyerrctx); yyerrctx = NULL;", " }", " yychar = -1;", " yyps->ssp = yyps->ss + (yypath->ssp - yypath->ss);", " yyps->vsp = yyps->vs + (yypath->vsp - yypath->vs);", " yyps->psp = yyps->ps + (yypath->psp - yypath->ps);", " memcpy (yyps->ss, yypath->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort));", " YYSCopy(yyps->vs, yypath->vs, yyps->vsp - yyps->vs + 1);", " YYPCopy(yyps->ps, yypath->ps, yyps->psp - yyps->ps + 1);", " yylvp = yylvals + yypath->lexeme;", " yylpp = yylpsns + yypath->lexeme;", " yylexp = yylexemes + yypath->lexeme;", " yystate = yypath->state;", " goto yyloop;", "", "", "yyabort:", " if(yyerrctx) {", " YYFreeState(yyerrctx); yyerrctx = NULL;", " }", "", " YYSTYPE *pv;", " for(pv=yyps->vs; pvvsp; pv++) {", " YYDELETEVAL(*pv,2);", " }", "", " YYPOSN *pp;", " for(pp=yyps->ps; pppsp; pp++) {", " YYDELETEPOSN(*pp,2);", " }", "", " while (yyps) {", " yyparsestate *save = yyps;", " yyps = save->save;", " YYFreeState(save);", " }", " while (yypath) {", " yyparsestate *save = yypath;", " yypath = save->save;", " YYFreeState(save); ", " }", " return (1);", "", "", "yyaccept:", " if (yyps->save) goto yyvalid;", " if(yyerrctx) {", " YYFreeState(yyerrctx); yyerrctx = NULL;", " }", " while (yyps) {", " yyparsestate *save = yyps;", " yyps = save->save;", " YYFreeState(save);", " }", " while (yypath) {", " yyparsestate *save = yypath;", " yypath = save->save;", " YYFreeState(save); ", " }", " return (0);", "}", "", "", "int YYLex1() {", " if(yylvpsave) {", " if(yylvp==yylvlim) {", "\tyyexpand();", " }", " *yylexp = yylex();", " *yylvp++ = yylval;", " yylve++;", " *yylpp++ = yyposn;", " yylpe++;", " return *yylexp++;", " } else {", " return yylex();", " }", " }", "}", "", "int yyexpand() {", " int p = yylvp-yylvals;", " int s = yylvlim-yylvals;", " s += YYSTACKGROWTH;", " { Yshort *tl = yylexemes; ", " YYSTYPE *tv = yylvals;", " YYPOSN *tp = yylpsns;", " yylvals = new YYSTYPE[s];", " yylpsns = new YYPOSN[s];", " yylexemes = new Yshort[s];", " memcpy(yylexemes, tl, (s-YYSTACKGROWTH)*sizeof(Yshort));", " YYSCopy(yylvals, tv, s-YYSTACKGROWTH);", " YYPCopy(yylpsns, tp, s-YYSTACKGROWTH);", " delete[] tl;", " delete[] tv;", " delete[] tp;", " }", " yylvp = yylve = yylvals + p;", " yylvlim = yylvals + s;", " yylpp = yylpe = yylpsns + p;", " yylplim = yylpsns + s;", " yylexp = yylexemes + p;", " return 0;", "}", "", "void YYSCopy(YYSTYPE *to, YYSTYPE *from, int size) {", " int i; ", " for (i = size-1; i >= 0; i--) {", " to[i] = from[i];", " }", "}", "", "void YYPCopy(YYPOSN *to, YYPOSN *from, int size) {", " int i; ", " for (i = size-1; i >= 0; i--) {", " to[i] = from[i];", " }", "}", "", "void YYMoreStack(yyparsestate *yyps) {", " int p = yyps->ssp - yyps->ss; ", " Yshort *tss = yyps->ss;", " YYSTYPE *tvs = yyps->vs;", " YYPOSN *tps = yyps->ps;", " yyps->ss = new Yshort [yyps->stacksize + YYSTACKGROWTH]; ", " yyps->vs = new YYSTYPE[yyps->stacksize + YYSTACKGROWTH]; ", " yyps->ps = new YYPOSN [yyps->stacksize + YYSTACKGROWTH]; ", " memcpy(yyps->ss, tss, yyps->stacksize * sizeof(Yshort)); ", " YYSCopy(yyps->vs, tvs, yyps->stacksize); ", " YYPCopy(yyps->ps, tps, yyps->stacksize); ", " yyps->stacksize += YYSTACKGROWTH; ", " delete[] tss;", " delete[] tvs;", " delete[] tps;", " yyps->ssp = yyps->ss + p; ", " yyps->vsp = yyps->vs + p; ", " yyps->psp = yyps->ps + p; ", "}", "", "yyparsestate *YYNewState(int size) {", " yyparsestate *p = new yyparsestate;", " p->stacksize = size+4;", " p->ss = new Yshort [size + 4];", " p->vs = new YYSTYPE[size + 4];", " p->ps = new YYPOSN [size + 4];", " memset(&p->vs[0], 0, (size+4)*sizeof(YYSTYPE));", " memset(&p->ps[0], 0, (size+4)*sizeof(YYPOSN));", " return p;", "}", "", "void YYFreeState(yyparsestate *p) {", " delete[] p->ss;", " delete[] p->vs;", " delete[] p->ps;", " delete p;", "}", 0 }; struct section section_list[] = { { "banner", &banner[0] }, { "tables", &tables[0] }, { "header", &header[0] }, { "body", &body[0] }, { "trailer", &trailer[0] }, { 0, 0 } }; btyacc-3.0+dfsg/readskel.c0000644000175000017500000000437006400471775015724 0ustar eribertoeriberto#include "defs.h" #include /* amount of memeory to allocate at once */ #define CHUNK 8192 static char *cp, *cp_end; static char **ap, **ap_end, **ap_start; static void add_ptr(char *p) { if (ap == ap_end) { int size = CHUNK; char **nap; while ((ap-ap_start) * sizeof(char *) >= size) size = size * 2; if (!(nap = malloc(size))) no_space(); if (ap > ap_start) memcpy(nap, ap_start, (ap-ap_start) * sizeof(char *)); ap = nap + (ap - ap_start); ap_start = nap; ap_end = nap + size/sizeof(char *); } *ap++ = p; } static void add_string(char *s) { int len = strlen(s)+1; if (len > cp_end - cp) { int size = len > CHUNK ? len : CHUNK; if (!(cp = malloc(size))) no_space(); cp_end = cp + size; } memcpy(cp, s, len); add_ptr(cp); cp += len; } static void add_fmt(char *fmt, ...) { va_list args; char buf[256]; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); add_string(buf); } static char **fin_section(void) { char **rv; add_ptr(0); rv = ap_start; ap_start = ap; return rv; } void read_skel(char *name) { char buf[256]; int section = -2; int line = 0, sline = 1, eline = 1; int i; FILE *fp; if (!(fp = fopen(name, "r"))) open_error(name); while(fgets(buf, 255, fp)) { if ((sline = eline)) line++; if ((i = strlen(buf)) == 0) continue; if (buf[i-1] == '\n') { buf[--i] = 0; eline = 1; } else { buf[i++] = '\\'; buf[i] = 0; eline = 0; } if (sline && buf[0] == '%' && buf[1] == '%') { char *p = buf+2; if (section >= 0) { section_list[section].ptr = fin_section(); } section = -1; while(*p && isspace(*p)) p++; if (isalpha(*p)) { char *e = p; while(isalnum(*++e)); *e = 0; for (i=0; section_list[i].name; i++) if (!strcmp(section_list[i].name, p)) section = i; } if (section >= 0) add_fmt("#line %d \"%s\"", line+1, name); else if (*p) error(0, buf, p, "line %d of \"%s\", bad section name", line, name); } else if (section >= 0) { add_string(buf); } } if (section >= 0) section_list[section].ptr = fin_section(); if (section == -2) error(0, 0, 0, "No sections found in skeleton file \"%s\"", name); } btyacc-3.0+dfsg/mstring.h0000644000175000017500000000111406367232302015604 0ustar eribertoeriberto#ifndef _string_h_ #define _string_h_ struct mstring { char *base, *ptr, *end; }; void msprintf(struct mstring *, const char *, ...); int mputchar(struct mstring *, int); struct mstring *msnew(void); char *msdone(struct mstring *); /* compare two strings, ignoring whitespace, except between two letters or ** digits (and treat all of these as equal) */ int strnscmp(const char *, const char *); /* hash a string, ignoring whitespace */ unsigned int strnshash(const char *); #define mputc(m, ch) ((m)->ptr==(m)->end?mputchar(m,ch):(*(m)->ptr++=(ch))) #endif /* _string_h_ */