X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/8ea6525e3a092b76256fbed7d6edbb0a1861aee1..ae7cd18c98d9bad7e95d4f4070d2d09e8db675f8:/data/bison.m4 diff --git a/data/bison.m4 b/data/bison.m4 index 0d2a39eb..ca27159c 100644 --- a/data/bison.m4 +++ b/data/bison.m4 @@ -2,7 +2,7 @@ # Language-independent M4 Macros for Bison. -# Copyright (C) 2002, 2004-2012 Free Software Foundation, Inc. +# Copyright (C) 2002, 2004-2013 Free Software Foundation, Inc. # 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 @@ -61,6 +61,44 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison.])]) +## -------- ## +## Output. ## +## -------- ## + +# b4_output_begin(FILE) +# --------------------- +# Enable output, i.e., send to diversion 0, expand after "#", and +# generate the tag to output into FILE. Must be followed by EOL. +m4_define([b4_output_begin], +[m4_changecom() +m4_divert_push(0)dnl +@output(m4_unquote([$1])@)@dnl +]) + + +# b4_output_end() +# --------------- +# Output nothing, restore # as comment character (no expansions after #). +m4_define([b4_output_end], +[m4_divert_pop(0) +m4_changecom([#]) +]) + + +# b4_divert_kill(CODE) +# -------------------- +# Expand CODE for its side effects, discard its output. +m4_define([b4_divert_kill], +[m4_divert_text([KILL], [$1])]) + + +# b4_define_silent(MACRO, CODE) +# ----------------------------- +# Same as m4_define, but throw away the expansion of CODE. +m4_define([b4_define_silent], +[m4_define([$1], [b4_divert_kill([$2])])]) + + ## ---------------- ## ## Error handling. ## ## ---------------- ## @@ -226,30 +264,30 @@ m4_define([b4_integral_parser_tables_map], STATE-NUM.]]) $1([defact], [b4_defact], - [[YYDEFACT[S] -- default reduction number in state S. Performed when -YYTABLE does not specify something else to do. Zero means the default -is an error.]]) + [[YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. +Performed when YYTABLE does not specify something else to do. Zero +means the default is an error.]]) $1([pgoto], [b4_pgoto], [[YYPGOTO[NTERM-NUM].]]) $1([defgoto], [b4_defgoto], [[YYDEFGOTO[NTERM-NUM].]]) $1([table], [b4_table], - [[YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -positive, shift that token. If negative, reduce the rule which + [[YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If +positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error.]]) $1([check], [b4_check]) $1([stos], [b4_stos], - [[STOS_[STATE-NUM] -- The (internal number of the) accessing + [[YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM.]]) $1([r1], [b4_r1], [[YYR1[YYN] -- Symbol number of symbol that rule YYN derives.]]) $1([r2], [b4_r2], - [[YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.]]) + [[YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.]]) ]) @@ -276,7 +314,7 @@ m4_define([b4_flag_if], [m4_case(b4_$1_flag, [0], [$3], [1], [$2], - [m4_fatal([invalid $1 value: ]$1)])]) + [m4_fatal([invalid $1 value: ]b4_$1_flag)])]) # b4_define_flag_if(FLAG) @@ -289,7 +327,7 @@ m4_define([b4_define_flag_if], # _b4_define_flag_if($1, $2, FLAG) # -------------------------------- # Work around the impossibility to define macros inside macros, -# because issuing `[$1]' is not possible in M4. GNU M4 should provide +# because issuing '[$1]' is not possible in M4. GNU M4 should provide # $$1 a la M5/TeX. m4_define([_b4_define_flag_if], [m4_if([$1$2], $[1]$[2], [], @@ -317,6 +355,38 @@ b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated. # macro per (token, field), where field can has_id, id, etc.: see # src/output.c:prepare_symbols_definitions(). # +# The various FIELDS are: +# +# - has_id: 0 or 1. +# Whether the symbol has an id. +# - id: string +# If has_id, the id. Guaranteed to be usable as a C identifier. +# Prefixed by api.token.prefix if defined. +# - tag: string. +# A representat of the symbol. Can be 'foo', 'foo.id', '"foo"' etc. +# - user_number: integer +# The assigned (external) number as used by yylex. +# - is_token: 0 or 1 +# Whether this is a terminal symbol. +# - number: integer +# The internalized number (used after yytranslate). +# - has_type: 0, 1 +# Whether has a semantic value. +# - type_tag: string +# When api.value.type=union, the generated name for the union member. +# yytype_INT etc. for symbols that has_id, otherwise yytype_1 etc. +# - type +# If it has a semantic value, its type tag, or, if variant are used, +# its type. +# In the case of api.value.type=union, type is the real type (e.g. int). +# - has_printer: 0, 1 +# - printer: string +# - printer_file: string +# - printer_line: integer +# If the symbol has a printer, everything about it. +# - has_destructor, destructor, destructor_file, destructor_line +# Likewise. +# # The following macros provide access to these values. # b4_symbol_(NUM, FIELD) @@ -330,7 +400,7 @@ m4_define([b4_symbol_], # b4_symbol(NUM, FIELD) # --------------------- # Recover a FIELD about symbol #NUM. Thanks to m4_indir, fails if -# undefined. If FIELD = id, prepend the prefix. +# undefined. If FIELD = id, prepend the token prefix. m4_define([b4_symbol], [m4_case([$2], [id], [m4_do([b4_percent_define_get([api.token.prefix])], @@ -349,6 +419,14 @@ m4_define([b4_symbol_if], [m4_fatal([$0: field $2 of $1 is not a Boolean:] b4_symbol([$1], [$2]))])]) +# b4_symbol_tag_comment(SYMBOL-NUM) +# --------------------------------- +# Issue a comment giving the tag of symbol NUM. +m4_define([b4_symbol_tag_comment], +[b4_comment([b4_symbol([$1], [tag])]) +]) + + # b4_symbol_action_location(SYMBOL-NUM, KIND) # ------------------------------------------- # Report the location of the KIND action as FILE:LINE. @@ -366,9 +444,9 @@ m4_define([b4_symbol_action], b4_symbol_if([$1], [has_type], [m4_dquote(b4_symbol([$1], [type]))]), [(*yylocationp)])dnl - b4_symbol_case_([$1])[]dnl + b4_symbol_case_([$1])[]dnl b4_syncline([b4_symbol([$1], [$2_line])], ["b4_symbol([$1], [$2_file])"]) - b4_symbol([$1], [$2]) + b4_symbol([$1], [$2]) b4_syncline([@oline@], [@ofile@]) break; @@ -383,11 +461,29 @@ m4_define([b4_symbol_destructor], [b4_symbol_action([$1], [destructor])]) m4_define([b4_symbol_printer], [b4_symbol_action([$1], [printer])]) +# b4_symbol_actions(KIND, [TYPE = yytype]) +# ---------------------------------------- +# Emit the symbol actions for KIND ("printer" or "destructor"). +# Dispatch on TYPE. +m4_define([b4_symbol_actions], +[m4_pushdef([b4_actions_], m4_expand([b4_symbol_foreach([b4_symbol_$1])]))dnl +m4_ifval(m4_defn([b4_actions_]), +[switch (m4_default([$2], [yytype])) + { + m4_defn([b4_actions_]) + default: + break; + }dnl +], +[YYUSE (m4_default([$2], [yytype]));])dnl +m4_popdef([b4_actions_])dnl +]) + # 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]) +[case b4_symbol([$1], [number]): b4_symbol_tag_comment([$1])]) ]) @@ -445,9 +541,12 @@ m4_define([b4_token_format], # --------------------- # Run actions for the symbol NUMS that all have the same type-name. # Skip NUMS that have no type-name. +# +# To specify the action to run, define b4_dollar_dollar(NUMBER, +# TAG, TYPE). m4_define([b4_type_action_], [b4_symbol_if([$1], [has_type], -[m4_map([b4_symbol_case_], [$@])[]dnl +[m4_map([ b4_symbol_case_], [$@])[]dnl b4_dollar_dollar([b4_symbol([$1], [number])], [b4_symbol([$1], [tag])], [b4_symbol([$1], [type])]); @@ -479,11 +578,21 @@ m4_define([b4_basename], # ----------------------- m4_define([b4_syncline], [b4_flag_if([synclines], -[b4_sync_end([__line__], [b4_basename(m4_quote(__file__))]) -b4_sync_start([$1], [$2])])]) +[b4_sync_start([$1], [$2]) b4_sync_end([__line__], + [b4_basename(m4_quote(__file__))])[]dnl +])]) + +# b4_sync_start(LINE, FILE) +# ----------------------- +# Syncline for the new place. Typically a directive for the compiler. +m4_define([b4_sync_start], [b4_comment([$2:$1])]) + +# b4_sync_end(LINE, FILE) +# ----------------------- +# Syncline for the current place, which ends. Typically a comment +# left for the reader. +m4_define([b4_sync_end], [b4_comment([$2:$1])]) -m4_define([b4_sync_end], [b4_comment([Line $1 of $2])]) -m4_define([b4_sync_start], [b4_comment([Line $1 of $2])]) # b4_user_code(USER-CODE) # ----------------------- @@ -505,14 +614,14 @@ m4_define([b4_define_user_code], # b4_user_initial_action # b4_user_post_prologue # b4_user_pre_prologue -# b4_user_stype +# b4_user_union_members # ---------------------- # Macros that issue user code, ending with synclines. b4_define_user_code([actions]) b4_define_user_code([initial_action]) b4_define_user_code([post_prologue]) b4_define_user_code([pre_prologue]) -b4_define_user_code([stype]) +b4_define_user_code([union_members]) # b4_check_user_names(WHAT, USER-LIST, BISON-NAMESPACE) @@ -593,9 +702,9 @@ m4_define([b4_percent_define_use], # b4_percent_define_get([[foo]]) m4_define([b4_percent_define_get], [b4_percent_define_use([$1])dnl -m4_ifdef([b4_percent_define(]$1[)], - [m4_indir([b4_percent_define(]$1[)])], - [$2])]) +b4_percent_define_ifdef_([$1], + [m4_indir([b4_percent_define(]$1[)])], + [$2])]) # b4_percent_define_get_loc(VARIABLE) # ----------------------------------- @@ -614,7 +723,21 @@ m4_define([b4_percent_define_get_loc], [m4_pushdef([b4_loc], m4_indir([b4_percent_define_loc(]$1[)]))dnl b4_loc[]dnl m4_popdef([b4_loc])], - [b4_fatal([[b4_percent_define_get_loc: undefined %%define variable '%s']], [$1])])]) + [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) + +# b4_percent_define_get_kind(VARIABLE) +# ------------------------------------ +# Get the kind (code, keyword, string) of VARIABLE, i.e., how its +# value was defined (braces, not delimiters, quotes). +# +# If the %define variable VARIABLE is undefined, complain fatally +# since that's a Bison or skeleton error. Don't record this as a +# Bison usage of VARIABLE as there's no reason to suspect that the +# user-supplied value has yet influenced the output. +m4_define([b4_percent_define_get_kind], +[m4_ifdef([b4_percent_define_kind(]$1[)], + [m4_indir([b4_percent_define_kind(]$1[)])], + [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) # b4_percent_define_get_syncline(VARIABLE) # ---------------------------------------- @@ -631,7 +754,20 @@ m4_popdef([b4_loc])], m4_define([b4_percent_define_get_syncline], [m4_ifdef([b4_percent_define_syncline(]$1[)], [m4_indir([b4_percent_define_syncline(]$1[)])], - [b4_fatal([[b4_percent_define_get_syncline: undefined %%define variable '%s']], [$1])])]) + [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) + +# b4_percent_define_ifdef_(VARIABLE, IF-TRUE, [IF-FALSE]) +# ------------------------------------------------------ +# If the %define variable VARIABLE is defined, expand IF-TRUE, else expand +# IF-FALSE. Don't record usage of VARIABLE. +# +# For example: +# +# b4_percent_define_ifdef_([[foo]], [[it's defined]], [[it's undefined]]) +m4_define([b4_percent_define_ifdef_], +[m4_ifdef([b4_percent_define(]$1[)], + [$2], + [$3])]) # b4_percent_define_ifdef(VARIABLE, IF-TRUE, [IF-FALSE]) # ------------------------------------------------------ @@ -644,9 +780,9 @@ m4_define([b4_percent_define_get_syncline], # # b4_percent_define_ifdef([[foo]], [[it's defined]], [[it's undefined]]) m4_define([b4_percent_define_ifdef], -[m4_ifdef([b4_percent_define(]$1[)], - [b4_percent_define_use([$1])$2], - [$3])]) +[b4_percent_define_ifdef_([$1], + [b4_percent_define_use([$1])$2], + [$3])]) ## --------- ## @@ -675,11 +811,11 @@ m4_define([b4_percent_define_flag_if], [[invalid value for %%define Boolean variable '%s']], [$1])], [[b4_percent_define_flag_if($1)]])])], - [b4_fatal([[b4_percent_define_flag_if: undefined %%define variable '%s']], [$1])])]) + [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) -# b4_percent_define_default(VARIABLE, DEFAULT) -# -------------------------------------------- +# b4_percent_define_default(VARIABLE, DEFAULT, [KIND = keyword]) +# -------------------------------------------------------------- # Mimic muscle_percent_define_default in ../src/muscle-tab.h exactly. That is, # if the %define variable VARIABLE is undefined, set its value to DEFAULT. # Don't record this as a Bison usage of VARIABLE as there's no reason to @@ -689,25 +825,43 @@ m4_define([b4_percent_define_flag_if], # # b4_percent_define_default([[foo]], [[default value]]) m4_define([b4_percent_define_default], -[m4_ifndef([b4_percent_define(]$1[)], +[b4_percent_define_ifdef_([$1], [], [m4_define([b4_percent_define(]$1[)], [$2])dnl + m4_define([b4_percent_define_kind(]$1[)], + [m4_default([$3], [keyword])])dnl m4_define([b4_percent_define_loc(]$1[)], [[[[:-1.-1]], [[:-1.-1]]]])dnl m4_define([b4_percent_define_syncline(]$1[)], [[]])])]) -# b4_percent_define_if_define(VARIABLE) -# ------------------------------------- -# Define b4_VARIABLE_if that executes its $1 or $2 depending whether -# VARIABLE was %defined. The characters `.' and `-' in VARIABLE are mapped -# to `_'. +# b4_percent_define_if_define(NAME, [VARIABLE = NAME]) +# ---------------------------------------------------- +# Define b4_NAME_if that executes its $1 or $2 depending whether +# VARIABLE was %defined. The characters '.' and `-' in VARIABLE are mapped +# to '_'. m4_define([b4_percent_define_if_define_], [m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]), - [b4_percent_define_flag_if([$1], [$2], [$3])])]) + [b4_percent_define_flag_if(m4_default([$2], [$1]), + [$3], [$4])])]) m4_define([b4_percent_define_if_define], -[b4_percent_define_default([[$1]], [[false]]) -b4_percent_define_if_define_([$1], $[1], $[2])]) +[b4_percent_define_default([m4_default([$2], [$1])], [[false]]) +b4_percent_define_if_define_([$1], [$2], $[1], $[2])]) + + +# b4_percent_define_check_kind(VARIABLE, KIND, [DIAGNOSTIC = complain]) +# --------------------------------------------------------------------- +m4_define([b4_percent_define_check_kind], +[b4_percent_define_ifdef_([$1], + [m4_if(b4_percent_define_get_kind([$1]), [$2], [], + [b4_error([m4_default([$3], [complain])], + b4_percent_define_get_loc([$1]), + [m4_case([$2], + [code], [[%%define variable '%s' requires '{...}' values]], + [keyword], [[%%define variable '%s' requires keyword values]], + [string], [[%%define variable '%s' requires '"..."' values]])], + [$1])])])dnl +]) # b4_percent_define_check_values(VALUES) @@ -731,8 +885,9 @@ m4_define([b4_percent_define_check_values], [_b4_percent_define_check_values(b4_sublist)])]) m4_define([_b4_percent_define_check_values], -[m4_ifdef([b4_percent_define(]$1[)], - [m4_pushdef([b4_good_value], [0])dnl +[b4_percent_define_ifdef_([$1], + [b4_percent_define_check_kind(]$1[, [keyword], [deprecated])dnl + m4_pushdef([b4_good_value], [0])dnl m4_if($#, 1, [], [m4_foreach([b4_value], m4_dquote(m4_shift($@)), [m4_if(m4_indir([b4_percent_define(]$1[)]), b4_value, @@ -747,7 +902,7 @@ m4_define([_b4_percent_define_check_values], [[accepted value: '%s']], m4_dquote(b4_value))])])dnl m4_popdef([b4_good_value])], - [b4_fatal([[b4_percent_define_check_values: undefined %%define variable '%s']], [$1])])]) + [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) # b4_percent_code_get([QUALIFIER]) # -------------------------------- @@ -788,21 +943,23 @@ m4_define([b4_percent_code_ifdef], ## Common variables. ## ## ------------------ ## -# Default values for %define. -# --------------------------- -# If the api.token.prefix, it is empty. -m4_percent_define_default([[api.token.prefix]], [[]]) # b4_parse_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT]) # b4_parse_trace_if([IF-DEBUG-TRACES-ARE-ENABLED], [IF-NOT]) -# b4_lex_symbol_if([IF-YYLEX-RETURNS-A-COMPLETE-SYMBOL], [IF-NOT]) -# b4_variant_if([IF-VARIANT-ARE-USED], [IF-NOT]) +# b4_token_ctor_if([IF-YYLEX-RETURNS-A-TOKEN], [IF-NOT]) # ---------------------------------------------- -b4_percent_define_if_define([lex_symbol]) +b4_percent_define_if_define([token_ctor], [api.token.constructor]) b4_percent_define_if_define([locations]) # Whether locations are tracked. b4_percent_define_if_define([parse.assert]) b4_percent_define_if_define([parse.trace]) -b4_percent_define_if_define([variant]) + + +# b4_bison_locations_if([IF-TRUE]) +# -------------------------------- +# Expand IF-TRUE if using locations, and using the default location +# type. +m4_define([b4_bison_locations_if], +[b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [], [$1])])]) # b4_error_verbose_if([IF-ERRORS-ARE-VERBOSE], [IF-NOT]) @@ -822,6 +979,17 @@ b4_define_flag_if([error_verbose]) b4_error_verbose_if([m4_define([b4_token_table_flag], [1])]) +# b4_variant_if([IF-VARIANT-ARE-USED], [IF-NOT]) +# ---------------------------------------------- +b4_percent_define_if_define([variant]) +m4_define([b4_variant_flag], [[0]]) +b4_percent_define_ifdef([[api.value.type]], + [m4_case(b4_percent_define_get_kind([[api.value.type]]), [keyword], + [m4_case(b4_percent_define_get([[api.value.type]]), [variant], + [m4_define([b4_variant_flag], [[1]])])])]) +b4_define_flag_if([variant]) + + ## ----------------------------------------------------------- ## ## After processing the skeletons, check that all the user's ## ## %define variables and %code qualifiers were used by Bison. ## @@ -853,10 +1021,43 @@ m4_define_default([b4_parse_param], []) m4_define_default([b4_location_initial_column], [1]) m4_define_default([b4_location_initial_line], [1]) -# Sanity checks. + +## --------------- ## +## Sanity checks. ## +## --------------- ## + +# api.location.prefix={...} (Java and C++). +b4_percent_define_check_kind([api.location.type], [code], [deprecated]) + +# api.position.prefix={...} (Java). +b4_percent_define_check_kind([api.position.type], [code], [deprecated]) + +# api.prefix >< %name-prefix. +b4_percent_define_check_kind([api.prefix], [code], [deprecated]) b4_percent_define_ifdef([api.prefix], [m4_ifdef([b4_prefix], [b4_complain_at(b4_percent_define_get_loc([api.prefix]), [['%s' and '%s' cannot be used together]], [%name-prefix], [%define api.prefix])])]) + +# api.token.prefix={...} +# Make it a warning for those who used betas of Bison 3.0. +b4_percent_define_check_kind([api.token.prefix], [code], [deprecated]) + +# api.value.type >< %union. +b4_percent_define_ifdef([api.value.type], +[m4_ifdef([b4_union_members], +[b4_complain_at(b4_percent_define_get_loc([api.value.type]), + [['%s' and '%s' cannot be used together]], + [%union], + [%define api.value.type])])]) + +# api.value.type=union >< %yacc. +b4_percent_define_ifdef([api.value.type], +[m4_if(b4_percent_define_get([api.value.type]), [union], +[b4_yacc_if(dnl +[b4_complain_at(b4_percent_define_get_loc([api.value.type]), + [['%s' and '%s' cannot be used together]], + [%yacc], + [%define api.value.type "union"])])])])