/*-----------------------------------------------------------------.
| FIN is pointing to a location (i.e., a `@'). Output to OOUT a |
| reference to this location. STACK_OFFSET is the number of values |
-| in the current rule so far, which says where to find `$0' with |
+| in the current rule so far, which says where to find `@0' with |
| respect to the top of the stack. |
`-----------------------------------------------------------------*/
static inline void
-copy_at (FILE *fin, struct obstack *oout, int stack_offset)
+copy_at (FILE *fin, struct obstack *oout,
+ struct symbol_list *rule, int stack_offset)
{
+ symbol_list *rp;
int c;
c = getc (fin);
}
else if (isdigit (c) || c == '-')
{
- int n;
+ int n, i;
ungetc (c, fin);
n = read_signed_integer (fin);
+ rp = rule;
+ i = 0;
+
+ while (i < n)
+ {
+ rp = rp->next;
+ if (rp == NULL)
+ {
+ complain (_("invalid @ value"));
+ return;
+ }
+ i++;
+ }
+
obstack_fgrow1 (oout, "yylsp[%d]", n - stack_offset);
locations_flag = 1;
}
case tok_stropt:
case tok_intopt:
case tok_obsolete:
- case tok_illegal:
abort ();
break;
+ case tok_illegal:
default:
complain (_("unrecognized: %s"), token_buffer);
skip_to_char ('%');
case '@':
copy_at (finput, &action_obstack,
- stack_offset);
+ rule, stack_offset);
break;
case EOF:
}
}
- obstack_sgrow (&action_obstack, ";\n break;}");
+ /* As a Bison extension, add the ending semicolon. Since some Yacc
+ don't do that, help people using bison as a Yacc finding their
+ missing semicolons. */
+ if (yacc_flag)
+ obstack_sgrow (&action_obstack, "}\n break;");
+ else
+ obstack_sgrow (&action_obstack, ";\n break;}");
}
\f
/*-------------------------------------------------------------------.
break;
case '@':
- copy_at (finput, &guard_obstack, stack_offset);
+ copy_at (finput, &guard_obstack, rule, stack_offset);
break;
case EOF:
/* Make a dummy nonterminal, a gensym. */
bucket *sdummy = gensym ();
- /* Make a new rule, whose body is empty,
- before the current one, so that the action
- just read can belong to it. */
+ /* Make a new rule, whose body is empty, before the
+ current one, so that the action just read can
+ belong to it. */
nrules++;
nitems++;
p = symbol_list_new (sdummy);
+ /* Attach its lineno to that of the host rule. */
+ p->line = crule->line;
if (crule1)
crule1->next = p;
else
rule_table[ruleno].lhs = p->sym->value;
rule_table[ruleno].rhs = itemno;
rule_table[ruleno].line = p->line;
+ rule_table[ruleno].useful = TRUE;
p = p->next;
while (p && p->sym)
}
ritem[itemno] = 0;
+
+ if (trace_flag)
+ ritem_print (stderr);
}
\f
/*-------------------------------------------------------------------.