X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/1462fcee1ed295b24f47758b370068aa6304bb41..0e16927b48c881317a38132923b6f3150802a7d3:/src/parse-gram.y?ds=inline diff --git a/src/parse-gram.y b/src/parse-gram.y index b7f7ad65..eb034b08 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -1,6 +1,6 @@ %{/* Bison Grammar Parser -*- C -*- - Copyright (C) 2002-2010 Free Software Foundation, Inc. + Copyright (C) 2002-2012 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -32,6 +32,7 @@ #include "symlist.h" #include "scan-gram.h" #include "scan-code.h" +#include "xmemdup0.h" #define YYLLOC_DEFAULT(Current, Rhs, N) (Current) = lloc_default (Rhs, N) static YYLTYPE lloc_default (YYLTYPE const *, int); @@ -61,11 +62,30 @@ static void add_param (char const *type, char *decl, location loc); static symbol_class current_class = unknown_sym; static uniqstr current_type = NULL; -static symbol *current_lhs; +static symbol *current_lhs_symbol; static location current_lhs_location; static named_ref *current_lhs_named_ref; static int current_prec = 0; +/** Set the new current left-hand side symbol, possibly common + * to several right-hand side parts of rule. + */ +static +void +current_lhs(symbol *sym, location loc, named_ref *ref) +{ + current_lhs_symbol = sym; + current_lhs_location = loc; + /* In order to simplify memory management, named references for lhs + are always assigned by deep copy into the current symbol_list + node. This is because a single named-ref in the grammar may + result in several uses when the user factors lhs between several + rules using "|". Therefore free the parser's original copy. */ + free (current_lhs_named_ref); + current_lhs_named_ref = ref; +} + + #define YYTYPE_INT16 int_fast16_t #define YYTYPE_INT8 int_fast8_t #define YYTYPE_UINT16 uint_fast16_t @@ -78,6 +98,7 @@ static int current_prec = 0; %locations %pure-parser %error-verbose +%define parse.lac full %name-prefix="gram_" %expect 0 @@ -290,7 +311,7 @@ prologue_declaration: | "%skeleton" STRING { char const *skeleton_user = $2; - if (strchr (skeleton_user, '/')) + if (mbschr (skeleton_user, '/')) { size_t dir_length = strlen (current_file); char *skeleton_build; @@ -302,7 +323,7 @@ prologue_declaration: xmalloc (dir_length + 1 + strlen (skeleton_user) + 1); if (dir_length > 0) { - strncpy (skeleton_build, current_file, dir_length); + memcpy (skeleton_build, current_file, dir_length); skeleton_build[dir_length++] = '/'; } strcpy (skeleton_build + dir_length, skeleton_user); @@ -525,8 +546,11 @@ rules_or_grammar_declaration: ; rules: - id_colon named_ref.opt { current_lhs = $1; current_lhs_location = @1; - current_lhs_named_ref = $2; } rhses.1 + id_colon named_ref.opt { current_lhs ($1, @1, $2); } rhses.1 + { + /* Free the current lhs. */ + current_lhs (0, @1, 0); + } ; rhses.1: @@ -537,7 +561,7 @@ rhses.1: rhs: /* Nothing. */ - { grammar_current_rule_begin (current_lhs, current_lhs_location, + { grammar_current_rule_begin (current_lhs_symbol, current_lhs_location, current_lhs_named_ref); } | rhs symbol named_ref.opt { grammar_current_rule_symbol_append ($2, @2, $3); } @@ -663,7 +687,7 @@ lloc_default (YYLTYPE const *rhs, int n) loc.start = rhs[n].end; loc.end = rhs[n].end; - /* Ignore empty nonterminals the start of the the right-hand side. + /* Ignore empty nonterminals the start of the right-hand side. Do not bother to ignore them at the end of the right-hand side, since empty nonterminals have the same end as their predecessors. */ for (i = 1; i <= n; i++) @@ -710,17 +734,7 @@ add_param (char const *type, char *decl, location loc) complain_at (loc, _("missing identifier in parameter declaration")); else { - char *name; - size_t name_len; - - for (name_len = 1; - memchr (alphanum, name_start[name_len], sizeof alphanum); - name_len++) - continue; - - name = xmalloc (name_len + 1); - memcpy (name, name_start, name_len); - name[name_len] = '\0'; + char *name = xmemdup0 (name_start, strspn (name_start, alphanum)); muscle_pair_list_grow (type, decl, name); free (name); } @@ -735,8 +749,8 @@ version_check (location const *loc, char const *version) if (strverscmp (version, PACKAGE_VERSION) > 0) { complain_at (*loc, "require bison %s, but have %s", - version, PACKAGE_VERSION); - exit (63); + version, PACKAGE_VERSION); + exit (EX_MISMATCH); } }