diff --git a/cpp/cpp.h b/cpp/cpp.h index b1ff8b88..7b5b5f0e 100755 --- a/cpp/cpp.h +++ b/cpp/cpp.h @@ -156,3 +156,6 @@ extern int Cplusplus; extern Nlist *kwdefined; extern Includelist includelist[NINCLUDE]; extern char wd[]; + +#define memmove mymemmove +extern void *memmove(void *dp, const void *sp, size_t n); diff --git a/cpp/tokens.c b/cpp/tokens.c index d4fe054d..208f3e2d 100755 --- a/cpp/tokens.c +++ b/cpp/tokens.c @@ -267,7 +267,7 @@ peektokens(Tokenrow *trp, char *str) if (str) fprintf(stderr, "%s ", str); if (tpbp || tp>trp->lp) - fprintf(stderr, "(tp offset %d) ", tp-trp->bp); + fprintf(stderr, "(tp offset %d) ", (int)(tp-trp->bp)); for (tp=trp->bp; tplp && tpbp+32; tp++) { if (tp->type!=NL) { int c = tp->t[tp->len]; diff --git a/cpp/unix.c b/cpp/unix.c index 400af35d..e84b64e2 100755 --- a/cpp/unix.c +++ b/cpp/unix.c @@ -19,10 +19,12 @@ setup(int argc, char **argv) FILE *fd; char *fp, *dp; Tokenrow tr; + char *preincl = 0; + FILE *prefd = 0; extern void setup_kwtab(void); setup_kwtab(); - while ((c = getopt(argc, argv, "MNOVv+I:D:U:F:lg")) != -1) + while ((c = getopt(argc, argv, "MNOVv+I:D:U:F:lgi:")) != -1) switch (c) { case 'N': for (i=0; i. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.5.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* First part of user prologue. */ +#line 1 "lburg/gram.y" + +#include +#include "lburg.h" +static char rcsid[] = "$Id$"; +/*lint -e616 -e527 -e652 -esym(552,yynerrs) -esym(563,yynewstate,yyerrlab) */ +int yylineno = 0; +int linesum = 1; +extern int yylex(void); + +#line 80 "y.tab.c" + +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) +# else +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 #else -#define YYCONST -#define YYPARAMS(x) () -#define YYDEFUN(name, arglist, args) name arglist args; -#define YYAND ; -#define YYPTR char * +# define YYERROR_VERBOSE 0 #endif -#ifndef lint -YYCONST static char yysccsid[] = "@(#)yaccpar 1.8 (Berkeley +Cygnus.28) 01/20/91"; + + +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 #endif -#define YYBYACC 1 -#ifndef YYDONT_INCLUDE_STDIO -#include +#if YYDEBUG +extern int yydebug; #endif -#ifdef __cplusplus -#include /* for malloc/realloc/free */ + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + TERMINAL = 258, + START = 259, + PPERCENT = 260, + ID = 261, + TEMPLATE = 262, + CODE = 263, + INT = 264 + }; #endif -#line 2 "lburg/gram.y" -#include -#include "lburg.h" -static char rcsid[] = "$Id$"; -/*lint -e616 -e527 -e652 -esym(552,yynerrs) -esym(563,yynewstate,yyerrlab) */ -static int yylineno = 0; -#line 8 "lburg/gram.y" -typedef union { +/* Tokens. */ +#define TERMINAL 258 +#define START 259 +#define PPERCENT 260 +#define ID 261 +#define TEMPLATE 262 +#define CODE 263 +#define INT 264 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +union YYSTYPE +{ +#line 10 "lburg/gram.y" + int n; char *string; Tree tree; -} YYSTYPE; -#line 37 "y.tab.c" -#define TERMINAL 257 -#define START 258 -#define PPERCENT 259 -#define ID 260 -#define TEMPLATE 261 -#define CODE 262 -#define INT 263 -#define YYERRCODE 256 -static YYCONST short yylhs[] = { -1, - 0, 0, 4, 4, 6, 6, 6, 6, 7, 7, - 5, 5, 5, 5, 1, 3, 3, 3, 2, + +#line 153 "y.tab.c" + +}; +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + +int yyparse (void); + + + + + +#ifdef short +# undef short +#endif + +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif +#endif + +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; +#else +typedef short yytype_int16; +#endif + +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; +#else +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + +/* Stored state numbers (used for stacks). */ +typedef yytype_int8 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define YY_ATTRIBUTE_PURE +# endif +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +# else +# define YY_ATTRIBUTE_UNUSED +# 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__ && ! defined __ICC && 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 + +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif + + +#define YY_ASSERT(E) ((void) (0 && (E))) + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yy_state_t yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYPTRDIFF_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYPTRDIFF_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 3 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 35 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 16 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 9 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 20 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 37 + +#define YYUNDEFTOK 2 +#define YYMAXUTOK 264 + + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_int8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 13, 14, 2, 2, 15, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 12, 2, + 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9 +}; + +#if YYDEBUG + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_int8 yyrline[] = +{ + 0, 24, 24, 25, 28, 29, 32, 33, 37, 38, + 41, 42, 45, 46, 47, 48, 51, 54, 55, 56, + 59 }; -static YYCONST short yylen[] = { 2, - 3, 1, 0, 2, 3, 3, 1, 2, 0, 4, - 0, 7, 2, 3, 1, 1, 4, 6, 1, +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "TERMINAL", "START", "PPERCENT", "ID", + "TEMPLATE", "CODE", "INT", "'\\n'", "'='", "':'", "'('", "')'", "','", + "$accept", "spec", "decls", "decl", "blist", "rules", "nonterm", "tree", + "cost", YY_NULLPTR }; -static YYCONST short yydefred[] = { 3, - 0, 0, 0, 9, 0, 11, 7, 4, 8, 0, - 15, 0, 0, 0, 5, 6, 0, 13, 0, 0, - 14, 0, 10, 0, 0, 0, 0, 0, 19, 0, - 17, 0, 12, 0, 18, +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_int16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 10, 61, 58, 40, 41, 44 }; -static YYCONST short yydgoto[] = { 1, - 12, 30, 25, 2, 13, 8, 10, +# endif + +#define YYPACT_NINF (-26) + +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) + +#define YYTABLE_NINF (-4) + +#define yytable_value_is_error(Yyn) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int8 yypact[] = +{ + -26, 11, 0, -26, 5, -26, 8, -26, -26, -26, + -26, 3, -26, 7, 6, 9, -26, -26, 12, -26, + 13, 14, -26, 15, -26, 16, 17, 15, 18, 4, + -26, 20, -26, 15, -26, 19, -26 }; -static YYCONST short yysindex[] = { 0, - 0, -4, -2, 0, -250, 0, 0, 0, 0, -9, - 0, 1, -10, -49, 0, 0, 3, 0, -44, -248, - 0, -244, 0, -22, -242, -244, -245, -37, 0, 10, - 0, -244, 0, -20, 0, + + /* 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. */ +static const yytype_int8 yydefact[] = +{ + 4, 0, 0, 1, 0, 10, 0, 12, 8, 5, + 9, 0, 16, 0, 0, 0, 6, 7, 0, 14, + 0, 0, 15, 0, 11, 17, 0, 0, 0, 0, + 20, 0, 18, 0, 13, 0, 19 }; -static YYCONST short yyrindex[] = { 0, - 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -39, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -26, -26, -26, -26, -26, -26, 21, -25, -26 }; -static YYCONST short yygindex[] = { 0, - 11, 0, -23, 0, 0, 0, 0, + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 1, 2, 9, 11, 14, 13, 26, 31 }; -#define YYTABLESIZE 255 -static YYCONST short yytable[] = { 18, - 15, 16, 28, 31, 16, 7, 32, 9, 34, 11, - 16, 20, 21, 22, 23, 24, 29, 26, 27, 33, - 35, 2, 1, 19, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 17, 0, 0, 0, 11, - 14, 3, 4, 5, 6, + + /* 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. */ +static const yytype_int8 yytable[] = +{ + -3, 4, 29, 5, 6, 7, -2, 18, 35, 15, + 8, 3, 12, 16, 12, 10, 19, 17, 32, 33, + 21, 25, 22, 24, 28, 23, 30, 0, 0, 27, + 34, 0, 0, 36, 0, 20 }; -static YYCONST short yycheck[] = { 10, - 10, 41, 26, 41, 44, 10, 44, 10, 32, 260, - 10, 61, 10, 58, 263, 260, 262, 40, 261, 10, - 41, 0, 0, 13, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 261, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 256, -1, -1, -1, 260, - 260, 256, 257, 258, 259, + +static const yytype_int8 yycheck[] = +{ + 0, 1, 27, 3, 4, 5, 0, 1, 33, 6, + 10, 0, 6, 10, 6, 10, 10, 10, 14, 15, + 11, 6, 10, 9, 7, 12, 8, -1, -1, 13, + 10, -1, -1, 14, -1, 14 }; -#define YYFINAL 1 -#ifndef YYDEBUG -#define YYDEBUG 0 -#endif -#define YYMAXTOKEN 263 -#if YYDEBUG -static YYCONST char *YYCONST yyname[] = { -"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,"'('","')'",0,0,"','",0,0,0,0,0,0,0,0,0,0,0,0,0,"':'",0,0, -"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -"TERMINAL","START","PPERCENT","ID","TEMPLATE","CODE","INT", + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_int8 yystos[] = +{ + 0, 17, 18, 0, 1, 3, 4, 5, 10, 19, + 10, 20, 6, 22, 21, 6, 10, 10, 1, 10, + 22, 11, 10, 12, 9, 6, 23, 13, 7, 23, + 8, 24, 14, 15, 10, 23, 14 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_int8 yyr1[] = +{ + 0, 16, 17, 17, 18, 18, 19, 19, 19, 19, + 20, 20, 21, 21, 21, 21, 22, 23, 23, 23, + 24 }; -static YYCONST char *YYCONST yyrule[] = { -"$accept : spec", -"spec : decls PPERCENT rules", -"spec : decls", -"decls :", -"decls : decls decl", -"decl : TERMINAL blist '\\n'", -"decl : START nonterm '\\n'", -"decl : '\\n'", -"decl : error '\\n'", -"blist :", -"blist : blist ID '=' INT", -"rules :", -"rules : rules nonterm ':' tree TEMPLATE cost '\\n'", -"rules : rules '\\n'", -"rules : rules error '\\n'", -"nonterm : ID", -"tree : ID", -"tree : ID '(' tree ')'", -"tree : ID '(' tree ',' tree ')'", -"cost : CODE", + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_int8 yyr2[] = +{ + 0, 2, 3, 1, 0, 2, 3, 3, 1, 2, + 0, 4, 0, 7, 2, 3, 1, 1, 4, 6, + 1 }; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif -#define YYLEX yylex() -#define YYEMPTY -1 -#define yyclearin (yychar=(YYEMPTY)) -#define yyerrok (yyerrflag=0) + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) +{ + FILE *yyoutput = yyo; + YYUSE (yyoutput); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); +# endif + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyo, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyo, yytype, yyvaluep); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule) +{ + int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[+yyssp[yyi + 1 - yynrhs]], + &yyvsp[(yyi + 1) - (yynrhs)] + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH -#define YYINITDEPTH 200 +# define YYINITDEPTH 200 #endif -#ifdef YYSTACKSIZE + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + #ifndef YYMAXDEPTH -#define YYMAXDEPTH YYSTACKSIZE -#endif -#else -#ifdef YYMAXDEPTH -#define YYSTACKSIZE YYMAXDEPTH -#else -#define YYSTACKSIZE 500 -#define YYMAXDEPTH 500 -#endif +# define YYMAXDEPTH 10000 #endif -#ifndef YYMAXSTACKSIZE -#define YYMAXSTACKSIZE 10000 -#endif -int yydebug; -int yynerrs; -int yyerrflag; -int yychar; -YYSTYPE yyval; -YYSTYPE yylval; -static short *yyss; -static YYSTYPE *yyvs; -static int yystacksize; -#define yyfree(x) free(x) -extern int yylex(); - -static YYPTR -YYDEFUN (yymalloc, (bytes), unsigned bytes) + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) +# else +/* Return the length of YYSTR. */ +static YYPTRDIFF_T +yystrlen (const char *yystr) { - YYPTR ptr = (YYPTR) malloc (bytes); - if (ptr != 0) return (ptr); - yyerror ("yyparse: memory exhausted"); - return (0); + YYPTRDIFF_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; } +# endif +# endif -static YYPTR -YYDEFUN (yyrealloc, (old, bytes), YYPTR old YYAND unsigned bytes) +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) { - YYPTR ptr = (YYPTR) realloc (old, bytes); - if (ptr != 0) return (ptr); - yyerror ("yyparse: memory exhausted"); - return (0); + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; } +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYPTRDIFF_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYPTRDIFF_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + else + goto append; + + append: + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (yyres) + return yystpcpy (yyres, yystr) - yyres; + else + return yystrlen (yystr); +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ static int -#ifdef __GNUC__ -inline -#endif -yygrow () +yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, + yy_state_t *yyssp, int yytoken) { - int old_stacksize = yystacksize; - short *new_yyss; - YYSTYPE *new_yyvs; - - if (yystacksize == YYMAXSTACKSIZE) - return (1); - yystacksize += (yystacksize + 1 ) / 2; - if (yystacksize > YYMAXSTACKSIZE) - yystacksize = YYMAXSTACKSIZE; -#if YYDEBUG - if (yydebug) - printf("yydebug: growing stack size from %d to %d\n", - old_stacksize, yystacksize); -#endif - new_yyss = (short *) yyrealloc ((char *)yyss, yystacksize * sizeof (short)); - if (new_yyss == 0) - return (1); - new_yyvs = (YYSTYPE *) yyrealloc ((char *)yyvs, yystacksize * sizeof (YYSTYPE)); - if (new_yyvs == 0) + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat: reported tokens (one for the "unexpected", + one per "expected"). */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Actual size of YYARG. */ + int yycount = 0; + /* Cumulated lengths of YYARG. */ + YYPTRDIFF_T yysize = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) { - yyfree (new_yyss); - return (1); + int yyn = yypact[+*yyssp]; + YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + yysize = yysize0; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYPTRDIFF_T yysize1 + = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + } + } } - yyss = new_yyss; - yyvs = new_yyvs; - return (0); + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + /* Don't count the "%s"s in the final size, but reserve room for + the terminator. */ + YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1; + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + ++yyp; + ++yyformat; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +{ + YYUSE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END } -#line 60 "lburg/gram.y" + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + yy_state_fast_t yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss; + yy_state_t *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYPTRDIFF_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yysetstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYPTRDIFF_T yysize = yyssp - yyss + 1; + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + yy_state_t *yyss1 = yyss; + YYSTYPE *yyvs1 = yyvs; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yy_state_t *yyss1 = yyss; + union yyalloc *yyptr = + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + /* Discard the shifted token. */ + yychar = YYEMPTY; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 7: +#line 33 "lburg/gram.y" + { + if (nonterm((yyvsp[-1].string))->number != 1) + yyerror("redeclaration of the start symbol\n"); + } +#line 1343 "y.tab.c" + break; + + case 9: +#line 38 "lburg/gram.y" + { yyerrok; } +#line 1349 "y.tab.c" + break; + + case 11: +#line 42 "lburg/gram.y" + { term((yyvsp[-2].string), (yyvsp[0].n)); } +#line 1355 "y.tab.c" + break; + + case 13: +#line 46 "lburg/gram.y" + { rule((yyvsp[-5].string), (yyvsp[-3].tree), (yyvsp[-2].string), (yyvsp[-1].string)); } +#line 1361 "y.tab.c" + break; + + case 15: +#line 48 "lburg/gram.y" + { yyerrok; } +#line 1367 "y.tab.c" + break; + + case 16: +#line 51 "lburg/gram.y" + { nonterm((yyval.string) = (yyvsp[0].string)); } +#line 1373 "y.tab.c" + break; + + case 17: +#line 54 "lburg/gram.y" + { (yyval.tree) = tree((yyvsp[0].string), 0, 0); } +#line 1379 "y.tab.c" + break; + + case 18: +#line 55 "lburg/gram.y" + { (yyval.tree) = tree((yyvsp[-3].string), (yyvsp[-1].tree), 0); } +#line 1385 "y.tab.c" + break; + + case 19: +#line 56 "lburg/gram.y" + { (yyval.tree) = tree((yyvsp[-5].string), (yyvsp[-3].tree), (yyvsp[-1].tree)); } +#line 1391 "y.tab.c" + break; + + case 20: +#line 59 "lburg/gram.y" + { if (*(yyvsp[0].string) == 0) (yyval.string) = "0"; } +#line 1397 "y.tab.c" + break; + + +#line 1401 "y.tab.c" + + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[+*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; +} +#line 61 "lburg/gram.y" + #include #include #include @@ -265,6 +1640,8 @@ yygrow () int errcnt = 0; FILE *infp = NULL; FILE *outfp = NULL; +const char *infname = 0; +const char *outfname = 0; static char buf[BUFSIZ], *bp = buf; static int ppercent = 0; static int code = 0; @@ -276,7 +1653,15 @@ static int get(void) { if (fgets(buf, sizeof buf, infp) == NULL) return EOF; yylineno++; + while (buf[0] == '#') { + if (fgets(buf, sizeof buf, infp) == NULL) + return EOF; + yylineno++; + } while (buf[0] == '%' && buf[1] == '{' && buf[2] == '\n') { + linesum -= yylineno; + if (infname) + fprintf(outfp, "#line %d \"%s\"\n", yylineno+1, infname); for (;;) { if (fgets(buf, sizeof buf, infp) == NULL) { yywarn("unterminated %{...%}\n"); @@ -290,6 +1675,14 @@ static int get(void) { if (fgets(buf, sizeof buf, infp) == NULL) return EOF; yylineno++; + linesum += yylineno; + if (outfname) + fprintf(outfp, "#line %d \"%s\"\n", linesum, outfname); + } + while (buf[0] == '#') { + if (fgets(buf, sizeof buf, infp) == NULL) + return EOF; + yylineno++; } } return *bp++; @@ -399,283 +1792,3 @@ void yywarn(char *fmt, ...) { fprintf(stderr, "warning: "); vfprintf(stderr, fmt, ap); } -#line 403 "y.tab.c" -#define YYABORT goto yyabort -#define YYACCEPT goto yyaccept -#define YYERROR goto yyerrlab - -#if YYDEBUG -#ifdef __cplusplus -extern "C" char *getenv(); -#else -extern char *getenv(); -#endif -#endif - -int -yyparse() -{ - register int yym, yyn, yystate; - register YYSTYPE *yyvsp; - register short *yyssp; - short *yysse; -#if YYDEBUG - register YYCONST char *yys; - - if (yys = getenv("YYDEBUG")) - { - yyn = *yys; - if (yyn >= '0' && yyn <= '9') - yydebug = yyn - '0'; - } -#endif - - yynerrs = 0; - yyerrflag = 0; - yychar = (-1); - - if (yyss == 0) - { - yyss = (short *) yymalloc (YYSTACKSIZE * sizeof (short)); - if (yyss == 0) - goto yyabort; - yyvs = (YYSTYPE *) yymalloc (YYSTACKSIZE * sizeof (YYSTYPE)); - if (yyvs == 0) - { - yyfree (yyss); - goto yyabort; - } - yystacksize = YYSTACKSIZE; - } - yysse = yyss + yystacksize - 1; - yyssp = yyss; - yyvsp = yyvs; - *yyssp = yystate = 0; - goto yyloop; - -yypush_lex: - yyval = yylval; - yystate = yytable[yyn]; -yypush: - if (yyssp >= yysse) - { - int depth = yyssp - yyss; - if (yygrow() != 0) - goto yyoverflow; - yysse = yyss + yystacksize -1; - yyssp = depth + yyss; - yyvsp = depth + yyvs; - } - *++yyssp = yystate; - *++yyvsp = yyval; - -yyloop: - if (yyn = yydefred[yystate]) goto yyreduce; - yyn = yysindex[yystate]; - if (yychar < 0) - { - if ((yychar = yylex()) < 0) yychar = 0; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("yydebug: state %d, reading %d (%s)\n", yystate, - yychar, yys); - } -#endif - } - if (yyn != 0 - && ((yyn += yychar), ((unsigned)yyn <= (unsigned)YYTABLESIZE)) - && yycheck[yyn] == yychar) - { -#if YYDEBUG - if (yydebug) - printf("yydebug: state %d, shifting to state %d\n", - yystate, yytable[yyn]); -#endif - if (yyerrflag > 0) --yyerrflag; - yychar = (-1); - goto yypush_lex; - } - yyn = yyrindex[yystate]; - if (yyn != 0 - && ((yyn += yychar), ((unsigned)yyn <= (unsigned)YYTABLESIZE)) - && yycheck[yyn] == yychar) - { - yyn = yytable[yyn]; - goto yyreduce; - } - if (yyerrflag) goto yyinrecovery; -#ifdef lint - goto yynewerror; -#endif -yynewerror: - yyerror("syntax error"); -#ifdef lint - goto yyerrlab; -#endif -yyerrlab: - ++yynerrs; -yyinrecovery: - if (yyerrflag < 3) - { - yyerrflag = 3; - for (;;) - { - yyn = yysindex[*yyssp]; - if (yyn != 0 - && ((yyn += YYERRCODE), ((unsigned)yyn <= (unsigned)YYTABLESIZE)) - && yycheck[yyn] == YYERRCODE) - { -#if YYDEBUG - if (yydebug) - printf("yydebug: state %d, error recovery shifting\ - to state %d\n", *yyssp, yytable[yyn]); -#endif - goto yypush_lex; - } - else - { -#if YYDEBUG - if (yydebug) - printf("yydebug: error recovery discarding state %d\n", - *yyssp); -#endif - if (yyssp <= yyss) goto yyabort; - --yyssp; - --yyvsp; - } - } - } - else - { - if (yychar == 0) goto yyabort; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("yydebug: state %d, error recovery discards token %d (%s)\n", - yystate, yychar, yys); - } -#endif - yychar = (-1); - goto yyloop; - } -yyreduce: -#if YYDEBUG - if (yydebug) - printf("yydebug: state %d, reducing by rule %d (%s)\n", - yystate, yyn, yyrule[yyn]); -#endif - yym = yylen[yyn]; - yyval = yyvsp[1-yym]; - switch (yyn) - { -case 1: -#line 22 "lburg/gram.y" -{ yylineno = 0; } -break; -case 2: -#line 23 "lburg/gram.y" -{ yylineno = 0; } -break; -case 6: -#line 31 "lburg/gram.y" -{ - if (nonterm(yyvsp[-1].string)->number != 1) - yyerror("redeclaration of the start symbol\n"); - } -break; -case 8: -#line 36 "lburg/gram.y" -{ yyerrok; } -break; -case 10: -#line 40 "lburg/gram.y" -{ term(yyvsp[-2].string, yyvsp[0].n); } -break; -case 12: -#line 44 "lburg/gram.y" -{ rule(yyvsp[-5].string, yyvsp[-3].tree, yyvsp[-2].string, yyvsp[-1].string); } -break; -case 14: -#line 46 "lburg/gram.y" -{ yyerrok; } -break; -case 15: -#line 49 "lburg/gram.y" -{ nonterm(yyval.string = yyvsp[0].string); } -break; -case 16: -#line 52 "lburg/gram.y" -{ yyval.tree = tree(yyvsp[0].string, 0, 0); } -break; -case 17: -#line 53 "lburg/gram.y" -{ yyval.tree = tree(yyvsp[-3].string, yyvsp[-1].tree, 0); } -break; -case 18: -#line 54 "lburg/gram.y" -{ yyval.tree = tree(yyvsp[-5].string, yyvsp[-3].tree, yyvsp[-1].tree); } -break; -case 19: -#line 57 "lburg/gram.y" -{ if (*yyvsp[0].string == 0) yyval.string = "0"; } -break; -#line 630 "y.tab.c" - } - yyssp -= yym; - yyvsp -= yym; - yym = yylhs[yyn]; - yystate = *yyssp; - if (yystate == 0 && yym == 0) - { -#if YYDEBUG - if (yydebug) - printf("yydebug: after reduction, shifting from state 0 to\ - state %d\n", YYFINAL); -#endif - yystate = YYFINAL; - *++yyssp = YYFINAL; - *++yyvsp = yyval; - if (yychar < 0) - { - if ((yychar = yylex()) < 0) yychar = 0; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("yydebug: state %d, reading %d (%s)\n", - YYFINAL, yychar, yys); - } -#endif - } - if (yychar == 0) goto yyaccept; - goto yyloop; - } - yyn = yygindex[yym]; - if (yyn != 0 - && ((yyn += yystate), ((unsigned)yyn <= (unsigned)YYTABLESIZE)) - && yycheck[yyn] == yystate) - yystate = yytable[yyn]; - else - yystate = yydgoto[yym]; -#if YYDEBUG - if (yydebug) - printf("yydebug: after reduction, shifting from state %d \ -to state %d\n", *yyssp, yystate); -#endif - goto yypush; -yyoverflow: - yyerror("yacc stack overflow"); -yyabort: - return (1); -yyaccept: - return (0); -} diff --git a/lburg/gram.y b/lburg/gram.y index 84d3ef31..8a638456 100755 --- a/lburg/gram.y +++ b/lburg/gram.y @@ -3,7 +3,9 @@ #include "lburg.h" static char rcsid[] = "$Id$"; /*lint -e616 -e527 -e652 -esym(552,yynerrs) -esym(563,yynewstate,yyerrlab) */ -static int yylineno = 0; +int yylineno = 0; +int linesum = 1; +extern int yylex(void); %} %union { int n; @@ -19,8 +21,8 @@ static int yylineno = 0; %type nonterm cost %type tree %% -spec : decls PPERCENT rules { yylineno = 0; } - | decls { yylineno = 0; } +spec : decls PPERCENT rules + | decls ; decls : /* lambda */ @@ -66,6 +68,8 @@ cost : CODE { if (*$1 == 0) $$ = "0"; } int errcnt = 0; FILE *infp = NULL; FILE *outfp = NULL; +const char *infname = 0; +const char *outfname = 0; static char buf[BUFSIZ], *bp = buf; static int ppercent = 0; static int code = 0; @@ -77,7 +81,15 @@ static int get(void) { if (fgets(buf, sizeof buf, infp) == NULL) return EOF; yylineno++; + while (buf[0] == '#') { + if (fgets(buf, sizeof buf, infp) == NULL) + return EOF; + yylineno++; + } while (buf[0] == '%' && buf[1] == '{' && buf[2] == '\n') { + linesum -= yylineno; + if (infname) + fprintf(outfp, "#line %d \"%s\"\n", yylineno+1, infname); for (;;) { if (fgets(buf, sizeof buf, infp) == NULL) { yywarn("unterminated %{...%}\n"); @@ -91,6 +103,14 @@ static int get(void) { if (fgets(buf, sizeof buf, infp) == NULL) return EOF; yylineno++; + linesum += yylineno; + if (outfname) + fprintf(outfp, "#line %d \"%s\"\n", linesum, outfname); + } + while (buf[0] == '#') { + if (fgets(buf, sizeof buf, infp) == NULL) + return EOF; + yylineno++; } } return *bp++; diff --git a/lburg/lburg.c b/lburg/lburg.c index 55995ff1..b486ce65 100755 --- a/lburg/lburg.c +++ b/lburg/lburg.c @@ -53,14 +53,18 @@ int main(int argc, char *argv[]) { argv[0]); exit(1); } else if (infp == NULL) { - if (strcmp(argv[i], "-") == 0) + infname = argv[i]; + if (strcmp(argv[i], "-") == 0) { + infname = 0; infp = stdin; - else if ((infp = fopen(argv[i], "r")) == NULL) { + } else if ((infp = fopen(argv[i], "r")) == NULL) { yyerror("%s: can't read `%s'\n", argv[0], argv[i]); exit(1); } } else if (outfp == NULL) { + outfname = argv[i]; if (strcmp(argv[i], "-") == 0) + outfname = 0; outfp = stdout; if ((outfp = fopen(argv[i], "w")) == NULL) { yyerror("%s: can't write `%s'\n", argv[0], argv[i]); @@ -90,6 +94,8 @@ int main(int argc, char *argv[]) { if (start) emitlabel(terms, start, ntnumber); emitkids(rules, nrules); + if (infname) + fprintf(outfp,"#line %d \"%s\"\n", yylineno+1, infname); if (!feof(infp)) while ((c = getc(infp)) != EOF) putc(c, outfp); @@ -576,12 +582,16 @@ static void emitrecalc(char *pre, Term root, Term kid) { Nonterm p; print("%sif (mayrecalc(a)) {\n", pre); print("%s%1struct %Pstate *q = a->syms[RX]->u.t.cse->x.state;\n", pre); +#ifndef ORIGINAL_LBURG_RECALC + print("%s%1*p = *q;\n", pre); +#else for (p = nts; p; p = p->link) { print("%s%1if (q->cost[%P%S_NT] == 0) {\n", pre, p); print("%s%2p->cost[%P%S_NT] = 0;\n", pre, p); print("%s%2p->rule.%P%S = q->rule.%P%S;\n", pre, p, p); print("%s%1}\n", pre); } +#endif print("%s}\n", pre); } } @@ -672,3 +682,4 @@ static void emittest(Tree t, char *v, char *suffix) { emittest(t->right, stringf("RIGHT_CHILD(%s)", v), suffix); } } + diff --git a/lburg/lburg.h b/lburg/lburg.h index c78507a2..a84c53fe 100755 --- a/lburg/lburg.h +++ b/lburg/lburg.h @@ -59,8 +59,10 @@ extern Rule rule(char *id, Tree pattern, char *template, char *code); void yyerror(char *fmt, ...); int yyparse(void); void yywarn(char *fmt, ...); +extern int yylineno; extern int errcnt; extern FILE *infp; extern FILE *outfp; - +extern const char *infname; +extern const char *outfname; #endif diff --git a/src/alloc.c b/src/alloc.c index e0566dfd..b588788d 100755 --- a/src/alloc.c +++ b/src/alloc.c @@ -9,6 +9,7 @@ union align { char *p; double d; int (*f)(void); + long double ld; }; union header { struct block b; diff --git a/src/alpha.md b/src/alpha.md index df5b326c..dcc0cc2a 100755 --- a/src/alpha.md +++ b/src/alpha.md @@ -1147,6 +1147,7 @@ Interface alphaIR = { 1, /* left_to_right */ 0, /* wants_dag */ 0, /* unsigned_char */ + 0, /* wants_cvfu_cvuf */ address, blockbeg, blockend, @@ -1179,6 +1180,7 @@ Interface alphaIR = { _isinstruction, _ntname, emit2, + emitfmt, doarg, target, clobber, diff --git a/src/bytecode.c b/src/bytecode.c index d5ddc27f..9a413c73 100755 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -254,6 +254,7 @@ Interface bytecodeIR = { 1, /* left_to_right */ 0, /* wants_dag */ 0, /* unsigned_char */ + 0, /* wants_cvfu_cvuf */ I(address), I(blockbeg), I(blockend), diff --git a/src/c.h b/src/c.h index 207aaf53..77377b5e 100755 --- a/src/c.h +++ b/src/c.h @@ -121,6 +121,7 @@ typedef struct interface { unsigned left_to_right:1; unsigned wants_dag:1; unsigned unsigned_char:1; + unsigned wants_cvfu_cvuf: 1; void (*address)(Symbol p, Symbol q, long n); void (*blockbeg)(Env *); void (*blockend)(Env *); diff --git a/src/config.h b/src/config.h index b1b6784c..120f6ee5 100755 --- a/src/config.h +++ b/src/config.h @@ -17,13 +17,16 @@ typedef struct { char *_isinstruction; char **_ntname; void (*emit2)(Node); + void (*emitfmt)(const char*, Node, Node*, short*); void (*doarg)(Node); void (*target)(Node); void (*clobber)(Node); + void (*preralloc)(Node); } Xinterface; extern int askregvar(Symbol, Symbol); extern void blkcopy(int, int, int, int, int, int[]); extern unsigned emitasm(Node, int); +extern void emitfmt(const char*, Node, Node*, short*); extern int getregnum(Node); extern int mayrecalc(Node); extern int mkactual(int, int); @@ -58,7 +61,8 @@ typedef struct { unsigned mayrecalc:1; void *state; short inst; - Node kids[3]; + short nt; + Node kids[16]; Node prev, next; Node prevuse; short argno; diff --git a/src/dag.c b/src/dag.c index d8f2d965..a6c7cf54 100755 --- a/src/dag.c +++ b/src/dag.c @@ -433,7 +433,9 @@ void gencode(Symbol caller[], Symbol callee[]) { codelist = codehead.next; for (i = 0; (p = callee[i]) != NULL && (q = caller[i]) != NULL; i++) - if (p->sclass != q->sclass || p->type != q->type) + if ((p->sclass != q->sclass) || + (p->sclass == REGISTER && p->x.regnode && q->x.regnode && p->x.regnode != q->x.regnode) || + (p->type != q->type) && !(isint(p->type) && IR->little_endian) ) walk(asgn(p, idtree(q)), 0, 0); codelist->next = cp; cp->prev = codelist; @@ -556,7 +558,8 @@ static Node undag(Node forest) { visit(p, 1); if (p->syms[2]) { assert(p->syms[2]->u.t.cse); - p->syms[2]->u.t.cse = NULL; + //p->syms[2]->u.t.cse = NULL; + p->syms[2]->u.t.replace = -1; addlocal(p->syms[2]); } } else if (iscall(p->op) && p->count >= 1) @@ -574,7 +577,7 @@ static Node replace(Node p) { if (p && ( generic(p->op) == INDIR && generic(p->kids[0]->op) == ADDRL && p->kids[0]->syms[0]->temporary - && p->kids[0]->syms[0]->u.t.replace)) { + && p->kids[0]->syms[0]->u.t.replace > 0)) { p = p->kids[0]->syms[0]->u.t.cse; if (generic(p->op) == INDIR && isaddrop(p->kids[0]->op)) p = newnode(p->op, newnode(p->kids[0]->op, NULL, NULL, @@ -613,9 +616,11 @@ static Node prune(Node forest) { || (( generic(p->kids[1]->op) == INDIR && isaddrop(p->kids[1]->kids[0]->op)) && tmp->sclass == AUTO) || (generic(p->kids[1]->op) == ADDRG && tmp->sclass == AUTO)) { - tmp->u.t.replace = 1; - count++; - continue; /* and omit the assignment */ + if (tmp->u.t.replace >= 0) { + tmp->u.t.replace = 1; + count++; + continue; /* and omit the assignment */ + } } } /* keep the assignment and other roots */ diff --git a/src/enode.c b/src/enode.c index 2eb451a6..089b6e10 100755 --- a/src/enode.c +++ b/src/enode.c @@ -379,8 +379,12 @@ Tree condtree(Tree e, Tree l, Tree r) { case CNST+F: return cast(e->u.v.d != 0.0 ? l : r, ty); } if (ty != voidtype && ty->size > 0) { - t1 = genident(REGISTER, unqual(ty), level); - /* t1 = temporary(REGISTER, unqual(ty)); */ + if (r && r->op == COND && r->u.sym) + t1 = r->u.sym; + else if (l && l->op == COND && l->u.sym) + t1 = l->u.sym; + else + t1 = genident(REGISTER, unqual(ty), level); l = asgn(t1, l); r = asgn(t1, r); } else @@ -512,10 +516,11 @@ static Tree subtree(int op, Tree l, Tree r) { n = unqual(ty->type)->size; if (n == 0) error("unknown size for type `%t'\n", ty->type); - l = simplify(SUB+U, unsignedptr, - cast(l, unsignedptr), cast(r, unsignedptr)); - return simplify(DIV+I, longtype, - cast(l, longtype), cnsttree(longtype, n)); + l = simplify(SUB+I, signedptr, + cast(l, signedptr), cast(r, signedptr)); + if (n == 1) + return l; + return simplify(DIV+I, signedptr, l, cnsttree(signedptr, n)); } else typeerror(op, l, r); return simplify(op, ty, l, r); diff --git a/src/expr.c b/src/expr.c index 36739fc6..bb083309 100755 --- a/src/expr.c +++ b/src/expr.c @@ -363,7 +363,9 @@ static Tree primary(void) { p->type = func(inttype, NULL, 1); p->sclass = EXTERN; if (Aflag >= 1) - warning("missing prototype\n"); + warning("missing prototype for `%s'\n", q->name); + else + warning("implicit declaration of `%s'\n", q->name); if (q && !eqtype(q->type, p->type, 1)) warning("implicit declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src); @@ -492,23 +494,38 @@ int hascall(Tree p) { return hascall(p->kids[0]) || hascall(p->kids[1]); } Type binary(Type xty, Type yty) { -#define xx(t) if (xty == t || yty == t) return t + /* Implementing rules from + https://en.cppreference.com/w/c/language/conversion + using sizes instead of rank (imperfect but better than before). */ +#define xy(t,r) if (xty == t || yty == t) return r +#define xx(t) xy(t,t) xx(longdouble); xx(doubletype); xx(floattype); - xx(unsignedlonglong); - xx(longlong); - xx(unsignedlong); - if (xty == longtype && yty == unsignedtype - || xty == unsignedtype && yty == longtype) - if (longtype->size > unsignedtype->size) - return longtype; - else - return unsignedlong; - xx(longtype); - xx(unsignedtype); - return inttype; + xty = promote(xty); + yty = promote(yty); + if (xty == yty) + return xty; + if (xty->size > yty->size) + return xty; + if (yty->size > xty->size) + return yty; + if (xty->op == yty->op) { + xx(unsignedlonglong); + xx(longlong); + xx(unsignedlong); + xx(longtype); + xx(unsignedtype); + return inttype; + } else { + xy(unsignedlonglong, unsignedlonglong); + xy(longlong, unsignedlonglong); + xy(unsignedlong, unsignedlong); + xy(longtype, unsignedlong); + return unsignedtype; + } #undef xx +#undef xy } Tree pointer(Tree p) { if (isarray(p->type)) @@ -569,7 +586,7 @@ Tree cast(Tree p, Type type) { p = simplify(CVI, dst, p, NULL); break; case UNSIGNED: - if (isfloat(dst)) { + if (isfloat(dst) && !IR->wants_cvfu_cvuf) { Type ssrc = signedint(src); Tree two = cnsttree(longdouble, (long double)2.0); p = (*optree['+'])(ADD, @@ -585,7 +602,7 @@ Tree cast(Tree p, Type type) { p = simplify(CVU, dst, p, NULL); break; case FLOAT: - if (isunsigned(dst)) { + if (isunsigned(dst) && !IR->wants_cvfu_cvuf) { Type sdst = signedint(dst); Tree c = cast(cnsttree(longdouble, (long double)sdst->u.sym->u.limits.max.i + 1), src); p = condtree( diff --git a/src/gen.c b/src/gen.c index cff0bd70..301a4e37 100755 --- a/src/gen.c +++ b/src/gen.c @@ -24,7 +24,7 @@ static Symbol getreg(Symbol, unsigned*, Node); static int getrule(Node, int); static void linearize(Node, Node); static int moveself(Node); -static void prelabel(Node); +static void prelabel(Node, Node*); static Node* prune(Node, Node*); static void putreg(Symbol); static void ralloc(Node); @@ -32,7 +32,7 @@ static void reduce(Node, int); static int reprune(Node*, int, int, Node); static int requate(Node); static Node reuse(Node, int); -static void rewrite(Node); +static void rewrite(Node, int); static Symbol spillee(Symbol, unsigned mask[], Node); static void spillr(Symbol, Node); static int uses(Node, Regnode); @@ -46,6 +46,8 @@ int argoffset; int maxargoffset; +int spilling; + int dalign, salign; int bflag = 0; /* omit */ int dflag = 0; @@ -191,6 +193,8 @@ static void reduce(Node p, int nt) { rulenum = getrule(p, nt); nts = IR->x._nts[rulenum]; (*IR->x._kids)(p, rulenum, kids); + if (! p->x.nt) + p->x.nt = nt; for (i = 0; nts[i]; i++) reduce(kids[i], nts[i]); if (IR->x._isinstruction[rulenum]) { @@ -210,7 +214,7 @@ static Node reuse(Node p, int nt) { if (generic(p->op) == INDIR && p->kids[0]->op == VREG+P && r->u.t.cse && p->x.mayrecalc - && ((struct _state*)r->u.t.cse->x.state)->cost[nt] == 0) + && ((struct _state*)r->u.t.cse->x.state)->cost[nt] <= ((struct _state*)p->x.state)->cost[nt] ) return r->u.t.cse; else return p; @@ -230,9 +234,11 @@ int mayrecalc(Node p) { return 0; } static Node *prune(Node p, Node pp[]) { + int i; if (p == NULL) return pp; - p->x.kids[0] = p->x.kids[1] = p->x.kids[2] = NULL; + for(i = 0; i < NELEMS(p->x.kids); i++) + p->x.kids[i] = NULL; if (p->x.inst == 0) return prune(p->kids[1], prune(p->kids[0], pp)); else if (p->syms[RX] && p->syms[RX]->temporary @@ -266,11 +272,6 @@ static void dumptree(Node p) { if (p->op == VREG+P && p->syms[0]) { fprint(stderr, "VREGP(%s)", p->syms[0]->name); return; - } else if (generic(p->op) == LOAD) { - fprint(stderr, "LOAD("); - dumptree(p->kids[0]); - fprint(stderr, ")"); - return; } fprint(stderr, "%s(", opname(p->op)); switch (generic(p->op)) { @@ -284,7 +285,7 @@ static void dumptree(Node p) { dumptree(p->kids[0]); break; case CVF: case CVI: case CVP: case CVU: case JUMP: - case ARG: case BCOM: case NEG: case INDIR: + case ARG: case BCOM: case NEG: case INDIR: case LOAD: dumptree(p->kids[0]); break; case CALL: @@ -328,7 +329,27 @@ static void dumprule(int rulenum) { if (!IR->x._isinstruction[rulenum]) fprint(stderr, "\n"); } -unsigned emitasm(Node p, int nt) { + +void emitfmt(const char *fmt, Node p, Node *kids, short *nts) +{ + /* Enhancements of emitasm with respect to the original + version: emitasm() now retrieves the template and calls the + IR function emitfmt() which parses the template and prints + the output. This is the default version. */ + for (; *fmt; fmt++) + if (*fmt != '%') + (void)putchar(*fmt); + else if (*++fmt == 'F') /* %F */ + print("%d", framesize); + else if (*fmt >= 'a' && *fmt < 'a' + NELEMS(p->syms)) /* %a..%c */ + fputs(p->syms[*fmt - 'a']->x.name, stdout); + else if (*fmt >= '0' && *fmt <= '9') /* %0..%9 */ + emitasm(kids[*fmt - '0'], nts[*fmt - '0']); + else + (void)putchar(*fmt); +} +unsigned emitasm(Node p, int nt) +{ int rulenum; short *nts; char *fmt; @@ -351,17 +372,8 @@ unsigned emitasm(Node p, int nt) { while (*fmt++ != '\n') ; } - for ((*IR->x._kids)(p, rulenum, kids); *fmt; fmt++) - if (*fmt != '%') - (void)putchar(*fmt); - else if (*++fmt == 'F') - print("%d", framesize); - else if (*fmt >= '0' && *fmt <= '9') - emitasm(kids[*fmt - '0'], nts[*fmt - '0']); - else if (*fmt >= 'a' && *fmt < 'a' + NELEMS(p->syms)) - fputs(p->syms[*fmt - 'a']->x.name, stdout); - else - (void)putchar(*fmt); + (*IR->x._kids)(p, rulenum, kids); + (*IR->x.emitfmt)(fmt, p, kids, nts); } return 0; } @@ -377,6 +389,7 @@ void emit(Node p) { } static int moveself(Node p) { return p->x.copy + && p->x.kids[0] && p->x.kids[0]->syms[RX] && p->syms[RX]->x.name == p->x.kids[0]->syms[RX]->x.name; } int move(Node p) { @@ -418,11 +431,11 @@ static int requate(Node q) { } return 1; } -static void prelabel(Node p) { +static void prelabel(Node p, Node* pp) { if (p == NULL) return; - prelabel(p->kids[0]); - prelabel(p->kids[1]); + prelabel(p->kids[0], &(p->kids[0])); + prelabel(p->kids[1], &(p->kids[1])); if (NeedsReg[opindex(p->op)]) setreg(p, (*IR->x.rmap)(opkind(p->op))); switch (generic(p->op)) { @@ -439,9 +452,14 @@ static void prelabel(Node p) { rtarget(p, 1, p->kids[0]->syms[0]); break; case CVI: case CVU: case CVP: - if (optype(p->op) != F - && opsize(p->op) <= p->syms[0]->u.c.v.i) - p->op = LOAD + opkind(p->op); + if (optype(p->op) != F) { + int ts = opsize(p->op); + int fs = p->syms[0]->u.c.v.i; + if (pp && ts == fs) + *pp = p->kids[0]; + else if (ts <= fs) + p->op = LOAD + opkind(p->op); + } break; } (IR->x.target)(p); @@ -467,20 +485,21 @@ void rtarget(Node p, int n, Symbol r) { setreg(q, r); debug(fprint(stderr, "(targeting %x->x.kids[%d]=%x to %s)\n", p, n, p->kids[n], r->x.name)); } -static void rewrite(Node p) { +static void rewrite(Node p, int nt) { assert(p->x.inst == 0); - prelabel(p); + prelabel(p, 0); debug(dumptree(p)); debug(fprint(stderr, "\n")); (*IR->x._label)(p); - debug(dumpcover(p, 1, 0)); - reduce(p, 1); + debug(dumpcover(p, nt, 0)); + reduce(p, nt); } Node gen(Node forest) { int i; struct node sentinel; Node dummy, p; + spilling = 0; head = forest; for (p = forest; p; p = p->link) { assert(p->count == 0); @@ -491,7 +510,7 @@ Node gen(Node forest) { docall(p->kids[1]); else if (generic(p->op) == ARG) (*IR->x.doarg)(p); - rewrite(p); + rewrite(p, 1); p->x.listed = 1; } for (p = forest; p; p = p->link) @@ -600,9 +619,11 @@ static void linearize(Node p, Node next) { for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) linearize(p->x.kids[i], next); - relink(next->x.prev, p); - relink(p, next); - debug(fprint(stderr, "(listing %x)\n", p)); + if (p->x.inst) { + relink(next->x.prev, p); + relink(p, next); + debug(fprint(stderr, "(listing %x)\n", p)); + } } static void ralloc(Node p) { int i; @@ -619,8 +640,13 @@ static void ralloc(Node p) { if (r->sclass != REGISTER && r->x.lastuse == kid) putreg(r); } + if (!p->x.registered && (IR->x.preralloc) + && NeedsReg[opindex(p->op)] + && (*IR->x.rmap)(opkind(p->op)) ) { + IR->x.preralloc(p); + } if (!p->x.registered && NeedsReg[opindex(p->op)] - && (*IR->x.rmap)(opkind(p->op))) { + && (*IR->x.rmap)(opkind(p->op)) ) { Symbol sym = p->syms[RX], set = sym; assert(sym); if (sym->temporary) @@ -714,6 +740,7 @@ static void spillr(Symbol r, Node here) { p = p->x.prevuse; assert(p->x.registered && !readsreg(p)); tmp = newtemp(AUTO, optype(p->op), opsize(p->op)); + spilling = 1; genspill(r, p, tmp); for (p = here->x.next; p; p = p->x.next) for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) { @@ -721,6 +748,7 @@ static void spillr(Symbol r, Node here) { if (k->x.registered && k->syms[RX] == r) genreload(p, tmp, i); } + spilling = 0; putreg(r); } static void genspill(Symbol r, Node last, Symbol tmp) { @@ -742,7 +770,7 @@ static void genspill(Symbol r, Node last, Symbol tmp) { p = newnode(ADDRL+P + sizeop(IR->ptrmetric.size), NULL, NULL, tmp); p = newnode(ASGN + ty, p, q, NULL); p->x.spills = 1; - rewrite(p); + rewrite(p, 1); prune(p, &q); q = last->x.next; linearize(p, q); @@ -754,20 +782,21 @@ static void genspill(Symbol r, Node last, Symbol tmp) { static void genreload(Node p, Symbol tmp, int i) { Node q; - int ty; + int ty, ntk; debug(fprint(stderr, "(replacing %x with a reload from %s)\n", p->x.kids[i], tmp->x.name)); debug(fprint(stderr, "(genreload: ")); debug(dumptree(p->x.kids[i])); debug(fprint(stderr, ")\n")); ty = opkind(p->x.kids[i]->op); + ntk = p->x.kids[i]->x.nt; q = newnode(ADDRL+P + sizeop(IR->ptrmetric.size), NULL, NULL, tmp); p->x.kids[i] = newnode(INDIR + ty, q, NULL, NULL); - rewrite(p->x.kids[i]); + rewrite(p->x.kids[i], ntk); prune(p->x.kids[i], &q); reprune(&p->kids[1], reprune(&p->kids[0], 0, i, p), i, p); - prune(p, &q); linearize(p->x.kids[i], p); + prune(p, &q); } static int reprune(Node *pp, int k, int n, Node p) { struct node x, *q = *pp; diff --git a/src/lex.c b/src/lex.c index af8a78fe..8a604d37 100755 --- a/src/lex.c +++ b/src/lex.c @@ -188,7 +188,27 @@ int gettok(void) { cp = rcp; continue; } - return '/'; + if (*rcp == '/') { + /* c++ style comments */ + rcp++; + for(;;) { + if (map[*rcp] & NEWLINE) { + /* new line -or- end of buffer. */ + if (rcp < limit) break; + cp = rcp + 1; + nextline(); + rcp = cp; + if (rcp == limit) break; + } + else { + rcp++; + } + } + if (rcp < limit) rcp++; + cp = rcp; + continue; + } + return '/'; case '<': if (*rcp == '=') return cp++, LEQ; if (*rcp == '<') return cp++, LSHIFT; diff --git a/src/main.c b/src/main.c index 6ed68208..9d6ca983 100755 --- a/src/main.c +++ b/src/main.c @@ -100,6 +100,8 @@ int main(int argc, char *argv[]) { finalize(); (*IR->progend)(); deallocate(PERM); + if (errcnt > 0) + error("%d error(s)\n", errcnt); return errcnt > 0; } /* main_init - process program arguments */ diff --git a/src/mips.md b/src/mips.md index 4c86923c..2e1b84b5 100755 --- a/src/mips.md +++ b/src/mips.md @@ -1024,6 +1024,7 @@ Interface mipsebIR = { 1, /* left_to_right */ 0, /* wants_dag */ 0, /* unsigned_char */ + 0, /* wants_cvfu_cvuf */ address, blockbeg, blockend, @@ -1056,6 +1057,7 @@ Interface mipsebIR = { _isinstruction, _ntname, emit2, + emitfmt, doarg, target, clobber, @@ -1079,6 +1081,7 @@ Interface mipsebIR = { 1, /* left_to_right */ 0, /* wants_dag */ 0, /* unsigned_char */ + 0, /* wants_cvfu_cvuf */ address, blockbeg, blockend, @@ -1111,6 +1114,7 @@ Interface mipsebIR = { _isinstruction, _ntname, emit2, + emitfmt, doarg, target, clobber, diff --git a/src/null.c b/src/null.c index 2519d053..78ecb77b 100755 --- a/src/null.c +++ b/src/null.c @@ -47,6 +47,7 @@ Interface nullIR = { 1, /* left_to_right */ 0, /* wants_dag */ 0, /* unsigned_char */ + 0, /* wants_cvfu_cvuf */ I(address), I(blockbeg), I(blockend), diff --git a/src/simp.c b/src/simp.c index f95591fb..da6d6690 100755 --- a/src/simp.c +++ b/src/simp.c @@ -20,7 +20,7 @@ static char rcsid[] = "$Id$"; if (!explicitCast\ && ((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\ warning("overflow in converting constant expression from `%t' to `%t'\n", l->type, DST);\ - if (needconst\ + if (explicitCast || needconst\ || !((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\ return cnsttree(ty, (EXPR)); } while(0) #define identity(X,Y,TYPE,VAR,VAL) \ @@ -254,6 +254,7 @@ Tree simplify(int op, Type ty, Tree l, Tree r) { xcvtcnst(U,l->u.v.u,ty,d,(long double)l->u.v.u); break; case CVF+I: + case CVF+U: xcvtcnst(F,l->u.v.d,ty,i,(long)l->u.v.d); break; case CVF+F: { diff --git a/src/sparc.md b/src/sparc.md index 94d042b0..a38de3b6 100755 --- a/src/sparc.md +++ b/src/sparc.md @@ -1079,6 +1079,7 @@ Interface sparcIR = { 1, /* left_to_right */ 0, /* wants_dag */ 0, /* unsigned_char */ + 0, /* wants_cvfu_cvuf */ address, blockbeg, blockend, @@ -1111,6 +1112,7 @@ Interface sparcIR = { _isinstruction, _ntname, emit2, + emitfmt, doarg, target, clobber, @@ -1136,6 +1138,7 @@ Interface solarisIR = { 1, /* left_to_right */ 0, /* wants_dag */ 0, /* unsigned_char */ + 0, /* wants_cvfu_cvuf */ address, blockbeg, blockend, @@ -1168,6 +1171,7 @@ Interface solarisIR = { _isinstruction, _ntname, emit2, + emitfmt, doarg, target, clobber, diff --git a/src/symbolic.c b/src/symbolic.c index 9e34422d..555bd487 100755 --- a/src/symbolic.c +++ b/src/symbolic.c @@ -452,6 +452,7 @@ Interface symbolicIR = { 1, /* left_to_right */ 1, /* wants_dag */ 0, /* unsigned_char */ + 0, /* wants_cvfu_cvuf */ I(address), I(blockbeg), I(blockend), @@ -497,6 +498,7 @@ Interface symbolic64IR = { 1, /* left_to_right */ 1, /* wants_dag */ 0, /* unsigned_char */ + 0, /* wants_cvfu_cvuf */ I(address), I(blockbeg), I(blockend), diff --git a/src/tree.c b/src/tree.c index dca9f921..f76521f5 100755 --- a/src/tree.c +++ b/src/tree.c @@ -145,7 +145,7 @@ char *opname(int op) { "CVU", "NEG", "CALL", - "*LOAD*", + "LOAD", "RET", "ADDRG", "ADDRF", diff --git a/src/types.c b/src/types.c index 36b2c168..04943d88 100755 --- a/src/types.c +++ b/src/types.c @@ -362,17 +362,17 @@ Type promote(Type ty) { case ENUM: return inttype; case INT: - if (ty->size < inttype->size) + if (ty->size <= inttype->size) return inttype; break; case UNSIGNED: if (ty->size < inttype->size) return inttype; - if (ty->size < unsignedtype->size) + if (ty->size <= unsignedtype->size) return unsignedtype; break; case FLOAT: - if (ty->size < doubletype->size) + if (ty->size <= doubletype->size) return doubletype; } return ty; diff --git a/src/x86.md b/src/x86.md index 422a7438..125423cd 100755 --- a/src/x86.md +++ b/src/x86.md @@ -974,6 +974,7 @@ Interface x86IR = { 0, /* left_to_right */ 0, /* wants_dag */ 0, /* unsigned_char */ + 0, /* wants_cvfu_cvuf */ address, blockbeg, blockend, @@ -1004,6 +1005,7 @@ Interface x86IR = { _isinstruction, _ntname, emit2, + emitfmt, doarg, target, clobber, diff --git a/src/x86linux.md b/src/x86linux.md index 5546362f..a41d498a 100755 --- a/src/x86linux.md +++ b/src/x86linux.md @@ -1046,6 +1046,7 @@ Interface x86linuxIR = { 0, /* left_to_right */ 0, /* wants_dag */ 0, /* unsigned_char */ + 0, /* wants_cvfu_cvuf */ 0, /* address */ blockbeg, blockend, @@ -1076,6 +1077,7 @@ Interface x86linuxIR = { _isinstruction, _ntname, emit2, + emitfmt, 0, /* doarg */ target, clobber,