+2000-03-17 Akim Demaille <akim@epita.fr>
+
+ Change the handling of @s so that they behave exactly like $s.
+ There is now a pseudo variable @$ (readble and writable), location
+ of the lhs of the rule (by default ranging from the location of
+ the first symbol of the rhs, to the location of the last symbol,
+ or, if the rhs is empty, YYLLOC).
+
+ * src/bison.s1 [YYLSP_NEEDED] (yyloc): New variable, twin of
+ yyval.
+ (yyparse): When providing a default semantic action, provide a
+ default location action.
+ (after the $): No longer change `*YYLSP', just stack YYLOC the
+ same way you stack YYVAL.
+ * src/reader.c (read_declarations): Use warns.
+ (copy_guard, case '@'): Also recognize `@$', expanded as `YYLOC'.
+ (copy_action, case '@'): Likewise.
+ Use a standard error message, to save useless work from
+ translators.
+
2000-03-17 Akim Demaille <akim@epita.fr>
* bison.s1: Formatting and cosmetics changes.
#endif
- /* The variable used to return semantic values from the action
- routines. */
+ /* The variables used to return semantic value and location from the
+ action routines. */
YYSTYPE yyval;
+# ifdef YYLSP_NEEDED
+ YYLTYPE yyloc;
+# endif
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
int yylen;
if (yydebug)
/* Do a reduction. yyn is the number of a rule to reduce with. */
yyreduce:
yylen = yyr2[yyn];
+ /* Implement default value of the action:
+ `{dollar}{dollar} = {dollar}1'. */
+ if (yylen > 0)
+ yyval = yyvsp[1-yylen];
+#ifdef YYLSP_NEEDED
+ /* Implement default location. If the rhs is empty, extend YYLOC to
+ YYLLOC, which corresponds to the current token, otherwise
+ implement `@{dollar} = Starts at @1, ends at @YYLEN'. */
if (yylen > 0)
- yyval = yyvsp[1-yylen]; /* implement default value of the action */
+ {
+ yyloc = yylsp[1-yylen];
+ yyloc.last_line = yylsp[0].last_line;
+ yyloc.last_column = yylsp[0].last_column;
+ }
+ else
+ {
+ yyloc.last_line = yylsp[0].last_line;
+ yyloc.last_column = yylsp[0].last_column;
+ yyloc.text = 0;
+ }
+#endif
#if YYDEBUG
/* We have to keep this `#if YYDEBUG', since we use variables which
}
*++yyvsp = yyval;
-
#ifdef YYLSP_NEEDED
- yylsp++;
- if (yylen == 0)
- {
- yylsp->first_line = yylloc.first_line;
- yylsp->first_column = yylloc.first_column;
- yylsp->last_line = (yylsp-1)->last_line;
- yylsp->last_column = (yylsp-1)->last_column;
- yylsp->text = 0;
- }
- else
- {
- yylsp->last_line = (yylsp+yylen-1)->last_line;
- yylsp->last_column = (yylsp+yylen-1)->last_column;
- }
+ *++yylsp = yyloc;
#endif
/* Now `shift' the result of the reduction. Determine what state
#endif
- /* The variable used to return semantic values from the action
- routines. */
+ /* The variables used to return semantic value and location from the
+ action routines. */
YYSTYPE yyval;
+# ifdef YYLSP_NEEDED
+ YYLTYPE yyloc;
+# endif
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
int yylen;
if (yydebug)
/* Do a reduction. yyn is the number of a rule to reduce with. */
yyreduce:
yylen = yyr2[yyn];
+ /* Implement default value of the action:
+ `{dollar}{dollar} = {dollar}1'. */
+ if (yylen > 0)
+ yyval = yyvsp[1-yylen];
+#ifdef YYLSP_NEEDED
+ /* Implement default location. If the rhs is empty, extend YYLOC to
+ YYLLOC, which corresponds to the current token, otherwise
+ implement `@{dollar} = Starts at @1, ends at @YYLEN'. */
if (yylen > 0)
- yyval = yyvsp[1-yylen]; /* implement default value of the action */
+ {
+ yyloc = yylsp[1-yylen];
+ yyloc.last_line = yylsp[0].last_line;
+ yyloc.last_column = yylsp[0].last_column;
+ }
+ else
+ {
+ yyloc.last_line = yylsp[0].last_line;
+ yyloc.last_column = yylsp[0].last_column;
+ yyloc.text = 0;
+ }
+#endif
#if YYDEBUG
/* We have to keep this `#if YYDEBUG', since we use variables which
}
*++yyvsp = yyval;
-
#ifdef YYLSP_NEEDED
- yylsp++;
- if (yylen == 0)
- {
- yylsp->first_line = yylloc.first_line;
- yylsp->first_column = yylloc.first_column;
- yylsp->last_line = (yylsp-1)->last_line;
- yylsp->last_column = (yylsp-1)->last_column;
- yylsp->text = 0;
- }
- else
- {
- yylsp->last_line = (yylsp+yylen-1)->last_line;
- yylsp->last_column = (yylsp+yylen-1)->last_column;
- }
+ *++yylsp = yyloc;
#endif
/* Now `shift' the result of the reduction. Determine what state
#include "gram.h"
#include "machine.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"
+#define LTYPESTR "\
+\n\
+#ifndef YYLTYPE\n\
+typedef\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;
fatal(_("no input grammar"));
else
{
- char buff[100];
- sprintf(buff, _("unknown character: %s"), printable_version(c));
- warn(buff);
- skip_to_char('%');
+ warns (_("unknown character: %s"), printable_version(c));
+ skip_to_char('%');
}
}
}
fprintf(fguard, "yyvsp[%d]", n - stack_offset);
if (type_name)
fprintf(fguard, ".%s", type_name);
- if(!type_name && typed)
- warnss(_("$%s of `%s' has no declared type"), int_to_string(n), rule->sym->tag);
+ if (!type_name && typed)
+ warnss (_("$%s of `%s' has no declared type"),
+ int_to_string(n), rule->sym->tag);
continue;
}
else
warns(_("$%s is invalid"), printable_version(c));
-
break;
case '@':
- c = getc(finput);
- if (isdigit(c) || c == '-')
+ c = getc (finput);
+ if (c == '$')
+ {
+ fprintf (fguard, "yyloc");
+ yylsp_needed = 1;
+ }
+ else if (isdigit(c) || c == '-')
{
ungetc (c, finput);
- n = read_signed_integer(finput);
- c = getc(finput);
+ n = read_signed_integer (finput);
+ c = getc (finput);
+ fprintf (fguard, "yylsp[%d]", n - stack_offset);
+ yylsp_needed = 1;
+ continue;
}
else
{
- warns(_("@%s is invalid"), printable_version(c));
+ warns (_("@%s is invalid"), printable_version (c));
n = 1;
}
-
- fprintf(fguard, "yylsp[%d]", n - stack_offset);
- yylsp_needed = 1;
-
- continue;
+ break;
case EOF:
- fatal(_("unterminated %%guard clause"));
+ fatal (_("unterminated %%guard clause"));
default:
- putc(c, fguard);
+ putc (c, fguard);
}
if (c != '}' || count != 0)
break;
case '@':
- c = getc(finput);
- if (isdigit(c) || c == '-')
+ c = getc (finput);
+ if (c == '$')
+ {
+ fprintf (faction, "yyloc");
+ yylsp_needed = 1;
+ }
+ else if (isdigit(c) || c == '-')
{
ungetc (c, finput);
- n = read_signed_integer(finput);
- c = getc(finput);
+ n = read_signed_integer (finput);
+ c = getc (finput);
+ fprintf (faction, "yylsp[%d]", n - stack_offset);
+ yylsp_needed = 1;
+ continue;
}
else
{
- warn(_("invalid @-construct"));
+ warns (_("@%s is invalid"), printable_version (c));
n = 1;
}
-
- fprintf(faction, "yylsp[%d]", n - stack_offset);
- yylsp_needed = 1;
-
- continue;
+ break;
case EOF:
fatal(_("unmatched `{'"));
else if (t == LEFT_CURLY)
{
/* This case never occurs -wjh */
- if (actionflag) warn(_("two actions at end of one rule"));
+ if (actionflag)
+ warn(_("two actions at end of one rule"));
copy_action(crule, rulelength);
actionflag = 1;
xactions++; /* -wjh */
t = lex();
}
- /* If $$ is being set in default way,
- warn if any type mismatch. */
- else if (!xactions && first_rhs && lhs->type_name != first_rhs->type_name)
+ /* If $$ is being set in default way, warn if any type
+ mismatch. */
+ else if (!xactions
+ && first_rhs
+ && lhs->type_name != first_rhs->type_name)
{
- if (lhs->type_name == 0 || first_rhs->type_name == 0
+ if (lhs->type_name == 0
+ || first_rhs->type_name == 0
|| strcmp(lhs->type_name,first_rhs->type_name))
warnss(_("type clash (`%s' `%s') on default action"),
- lhs->type_name ? lhs->type_name : "",
- first_rhs->type_name ? first_rhs->type_name : "");
+ lhs->type_name ? lhs->type_name : "",
+ first_rhs->type_name ? first_rhs->type_name : "");
}
/* Warn if there is no default for $$ but we need one. */
else if (!xactions && !first_rhs && lhs->type_name != 0)