📄 reader.c
字号:
fatals("type redeclaration for %s", symval->tag);
}
break;
case NUMBER:
if (prev == IDENTIFIER)
{
symval->user_token_number = numval;
translations = 1;
}
else
fatal("invalid text in association declaration");
break;
case SEMICOLON:
return;
default:
fatal("malformatted association declaration");
}
prev = t;
}
}
/* copy the union declaration into fattrs (and fdefines),
where it is made into the
definition of YYSTYPE, the type of elements of the parser value stack. */
void
parse_union_decl()
{
register int c;
register int count;
register int in_comment;
int cplus_comment;
if (typed)
fatal("multiple %union declarations");
typed = 1;
if (!nolinesflag)
fprintf(fattrs, "\n#line %d \"%s\"\n", lineno, infile);
else
fprintf(fattrs, "\n");
fprintf(fattrs, "typedef union");
if (fdefines)
fprintf(fdefines, "typedef union");
count = 0;
in_comment = 0;
c = getc(finput);
while (c != EOF)
{
putc(c, fattrs);
if (fdefines)
putc(c, fdefines);
switch (c)
{
case '\n':
lineno++;
break;
case '/':
c = getc(finput);
if (c != '*' && c != '/')
ungetc(c, finput);
else
{
putc(c, fattrs);
if (fdefines)
putc(c, fdefines);
cplus_comment = (c == '/');
in_comment = 1;
c = getc(finput);
while (in_comment)
{
putc(c, fattrs);
if (fdefines)
putc(c, fdefines);
if (c == '\n')
{
lineno++;
if (cplus_comment)
{
in_comment = 0;
break;
}
}
if (c == EOF)
fatal("unterminated comment");
if (!cplus_comment && c == '*')
{
c = getc(finput);
if (c == '/')
{
putc('/', fattrs);
if (fdefines)
putc('/', fdefines);
in_comment = 0;
}
}
else
c = getc(finput);
}
}
break;
case '{':
count++;
break;
case '}':
if (count == 0)
fatal ("unmatched close-brace (`}')");
count--;
if (count == 0)
{
fprintf(fattrs, " YYSTYPE;\n");
if (fdefines)
fprintf(fdefines, " YYSTYPE;\n");
/* JF don't choke on trailing semi */
c=skip_white_space();
if(c!=';') ungetc(c,finput);
return;
}
}
c = getc(finput);
}
}
/* parse the declaration %expect N which says to expect N
shift-reduce conflicts. */
void
parse_expect_decl()
{
register int c;
register int count;
char buffer[20];
c = getc(finput);
while (c == ' ' || c == '\t')
c = getc(finput);
count = 0;
while (c >= '0' && c <= '9')
{
if (count < 20)
buffer[count++] = c;
c = getc(finput);
}
buffer[count] = 0;
ungetc (c, finput);
expected_conflicts = atoi (buffer);
}
/* that's all of parsing the declaration section */
/* Get the data type (alternative in the union) of the value for symbol n in rule rule. */
char *
get_type_name(n, rule)
int n;
symbol_list *rule;
{
static char *msg = "invalid $ value";
register int i;
register symbol_list *rp;
if (n < 0)
fatal(msg);
rp = rule;
i = 0;
while (i < n)
{
rp = rp->next;
if (rp == NULL || rp->sym == NULL)
fatal(msg);
i++;
}
return (rp->sym->type_name);
}
/* after %guard is seen in the input file,
copy the actual guard into the guards file.
If the guard is followed by an action, copy that into the actions file.
stack_offset is the number of values in the current rule so far,
which says where to find $0 with respect to the top of the stack,
for the simple parser in which the stack is not popped until after the guard is run. */
void
copy_guard(rule, stack_offset)
symbol_list *rule;
int stack_offset;
{
register int c;
register int n;
register int count;
register int match;
register int ended;
register char *type_name;
int brace_flag = 0;
int cplus_comment;
/* offset is always 0 if parser has already popped the stack pointer */
if (semantic_parser) stack_offset = 0;
fprintf(fguard, "\ncase %d:\n", nrules);
if (!nolinesflag)
fprintf(fguard, "#line %d \"%s\"\n", lineno, infile);
putc('{', fguard);
count = 0;
c = getc(finput);
while (brace_flag ? (count > 0) : (c != ';'))
{
switch (c)
{
case '\n':
putc(c, fguard);
lineno++;
break;
case '{':
putc(c, fguard);
brace_flag = 1;
count++;
break;
case '}':
putc(c, fguard);
if (count > 0)
count--;
else
fatal("unmatched right brace ('}')");
break;
case '\'':
case '"':
match = c;
putc(c, fguard);
c = getc(finput);
while (c != match)
{
if (c == EOF || c == '\n')
fatal("unterminated string");
putc(c, fguard);
if (c == '\\')
{
c = getc(finput);
if (c == EOF)
fatal("unterminated string");
putc(c, fguard);
if (c == '\n')
lineno++;
}
c = getc(finput);
}
putc(c, fguard);
break;
case '/':
putc(c, fguard);
c = getc(finput);
if (c != '*' && c != '/')
continue;
cplus_comment = (c == '/');
putc(c, fguard);
c = getc(finput);
ended = 0;
while (!ended)
{
if (!cplus_comment && c == '*')
{
while (c == '*')
{
putc(c, fguard);
c = getc(finput);
}
if (c == '/')
{
putc(c, fguard);
ended = 1;
}
}
else if (c == '\n')
{
lineno++;
putc(c, fguard);
if (cplus_comment)
ended = 1;
else
c = getc(finput);
}
else if (c == EOF)
fatal("unterminated comment");
else
{
putc(c, fguard);
c = getc(finput);
}
}
break;
case '$':
c = getc(finput);
type_name = NULL;
if (c == '<')
{
register char *cp = token_buffer;
while ((c = getc(finput)) != '>' && c > 0)
*cp++ = c;
*cp = 0;
type_name = token_buffer;
c = getc(finput);
}
if (c == '$')
{
fprintf(fguard, "yyval");
if (!type_name) type_name = rule->sym->type_name;
if (type_name)
fprintf(fguard, ".%s", type_name);
if(!type_name && typed) /* JF */
fprintf(stderr,"%s:%d: warning: $$ of '%s' has no declared type.\n",infile,lineno,rule->sym->tag);
}
else if (isdigit(c) || c == '-')
{
ungetc (c, finput);
n = read_signed_integer(finput);
c = getc(finput);
if (!type_name && n > 0)
type_name = get_type_name(n, rule);
fprintf(fguard, "yyvsp[%d]", n - stack_offset);
if (type_name)
fprintf(fguard, ".%s", type_name);
if(!type_name && typed) /* JF */
fprintf(stderr,"%s:%d: warning: $%d of '%s' has no declared type.\n",infile,lineno,n,rule->sym->tag);
continue;
}
else
fatals("$%c is invalid",c); /* JF changed style */
break;
case '@':
c = getc(finput);
if (isdigit(c) || c == '-')
{
ungetc (c, finput);
n = read_signed_integer(finput);
c = getc(finput);
}
else
fatals("@%c is invalid",c); /* JF changed style */
fprintf(fguard, "yylsp[%d]", n - stack_offset);
yylsp_needed = 1;
continue;
case EOF:
fatal("unterminated %guard clause");
default:
putc(c, fguard);
}
if (c != '}' || count != 0)
c = getc(finput);
}
c = skip_white_space();
fprintf(fguard, ";\n break;}");
if (c == '{')
copy_action(rule, stack_offset);
else if (c == '=')
{
c = getc(finput);
if (c == '{')
copy_action(rule, stack_offset);
}
else
ungetc(c, finput);
}
/* Assuming that a { has just been seen, copy everything up to the matching }
into the actions file.
stack_offset is the number of values in the current rule so far,
which says where to find $0 with respect to the top of the stack. */
void
copy_action(rule, stack_offset)
symbol_list *rule;
int stack_offset;
{
register int c;
register int n;
register int count;
register int match;
register int ended;
register char *type_name;
int cplus_comment;
/* offset is always 0 if parser has already popped the stack pointer */
if (semantic_parser) stack_offset = 0;
fprintf(faction, "\ncase %d:\n", nrules);
if (!nolinesflag)
fprintf(faction, "#line %d \"%s\"\n", lineno, infile);
putc('{', faction);
count = 1;
c = getc(finput);
while (count > 0)
{
while (c != '}')
{
switch (c)
{
case '\n':
putc(c, faction);
lineno++;
break;
case '{':
putc(c, faction);
count++;
break;
case '\'':
case '"':
match = c;
putc(c, faction);
c = getc(finput);
while (c != match)
{
if (c == EOF || c == '\n')
fatal("unterminated string");
putc(c, faction);
if (c == '\\')
{
c = getc(finput);
if (c == EOF)
fatal("unterminated string");
putc(c, faction);
if (c == '\n')
lineno++;
}
c = getc(finput);
}
putc(c, faction);
break;
case '/':
putc(c, faction);
c = getc(finput);
if (c != '*' && c != '/')
continue;
cplus_comment = (c == '/');
putc(c, faction);
c = getc(finput);
ended = 0;
while (!ended)
{
if (!cplus_comment && c == '*')
{
while (c == '*')
{
putc(c, faction);
c = getc(finput);
}
if (c == '/')
{
putc(c, faction);
ended = 1;
}
}
else if (c == '\n')
{
lineno++;
putc(c, faction);
if (cplus_comment)
ended = 1;
else
c = getc(finput);
}
else if (c == EOF)
fatal("unterminated comment");
else
{
putc(c, faction);
c = getc(finput);
}
}
break;
case '$':
c = getc(finput);
type_name = NULL;
if (c == '<')
{
register char *cp = token_buffer;
while ((c = getc(finput)) != '>' && c > 0)
*cp++ = c;
*cp = 0;
type_name = token_buffer;
value_components_used = 1;
c = getc(finput);
}
if (c == '$')
{
fprintf(faction, "yyval");
if (!type_name) type_name = get_type_name(0, rule);
if (type_name)
fprintf(faction, ".%s", type_name);
if(!type_name && typed) /* JF */
fprintf(stderr,"%s:%d: warning: $$ of '%s' has no declared type.\n",infile,lineno,rule->sym->tag);
}
else if (isdigit(c) || c == '-')
{
ungetc (c, finput);
n = read_signed_integer(finput);
c = getc(finput);
if (!type_name && n > 0)
type_name = get_type_name(n, rule);
fprintf(faction, "yyvsp[%d]", n - stack_offset);
if (type_name)
fprintf(faction, ".%s", type_name);
if(!type_name && typed) /* JF */
fprintf(stderr,"%s:%d: warning: $%d of '%s' has no declared type.\n",infile,lineno,n,rule->sym->tag);
continue;
}
else
fatals("$%c is invalid",c); /* JF changed format */
break;
case '@':
c = getc(finput);
if (isdigit(c) || c == '-')
{
ungetc (c, finput);
n = read_signed_integer(finput);
c = getc(finput);
}
else
fatal("invalid @-construct");
fprintf(faction, "yylsp[%d]", n - stack_offset);
yylsp_needed = 1;
continue;
case EOF:
fatal("unmatched '{'");
default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -