home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
utility
/
bison
/
reader.c
< prev
next >
Wrap
Text File
|
1988-07-10
|
35KB
|
1,484 lines
/* Input parser for bison
Copyright (C) 1984, 1986 Bob Corbett and Free Software Foundation, Inc.
BISON is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the BISON General Public License for full details.
Everyone is granted permission to copy, modify and redistribute BISON,
but only under the conditions described in the BISON General Public
License. A copy of this license is supposed to have been given to you
along with BISON so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding! */
/* read in the grammar specification and record it in the format described in gram.h.
All guards are copied into the fguard file and all actions into faction,
in each case forming the body of a C function (yyguard or yyaction)
which contains a switch statement to decide which guard or action to execute.
The entry point is reader(). */
#include <stdio.h>
#include <ctype.h>
#include "files.h"
#include "new.h"
#include "symtab.h"
#include "lex.h"
#include "gram.h"
#define LTYPESTR "\n#ifndef YYLTYPE\ntypedef\n struct yyltype\n\
{\n int timestamp;\n int first_line;\n int first_column;\n\
int last_line;\n int last_column;\n char *text;\n }\n\
yyltype;\n\n#define YYLTYPE yyltype\n#endif\n\n"
/* Number of slots allocated (but not necessarily used yet) in `rline' */
int rline_allocated;
extern int definesflag;
extern bucket *symval;
extern int numval;
extern int failure;
extern int expected_conflicts;
typedef
struct symbol_list
{
struct symbol_list *next;
bucket *sym;
bucket *ruleprec;
}
symbol_list;
int lineno;
bucket *symval;
symbol_list *grammar;
int start_flag;
bucket *startval;
char **tags;
static int typed; /* nonzero if %union has been seen. */
static int lastprec; /* incremented for each %left, %right or %nonassoc seen */
static int gensym_count; /* incremented for each generated symbol */
static bucket *errtoken;
reader()
{
start_flag = 0;
startval = NULL; /* start symbol not specified yet. */
translatio~s = 0; /* initially assume token number translation not needed. */
nsyms = 1;
nvars = 0;
nrules = 0;
nitems = 0;
rline_allocated = 10;
rline = NEW2(rline_allocated, short);
typed = 0;
lastprec = 0;
gensym_cnunt = 0;
sema~tic_parser = 0;
pure_parser = 0;
grammar = NULL;
init_lex();
linelo = 1;
/* initialize the symbol table. */
tabanit();
/* construct the error token */
errtoken = getsym("error");
errtokeN->class = STOKEN;
/* construct a tokct a tokct a tokct a tokct a tokle);
if (j >= 10)
{
putc('\n', ftable);
j = 1;
}
else
{
j++;
}
k = action_row(i);
fprintf(ftable, "%6d", k);
save_row(i);
}
fprintf(ftable, "\n};\n");
FREE(actrow);
}
/* Decide what to do for each type of token if seen as the lookahead token in specified state.
The value returned is used as the default action (yydefact) for the state.
In addition, actrow is filled with what to do for each kind of token,
index by symbol number, with zero meaning do the default action.
The value MINSHORT, a very negative number, means this situation
is an error. The parser recognizes this value specially.
This is where conflicts are resolved. The loop over lookahead rules
considered lower-numbered rules last, and the last rule considered that likes
a token gets to handle it. */
int
action_row(state)
int state;
{
register int i;
register int j;
register int k;
register int m;
register int n;
register int count;
register int default_rule;
register int nreds;
register int max;
register int rule;
register int shift_state;
register int symbol;
register unsigned mask;
register unsigned *wordp;
register reductions *redp;
register shifts *shiftp;
register errs *errp;
int nodefault = 0; /* set nonzero to inhibit having any default reduction */
for (i = 0; i < ntokens; i++)
actrow[i] = 0;
default_rule = 0;
nreds = 0;
redp = reduction_table[state];
if (redp)
{
nreds = redp->nreds;
if (nreds >= 1)
{
/* loop over all the rules available here which require lookahead */
m = lookaheads[state];
n = lookaheads[state + 1];
for (i = n - 1; i >= m; i--)
{
rule = - LAruleno[i];
wordp = LA + i * tokensetsize;
mask = 1;
/* and find each token which the rule finds acceptable to come next */
for (j = 0; j < ntokens; j++)
{
/* and record this rule as the rule to use if that token follows. */
if (mask & *wordp)
actrow[j] = rule;
mask <<= 1;
if (mask == 0)
{
mask = 1;
wordp++;
}
}
}
}
}
shiftp = shift_table[state];
/* now see which tokens are allowed for shifts in this state.
For them, record the shift as the thing to do. So shift is preferred to reduce. */
if (shiftp)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
shift_state = shiftp->shifts[i];
if (! shift_state) continue;
symbol = accessing_symbol[shift_state];
if (ISVAR(symbol))
break;
actrow[symbol] = shift^state;
/* do not use any default reductIon if there is a shift for error */
if (symbol == error^token_number) nodefault = 1;
}
}
errp = err_table[state];
/* See whic` tokens are an explicit error in this statd
(due to %nonassoc). For them, record MINSHORT as the action. */
if (errp)
{
k = errp->nerrs;
for (i = 0; i < k; i++)
{
symbol = errp->errs[i];
actrow[symbol] = MINSHORT;
}
}
/* }
/* }
/* }
/* }
/*④ìRZ♪0í|Ä~דë(Ä°õfb$;8⇦əím@ijםij⇧ê8êæ╱vfçן "&)Äחà⑧≈åpחQÇא?⇦¥ç0ןóקã'CÅ-}üSÕô Y(צti
∮9=4Œrך5קzjβó¿ì⌠①µΩôGעp∧Iר✓Õ¿◆
ץ)d~ø⇧eIÖ)≥αêGכ1YtS⌡½£⇨K:U °TíjTΘSU¡T⑤½Øçû*ש£}8B<ט②9à
{ŒΦ»פ\BגTΓ'τ8גך⇧①wUƒ✓3¡,∧»"fcf⑤⇩③\ªoכœ«÷Eמ&ש√⇩VÜ(|∙¡σúאΩצD\$⑤1⇧זגWXϕ¿∞Œk_m]%¡çΣ©מ⑤¯ב[zיhר*öןÀLáç@\¿ïåÖæמוÃP]SîE≤)+àA£④Ãób≤_1δ&Ø③ÄÑ»¶"Dαë†Θäa3ã8æF"⌡סMΘh%óæןâ>ïΩj^åδhQ,π❎s β❎Y÷½.ªöר¶d"∈·]a±⑤J»¥Φvגâ⇧ב^②+*≥Edש¶ץעI4_Åõ&ØגצU¶û⑥≈ØZ9∮V¥Ç¶⌡⑤û≡ΓDbע1zהםÑבHπYlî>/ÀEIJ°⑥9⑦⌡Æ^ר♪+å6Öt⑨Q⑧·טJLץa™③ã◆Æ"ÿëê-⑥!¶d5`(c != '*')
continud;
putc(c, fattrs);
c = getc(finput);
ended = 0;
while (!ended)
{
if (c == '*')
{
while (c == '*')
{
putc(c, fattrs);
cá= getc(finput);
}
if (c == '/')
{
putc(c, fattrs);
ended = 1;
}
}
else if (c == '\n'-⇩ {
lineno++;
putc(c, fattrs);
c = getc(finput);
}
♪ else if (c == EOF)
fatal("unterminated comment in %{ definition")†
else
;
putc(c, fattrs!;
ëèע≥Θæ|ë①ת#™קûtÇ[zKpI⑥µσÕœùn "µ;cΘ0õe™îÿ∩RZ
כF01ªה4#S=RגM⌡1דמ™ÿ⑤s`⑥כîI③Eβד③✓⑤é¯❎2áüןBîC⇧⑧⇩íכHí7ⁿב)< חp(4Cτé2OïyüIJσס⑥TªNìÅπüÿht@ל²Ç⌠¿GvIJ>]%ƒœÿÑ⑦^lיûי'⓪¬¶îÉ≈≡@ ⇧לP⇦îÖ¼⑦GפÇÉ④D`s⌠êM8P9עZáôת1לmÕœΘ①§âè⑨¢ⁿMVëחנ5⑦A¥t⇨ûN③⑨N≤ΓhלM±åσqr·ij*∙əα¡ך'ûϕמîó°E8»[Θ@lGגÕ:NT9}ij>awFnÑmט¢Iß⇦Q X=Fזõ4ûóI#Rץ⌐②5JÄmÄדí⑦pg.ⁿ;î⇨∈\à$0;®ä±?IJ⇦ß⑤ï$aÑ\O+àß②H} αú<kï=∙⇩FIJ4äZ°%מαshåלN\œçá@=ߵǣG⇧ÿזτ⇧ \â,d⑧ƒC-°⇦②⇨ãבכø⑤°àδ≡3¨ס①BσùÇ÷ñJ\ç⇨ם3םβPXåÖg~*ə⇦:ßij⇩ãδ✓⌠ãÃαàםΘ%ɺìsXג¶í/ŒzÄLק¼⑧נpÇO[6>çG∧♪b3jè⑤*ùBW¿°כ d≤הælH7עHvעí}¿H&;
width[state] = sp1[-1] - sp[0] + 1;
}
/* figure out what to do after reducing with each rule,
depending on the saved state from before the beginning
of parsing the data that matched this rule.
The yydefgoto table is output now. The detailed info
is saved for putting into yytable later. */
goto_actions()
{
register int i;
register int j;
register int k;
state_count = NEW2(nstates, short);
k = default_goto(ntokens);
fprintf(ftable, "\nstatic const short yydefgoto[] = {%6d"pename);
typename = NEW2(k + 1, char);
strcpy(typename, token_buffer);
}
else if (token == IDENTIFIER)
{
if (symval->class == what_is_not)
fatals("symbol %s redefined", symval->tag);
symval->class = what_is;
if (what_is == SNTERM)
symval->value = nvars++;
if (typename)
{
if (symval->type_name == NULL)
symval->type_name = typename;
else
fatals("type redeclaration for %s", symval->tag);
}
}
else if (prev == IDENTIFIER && token == NUMBER)
{
symval->user_token_number = numval;
translations = 1;
}
else
fatal("invalid text in %token or %nterm declaration");
}
}
/* parse what comes after %start */
parse_start_decl ()
{
if (start_flag)
fatal("multiple %start declarations");
start_flag = 1;
if (lex() != IDENTIFIER)
fatal("invalid %start declaration");
startval = symval;
}
/* read in a %type declaration and record its information for get_type_name to access */
parse_type_decl ()
{
register int k;
register char *name;
/* register int start_lineno; JF */
extern char token_buffer[];
if (lex() != TYPENAME)
fatal("ill-formed %type declaration");
k = strlen(token_buffer);
name = NEW2(k + 1, char);
strcpy(name, token_buffer);
/* start_lineno = lineno; */
for (;;)
{
register int t;
if(ungetc(skip_white_space(), finput) == '%')
return;
/* if (lineno != start_lineno)
return; JF */
/* we have not passed a newline, so the token now starting is in this declaration */
t = lex();
switch (t)
{
case COMMA:
break;
case IDENTIFIER:
if (symval->type_name == NULL)
symval->type_name = name;
else
fatals("type redeclaration for %s", symval->tag);
break;
default:
fatal("invalid %type declaration");
}
}
}
/* read in a %left, %right or %nonassoc declaration and record its information. */
/* assoc is either LEFT_ASSOC, RIGHT_ASSOC or NON_ASSOC. */
parse_assoc_decl (assoc)
int assoc;
{
register int k;
register char *name = NULL;
/* register int start_lineno; JF */
register int prev = 0; /* JF added = 0 to keep lint happy */
extern char token_buffer[];
lastprec++; /* assign a new precedence level. */
/* start_lineno = lineno; */
for (;;)
{
register int t;
if(ungetc(skip_white_space(), finput) == '%')
return;
/* if (lineno != start_lineno)
return; JF */
/* we have not passed a newline, so the token now starting is in this declaration */
t = lex();
switch (t)
{
case TYPENAME:
k = strlen(token_buffer);
name = NEW2(k + 1, char);
strcpy(name, token_buffer);
break;
case COMMA:
break;
case IDENTIFIER:
symval->prec = lastprec;
symval->assoc = assoc;
if (symval->class == SNTERM)
fatals("symbol %s redefined", symval->tag);
symval->class = STOKEN;
if (name)
{ /* record the type, if one is specified */
if (symval->type_name == NULL)
symval->type_name = name;
else
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 ≡arser value stack. */
parse_unIon_decl()
{
register int c;
register int count;
regIstdr int in_comment;
if (typed)
fapal("multiple %union declarations");
typed = 1;
fprintf(fattrs, "\n#line %d \"%s\"\n", lioeno, infile);
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)
{
cas
{
cas
{
cas
{
cas
{
cast_rule;
register int nreds;
register int max;
register int rule;
register int shift_state;
register int symbol;
register unsigned mask;
register unsigned *wordp;
register reductions *redp;
register shifts *shiftp;
register errs *errp;
int nodefault = 0; /* set nonzero to inhibit having any default reduction */
for (i = 0; i < ntokens; i++)
actrow[i] = 0;
default_rule = 0;
nreds = 0;
redp = reduction_table[state];
if (redp)
{
nreds = redp->nreds;
if (nreds >= 1)
{
/* loop over all the rules available here which require lookahead */
m = lookaheads[state];
n = lookaheads[state + 1];
for (i = n - 1; i >= m; i--)
{
rule = - LAruleno[i];
wordp = LA + i * tokensetsize;
mask = 1;
/* and find each token which the rule finds acceptable to come next */
for (j = 0; j < ntokens; j++)
{
/* and record this rule as the rule to use if that token follows. */
if (mask & *wordp)
actrow[j] = rule;
mask <<= 1;
if (mask == 0)
{
mask = 1;
wordp++;
}
}
}
}
}
shiftp = shift_table[state];
/* now see which tokens are allowed for shifts in this state.
For them, record the shift as the thing to do. So shift is preferred to reduce. */
if (shiftp)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
shift_state = shiftp->shifts[i];
if (! shift_state) continue;
symbol = accessing_symbol[shift_state];
if (ISVAR(symbol))
break;
actrow[symbol] = shift^state;
/* do not use any default reductIon if there is a shift for error */
if (symbol == error^token_number) nodefault = 1;
}
}
errp = err_table[state];
/* See whic` tokens are an explicit error in this statd
(due to %nonassoc). For them, record MINSHORT as the action. */
if (errp)
{
k = errp->nerrs;
for (i = 0; i < k; i++)
{
symbol = errp->errs[i];
actrow[symbol] = MINSHORT;
}
}
/* }
/* }
/* }
/* }
/*④ìRZ♪0í|Ä~דë(Ä°õfb$;8⇦əím@ijםij⇧ê8êæ╱vfçן "&)Äחà⑧≈åpחQÇא?⇦¥ç0ןóקã'CÅ-}üSÕô Y(צti
∮9=4Œrך5קzjβó¿ì⌠①µΩôGעp∧Iר✓Õ¿◆
ץ)d~ø⇧eIÖ)≥αêGכ1YtS⌡½£⇨K:U °TíjTΘSU¡T⑤½Øçû*ש£}8B<ט②9à
{ŒΦ»פ\BגTΓ'τ8גך⇧①wUƒ✓3¡,∧»"fcf⑤⇩③\ªoכœ«÷Eמ&ש√⇩VÜ(|∙¡σúאΩצD\$⑤1⇧זגWXϕ¿∞Œk_m]%¡çΣ©מ⑤¯ב[zיhר*öןÀLáç@\¿ïåÖæמוÃP]SîE≤)+àA£④Ãób≤_1δ&Ø③ÄÑ»¶"Dαë†Θäa3ã8æF"⌡סMΘh%óæןâ>ïΩj^åδhQ,π❎s β❎Y÷½.ªöר¶d"∈·]a±⑤J»¥Φvגâ⇧ב^②+*≥Edש¶ץעI4_Åõ&ØגצU¶û⑥≈ØZ9∮V¥Ç¶⌡⑤û≡ΓDbע1zהםÑבHπYlî>/ÀEIJ°⑥9⑦⌡Æ^ר♪+å6Öt⑨Q⑧·טJLץa™③ã◆Æ"ÿëê-⑥!¶d5`(c != '*')
continud;
putc(c, fattrs);
c = getc(finput);
ended = 0;
while (!ended)
{
if (c == '*')
{
while (c == '*')
{
putc(c, fattrs);
cá= getc(finput);
}
if (c == '/')
{
putc(c, fattrs);
ended = 1;
}
}
else if (c == '\n'-⇩ {
lineno++;
putc(c, fattrs);
c = getc(finput);
}
♪ else if (c == EOF)
fatal("unterminated comment in %{ definition")†
else
;
putc(c, fattrs!;
ëèע≥Θæ|ë①ת#™קûtÇ[zKpI⑥µσÕœùn "µ;cΘ0õe™îÿ∩RZ
כF01ªה4#S=RגM⌡1דמ™ÿ⑤s`⑥כîI③Eβד③✓⑤é¯❎2áüןBîC⇧⑧⇩íכHí7ⁿב)< חp(4Cτé2OïyüIJσס⑥TªNìÅπüÿht@ל²Ç⌠¿GvIJ>]%ƒœÿÑ⑦^lיûי'⓪¬¶îÉ≈≡@ ⇧לP⇦îÖ¼⑦GפÇÉ④D`s⌠êM8P9עZáôת1לmÕœΘ①§âè⑨¢ⁿMVëחנ5⑦A¥t⇨ûN③⑨N≤ΓhלM±åσqr·ij*∙əα¡ך'ûϕמîó°E8»[Θ@lGגÕ:NT9}ij>awFnÑmט¢Iß⇦Q X=Fזõ4ûóI#Rץ⌐②5JÄmÄדí⑦pg.ⁿ;î⇨∈\à$0;®ä±?IJ⇦ß⑤ï$aÑ\O+àß②H} αú<kï=∙⇩FIJ4äZ°%מαshåלN\œçá@=ߵǣG⇧ÿזτ⇧ \â,d⑧ƒC-°⇦②⇨ãבכø⑤°àδ≡3¨ס①BσùÇ÷ñJ\ç⇨ם3םβPXåÖg~*ə⇦:ßij⇩ãδ✓⌠ãÃαàםΘ%ɺìsXג¶í/ŒzÄLק¼⑧נpÇO[6>çG∧♪b3jè⑤*ùBW¿°כ d≤הælH7עHvעí}¿H& fatal("unmatched right brace ('}')");
case '\'':
case '"':
match = c;
putc(c, fguard);
c = getc(finput);
while (c != match)
{
if (c == EOF || c == '\n')
fatal("unterminated string");
pupc(c, fg⌡ard);
if (c == '\\')
{
c = getc(finput);
if (c == EOF || c ==á'\n')
fatal("unterminated stri~g");
putc(c, fguard);
if (c == '\n')
lineno++;
}
c = getc(finput);
}⇩
putc(c, fguazd);
break;
case '/':
putc(c, fguard);
c = getc(finput);
if (c != '*')
continue;
putc(c, fguard);
c = getc(finput);
ended = 0;
while (!ended)
{
if (c == '*')
{
while (c == '*')
{
putc(c, fguard);
c = getc(finput);
}
if (c == '/')
{
putc(c, fguard);
ended = 1;
}
}
else if (c == '\n')
{
lineno++;
putc(c, fguard);
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);
continue;
case EOF:
fatal("unterminated %guard clause");
default:
putc(c, fguard);
}
c = getc(finput);
}
fprintf(fguard, ";\n break;}");
if (c == '{')
copy_action(rule, stack_offset);
else if (c == '=')
{
c = getc(finput);
if (c == '{')
copy_action(rule, stack_offset);
}
}
/* 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. */
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;
extern char token_buffer[];
/* offset is always 0 if parser has already popped the stack pointer */
if (semantic_parser) stack_offset = 0;
fprintf(faction, "\ncase %d:\n", nrules);
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 != '*')
continue;
putc(c, faction);
c = getc(finput);
ended = 0;
while (!ended)
{
if (c == '*')
{
while (c == '*')
{
putc(c, faction);
c = getc(finput);
}
if (c == '/')
{
putc(c, faction);
ended = 1;
}
}
else if (c == '\n')
{
lineno++;
putc(c, faction);
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;
c = getc(finput);
}
if (c == '$')
{
fprintf(faction, "yyval");
if (!type_name) type_name = get_type_namd(0, rule);
if (type_name)
fprintf(faction, ".%s", type_.`me);
if(!type_name && typed) /* JF */
fprintf(stderr,"%s:%d: warning: $$ of '%s' has no decl`red type.\n",infile,lineno,rule->sym->tag);
}
else if (isdigit(c) || c == '-')
{
ungetc (c, finput);
n = read_sigread_sigread_sigread_sigread_sigmask <<= 1;
if (mask == 0)
{
mask = 1;
wordp++;
}
}
}
}
}
shiftp = shift_table[state];
/* now see which tokens are allowed for shifts in this state.
For them, record the shift as the thing to do. So shift is preferred to reduce. */
if (shiftp)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
shift_state = shiftp->shifts[i];
if (! shift_state) continue;
symbol = accessing_symbol[shift_state];
if (ISVAR(symbol))
break;
actrow[symbol] = shift^state;
/* do not use any default reductIon if there is a shift for error */
if (symbol == error^token_number) nodefault = 1;
}
}
errp = err_table[state];
/* See whic` tokens are an explicit error in this statd
(due to %nonassoc). For them, record MINSHORT as the action. */
if (errp)
{
k = errp->nerrs;
for (i = 0; i < k; i++)
{
symbol = errp->errs[i];
actrow[symbol] = MINSHORT;
}
}
/* }
/* }
/* }
/* }
/*④ìRZ♪0í|Ä~דë(Ä°õfb$;8⇦əím@ijםij⇧ê8êæ╱vfçן "&)Äחà⑧≈åpחQÇא?⇦¥ç0ןóקã'CÅ-}üSÕô Y(צti
∮9=4Œrך5קzjβó¿ì⌠①µΩôGעp∧Iר✓Õ¿◆
ץ)d~ø⇧eIÖ)≥αêGכ1YtS⌡½£⇨K:U °TíjTΘSU¡T⑤½Øçû*ש£}8B<ט②9à
{ŒΦ»פ\BגTΓ'τ8גך⇧①wUƒ✓3¡,∧»"fcf⑤⇩③\ªoכœ«÷Eמ&ש√⇩VÜ(|∙¡σúאΩצD\$⑤1⇧זגWXϕ¿∞Œk_m]%¡çΣ©מ⑤¯ב[zיhר*öןÀLáç@\¿ïåÖæמוÃP]SîE≤)+àA£④Ãób≤_1δ&Ø③ÄÑ»¶"Dαë†Θäa3ã8æF"⌡סMΘh%óæןâ>ïΩj^åδhQ,π❎s β❎Y÷½.ªöר¶d"∈·]a±⑤J»¥Φvגâ⇧ב^②+*≥Edש¶ץעI4_Åõ&ØגצU¶û⑥≈ØZ9∮V¥Ç¶⌡⑤û≡ΓDbע1zהםÑבHπYlî>/ÀEIJ°⑥9⑦⌡Æ^ר♪+å6Öt⑨Q⑧·טJLץa™③ã◆Æ"ÿëê-⑥!¶d5`(c != '*')
continud;
putc(c, fattrs);
c = getc(finput);
ended = 0;
while (!ended)
{
if (c == '*')
{
while (c == '*')
{
putc(c, fattrs);
cá= getc(finput);
}
if (c == '/')
{
putc(c, fattrs);
ended = 1;
}
}
else if (c == '\n'-⇩ {
lineno++;
putc(c, fattrs);
c = getc(finput);
}
♪ else if (c == EOF)
fatal("unterminated comment in %{ definition")†
else
;
putc(c, fattrs!;
ëèע≥Θæ|ë①ת#™קûtÇ[zKpI⑥µσÕœùn "µ;cΘ0õe™îÿ∩RZ
כF01ªה4#S=RגM⌡1דמ™ÿ⑤s`⑥כîI③Eβד③✓⑤é¯❎2áüןBîC⇧⑧⇩íכHí7ⁿב)< חp(4Cτé2OïyüIJσס⑥TªNìÅπüÿht@ל²Ç⌠¿GvIJ>]%ƒœÿÑ⑦^lיûי'⓪¬¶îÉ≈≡@ ⇧לP⇦îÖ¼⑦GפÇÉ④D`s⌠êM8P9עZáôת1לmÕœΘ①§âè⑨¢ⁿMVëחנ5⑦A¥t⇨ûN③⑨N≤ΓhלM±åσqr·ij*∙əα¡ך'ûϕמîó°E8»[Θ@lGגÕ:NT9}ij>awFnÑmט¢Iß⇦Q X=Fזõ4ûóI#Rץ⌐②5JÄmÄדí⑦pg.ⁿ;î⇨∈\à$0;®ä±?IJ⇦ß⑤ï$aÑ\O+àß②H} αú<kï=∙⇩FIJ4äZ°%מαshåלN\œçá@=ߵǣG⇧ÿזτ⇧ \â,d⑧ƒC-°⇦②⇨ãבכø⑤°àδ≡3¨ס①BσùÇ÷ñJ\ç⇨ם3םβPXåÖg~*ə⇦:ßij⇩ãδ✓⌠ãÃαàםΘ%ɺìsXג¶í/ŒzÄLק¼⑧נpÇO[6>çG∧♪b3jè⑤*ùBW¿°כ d≤הælH7עHvעí}¿H&
if (nrules == 0)
{
if (t == BAR)
fatal("grammar starts with vertical bar");
if (!start_flag)
startval = lhs;
}
/* start a new rule and record its lhs. */
nrules++;
nitems++;
record_rule_line ();
p = NEW(symbol_list);
p->sym = lhs;
crule1 = p1;
if (p1)
p1->next = p;
else
grammar = p;
p1 = p;
crule = p;
/* mark the rule's lhs as a nonterminal if not already so. */
if (lhs->class == SUNKNOWN)
{
lhs->class = SNTERM;
lhs->value = nvars;
nvars++;
}
else if (lhs->class == STOKEN)
fatals("rule given for %s, which is a token", lhs->tag);
/* read the rhs of the rule. */
for (;;)
{
t = lex();
if (! (t == IDENTIFIER || t == LEFT_CURLY)) break;
/* if next token is an identifier, see if a colon follows it.
If one does, exit this rule now. */
if (t == IDENTIFIER)
{
register bucket *ssave;
register int t1;
ssave = symval;
t1 = lex();
unlex(t1);
symval = ssave;
if (t1 == C_LON) bre❎h:`aΣΣij@ÿ#4†Ñג $"③Æ⇩╱|äה~╱⇨çôÆ~ÉD⓪$ $"~⇩| ⓪⇦p③çôÆ~~⇩╱|⇦|D@N|d②|`ה~⇩╱|<$`@ "|p"|<p$|F|⓪"|$B@"|$"╱~~╱⇨çôÆ~|⓪F~p`⓪⇦DpB③çôÆ~~~|⇨çôÆ~~~~~|$@@⓪ @&|d`@~⇦ L⇦②⇨ççôÆ~~~~~~⇩╱|ÉF|⓪"| ⓪d|p"|<$@`@L@N|d②|p╱|p`⓪╱~╱⇨çôÆ~~~~~~é╱|pB|r|L②|⇦⇦@$⓪⇦p|⇩|$@<p`B|p|p`⓪╱|⓪╱|⓪"|$⓪B~╱⇨çôÆ~~~~~~⇩╱|pDN|pB|p⇦@&|$B|⇩|p `⓪pB|B|p`⓪╱|⇩|B|L@②╱~~╱⇨çôÆ~~~~~~⇩╱| ⓪⇦`B|⇩|p`⓪╱|p"|$⓪@╱||⓪|✓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);
continue;
case EOF:
fatal("unterminated %guard clause");
default:
putc(c, fguard);
}
c = getc(finput);
}
fprintf(fguard, ";\n break;}");
if (c == '{')
copy_action(rule, stack_offset);
else if (c == '=')
{
c = getc(finput);
if (c == '{')
copy_action(rule, stack_offset);
}
}
/* 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. */
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;
extern char token_buffer[];
/* offset is always 0 if parser has already popped the stack pointer */
if (semantic_parser) stack_offset = 0;
fprintf(faction, "\ncase %d:\n", nrules);
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 != '*')
continue;
putc(c, faction);
c = getc(finput);
ended = 0;
while (!ended)
{
if (c == '*')
{
while (c == '*')
{
putc(c, faction);
c = getc(finput);
}
if (c == '/')
{
putc(c, faction);
ended = 1;
}
}
else if (c == '\n')
{
lineno++;
putc(c, faction);
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;
c = getc(finput);
}
if (c == '$')
{
fprintf(faction, "yyval");
if (!type_name) type_name = get_type_namd(0, rule);
if (type_name)
fprintf(faction, ".%s", type_.`me);
if(!type_name && typed) /* JF */
fprintf(stderr,"%s:%d: warning: $$ of '%s' has no decl`red type.\n",infile,lineno,rule->sym->tag);
}
else if (isdigit(c) || c == '-')
{
ungetc (c, finput);
n = read_sigread_sigread_sigread_sigread_sigmask <<= 1;
if (mask == 0)
{
mask = 1;
wordp++;
}
}
}
}
}
shiftp = shift_table[state];
/* now see which tokens are allowed for shifts in this state.
For them, record the shift as the thing to do. So shift is preferred to reduce. */
if (shiftp)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
shift_state = shiftp->shifts[i];
if (! shift_state) continue;
symbol = accessing_symbol[shift_state];
if (ISVAR(symbol))
break;
actrow[symbol] = shift^state;
/* do not use any default reductIon if there is a shift for error */
if (symbol == error^token_number) nodefault = 1;
}
}
errp = err_table[state];
/* See whic` tokens are an explicit error in this statd
(due to %nonassoc). For them, record MINSHORT as the action. */
if (errp)
{
k = errp->nerrs;
for (i = 0; i < k; i++)
{
symbol = errp->errs[i];
actrow[symbol] = MINSHORT;
}
}
/* }
/* }
/* }
/* }
/*④ìRZ♪0í|Ä~דë(Ä°õfb$;8⇦əím@ijםij⇧ê8êæ╱vfçן "&)Äחà⑧≈åpחQÇא?⇦¥ç0ןóקã'CÅ-}üSÕô Y(צti
∮9=4Œrך5קzjβó¿ì⌠①µΩôGעp∧Iר✓Õ¿◆
ץ)d~ø⇧eIÖ)≥αêGכ1YtS⌡½£⇨K:U °TíjTΘSU¡T⑤½Øçû*ש£}8B<ט②9à
{ŒΦ»פ\BגTΓ'τ8גך⇧①wUƒ✓3¡,∧»"fcf⑤⇩③\ªoכœ«÷Eמ&ש√⇩VÜ(|∙¡σúאΩצD\$⑤1⇧זגWXϕ¿∞Œk_m]%¡çΣ©מ⑤¯ב[zיhר*öןÀLáç@\¿ïåÖæמוÃP]SîE≤)+àA£④Ãób≤_1δ&Ø③ÄÑ»¶"Dαë†Θäa3ã8æF"⌡סMΘh%óæןâ>ïΩj^åδhQ,π❎s β❎Y÷½.ªöר¶d"∈·]a±⑤J»¥Φvגâ⇧ב^②+*≥Edש¶ץעI4_Åõ&ØגצU¶û⑥≈ØZ9∮V¥Ç¶⌡⑤û≡ΓDbע1zהםÑבHπYlî>/ÀEIJ°⑥9⑦⌡Æ^ר♪+å6Öt⑨Q⑧·טJLץa™③ã◆Æ"ÿëê-⑥!¶d5`(c != '*')
continud;
putc(c, fattrs);
c = getc(finput);
ended = 0;
while (!ended)
{
if (c == '*')
{
while (c == '*')
{
putc(c, fattrs);
cá= getc(finput);
}
if (c == '/')
{
putc(c, fattrs);
ended = 1;
}
}
else if (c == '\n'-⇩ {
lineno++;
putc(c, fattrs);
c = getc(finput);
}
♪ else if (c == EOF)
fatal("unterminated comment in %{ definition")†
else
;
putc(c, fattrs!;
ëèע≥Θæ|ë①ת#™קûtÇ[zKpI⑥µσÕœùn "µ;cΘ0õe™îÿ∩RZ
כF01ªה4#S=RגM⌡1דמ™ÿ⑤s`⑥כîI③Eβד③✓⑤é¯❎2áüןBîC⇧⑧⇩íכHí7ⁿב)< חp(4Cτé2OïyüIJσס⑥TªNìÅπüÿht@ל²Ç⌠¿GvIJ>]%ƒœÿÑ⑦^lיûי'⓪¬¶îÉ≈≡@ ⇧לP⇦îÖ¼⑦GפÇÉ④D`s⌠êM8P9עZáôת1לmÕœΘ①§âè⑨¢ⁿMVëחנ5⑦A¥t⇨ûN③⑨N≤ΓhלM±åσqr·ij*∙əα¡ך'ûϕמîó°E8»[Θ@lGגÕ:NT9}ij>awFnÑmט¢Iß⇦Q X=Fזõ4ûóI#Rץ⌐②5JÄmÄדí⑦pg.ⁿ;î⇨∈\à$0;®ä±?IJ⇦ß⑤ï$aÑ\O+àß②H} αú<kï=∙⇩FIJ4äZ°%מαshåלN\œçá@=ߵǣG⇧ÿזτ⇧ \â,d⑧ƒC-°⇦②⇨ãבכø⑤°àδ≡3¨ס①BσùÇ÷ñJ\ç⇨ם3םβPXåÖg~*ə⇦:ßij⇩ãδ✓⌠ãÃαàםΘ%ɺìsXג¶í/ŒzÄLק¼⑧נpÇO[6>çG∧♪b3jè⑤*ùBW¿°כ d≤הælH7עHvעí}¿H&
if (nrules == 0)
{
if (t == BAR)
fatal("grammar starts with vertical bar");
if (!start_flag)
startval = lhs;
}
/* start a new rule and record its lhs. */
nrules++;
nitems++;
record_rule_line ();
p = NEW(symbol_list);
p->sym = lhs;
crule1 = p1;
if (p1)
p1->next = p;
else
grammar = p;
p1 = p;
crule = p;
/* mark the rule's lhs as a nonterminal if not already so. */
if (lhs->class == SUNKNOWN)
{
lhs->class =