# -----------------------------
# Expand IF-TRUE, if FLAG is true, IF-FALSE otherwise.
b4_define_flag_if([defines]) # Whether headers are requested.
-b4_define_flag_if([error_verbose]) # Whether error are verbose.
b4_define_flag_if([glr]) # Whether a GLR parser is requested.
-b4_define_flag_if([locations]) # Whether locations are tracked.
b4_define_flag_if([nondeterministic]) # Whether conflicts should be handled.
+ b4_define_flag_if([token_table]) # Whether yytoken_table is demanded.
b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
+ # yytoken_table is needed to support verbose errors.
+ b4_error_verbose_if([m4_define([b4_token_table_flag], [1])])
+
-## ------------------------- ##
-## Assigning token numbers. ##
-## ------------------------- ##
+## --------- ##
+## Symbols. ##
+## --------- ##
+
+# b4_symbol_(NUM, FIELD)
+# ----------------------
+# Recover a FIELD about symbol #NUM. Thanks to m4_indir, fails if
+# undefined.
+m4_define([b4_symbol_],
+[m4_indir([b4_symbol($1, $2)])])
+
+
+# b4_symbol(NUM, FIELD)
+# ---------------------
+# Recover a FIELD about symbol #NUM. Thanks to m4_indir, fails if
+# undefined. If FIELD = id, prepend the prefix.
+m4_define([b4_symbol],
+[m4_case([$2],
+ [id], [m4_do([b4_percent_define_get([api.tokens.prefix])],
+ [b4_symbol_([$1], [id])])],
+ [b4_symbol_($@)])])
+
+
+# b4_symbol_if(NUM, FIELD, IF-TRUE, IF-FALSE)
+# -------------------------------------------
+# If FIELD about symbol #NUM is 1 expand IF-TRUE, if is 0, expand IF-FALSE.
+# Otherwise an error.
+m4_define([b4_symbol_if],
+[m4_case(b4_symbol([$1], [$2]),
+ [1], [$3],
+ [0], [$4],
+ [m4_fatal([$0: field $2 of $1 is not a Boolean:] b4_symbol([$1], [$2]))])])
+
+
+# b4_symbol_action_location(SYMBOL-NUM, KIND)
+# -------------------------------------------
+# Report the location of the KIND action as FILE:LINE.
+m4_define([b4_symbol_action_location],
+[b4_symbol([$1], [$2_file]):b4_syncline([b4_symbol([$1], [$2_line])])])
+
+
+# b4_symbol_action(SYMBOL-NUM, KIND)
+# ----------------------------------
+# Run the action KIND (destructor or printer) for SYMBOL-NUM.
+# Same as in C, but using references instead of pointers.
+m4_define([b4_symbol_action],
+[b4_symbol_if([$1], [has_$2],
+[m4_pushdef([b4_dollar_dollar],
+ [b4_symbol_value([(*yyvaluep)],
+ b4_symbol_if([$1], [has_type],
+ [b4_symbol([$1], [type])]))])dnl
+m4_pushdef([b4_at_dollar], [(*yylocationp)])dnl
+ b4_symbol_case_([$1])
+b4_syncline([b4_symbol([$1], [$2_line])], ["b4_symbol([$1], [$2_file])"])
+ b4_symbol([$1], [$2])
+b4_syncline([@oline@], [@ofile@])
+ break;
+
+m4_popdef([b4_at_dollar])dnl
+m4_popdef([b4_dollar_dollar])dnl
+])])
+
+
+# b4_symbol_destructor(SYMBOL-NUM)
+# b4_symbol_printer(SYMBOL-NUM)
+# --------------------------------
+m4_define([b4_symbol_destructor], [b4_symbol_action([$1], [destructor])])
+m4_define([b4_symbol_printer], [b4_symbol_action([$1], [printer])])
+
+
+# b4_symbol_case_(SYMBOL-NUM)
+# ---------------------------
+# Issue a "case NUM" for SYMBOL-NUM.
+m4_define([b4_symbol_case_],
+[ case b4_symbol([$1], [number]): // b4_symbol([$1], [tag])
+])
+
+
+# b4_symbol_foreach(MACRO)
+# ------------------------
+# Invoke MACRO(SYMBOL-NUM) for each SYMBOL-NUM.
+m4_define([b4_symbol_foreach],
+ [m4_map([$1], m4_defn([b4_symbol_numbers]))])
+
+
+## ------- ##
+## Types. ##
+## ------- ##
+
+# b4_type_action_(NUMS)
+# ---------------------
+# Run actions for the symbol NUMS that all have the same type-name.
+# Skip NUMS that have no type-name.
+m4_define([b4_type_action_],
+[b4_symbol_if([$1], [has_type],
+[m4_map([b4_symbol_case_], [$@])[]dnl
+ b4_dollar_dollar([b4_symbol([$1], [number])],
+ [b4_symbol([$1], [tag])],
+ [b4_symbol([$1], [type])]);
+ break;
+
+])])
+
+# b4_type_foreach(MACRO)
+# ----------------------
+# Invoke MACRO(SYMBOL-NUMS) for each set of SYMBOL-NUMS for each type set.
+m4_define([b4_type_foreach],
+ [m4_map([$1], m4_defn([b4_type_names]))])
+
## ----------- ##
/* Enabling traces. */
#ifndef YYDEBUG
-# define YYDEBUG ]b4_debug_flag[
+# define YYDEBUG ]b4_parse_trace_if([1], [0])[
#endif
- /* Enabling verbose error messages. */
- #ifdef YYERROR_VERBOSE
- # undef YYERROR_VERBOSE
- # define YYERROR_VERBOSE 1
- #else
- # define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[
- #endif
-
- /* Enabling the token table. */
- #ifndef YYTOKEN_TABLE
- # define YYTOKEN_TABLE ]b4_token_table[
- #endif
-
]b4_namespace_open[
/// A Bison parser.
/// Internal symbol numbers.
typedef ]b4_int_type_for([b4_translate])[ token_number_type;
- /* Tables. */
- /// For a state, the index in \a yytable_ of its portion.
- static const ]b4_int_type_for([b4_pact])[ yypact_[];
static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ yypact_ninf_;
-
- /// For a state, default reduction number.
- /// Unless\a yytable_ specifies something else to do.
- /// Zero means the default is an error.
- static const ]b4_int_type_for([b4_defact])[ yydefact_[];
-
- static const ]b4_int_type_for([b4_pgoto])[ yypgoto_[];
- static const ]b4_int_type_for([b4_defgoto])[ yydefgoto_[];
-
- /// What to do in a state.
- /// \a yytable_[yypact_[s]]: what to do in state \a s.
- /// - if positive, shift that token.
- /// - if negative, reduce the rule which number is the opposite.
- /// - if zero, do what YYDEFACT says.
- static const ]b4_int_type_for([b4_table])[ yytable_[];
static const ]b4_int_type(b4_table_ninf, b4_table_ninf)[ yytable_ninf_;
- /* Tables. */
- ]b4_parser_tables_declare[
- static const ]b4_int_type_for([b4_check])[ yycheck_[];
--
- #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
- /// For a symbol, its name in clear.
- static const char* const yytname_[];
- #endif]b4_error_verbose_if([
- /// For a state, its accessing symbol.
- static const ]b4_int_type_for([b4_stos])[ yystos_[];
-
- /// For a rule, its LHS.
- static const ]b4_int_type_for([b4_r1])[ yyr1_[];
- /// For a rule, its RHS length.
- static const ]b4_int_type_for([b4_r2])[ yyr2_[]; ]b4_error_verbose_if([
++ // Tables.
++]b4_parser_tables_declare[]b4_error_verbose_if([
/// Convert the symbol name \a n to a form suitable for a diagnostic.
static std::string yytnamerr_ (const char *n);])[
- #if YYDEBUG
+ ]b4_token_table_if([], [[#if YYDEBUG]])[
+ /// For a symbol, its name in clear.
+ static const char* const yytname_[];
+ ]b4_token_table_if([[#if YYDEBUG]])[
- /// A type to store symbol numbers and -1.
- typedef ]b4_int_type_for([b4_rhs])[ rhs_number_type;
- /// A `-1'-separated list of the rules' RHS.
- static const rhs_number_type yyrhs_[];
- /// For each rule, the index of the first RHS symbol in \a yyrhs_.
- static const ]b4_int_type_for([b4_prhs])[ yyprhs_[];
- /// For each rule, its source line number.
- static const ]b4_int_type_for([b4_rline])[ yyrline_[];
- /// For each scanner token number, its symbol number.
- static const ]b4_int_type_for([b4_toknum])[ yytoken_number_[];
+]b4_integral_parser_table_declare([rline], [b4_rline],
+ [YYRLINE[YYN] -- Source line where rule number YYN was defined.])[
/// Report on the debug stream that the rule \a r is going to be reduced.
virtual void yy_reduce_print_ (int r);
/// Print the state stack on the debug stream.
virtual void yystack_print_ ();
-- /* Debugging. */
++ // Debugging.
int yydebug_;
std::ostream* yycdebug_;
--#endif
++#endif // YYDEBUG
/// Convert a scanner token number \a t to a symbol number.
- token_number_type yytranslate_ (int t);
+ static inline token_number_type yytranslate_ (]b4_lex_symbol_if([token_type], [int])[ t);
+
+#if YYDEBUG
+ /// \brief Display a symbol type, value and location.
+ /// \param yyo The output stream.
+ /// \param yysym The symbol.
+ template <typename Exact>
+ void yy_print_ (std::ostream& yyo,
+ const symbol_base_type<Exact>& yysym) const;
+#endif
/// \brief Reclaim the memory associated to a symbol.
- /// \param yymsg Why this token is reclaimed.
- /// \param yytype The symbol type.
- /// \param yyvaluep Its semantic value.
- /// \param yylocationp Its location.
- inline void yydestruct_ (const char* yymsg,
- int yytype,
- semantic_type* yyvaluep,
- location_type* yylocationp);
+ /// \param yymsg Why this token is reclaimed.
+ /// If null, print nothing.
+ /// \param s The symbol.
+ template <typename Exact>
+ inline void yy_destroy_ (const char* yymsg,
+ symbol_base_type<Exact>& yysym) const;
+
+ private:
+ /// Element of the stack: a state and its attributes.
+ struct stack_symbol_type : symbol_base_type<stack_symbol_type>
+ {
+ /// The parent class.
+ typedef symbol_base_type<stack_symbol_type> super_type;
+
+ /// Default constructor.
+ inline stack_symbol_type ();
+
+ /// Constructor.
+ inline stack_symbol_type (]b4_args([state_type s],
+ [const semantic_type& v],
+ b4_locations_if([const location_type& l]))[);
+
+ /// The state.
+ state_type state;
+
+ /// The type (corresponding to \a state).
+ inline int type_get_ () const;
+ };
+
+ /// Stack type.
+ typedef stack<stack_symbol_type> stack_type;
+
+ /// The stack.
+ stack_type yystack_;
+
+ /// Push a new state on the stack.
+ /// \param m a debug message to display
+ /// if null, no trace is output.
+ /// \param s the symbol
+ /// \warning the contents of \a s.value is stolen.
+ inline void yypush_ (const char* m, stack_symbol_type& s);
+
+ /// Push a new look ahead token on the state on the stack.
+ /// \param m a debug message to display
+ /// if null, no trace is output.
+ /// \param s the state
+ /// \param sym the symbol (for its value and location).
+ /// \warning the contents of \a s.value is stolen.
+ inline void yypush_ (const char* m, state_type s, symbol_type& sym);
/// Pop \a n symbols the three stacks.
inline void yypop_ (unsigned int n = 1);
{
yydebug_ = l;
}
--#endif
++#endif // YYDEBUG
+
+ inline ]b4_parser_class_name[::state_type
+ ]b4_parser_class_name[::yy_lr_goto_state_ (state_type yystate, int yylhs)
+ {
+ int yyr = yypgoto_[yylhs - yyntokens_] + yystate;
+ if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
+ return yytable_[yyr];
+ else
+ return yydefgoto_[yylhs - yyntokens_];
+ }
inline bool
]b4_parser_class_name[::yy_pact_value_is_default_ (int yyvalue)
}
- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
const ]b4_int_type(b4_pact_ninf, b4_pact_ninf) b4_parser_class_name::yypact_ninf_ = b4_pact_ninf[;
- const ]b4_int_type_for([b4_pact])[
- ]b4_parser_class_name[::yypact_[] =
- {
- ]b4_pact[
- };
-
- /* YYDEFACT[S] -- default reduction number in state S. Performed when
- YYTABLE doesn't specify something else to do. Zero means the
- default is an error. */
- const ]b4_int_type_for([b4_defact])[
- ]b4_parser_class_name[::yydefact_[] =
- {
- ]b4_defact[
- };
-
- /* YYPGOTO[NTERM-NUM]. */
- const ]b4_int_type_for([b4_pgoto])[
- ]b4_parser_class_name[::yypgoto_[] =
- {
- ]b4_pgoto[
- };
-
- /* YYDEFGOTO[NTERM-NUM]. */
- const ]b4_int_type_for([b4_defgoto])[
- ]b4_parser_class_name[::yydefgoto_[] =
- {
- ]b4_defgoto[
- };
- /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule which
- number is the opposite. If YYTABLE_NINF_, syntax error. */
const ]b4_int_type(b4_table_ninf, b4_table_ninf) b4_parser_class_name::yytable_ninf_ = b4_table_ninf[;
- const ]b4_int_type_for([b4_table])[
- ]b4_parser_class_name[::yytable_[] =
- {
- ]b4_table[
- };
-
- /* YYCHECK. */
- const ]b4_int_type_for([b4_check])[
- ]b4_parser_class_name[::yycheck_[] =
- {
- ]b4_check[
- };
- /* STOS_[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
- const ]b4_int_type_for([b4_stos])[
- ]b4_parser_class_name[::yystos_[] =
- {
- ]b4_stos[
- };
-
-#if YYDEBUG
- /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding
- to YYLEX-NUM. */
- const ]b4_int_type_for([b4_toknum])[
- ]b4_parser_class_name[::yytoken_number_[] =
- {
- ]b4_toknum[
- };
-#endif
-
- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
- const ]b4_int_type_for([b4_r1])[
- ]b4_parser_class_name[::yyr1_[] =
- {
- ]b4_r1[
- };
-
- /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
- const ]b4_int_type_for([b4_r2])[
- ]b4_parser_class_name[::yyr2_[] =
- {
- ]b4_r2[
- };
+]b4_parser_tables_define[
- #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+ ]b4_token_table_if([], [[#if YYDEBUG]])[
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at \a yyntokens_, nonterminals. */
const char*
const ]b4_parser_class_name[::yytname_[] =
{
- ]b4_tname[
+ ]b4_tname[
};
- #endif
- #if YYDEBUG
+ ]b4_token_table_if([[#if YYDEBUG]])[
- /* YYRHS -- A `-1'-separated list of the rules' RHS. */
- const ]b4_parser_class_name[::rhs_number_type
- ]b4_parser_class_name[::yyrhs_[] =
- {
- ]b4_rhs[
- };
-
- /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
- YYRHS. */
- const ]b4_int_type_for([b4_prhs])[
- ]b4_parser_class_name[::yyprhs_[] =
- {
- ]b4_prhs[
- };
-
- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
- const ]b4_int_type_for([b4_rline])[
- ]b4_parser_class_name[::yyrline_[] =
- {
- ]b4_rline[
- };
+]b4_integral_parser_table_define([rline], [b4_rline])[
// Print the state stack on the debug stream.
void