static void gram_error (location const *, char const *);
static char const *char_name (char);
-
-/** Add a lex-param or a parse-param.
- *
- * \param type \a lex_param or \a parse_param
- * \param decl the formal argument
- * \param loc the location in the source.
- */
-static void add_param (char const *type, char *decl, location loc);
-
-
-static symbol_class current_class = unknown_sym;
-static uniqstr current_type = NULL;
-static symbol *current_lhs;
-static location current_lhs_location;
-static named_ref *current_lhs_named_ref;
-static int current_prec = 0;
-
-#define YYTYPE_INT16 int_fast16_t
-#define YYTYPE_INT8 int_fast8_t
-#define YYTYPE_UINT16 uint_fast16_t
-#define YYTYPE_UINT8 uint_fast8_t
%}
+%code
+{
+ static symbol_class current_class = unknown_sym;
+ static uniqstr current_type = NULL;
+ static symbol *current_lhs;
+ static location current_lhs_location;
+ static named_ref *current_lhs_named_ref;
+ static int current_prec = 0;
+
+ #define YYTYPE_INT16 int_fast16_t
+ #define YYTYPE_INT8 int_fast8_t
+ #define YYTYPE_UINT16 uint_fast16_t
+ #define YYTYPE_UINT8 uint_fast8_t
+}
+
%debug
%verbose
%defines
%union
{
+ assoc assoc;
+ char *code;
+ char const *chars;
+ int integer;
+ named_ref *named_ref;
symbol *symbol;
symbol_list *list;
- int integer;
- char const *chars;
- char *code;
- assoc assoc;
uniqstr uniqstr;
unsigned char character;
- named_ref *named_ref;
};
/* Define the tokens together with their human representation. */
PERCENT_DEFINES "%defines"
PERCENT_ERROR_VERBOSE "%error-verbose"
PERCENT_EXPECT "%expect"
- PERCENT_EXPECT_RR "%expect-rr"
+ PERCENT_EXPECT_RR "%expect-rr"
PERCENT_FLAG "%<flag>"
PERCENT_FILE_PREFIX "%file-prefix"
PERCENT_GLR_PARSER "%glr-parser"
PERCENT_INITIAL_ACTION "%initial-action"
PERCENT_LANGUAGE "%language"
- PERCENT_LEX_PARAM "%lex-param"
PERCENT_NAME_PREFIX "%name-prefix"
PERCENT_NO_DEFAULT_PREC "%no-default-prec"
PERCENT_NO_LINES "%no-lines"
PERCENT_NONDETERMINISTIC_PARSER
- "%nondeterministic-parser"
+ "%nondeterministic-parser"
PERCENT_OUTPUT "%output"
- PERCENT_PARSE_PARAM "%parse-param"
- PERCENT_REQUIRE "%require"
+ PERCENT_REQUIRE "%require"
PERCENT_SKELETON "%skeleton"
PERCENT_START "%start"
PERCENT_TOKEN_TABLE "%token-table"
%type <assoc> precedence_declarator
%type <list> symbols.1 symbols.prec generic_symlist generic_symlist_item
+
+/*---------.
+| %param. |
+`---------*/
+%code requires
+{
+# ifndef PARAM_TYPE
+# define PARAM_TYPE
+ typedef enum
+ {
+ param_lex = 1 << 0,
+ param_parse = 1 << 1,
+ param_both = param_lex | param_parse
+ } param_type;
+# endif
+};
+%code
+{
+ /** Add a lex-param and/or a parse-param.
+ *
+ * \param type where to push this formal argument.
+ * \param decl the formal argument. Destroyed.
+ * \param loc the location in the source.
+ */
+ static void add_param (param_type type, char *decl, location loc);
+};
+%union
+{
+ param_type param;
+}
+%token <param> PERCENT_PARAM "%param";
+%printer
+{
+ switch ($$)
+ {
+#define CASE(In, Out) \
+ case param_ ## In: fputs ("%" #Out, stderr); break
+
+ CASE(lex, lex-param);
+ CASE(parse, parse-param);
+ CASE(both, param);
+ }
+#undef CASE
+} <param>;
+
%%
input:
code_scanner_last_string_free ();
}
| "%language" STRING { language_argmatch ($2, grammar_prio, @1); }
-| "%lex-param" "{...}" { add_param ("lex_param", $2, @2); }
| "%name-prefix" STRING { spec_name_prefix = $2; }
| "%name-prefix" "=" STRING { spec_name_prefix = $3; } /* deprecated */
| "%no-lines" { no_lines_flag = true; }
| "%nondeterministic-parser" { nondeterministic_parser = true; }
| "%output" STRING { spec_outfile = $2; }
| "%output" "=" STRING { spec_outfile = $3; } /* deprecated */
-| "%parse-param" "{...}" { add_param ("parse_param", $2, @2); }
+| "%param" "{...}" { add_param ($1, $2, @2); }
| "%require" STRING { version_check (&@2, $2); }
| "%skeleton" STRING
{
| /*FIXME: Err? What is this horror doing here? */ ";"
;
+
+/*----------------------.
+| grammar_declaration. |
+`----------------------*/
+
grammar_declaration:
precedence_declaration
| symbol_declaration
}
-/* Add a lex-param or a parse-param (depending on TYPE) with
- declaration DECL and location LOC. */
-
static void
-add_param (char const *type, char *decl, location loc)
+add_param (param_type type, char *decl, location loc)
{
static char const alphanum[26 + 26 + 1 + 10] =
"abcdefghijklmnopqrstuvwxyz"
name = xmalloc (name_len + 1);
memcpy (name, name_start, name_len);
name[name_len] = '\0';
- muscle_pair_list_grow (type, decl, name);
+ if (type & param_lex)
+ muscle_pair_list_grow ("lex_param", decl, name);
+ if (type & param_parse)
+ muscle_pair_list_grow ("parse_param", decl, name);
free (name);
}
static size_t no_cr_read (FILE *, char *, size_t);
#define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))
-#define RETURN_PERCENT_FLAG(Value) \
+#define RETURN_PERCENT_PARAM(Value) \
+ RETURN_VALUE(PERCENT_PARAM, param, param_ ## Value)
+
+#define RETURN_PERCENT_FLAG(Value) \
+ RETURN_VALUE(PERCENT_FLAG, uniqstr, uniqstr_new (Value))
+
+#define RETURN_VALUE(Token, Field, Value) \
do { \
- val->uniqstr = uniqstr_new (Value); \
- return PERCENT_FLAG; \
+ val->Field = Value; \
+ return Token; \
} while (0)
#define ROLLBACK_CURRENT_TOKEN \
"%glr-parser" return PERCENT_GLR_PARSER;
"%language" return PERCENT_LANGUAGE;
"%left" return PERCENT_LEFT;
- "%lex-param" return PERCENT_LEX_PARAM;
+ "%lex-param" RETURN_PERCENT_PARAM(lex);
"%locations" RETURN_PERCENT_FLAG("locations");
"%merge" return PERCENT_MERGE;
"%name"[-_]"prefix" return PERCENT_NAME_PREFIX;
"%nondeterministic-parser" return PERCENT_NONDETERMINISTIC_PARSER;
"%nterm" return PERCENT_NTERM;
"%output" return PERCENT_OUTPUT;
- "%parse-param" return PERCENT_PARSE_PARAM;
+ "%param" RETURN_PERCENT_PARAM(both);
+ "%parse-param" RETURN_PERCENT_PARAM(parse);
"%prec" return PERCENT_PREC;
"%precedence" return PERCENT_PRECEDENCE;
"%printer" return PERCENT_PRINTER;