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.
This commit is contained in:
Akim Demaille
2000-03-17 11:30:24 +00:00
parent 41aca2e038
commit 6666f98f4f
4 changed files with 143 additions and 76 deletions

View File

@@ -1,3 +1,23 @@
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> 2000-03-17 Akim Demaille <akim@epita.fr>
* bison.s1: Formatting and cosmetics changes. * bison.s1: Formatting and cosmetics changes.

View File

@@ -309,10 +309,15 @@ yyparse(YYPARSE_PARAM_ARG)
#endif #endif
/* The variable used to return semantic values from the action /* The variables used to return semantic value and location from the
routines. */ action routines. */
YYSTYPE yyval; YYSTYPE yyval;
# ifdef YYLSP_NEEDED
YYLTYPE yyloc;
# endif
/* When reducing, the number of symbols on the RHS of the reduced
rule. */
int yylen; int yylen;
if (yydebug) if (yydebug)
@@ -533,8 +538,27 @@ yydefault:
/* Do a reduction. yyn is the number of a rule to reduce with. */ /* Do a reduction. yyn is the number of a rule to reduce with. */
yyreduce: yyreduce:
yylen = yyr2[yyn]; yylen = yyr2[yyn];
/* Implement default value of the action:
`{dollar}{dollar} = {dollar}1'. */
if (yylen > 0) if (yylen > 0)
yyval = yyvsp[1-yylen]; /* implement default value of the action */ 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)
{
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 #if YYDEBUG
/* We have to keep this `#if YYDEBUG', since we use variables which /* We have to keep this `#if YYDEBUG', since we use variables which
@@ -571,22 +595,8 @@ $ /* the action file gets copied in in place of this dollarsign */
} }
*++yyvsp = yyval; *++yyvsp = yyval;
#ifdef YYLSP_NEEDED #ifdef YYLSP_NEEDED
yylsp++; *++yylsp = yyloc;
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;
}
#endif #endif
/* Now `shift' the result of the reduction. Determine what state /* Now `shift' the result of the reduction. Determine what state

View File

@@ -309,10 +309,15 @@ yyparse(YYPARSE_PARAM_ARG)
#endif #endif
/* The variable used to return semantic values from the action /* The variables used to return semantic value and location from the
routines. */ action routines. */
YYSTYPE yyval; YYSTYPE yyval;
# ifdef YYLSP_NEEDED
YYLTYPE yyloc;
# endif
/* When reducing, the number of symbols on the RHS of the reduced
rule. */
int yylen; int yylen;
if (yydebug) if (yydebug)
@@ -533,8 +538,27 @@ yydefault:
/* Do a reduction. yyn is the number of a rule to reduce with. */ /* Do a reduction. yyn is the number of a rule to reduce with. */
yyreduce: yyreduce:
yylen = yyr2[yyn]; yylen = yyr2[yyn];
/* Implement default value of the action:
`{dollar}{dollar} = {dollar}1'. */
if (yylen > 0) if (yylen > 0)
yyval = yyvsp[1-yylen]; /* implement default value of the action */ 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)
{
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 #if YYDEBUG
/* We have to keep this `#if YYDEBUG', since we use variables which /* We have to keep this `#if YYDEBUG', since we use variables which
@@ -571,22 +595,8 @@ $ /* the action file gets copied in in place of this dollarsign */
} }
*++yyvsp = yyval; *++yyvsp = yyval;
#ifdef YYLSP_NEEDED #ifdef YYLSP_NEEDED
yylsp++; *++yylsp = yyloc;
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;
}
#endif #endif
/* Now `shift' the result of the reduction. Determine what state /* Now `shift' the result of the reduction. Determine what state

View File

@@ -36,10 +36,27 @@
#include "gram.h" #include "gram.h"
#include "machine.h" #include "machine.h"
#define LTYPESTR "\n#ifndef YYLTYPE\ntypedef\n struct yyltype\n\ #define LTYPESTR "\
{\n int timestamp;\n int first_line;\n int first_column;\ \n\
\n int last_line;\n int last_column;\n char *text;\n }\n\ #ifndef YYLTYPE\n\
yyltype;\n\n#define YYLTYPE yyltype\n#endif\n\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' */ /* Number of slots allocated (but not necessarily used yet) in `rline' */
int rline_allocated; int rline_allocated;
@@ -329,10 +346,8 @@ read_declarations (void)
fatal(_("no input grammar")); fatal(_("no input grammar"));
else else
{ {
char buff[100]; warns (_("unknown character: %s"), printable_version(c));
sprintf(buff, _("unknown character: %s"), printable_version(c)); skip_to_char('%');
warn(buff);
skip_to_char('%');
} }
} }
} }
@@ -1156,39 +1171,43 @@ copy_guard (symbol_list *rule, int stack_offset)
fprintf(fguard, "yyvsp[%d]", n - stack_offset); fprintf(fguard, "yyvsp[%d]", n - stack_offset);
if (type_name) if (type_name)
fprintf(fguard, ".%s", type_name); fprintf(fguard, ".%s", type_name);
if(!type_name && typed) if (!type_name && typed)
warnss(_("$%s of `%s' has no declared type"), int_to_string(n), rule->sym->tag); warnss (_("$%s of `%s' has no declared type"),
int_to_string(n), rule->sym->tag);
continue; continue;
} }
else else
warns(_("$%s is invalid"), printable_version(c)); warns(_("$%s is invalid"), printable_version(c));
break; break;
case '@': case '@':
c = getc(finput); c = getc (finput);
if (isdigit(c) || c == '-') if (c == '$')
{
fprintf (fguard, "yyloc");
yylsp_needed = 1;
}
else if (isdigit(c) || c == '-')
{ {
ungetc (c, finput); ungetc (c, finput);
n = read_signed_integer(finput); n = read_signed_integer (finput);
c = getc(finput); c = getc (finput);
fprintf (fguard, "yylsp[%d]", n - stack_offset);
yylsp_needed = 1;
continue;
} }
else else
{ {
warns(_("@%s is invalid"), printable_version(c)); warns (_("@%s is invalid"), printable_version (c));
n = 1; n = 1;
} }
break;
fprintf(fguard, "yylsp[%d]", n - stack_offset);
yylsp_needed = 1;
continue;
case EOF: case EOF:
fatal(_("unterminated %%guard clause")); fatal (_("unterminated %%guard clause"));
default: default:
putc(c, fguard); putc (c, fguard);
} }
if (c != '}' || count != 0) if (c != '}' || count != 0)
@@ -1394,23 +1413,27 @@ copy_action (symbol_list *rule, int stack_offset)
break; break;
case '@': case '@':
c = getc(finput); c = getc (finput);
if (isdigit(c) || c == '-') if (c == '$')
{
fprintf (faction, "yyloc");
yylsp_needed = 1;
}
else if (isdigit(c) || c == '-')
{ {
ungetc (c, finput); ungetc (c, finput);
n = read_signed_integer(finput); n = read_signed_integer (finput);
c = getc(finput); c = getc (finput);
fprintf (faction, "yylsp[%d]", n - stack_offset);
yylsp_needed = 1;
continue;
} }
else else
{ {
warn(_("invalid @-construct")); warns (_("@%s is invalid"), printable_version (c));
n = 1; n = 1;
} }
break;
fprintf(faction, "yylsp[%d]", n - stack_offset);
yylsp_needed = 1;
continue;
case EOF: case EOF:
fatal(_("unmatched `{'")); fatal(_("unmatched `{'"));
@@ -1651,21 +1674,25 @@ readgram (void)
else if (t == LEFT_CURLY) else if (t == LEFT_CURLY)
{ {
/* This case never occurs -wjh */ /* 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); copy_action(crule, rulelength);
actionflag = 1; actionflag = 1;
xactions++; /* -wjh */ xactions++; /* -wjh */
t = lex(); t = lex();
} }
/* If $$ is being set in default way, /* If $$ is being set in default way, warn if any type
warn if any type mismatch. */ mismatch. */
else if (!xactions && first_rhs && lhs->type_name != first_rhs->type_name) 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)) || strcmp(lhs->type_name,first_rhs->type_name))
warnss(_("type clash (`%s' `%s') on default action"), warnss(_("type clash (`%s' `%s') on default action"),
lhs->type_name ? lhs->type_name : "", lhs->type_name ? lhs->type_name : "",
first_rhs->type_name ? first_rhs->type_name : ""); first_rhs->type_name ? first_rhs->type_name : "");
} }
/* Warn if there is no default for $$ but we need one. */ /* Warn if there is no default for $$ but we need one. */
else if (!xactions && !first_rhs && lhs->type_name != 0) else if (!xactions && !first_rhs && lhs->type_name != 0)