⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reader.c

📁 yacc源码
💻 C
📖 第 1 页 / 共 3 页
字号:
#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	20char *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 1000char *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 OUTCvoid 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(){    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));    fprintf(text_file, "typedef union");    if (dflag) fprintf(union_file, "typedef union");    depth = 0;loop:    c = *cptr++;    putc(c, text_file);    if (dflag) putc(c, union_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(text_file, " YYSTYPE;\n");	    FREE(u_line);	    return; }	goto loop;    case '\'':    case '"':	copy_string(c, text_file, dflag ? union_file : 0);	goto loop;    case '/':	copy_comment(text_file, dflag ? union_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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -