X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/06ec0105b12cdfa2994283e345154e6720354808..ae7cd18c98d9bad7e95d4f4070d2d09e8db675f8:/data/c.m4 diff --git a/data/c.m4 b/data/c.m4 index 91126a82..b1b43948 100644 --- a/data/c.m4 +++ b/data/c.m4 @@ -2,7 +2,7 @@ # C 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 @@ -51,29 +51,6 @@ m4_define([b4_cpp_guard_close], ## Identification. ## ## ---------------- ## -# b4_comment_(TEXT, OPEN, CONTINUE, END) -# -------------------------------------- -# Put TEXT in comment. Avoid trailing spaces: don't indent empty lines. -# Avoid adding indentation to the first line, as the indentation comes -# from OPEN. That's why we don't patsubst([$1], [^\(.\)], [ \1]). -# -# Prefix all the output lines with PREFIX. -m4_define([b4_comment_], [$2[]m4_bpatsubst([$1], [ -\(.\)], [ -$3\1])$4]) - - -# b4_comment(TEXT, [PREFIX]) -# -------------------------- -# Put TEXT in comment. Avoid trailing spaces: don't indent empty lines. -# Avoid adding indentation to the first line, as the indentation comes -# from "/*". That's why we don't patsubst([$1], [^\(.\)], [ \1]). -# -# Prefix all the output lines with PREFIX. -m4_define([b4_comment], -[b4_comment_([$1], [$2/* ], [$2 ], [$2 */])]) - - # b4_identification # ----------------- # Depends on individual skeletons to define b4_pure_flag, b4_push_flag, or @@ -127,6 +104,23 @@ m4_define_default([b4_union_name], [b4_api_PREFIX[]STYPE]) ## Pure/impure interfaces. ## ## ------------------------ ## +# b4_lex_formals +# -------------- +# All the yylex formal arguments. +# b4_lex_param arrives quoted twice, but we want to keep only one level. +m4_define([b4_lex_formals], +[b4_pure_if([[[[YYSTYPE *yylvalp]], [[&yylval]]][]dnl +b4_locations_if([, [[YYLTYPE *yyllocp], [&yylloc]]])])dnl +m4_ifdef([b4_lex_param], [, ]b4_lex_param)]) + + +# b4_lex +# ------ +# Call yylex. +m4_define([b4_lex], +[b4_function_call([yylex], [int], b4_lex_formals)]) + + # b4_user_args # ------------ m4_define([b4_user_args], @@ -156,9 +150,9 @@ m4_popdef([$1])dnl # b4_parse_param_use([VAL], [LOC]) # -------------------------------- -# `YYUSE' VAL, LOC if locations are enabled, and all the parse-params. +# 'YYUSE' VAL, LOC if locations are enabled, and all the parse-params. m4_define([b4_parse_param_use], -[m4_ifvaln([$1], [ YYUSE([$1]);])dnl +[m4_ifvaln([$1], [ YYUSE ([$1]);])dnl b4_locations_if([m4_ifvaln([$2], [ YYUSE ([$2]);])])dnl b4_parse_param_for([Decl], [Formal], [ YYUSE (Formal); ])dnl @@ -188,7 +182,7 @@ m4_define([b4_int_type], # b4_int_type_for(NAME) # --------------------- # Return the smallest int type able to handle numbers ranging from -# `NAME_min' to `NAME_max' (included). +# 'NAME_min' to 'NAME_max' (included). m4_define([b4_int_type_for], [b4_int_type($1_min, $1_max)]) @@ -205,6 +199,50 @@ m4_define([b4_table_value_equals], [(!!(($2) == ($3)))])]) +## ----------------- ## +## Compiler issues. ## +## ----------------- ## + +# b4_attribute_define +# ------------------- +# Provide portability for __attribute__. +m4_define([b4_attribute_define], +[#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if (! defined __GNUC__ || __GNUC__ < 2 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) +# define __attribute__(Spec) /* empty */ +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif +]) + + ## ---------## ## Values. ## ## ---------## @@ -232,7 +270,7 @@ m4_define([b4_null], [YY_NULL]) # b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT) # ------------------------------------------------------------- -# Define "yy" which contents is CONTENT. +# Define "yy" whose contents is CONTENT. m4_define([b4_integral_parser_table_define], [m4_ifvaln([$3], [b4_comment([$3], [ ])])dnl static const b4_int_type_for([$2]) yy$1[[]] = @@ -273,11 +311,9 @@ m4_define([b4_token_enum], # -------------- # Output the definition of the tokens (if there are) as enums. m4_define([b4_token_enums], -[b4_any_token_visible_if([[/* Tokens. */ +[b4_any_token_visible_if([[/* Token type. */ #ifndef ]b4_api_PREFIX[TOKENTYPE # define ]b4_api_PREFIX[TOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ enum ]b4_api_prefix[tokentype { ]m4_join([, @@ -429,12 +465,9 @@ m4_ifset([b4_parse_param], [, b4_parse_param]))[ yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - switch (yytype) - { -]b4_symbol_foreach([b4_symbol_destructor])dnl -[ default: - break; - } + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + ]b4_symbol_actions([destructor])[ + YY_IGNORE_MAYBE_UNINITIALIZED_END }]dnl ]) @@ -444,9 +477,9 @@ m4_ifset([b4_parse_param], [, b4_parse_param]))[ # Define the "yy_symbol_print" function. m4_define_default([b4_yy_symbol_print_define], [[ -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*----------------------------------------. +| Print this symbol's value on YYOUTPUT. | +`----------------------------------------*/ ]b4_function_define([yy_symbol_value_print], [static void], @@ -467,12 +500,7 @@ m4_if(b4_skeleton, ["yacc.c"], YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # endif ]])dnl -[ switch (yytype) - { -]b4_symbol_foreach([b4_symbol_printer])dnl -[ default: - break; - } + b4_symbol_actions([printer])[ } @@ -488,10 +516,8 @@ m4_if(b4_skeleton, ["yacc.c"], b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl m4_ifset([b4_parse_param], [, b4_parse_param]))[ { - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + YYFPRINTF (yyoutput, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); ]b4_locations_if([ YY_LOCATION_PRINT (yyoutput, *yylocationp); YYFPRINTF (yyoutput, ": "); @@ -502,48 +528,192 @@ b4_locations_if([, yylocationp])[]b4_user_args[); }]dnl ]) + +## ---------------- ## +## api.value.type. ## +## ---------------- ## + + +# ---------------------- # +# api.value.type=union. # +# ---------------------- # + +# b4_symbol_type_register(SYMBOL-NUM) +# ----------------------------------- +# Symbol SYMBOL-NUM has a type (for variant) instead of a type-tag. +# Extend the definition of %union's body with a field of that type, +# and extend the symbol's "type" field to point to the field name, +# instead of the type name. +m4_define([b4_symbol_type_register], +[m4_define([b4_symbol($1, type_tag)], + [b4_symbol_if([$1], [has_id], + [b4_symbol([$1], [id])], + [yytype_[]b4_symbol([$1], [number])])])dnl +m4_append([b4_user_union_members], +m4_expand([ + b4_symbol_tag_comment([$1])dnl + b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);])) +]) + + +# b4_type_define_tag(SYMBOL1-NUM, ...) +# ------------------------------------ +# For the batch of symbols SYMBOL1-NUM... (which all have the same +# type), enhance the %union definition for each of them, and set +# there "type" field to the field tag name, instead of the type name. +m4_define([b4_type_define_tag], +[b4_symbol_if([$1], [has_type], + [m4_map([b4_symbol_type_register], [$@])]) +]) + + +# b4_symbol_value_union(VAL, [TYPE]) +# ---------------------------------- +# Same of b4_symbol_value, but when api.value.type=union. +m4_define([b4_symbol_value_union], +[m4_ifval([$2], + [(*($2*)(&$1))], + [$1])]) +]) + + +# b4_value_type_setup_union +# ------------------------- +# Setup support for api.value.type=union. Symbols are defined with a +# type instead of a union member name: build the corresponding union, +# and give the symbols their tag. +m4_define([b4_value_type_setup_union], +[m4_define([b4_union_members]) +b4_type_foreach([b4_type_define_tag]) +m4_copy_force([b4_symbol_value_union], [b4_symbol_value]) +]) + + +# ---------------- # +# api.value.type. # +# ---------------- # + + +# b4_value_type_setup_variant +# --------------------------- +# Setup support for api.value.type=variant. By default, fail, specialized +# by other skeletons. +m4_define([b4_value_type_setup_variant], +[b4_complain_at(b4_percent_define_get_loc([[api.value.type]]), + [['%s' does not support '%s']], + [b4_skeleton], + [%define api.value.type variant])]) + + +# _b4_value_type_setup_keyword +# ---------------------------- +# api.value.type is defined with a keyword/string syntax. Check if +# that is properly defined, and prepare its use. +m4_define([_b4_value_type_setup_keyword], +[b4_percent_define_check_values([[[[api.value.type]], + [[none]], + [[union]], + [[union-directive]], + [[variant]], + [[yystype]]]])dnl +m4_case(b4_percent_define_get([[api.value.type]]), + [union], [b4_value_type_setup_union], + [variant], [b4_value_type_setup_variant])]) + + +# b4_value_type_setup +# ------------------- +# Check if api.value.type is properly defined, and possibly prepare +# its use. +b4_define_silent([b4_value_type_setup], +[# Define default value. +b4_percent_define_ifdef([[api.value.type]], [], +[# %union => api.value.type=union-directive +m4_ifdef([b4_union_members], +[m4_define([b4_percent_define_kind(api.value.type)], [keyword]) +m4_define([b4_percent_define(api.value.type)], [union-directive])], +[# no tag seen => api.value.type={int} +m4_if(b4_tag_seen_flag, 0, +[m4_define([b4_percent_define_kind(api.value.type)], [code]) +m4_define([b4_percent_define(api.value.type)], [int])], +[# otherwise api.value.type=yystype +m4_define([b4_percent_define_kind(api.value.type)], [keyword]) +m4_define([b4_percent_define(api.value.type)], [yystype])])])]) + +# Set up. +m4_bmatch(b4_percent_define_get_kind([[api.value.type]]), + [keyword\|string], [_b4_value_type_setup_keyword]) +]) + + ## -------------- ## ## Declarations. ## ## -------------- ## -# b4_declare_yylstype -# ------------------- -# Declarations that might either go into the header (if --defines) or -# in the parser body. Declare YYSTYPE/YYLTYPE, and yylval/yylloc. -m4_define([b4_declare_yylstype], + +# b4_value_type_define +# -------------------- +m4_define([b4_value_type_define], +[b4_value_type_setup[]dnl +/* Value type. */ +m4_bmatch(b4_percent_define_get_kind([[api.value.type]]), +[code], +[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED +typedef ]b4_percent_define_get([[api.value.type]])[ ]b4_api_PREFIX[STYPE; +# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1 +# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1 +#endif +]], +[m4_bmatch(b4_percent_define_get([[api.value.type]]), +[union\|union-directive], [[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED -]m4_ifdef([b4_stype], -[[typedef union ]b4_union_name[ +typedef union ]b4_union_name[ ]b4_api_PREFIX[STYPE; +union ]b4_union_name[ { -]b4_user_stype[ -} ]b4_api_PREFIX[STYPE; -# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]], -[m4_if(b4_tag_seen_flag, 0, -[[typedef int ]b4_api_PREFIX[STYPE; -# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]])])[ +]b4_user_union_members[ +}; +# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1 # define ]b4_api_PREFIX[STYPE_IS_DECLARED 1 -#endif]b4_locations_if([[ +#endif +]])])]) + +# b4_location_type_define +# ----------------------- +m4_define([b4_location_type_define], +[[/* Location type. */ #if ! defined ]b4_api_PREFIX[LTYPE && ! defined ]b4_api_PREFIX[LTYPE_IS_DECLARED -typedef struct ]b4_api_PREFIX[LTYPE +typedef struct ]b4_api_PREFIX[LTYPE ]b4_api_PREFIX[LTYPE; +struct ]b4_api_PREFIX[LTYPE { int first_line; int first_column; int last_line; int last_column; -} ]b4_api_PREFIX[LTYPE; +}; # define ]b4_api_PREFIX[LTYPE_IS_DECLARED 1 # define ]b4_api_PREFIX[LTYPE_IS_TRIVIAL 1 -#endif]]) +#endif +]]) + + +# b4_declare_yylstype +# ------------------- +# Declarations that might either go into the header (if --defines) or +# in the parser body. Declare YYSTYPE/YYLTYPE, and yylval/yylloc. +m4_define([b4_declare_yylstype], +[b4_value_type_define[]b4_locations_if([ +b4_location_type_define]) b4_pure_if([], [[extern ]b4_api_PREFIX[STYPE ]b4_prefix[lval; ]b4_locations_if([[extern ]b4_api_PREFIX[LTYPE ]b4_prefix[lloc;]])])[]dnl ]) + # b4_YYDEBUG_define -# ------------------ +# ----------------- m4_define([b4_YYDEBUG_define], -[[/* Enabling traces. */ +[[/* Debug traces. */ ]m4_if(b4_api_prefix, [yy], [[#ifndef YYDEBUG # define YYDEBUG ]b4_parse_trace_if([1], [0])[ @@ -610,14 +780,40 @@ m4_define([b4_yy_location_print_define], #ifndef YY_LOCATION_PRINT # if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - do { \ - fprintf (File, "%d.%d", (Loc).first_line, (Loc).first_column); \ - if ((Loc).first_line < (Loc).last_line) \ - fprintf (File, "-%d.%d", (Loc).last_line, (Loc).last_column - 1); \ - else if ((Loc).first_column < (Loc).last_column - 1) \ - fprintf (File, "-%d", (Loc).last_column - 1); \ - } while (0) + +/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ + +__attribute__((__unused__)) +]b4_function_define([yy_location_print_], + [static unsigned], + [[FILE *yyo], [yyo]], + [[YYLTYPE const * const yylocp], [yylocp]])[ +{ + unsigned res = 0; + int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; + if (0 <= yylocp->first_line) + { + res += YYFPRINTF (yyo, "%d", yylocp->first_line); + if (0 <= yylocp->first_column) + res += YYFPRINTF (yyo, ".%d", yylocp->first_column); + } + if (0 <= yylocp->last_line) + { + if (yylocp->first_line < yylocp->last_line) + { + res += YYFPRINTF (yyo, "-%d", yylocp->last_line); + if (0 <= end_col) + res += YYFPRINTF (yyo, ".%d", end_col); + } + else if (0 <= end_col && yylocp->first_column < end_col) + res += YYFPRINTF (yyo, "-%d", end_col); + } + return res; + } + +# define YY_LOCATION_PRINT(File, Loc) \ + yy_location_print_ (File, &(Loc)) + # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif