/* Bison Action Scanner -*- C -*-
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
- This program is free software; you can redistribute it and/or modify
+ This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA
-*/
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
%option debug nodefault nounput noyywrap never-interactive
%option prefix="code_" outfile="lex.yy.c"
#include <quote.h>
#include "scan-code.h"
+#include "symlist.h"
/* The current calling start condition: SC_RULE_ACTION or
SC_SYMBOL_ACTION. */
-# define YY_DECL char *code_lex (int sc_context, symbol_list *rule)
+# define YY_DECL static char *code_lex (code_props *self, int sc_context)
YY_DECL;
#define YY_USER_ACTION location_compute (loc, &loc->end, yytext, yyleng);
static location the_location;
static location *loc = &the_location;
+/* A string representing the most recent translation. */
+static char *last_string;
+
/* True if an untyped $$ or $n was seen. */
static bool untyped_var_seen;
%}
<SC_RULE_ACTION>
{
- "$"("<"{tag}">")?(-?[0-9]+|"$") handle_action_dollar (rule, yytext, *loc);
- "@"(-?[0-9]+|"$") handle_action_at (rule, yytext, *loc);
+ "$"("<"{tag}">")?(-?[0-9]+|"$") {
+ handle_action_dollar (self->rule, yytext, *loc);
+ }
+ "@"(-?[0-9]+|"$") {
+ handle_action_at (self->rule, yytext, *loc);
+ }
"$" {
warn_at (*loc, _("stray `$'"));
"{" STRING_GROW; ++braces_level;
"}" {
- bool outer_brace = --braces_level < 0;
+ bool outer_brace = --braces_level == 0;
/* As an undocumented Bison extension, append `;' before the last
brace in braced code, so that the user code can omit trailing
`;'. But do not append `;' if emulating Yacc, since Yacc does
- not append one.
+ not append one. Also, some output languages (like Java) do not
+ accept an extra semicolon, so don't append if the user specified
+ a skeleton or language.
FIXME: Bison should warn if a semicolon seems to be necessary
here, and should omit the semicolon if it seems unnecessary
should also diagnose other Bison extensions like %yacc.
Perhaps there should also be a GCC-style --pedantic-errors
option, so that such warnings are diagnosed as errors. */
- if (outer_brace && ! yacc_flag)
+ if (outer_brace && !yacc_flag && language_prio == default_prio
+ && skeleton_prio == default_prio)
obstack_1grow (&obstack_for_string, ';');
STRING_GROW;
<SC_SYMBOL_ACTION>
{
- "$$" obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar[");
- "@$" obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
+ "$$" {
+ obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar[");
+ self->is_value_used = true;
+ }
+ "@$" {
+ obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
+ locations_flag = true;
+ }
}
/* End of processing. */
<*><<EOF>> {
- obstack_1grow (&obstack_for_string, '\0');
- return obstack_finish (&obstack_for_string);
+ STRING_FINISH;
+ return last_string;
}
%%
static void
handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
{
- const char *type_name = NULL;
+ char const *type_name = NULL;
char *cp = text + 1;
symbol_list *effective_rule;
int effective_rule_length;
obstack_fgrow1 (&obstack_for_string,
"]b4_lhs_value([%s])[", type_name);
- rule->used = true;
+ rule->action_props.is_value_used = true;
}
else
{
obstack_fgrow3 (&obstack_for_string,
"]b4_rhs_value(%d, %d, [%s])[",
effective_rule_length, n, type_name);
- symbol_list_n_used_set (effective_rule, n, true);
+ if (n > 0)
+ symbol_list_n_get (effective_rule, n)->action_props.is_value_used =
+ true;
}
else
complain_at (dollar_loc, _("integer out of range: %s"), quote (text));
| Initialize the scanner. |
`-------------------------*/
-/* Translate the dollars and ats in \a a, whose location is \a l. The
- translation is for \a rule, in the context \a sc_context
+/* Translate the dollars and ats in \a self, in the context \a sc_context
(SC_RULE_ACTION, SC_SYMBOL_ACTION, INITIAL). */
static char const *
-translate_action (int sc_context, symbol_list *rule, char const *a, location l)
+translate_action (code_props *self, int sc_context)
{
char *res;
static bool initialized = false;
if (!initialized)
{
obstack_init (&obstack_for_string);
- /* The initial buffer, never used. */
- yy_delete_buffer (YY_CURRENT_BUFFER);
yy_flex_debug = 0;
initialized = true;
}
- loc->start = loc->end = l.start;
- yy_switch_to_buffer (yy_scan_string (a));
- res = code_lex (sc_context, rule);
+ loc->start = loc->end = self->location.start;
+ yy_switch_to_buffer (yy_scan_string (self->code));
+ res = code_lex (self, sc_context);
yy_delete_buffer (YY_CURRENT_BUFFER);
return res;
}
-char const *
-translate_rule_action (symbol_list *rule)
+/*------------------------------------------------------------------------.
+| Implementation of the public interface as documented in "scan-code.h". |
+`------------------------------------------------------------------------*/
+
+void
+code_props_none_init (code_props *self)
+{
+ *self = code_props_none;
+}
+
+code_props const code_props_none = CODE_PROPS_NONE_INIT;
+
+void
+code_props_plain_init (code_props *self, char const *code, location code_loc)
+{
+ self->kind = CODE_PROPS_PLAIN;
+ self->code = code;
+ self->location = code_loc;
+ self->is_value_used = false;
+ self->rule = NULL;
+}
+
+void
+code_props_symbol_action_init (code_props *self, char const *code,
+ location code_loc)
{
- return translate_action (SC_RULE_ACTION, rule, rule->action,
- rule->action_location);
+ self->kind = CODE_PROPS_SYMBOL_ACTION;
+ self->code = code;
+ self->location = code_loc;
+ self->is_value_used = false;
+ self->rule = NULL;
}
-char const *
-translate_symbol_action (char const *a, location l)
+void
+code_props_rule_action_init (code_props *self, char const *code,
+ location code_loc, symbol_list *rule)
{
- return translate_action (SC_SYMBOL_ACTION, NULL, a, l);
+ self->kind = CODE_PROPS_RULE_ACTION;
+ self->code = code;
+ self->location = code_loc;
+ self->is_value_used = false;
+ self->rule = rule;
}
-char const *
-translate_code (char const *a, location l)
+void
+code_props_translate_code (code_props *self)
{
- return translate_action (INITIAL, NULL, a, l);
+ switch (self->kind)
+ {
+ case CODE_PROPS_NONE:
+ break;
+ case CODE_PROPS_PLAIN:
+ self->code = translate_action (self, INITIAL);
+ break;
+ case CODE_PROPS_SYMBOL_ACTION:
+ self->code = translate_action (self, SC_SYMBOL_ACTION);
+ break;
+ case CODE_PROPS_RULE_ACTION:
+ self->code = translate_action (self, SC_RULE_ACTION);
+ break;
+ }
}
-/*-----------------------------------------------.
-| Free all the memory allocated to the scanner. |
-`-----------------------------------------------*/
+void
+code_scanner_last_string_free (void)
+{
+ STRING_FREE;
+}
void
code_scanner_free (void)
{
obstack_free (&obstack_for_string, 0);
/* Reclaim Flex's buffers. */
- yy_delete_buffer (YY_CURRENT_BUFFER);
+ yylex_destroy ();
}