Compare commits

..
50 Commits
Author SHA1 Message Date
Akim Demaille e1eeecd384 version 2.6.2
* NEWS: Record release date.
2012-08-03 09:43:02 +02:00
Akim Demaille 43ca804096 NEWS: update.
* NEWS: Catch up with the other changes from 2.6.1.
2012-08-02 13:51:52 +02:00
Akim Demaille dcd5344dcd yacc: remove trailing end of line at end of file
There are still spurious spaces at the end of some lines.  But this is
addressed in the master branch, and I am reluctant to try to backport
this.

* data/yacc.c, data/glr.c, data/lalr1.cc, data/glr.cc: here.
* tests/calc.at (AT_CHECK_SPACES): New.
Use it.
Be sure not to introduce trailing empty lines in the *.y files.
* NEWS: Doc it.
* cfg.mk (syntax-check): Remove the exception.
2012-08-02 13:51:52 +02:00
Akim Demaille 62a58c14bd thanks: fix a contributor name
* THANKS: On his request.
2012-08-02 08:29:18 +02:00
Akim Demaille e39eff37e2 gnulib: update 2012-08-01 15:02:25 +02:00
Akim Demaille 06f2ac78d7 tests: synch line -> syncline, for consistency
* tests/synclines.at: Do it, as "syncline" is used consistently
everywhere else in Bison.
2012-08-01 15:02:25 +02:00
Akim Demaille 1914a78115 tests: synclines: style changes
* tests/synclines.at (AT_TEST_SYNCLINE): Rename as...
(AT_TEST): this.
Use pushdef/popdef.
Formatting changes.
Use '+' instead of '*' where appropriate.
2012-08-01 15:02:25 +02:00
Akim Demaille d6e2a57964 tests: synclines: fix perl invocation
Reported by Summum Bonum.

* tests/synclines.at: Fix Perl invocation: its -f is not like sed's.
2012-08-01 15:02:21 +02:00
Akim Demaille a0c45dd5d2 regen 2012-08-01 09:16:56 +02:00
Akim Demaille c9d546b2a8 c++: trailing end-of-lines in %parse-param
* src/parse-gram.y (add_param): No only skip ' ' and '\t', skip all
leading and trailing spaces.
* tests/regression.at (Lex and parse params): Check it.
* NEWS: Document it.
2012-08-01 09:16:55 +02:00
Akim Demaille d61e59ea0e tests: simplify
* tests/regression.at: Remove useless compilations: AT_FULL_COMPILE
includes the compilation by bison.
2012-08-01 09:16:55 +02:00
Akim Demaille aaf63e45b6 use obstack_printf
This is not just nicer, it is also much safer, since we were
using sprintf...

* bootstrap.conf: Require it.
* src/system.h (obstack_fgrow1, obstack_fgrow2, obstack_fgrow3)
(obstack_fgrow4): Remove.
Adjust dependencies.
2012-07-31 10:50:06 +02:00
Akim Demaille dbfcf7a89f scanner: restore a missing start condition
$ flex src/scan-skel.l
src/scan-skel.l:145: multiple <<EOF>> rules for start condition SC_AT_DIRECTIVE_ARGS
src/scan-skel.l:145: multiple <<EOF>> rules for start condition SC_AT_DIRECTIVE_SKIP_WS
This is warning, and it seems there are no means to make it an error.

* src/scan-skel.l: Restore the start-condition INITIAL for an <<EOF>>
clause.
2012-07-30 14:54:27 +02:00
Akim Demaille 8c707b10e7 gnulib: update 2012-07-30 14:53:58 +02:00
Akim Demaille 9c26b8fc03 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2012-07-30 11:47:29 +02:00
Akim Demaille 77b214ef48 version 2.6.1
* NEWS: Record release date.
2012-07-30 11:18:23 +02:00
Akim Demaille d35d6dd2cd gnulib: update 2012-07-30 11:17:44 +02:00
Akim Demaille 466a2de317 maint: fix some syntax-check issues
* cfg.mk: Nuke the following warnings which are confused by our
text reports (that state that the error token is number 256).
  prohibit_magic_number_exit
  ../../doc/bison.texi:8170:error (256)
  ../../tests/conflicts.at:570:error (256)
  ../../tests/conflicts.at:673:error (256)
  ../../tests/conflicts.at:811:error (256)
  ../../tests/conflicts.at:1154:error (256)
  ../../tests/regression.at:281:error (256)
  ../../tests/regression.at:582:error (256)
  maint.mk: use EXIT_* values rather than magic number
2012-07-27 17:00:28 +02:00
Akim Demaille 4acc22e5cf tests: do not depend on __cplusplus to decide for C++ or C output
Since we do support compiling C code with a C++ compiler.

* tests/actions.at (Qualified $$ in actions): Use AT_SKEL_CC_IF.
2012-07-27 16:36:07 +02:00
Akim Demaille 7b18c11231 regen 2012-07-27 14:52:55 +02:00
Akim Demaille e6cab382c5 synclines: remove spurious empty line
* data/bison.m4 (b4_syncline): Do not start with an empty line.
2012-07-27 14:52:23 +02:00
Akim Demaille cd735a8c6c also support $<foo>$ in the %initial-action
scan-code.l is already passing argument to b4_dollar_dollar for the
initial acton, but its definition (of b4_dollar_dollar) does not use
this argument.

Generalize this definition, and use it for the %initial-action too.

* data/c.m4 (b4_dollar_dollar_, b4_dollar_pushdef, b4_dollar_popdef):
Instead of expecting a pointer, require a value, and use ".".
Since they are now generic enough, move to...
* data/c-like.m4: this new file.
* data/c.m4, data/java.m4: Load it.
* data/glr.c, data/lalr1.cc, data/lalr1.java, data/yacc.c: Use
b4_dollar_pushdef for the %initial-action.
* tests/actions.at: Check that.
* data/Makefile.am: Adjust.
* NEWS, doc/bison.texi: Document.
2012-07-27 14:47:20 +02:00
Akim Demaille d6a44ffd00 skeletons: b4_dollar_pushdef and popdef to simpify complex definitions
M4 is really making it uselessly hard to define macros that define
macros.
* data/c.m4 (b4_dollar_pushdef, b4_dollar_popdef): New.
Use it.
2012-07-27 13:47:24 +02:00
Akim Demaille 93e3dbab95 regen 2012-07-27 12:54:31 +02:00
Akim Demaille 1c292035e1 printer/destructor: translate only once
Currently "%printer {...} a b c d e f" translates the {...} six times.
Not only is this bad for time and space, it also issues six times the
same warnings.

* src/symlist.h, src/symlist.c (symbol_list_destructor_set)
(symbol_list_printer_set): Take the action as code_props instead of
const char *.
* src/parse-gram.y: Translate these actions here.
* src/scan-code.h: Comment change.
* tests/input.at: Check that warnings are issued only once.
2012-07-27 12:54:31 +02:00
Akim Demaille 263137264f factor the handling of m4 escaping
The conversion from @ to @@ and so forth is coded is too many
different places.  Factor, a bit.

* src/scan-code.l: Instead of duplicating the logic of obstack_escape,
use it.
It sure is less efficient, but the cost is negligible.
This allows to factor rules that are alike.
And to factor some start-condition clauses.
* tests/input.at (Stray $ or @): New.
* NEWS: Document it.
2012-07-27 12:54:31 +02:00
Akim Demaille e20e6a50d5 news: schedule the removal of the ";" hack
scan-code.l is significantly more complex because of this.

* NEWS: Doc it.
2012-07-27 12:54:31 +02:00
Akim Demaille 4d24ffb75e style changes in the scanners
* src/scan-code.l, src/scan-skel.l: Use a more traditional indentation
style for start-conditions.
Prefer "continue" to a comment, for empty actions.
Strip useless {}.
Remove useless start-condition clauses.
2012-07-27 12:13:40 +02:00
Akim Demaille a74a3158d4 regen 2012-07-26 18:30:43 +02:00
Akim Demaille 4982f078bf support $<tag>$ in printers and destructors
* src/scan-code.l (SC_SYMBOL_ACTION): Accept $<tag>$, not just $$.
* data/c.m4 (b4_dollar_dollar_): New.
(b4_symbol_actions): Let b4_dollar_dollar use b4_dollar_dollar_.
* NEWS, doc/bison.texi: Document it.
* tests/actions.at: Check this for C and C++.
2012-07-26 18:30:43 +02:00
Akim Demaille 65a99eca25 scan-code: factor the handling of the type in $<TYPE>$
* src/scan-code.l (fetch_type_name): New.
(handle_action_dollar): Use it.
(gt_ptr): Remove, useless.
2012-07-26 17:03:54 +02:00
Akim Demaille 9a86ee6058 muscles: fix another occurrence of unescaped type name
* src/output.c (quoted_output): Split into...
(quoted_output, string_output): these.
Use the former when outputting a type_name.
* tests/input.at: Check this case.
* src/symtab.h: Comment changes.
2012-07-26 17:03:54 +02:00
Akim Demaille 0e164d43d1 glr.cc: fix the handling of yydebug
* data/glr.cc (yydebug_): Remove, unused.
(set_debug_level, debug_level): Work on yydebug instead.
* doc/bison.texi, NEWS: Document this.
2012-07-26 17:03:52 +02:00
Akim Demaille d511fbd576 gnulib: update 2012-07-26 16:51:26 +02:00
Akim Demaille 9c46ba16e3 formatting changes
* src/symtab.h: here.
2012-07-26 16:51:26 +02:00
Akim Demaille 55e075f229 tests: fix an assertion
* tests/local.at (AT_YYLEX_DEFINE): Be sure to check the array
against its length, not its size in bytes.
2012-07-26 16:51:26 +02:00
Akim Demaille 0bb672d87c tests: adjust to GCC 4.8, which displays caret errors
With GCC 4.8, the tests on synclines are skipped.  Transform

  input.y:1:2: error: #error "1"
   #error "1"
    ^

into

  input.y:1: #error "1"

* tests/synclines.at (AT_SYNCLINES_COMPILE): Do it, using Perl instead of
sed.
2012-07-26 16:51:26 +02:00
Akim Demaille 8617d87e24 be sure to properly escape type names
* src/scan-code.l: Use obstack_quote when passing type_name to m4.
* tests/input.at (Code injection): New.
* NEWS: Document it.
Thanks to Paul Eggert for the wording.
2012-07-26 14:20:47 +02:00
Akim Demaille 0601c3bf0f obstack_quote: escape and quote for M4
* src/system.h (obstack_quote): New.
* src/muscle-tab.c: Use it instead of obstack_escape where applicable.
* src/scan-code.l: Since obstack_quote supports NULL, leave type_name
as NULL instead of defaulting to "".
2012-07-26 14:20:18 +02:00
Akim Demaille eea7239a23 muscles: shuffle responsabilities
* src/muscle-tab.c (muscle_boundary_grow): Be in charge of quotation,
instead of leaving this to the caller.
2012-07-26 12:30:03 +02:00
Akim Demaille e58782294d muscles: make private functions static
* src/muscle-tab.h, src/muscle-tab.c (muscle_boundary_grow)
(muscle_location_grow): Now static.
2012-07-26 12:30:03 +02:00
Akim Demaille c1cc91bdcd muscles: rename private functions/macros
* src/muscle-tab.c (MUSCLE_COMMON_DECODE, muscle_string_decode)
(muscle_location_decode): Not related to muscles, rename as...
(COMMON_DECODE, string_decode, location_decode): these.
2012-07-26 12:30:03 +02:00
Akim Demaille 13b712d7d4 obstack_escape: escape M4 characters
* src/muscle-tab.h (MUSCLE_OBSTACK_SGROW): This is not related to
muscles, so move to, and rename as...
* src/system.h (obstack_escape): this.
Adjust dependencies.
2012-07-26 12:30:02 +02:00
Akim Demaille dba9149595 remove dead macro
* src/system.h (DEFAULT_TMPDIR): Remove, unused.
2012-07-26 12:28:40 +02:00
Akim Demaille 9b8585410a maint: style changes
* src/scan-code.l: Remove useless braces.
Formatting changes.
Prefer NULL to 0.
* src/muscle-tab.c, src/system.h: Formatting changes.
2012-07-26 12:28:17 +02:00
Akim Demaille f9b8635172 doc: avoid problems with case insensitive file systems
makeinfo --html generates index.html, and the node "Index" will result
in Index.html.  On case insensitive file systems, such as on Mac OS X
by default, this results in a single, invalid, file (Texinfo 4.13).
See http://lists.gnu.org/archive/html/bug-texinfo/2012-07/msg00032.html

* doc/bison.texi (Index): Rename as...
(Index of Terms): this.
2012-07-24 13:30:49 +02:00
Stefano LattariniandAkim Demaille 733d4546ce configure: fix botched quoting
* configure.ac: In the AC_SUBST call on 'VALGRIND_PREBISON'.  Without
this change, when running ./configure, I see:

    ...
    checking for valgrind... valgrind
    ./configure: line 35221: -q: command not found
    checking for Java compiler... gcj -C -fsource=1.3 -ftarget=1.4
    ...

Copyright-paperwork-exempt: yes
Signed-off-by: Stefano Lattarini <[email protected]>
2012-07-24 12:22:17 +02:00
Akim Demaille aaf6103699 news: fix typo.
* NEWS: here.
Reported by Ben Pfaff.
2012-07-20 10:01:48 +02:00
Akim Demaille d0d3313d10 maint: update gnu-web-doc-update.
* gnulib: here.
2012-07-19 16:24:33 +02:00
Akim Demaille a4107f24bc maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2012-07-19 15:38:29 +02:00
43 changed files with 1400 additions and 868 deletions
+1 -1
View File
@@ -11,6 +11,7 @@
/INSTALL /INSTALL
/Makefile /Makefile
/Makefile.in /Makefile.in
/README-release
/_* /_*
/a.exe /a.exe
/a.out /a.out
@@ -31,4 +32,3 @@
/patches /patches
/releases /releases
/stamp-h* /stamp-h*
/README-release
+1 -1
View File
@@ -1 +1 @@
2.5.91 2.6.1
+55 -1
View File
@@ -1,5 +1,59 @@
GNU Bison NEWS GNU Bison NEWS
* Noteworthy changes in release 2.6.2 (2012-08-03) [stable]
** Bug fixes
Buffer overruns, complaints from Flex, and portability issues in the test
suite have been fixed.
** Spaces in %lex- and %parse-param (lalr1.cc, glr.cc)
Trailing end-of-lines in %parse-param or %lex-param would result in
invalid C++. This is fixed.
** Spurious spaces and end-of-lines
The generated files no longer end (nor start) with empty lines.
* Noteworthy changes in release 2.6.1 (2012-07-30) [stable]
Bison no longer executes user-specified M4 code when processing a grammar.
** Future Changes
In addition to the removal of the features announced in Bison 2.6, the
next major release will remove the "Temporary hack for adding a semicolon
to the user action", as announced in the release 2.5. Instead of:
exp: exp "+" exp { $$ = $1 + $3 };
write:
exp: exp "+" exp { $$ = $1 + $3; };
** Bug fixes
*** Type names are now properly escaped.
*** glr.cc: set_debug_level and debug_level work as expected.
*** Stray @ or $ in actions
While Bison used to warn about stray $ or @ in action rules, it did not
for other actions such as printers, destructors, or initial actions. It
now does.
** Type names in actions
For consistency with rule actions, it is now possible to qualify $$ by a
type-name in destructors, printers, and initial actions. For instance:
%printer { fprintf (yyo, "(%d, %f)", $<ival>$, $<fval>$); } <*> <>;
will display two values for each typed and untyped symbol (provided
that YYSTYPE has both "ival" and "fval" fields).
* Noteworthy changes in release 2.6 (2012-07-19) [stable] * Noteworthy changes in release 2.6 (2012-07-19) [stable]
** Future Changes ** Future Changes
@@ -7,7 +61,7 @@ GNU Bison NEWS
The next major release of Bison will drop support for the following The next major release of Bison will drop support for the following
deprecated features. Please report disagreements to [email protected]. deprecated features. Please report disagreements to [email protected].
*** K&C parsers *** K&R C parsers
Support for generating parsers in K&R C will be removed. Parsers Support for generating parsers in K&R C will be removed. Parsers
generated for C support ISO C90, and are tested with ISO C99 and ISO C11 generated for C support ISO C90, and are tested with ISO C99 and ISO C11
+2 -1
View File
@@ -13,6 +13,7 @@ Anthony Heading [email protected]
Arnold Robbins [email protected] Arnold Robbins [email protected]
Art Haas [email protected] Art Haas [email protected]
Baron Schwartz [email protected] Baron Schwartz [email protected]
Ben Pfaff [email protected]
Benoit Perrot [email protected] Benoit Perrot [email protected]
Bernd Kiefer [email protected] Bernd Kiefer [email protected]
Bert Deknuydt [email protected] Bert Deknuydt [email protected]
@@ -100,7 +101,7 @@ Sergei Steshenko [email protected]
Shura [email protected] Shura [email protected]
Stefano Lattarini [email protected] Stefano Lattarini [email protected]
Steve Murphy [email protected] Steve Murphy [email protected]
Summum Bonum [email protected] Sum Wu [email protected]
Thiru Ramakrishnan [email protected] Thiru Ramakrishnan [email protected]
Tim Josling [email protected] Tim Josling [email protected]
Tim Landscheidt [email protected] Tim Landscheidt [email protected]
+3 -1
View File
@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Print a version string. # Print a version string.
scriptversion=2012-07-10.09; # UTC scriptversion=2012-07-19.14; # UTC
# Bootstrap this package from checked-out sources. # Bootstrap this package from checked-out sources.
@@ -214,6 +214,8 @@ use_git=true
# otherwise find the first of the NAMES that can be run (i.e., # otherwise find the first of the NAMES that can be run (i.e.,
# supports --version). If found, set ENVVAR to the program name, # supports --version). If found, set ENVVAR to the program name,
# die otherwise. # die otherwise.
#
# FIXME: code duplication, see also gnu-web-doc-update.
find_tool () find_tool ()
{ {
find_tool_envvar=$1 find_tool_envvar=$1
+4 -1
View File
@@ -24,7 +24,10 @@ gnulib_modules='
gettext git-version-gen gitlog-to-changelog gettext git-version-gen gitlog-to-changelog
gpl-3.0 hash inttypes isnan javacomp-script gpl-3.0 hash inttypes isnan javacomp-script
javaexec-script ldexpl malloc-gnu mbschr mbsrchr javaexec-script ldexpl malloc-gnu mbschr mbsrchr
mbswidth obstack perror progname mbswidth
obstack
obstack-printf
perror progname
quote quotearg quote quotearg
readme-release readme-release
realloc-posix realloc-posix
+3 -2
View File
@@ -65,12 +65,13 @@ exclude = \
$(call exclude, \ $(call exclude, \
bindtextdomain=^lib/main.c$$ \ bindtextdomain=^lib/main.c$$ \
program_name=^lib/main.c$$ \ program_name=^lib/main.c$$ \
prohibit_always-defined_macros=^data/yacc.c|^djgpp/ \ prohibit_always-defined_macros=^data/yacc.c$$|^djgpp/ \
prohibit_always-defined_macros+=?|^lib/timevar.c$$ \ prohibit_always-defined_macros+=?|^lib/timevar.c$$ \
prohibit_always-defined_macros+=?|^src/(parse-gram.c|system.h)$$ \ prohibit_always-defined_macros+=?|^src/(parse-gram.c|system.h)$$ \
prohibit_always-defined_macros+=?|^tests/regression.at$$ \ prohibit_always-defined_macros+=?|^tests/regression.at$$ \
prohibit_defined_have_decl_tests=?|^lib/timevar.c$$ \ prohibit_defined_have_decl_tests=?|^lib/timevar.c$$ \
prohibit_empty_lines_at_EOF=^src/parse-gram.[ch]$$ \ prohibit_magic_number_exit=^doc/bison.texi$$ \
prohibit_magic_number_exit+=?|^tests/(conflicts|regression).at$$ \
require_config_h_first=^(lib/yyerror|data/(glr|yacc))\.c$$ \ require_config_h_first=^(lib/yyerror|data/(glr|yacc))\.c$$ \
space_tab=^tests/(input|c\+\+)\.at$$ \ space_tab=^tests/(input|c\+\+)\.at$$ \
trailing_blank=^src/parse-gram.[ch]$$ \ trailing_blank=^src/parse-gram.[ch]$$ \
+1 -1
View File
@@ -170,7 +170,7 @@ case $VALGRIND:$host_os in
# VALGRIND+=' --suppressions=$(abs_top_srcdir)/build-aux/darwin11.4.0.valgrind' # VALGRIND+=' --suppressions=$(abs_top_srcdir)/build-aux/darwin11.4.0.valgrind'
VALGRIND=;; VALGRIND=;;
*:*) *:*)
AC_SUBST([VALGRIND_PREBISON], [$VALGRIND -q]);; AC_SUBST([VALGRIND_PREBISON], ["$VALGRIND -q"]);;
esac esac
AM_MISSING_PROG([AUTOM4TE], [autom4te]) AM_MISSING_PROG([AUTOM4TE], [autom4te])
+1
View File
@@ -14,6 +14,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
dist_pkgdata_DATA = README bison.m4 \ dist_pkgdata_DATA = README bison.m4 \
c-like.m4 \
c-skel.m4 c.m4 yacc.c glr.c \ c-skel.m4 c.m4 yacc.c glr.c \
c++-skel.m4 c++.m4 location.cc lalr1.cc glr.cc stack.hh \ c++-skel.m4 c++.m4 location.cc lalr1.cc glr.cc stack.hh \
java-skel.m4 java.m4 lalr1.java java-skel.m4 java.m4 lalr1.java
+2 -2
View File
@@ -259,8 +259,8 @@ m4_define([b4_basename],
# b4_syncline(LINE, FILE) # b4_syncline(LINE, FILE)
# ----------------------- # -----------------------
m4_define([b4_syncline], m4_define([b4_syncline],
[b4_flag_if([synclines], [ [b4_flag_if([synclines],
b4_sync_end([__line__], [b4_basename(m4_quote(__file__))]) [b4_sync_end([__line__], [b4_basename(m4_quote(__file__))])
b4_sync_start([$1], [$2])])]) b4_sync_start([$1], [$2])])])
m4_define([b4_sync_end], [b4_comment([Line $1 of $2])]) m4_define([b4_sync_end], [b4_comment([Line $1 of $2])])
+44
View File
@@ -0,0 +1,44 @@
-*- Autoconf -*-
# Common code for C-like languages (C, C++, Java, etc.)
# Copyright (C) 2012 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
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# b4_dollar_dollar_(VALUE, FIELD, DEFAULT-FIELD)
# ----------------------------------------------
# If FIELD (or DEFAULT-FIELD) is non-null, return "VALUE.FIELD",
# otherwise just VALUE. Be sure to pass "(VALUE)" is VALUE is a
# pointer.
m4_define([b4_dollar_dollar_],
[m4_if([$2], [[]],
[m4_ifval([$3], [($1.$3)],
[$1])],
[($1.$2)])])
# b4_dollar_pushdef(VALUE-POINTER, DEFAULT-FIELD, LOCATION)
# b4_dollar_popdef
# ---------------------------------------------------------
# Define b4_dollar_dollar for VALUE and DEFAULT-FIELD,
# and b4_at_dollar for LOCATION.
m4_define([b4_dollar_pushdef],
[m4_pushdef([b4_dollar_dollar],
[b4_dollar_dollar_([$1], m4_dquote($][1), [$2])])dnl
m4_pushdef([b4_at_dollar], [$3])dnl
])
m4_define([b4_dollar_popdef],
[m4_popdef([b4_at_dollar])dnl
m4_popdef([b4_dollar_dollar])dnl
])
+7 -5
View File
@@ -17,6 +17,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
m4_include(b4_pkgdatadir/[c-like.m4])
# b4_tocpp(STRING) # b4_tocpp(STRING)
# ---------------- # ----------------
@@ -421,17 +422,18 @@ $2
# SYMBOL-TAG, SYMBOL-NUM, # SYMBOL-TAG, SYMBOL-NUM,
# SYMBOL-ACTION, SYMBOL-TYPENAME) # SYMBOL-ACTION, SYMBOL-TYPENAME)
# ------------------------------------------------- # -------------------------------------------------
# Issue the code for a symbol action (e.g., %printer).
#
# Define b4_dollar_dollar([TYPE-NAME]), and b4_at_dollar, which are
# invoked where $<TYPE-NAME>$ and @$ were specified by the user.
m4_define([b4_symbol_actions], m4_define([b4_symbol_actions],
[m4_pushdef([b4_dollar_dollar], [b4_dollar_pushdef([(*yyvaluep)], [$6], [(*yylocationp)])dnl
[m4_ifval([$6], [(yyvaluep->$6)], [(*yyvaluep)])])dnl
m4_pushdef([b4_at_dollar], [(*yylocationp)])dnl
case $4: /* $3 */ case $4: /* $3 */
b4_syncline([$2], [$1]) b4_syncline([$2], [$1])
$5; $5;
b4_syncline([@oline@], [@ofile@]) b4_syncline([@oline@], [@ofile@])
break; break;
m4_popdef([b4_at_dollar])dnl b4_dollar_popdef[]dnl
m4_popdef([b4_dollar_dollar])dnl
]) ])
+6 -10
View File
@@ -2302,12 +2302,10 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
#endif #endif
]) ])
m4_ifdef([b4_initial_action], [ m4_ifdef([b4_initial_action], [
m4_pushdef([b4_at_dollar], [yylloc])dnl b4_dollar_pushdef([yylval], [], [yylloc])dnl
m4_pushdef([b4_dollar_dollar], [yylval])dnl /* User initialization code. */
/* User initialization code. */ b4_user_initial_action
b4_user_initial_action b4_dollar_popdef])[]dnl
m4_popdef([b4_dollar_dollar])dnl
m4_popdef([b4_at_dollar])])dnl
[ [
if (! yyinitGLRStack (yystackp, YYINITDEPTH)) if (! yyinitGLRStack (yystackp, YYINITDEPTH))
goto yyexhaustedlab; goto yyexhaustedlab;
@@ -2601,9 +2599,7 @@ yypdumpstack (yyGLRStack* yystackp)
YYFPRINTF (stderr, "\n"); YYFPRINTF (stderr, "\n");
} }
#endif #endif
] ]b4_epilogue[]dnl
b4_epilogue
dnl dnl
dnl glr.cc produces its own header. dnl glr.cc produces its own header.
dnl dnl
@@ -2616,5 +2612,5 @@ b4_copyright([Skeleton interface for Bison GLR parsers in C],
]b4_cpp_guard_open([b4_spec_defines_file])[ ]b4_cpp_guard_open([b4_spec_defines_file])[
]b4_shared_declarations[ ]b4_shared_declarations[
]b4_cpp_guard_close([b4_spec_defines_file])[ ]b4_cpp_guard_close([b4_spec_defines_file])[
]])]) ]])])dnl
m4_divert_pop(0) m4_divert_pop(0)
+5 -7
View File
@@ -131,7 +131,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [ ]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
:])[ :])[
#if ]b4_api_PREFIX[DEBUG #if ]b4_api_PREFIX[DEBUG
]m4_ifset([b4_parse_param], [ ], [ :])[yydebug_ (false), ]m4_ifset([b4_parse_param], [ ], [ :])[
yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[ yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
#endif]b4_parse_param_cons[ #endif]b4_parse_param_cons[
{ {
@@ -199,20 +199,19 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
]b4_parser_class_name[::debug_level_type ]b4_parser_class_name[::debug_level_type
]b4_parser_class_name[::debug_level () const ]b4_parser_class_name[::debug_level () const
{ {
return yydebug_; return yydebug;
} }
void void
]b4_parser_class_name[::set_debug_level (debug_level_type l) ]b4_parser_class_name[::set_debug_level (debug_level_type l)
{ {
yydebug_ = l; // Actually, it is yydebug which is really used.
yydebug = l;
} }
#endif #endif
]m4_popdef([b4_parse_param])dnl ]m4_popdef([b4_parse_param])dnl
b4_namespace_close[ b4_namespace_close])
]])
# Let glr.c believe that the user arguments include the parser itself. # Let glr.c believe that the user arguments include the parser itself.
@@ -320,7 +319,6 @@ b4_user_stype
const location_type* yylocationp); const location_type* yylocationp);
private: private:
/* Debugging. */ /* Debugging. */
int yydebug_;
std::ostream* yycdebug_; std::ostream* yycdebug_;
# endif # endif
+1
View File
@@ -17,6 +17,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
m4_include(b4_pkgdatadir/[c-like.m4])
# b4_comment(TEXT) # b4_comment(TEXT)
# ---------------- # ----------------
+5 -7
View File
@@ -536,12 +536,10 @@ do { \
YYCDEBUG << "Starting parse" << std::endl; YYCDEBUG << "Starting parse" << std::endl;
]m4_ifdef([b4_initial_action], [ ]m4_ifdef([b4_initial_action], [
m4_pushdef([b4_at_dollar], [yylloc])dnl b4_dollar_pushdef([yylval], [], [yylloc])dnl
m4_pushdef([b4_dollar_dollar], [yylval])dnl /* User initialization code. */
/* User initialization code. */ b4_user_initial_action
b4_user_initial_action b4_dollar_popdef])[]dnl
m4_popdef([b4_dollar_dollar])dnl
m4_popdef([b4_at_dollar])])dnl
[ /* Initialize the stacks. The initial state will be pushed in [ /* Initialize the stacks. The initial state will be pushed in
yynewstate, since the latter expects the semantical and the yynewstate, since the latter expects the semantical and the
@@ -1106,5 +1104,5 @@ b4_error_verbose_if([int yystate, int yytoken],
const ]b4_parser_class_name[::token_number_type ]b4_parser_class_name[::yyundef_token_ = ]b4_undef_token_number[; const ]b4_parser_class_name[::token_number_type ]b4_parser_class_name[::yyundef_token_ = ]b4_undef_token_number[;
]b4_namespace_close[ ]b4_namespace_close[
]b4_epilogue ]b4_epilogue[]dnl
m4_divert_pop(0) m4_divert_pop(0)
+4 -6
View File
@@ -458,12 +458,10 @@ b4_lexer_if([[
yyerrstatus_ = 0; yyerrstatus_ = 0;
]m4_ifdef([b4_initial_action], [ ]m4_ifdef([b4_initial_action], [
m4_pushdef([b4_at_dollar], [yylloc])dnl b4_dollar_pushdef([yylval], [], [yylloc])dnl
m4_pushdef([b4_dollar_dollar], [yylval])dnl /* User initialization code. */
/* User initialization code. */ b4_user_initial_action
b4_user_initial_action b4_dollar_popdef])[]dnl
m4_popdef([b4_dollar_dollar])dnl
m4_popdef([b4_at_dollar])])dnl
[ /* Initialize the stack. */ [ /* Initialize the stack. */
yystack.push (yystate, yylval]b4_locations_if([, yylloc])[); yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
+6 -7
View File
@@ -1570,17 +1570,16 @@ b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[
yylloc.first_column = yylloc.last_column = ]b4_location_initial_column[; yylloc.first_column = yylloc.last_column = ]b4_location_initial_column[;
#endif]]) #endif]])
m4_ifdef([b4_initial_action],[ m4_ifdef([b4_initial_action],[
m4_pushdef([b4_at_dollar], [m4_define([b4_at_dollar_used])yylloc])dnl b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [],
m4_pushdef([b4_dollar_dollar], [m4_define([b4_dollar_dollar_used])yylval])dnl [m4_define([b4_at_dollar_used])yylloc])dnl
/* User initialization code. */ /* User initialization code. */
b4_user_initial_action b4_user_initial_action
m4_popdef([b4_dollar_dollar])dnl b4_dollar_popdef[]dnl
m4_popdef([b4_at_dollar])])dnl
m4_ifdef([b4_dollar_dollar_used],[[ yyvsp[0] = yylval; m4_ifdef([b4_dollar_dollar_used],[[ yyvsp[0] = yylval;
]])dnl ]])dnl
m4_ifdef([b4_at_dollar_used], [[ yylsp[0] = yylloc; m4_ifdef([b4_at_dollar_used], [[ yylsp[0] = yylloc;
]])[ ]])])dnl
goto yysetstate; [ goto yysetstate;
/*------------------------------------------------------------. /*------------------------------------------------------------.
| yynewstate -- Push a new state, which is found in yystate. | | yynewstate -- Push a new state, which is found in yystate. |
@@ -2046,7 +2045,7 @@ yypushreturn:]])[
} }
]b4_epilogue ]b4_epilogue[]dnl
b4_defines_if( b4_defines_if(
[@output(b4_spec_defines_file@)@ [@output(b4_spec_defines_file@)@
b4_copyright([Bison interface for Yacc-like parsers in C], b4_copyright([Bison interface for Yacc-like parsers in C],
+16 -15
View File
@@ -110,7 +110,7 @@ Reference sections:
* Glossary:: Basic concepts are explained. * Glossary:: Basic concepts are explained.
* Copying This Manual:: License for copying this manual. * Copying This Manual:: License for copying this manual.
* Bibliography:: Publications cited in this manual. * Bibliography:: Publications cited in this manual.
* Index:: Cross-references to the text. * Index of Terms:: Cross-references to the text.
@detailmenu @detailmenu
--- The Detailed Node Listing --- --- The Detailed Node Listing ---
@@ -4552,9 +4552,9 @@ code.
@deffn {Directive} %initial-action @{ @var{code} @} @deffn {Directive} %initial-action @{ @var{code} @}
@findex %initial-action @findex %initial-action
Declare that the braced @var{code} must be invoked before parsing each time Declare that the braced @var{code} must be invoked before parsing each time
@code{yyparse} is called. The @var{code} may use @code{$$} and @code{yyparse} is called. The @var{code} may use @code{$$} (or
@code{@@$} --- initial value and location of the lookahead --- and the @code{$<@var{tag}>$}) and @code{@@$} --- initial value and location of the
@code{%parse-param}. lookahead --- and the @code{%parse-param}.
@end deffn @end deffn
For instance, if your locations use a file name, you may use For instance, if your locations use a file name, you may use
@@ -4592,11 +4592,11 @@ symbol is automatically discarded.
@deffn {Directive} %destructor @{ @var{code} @} @var{symbols} @deffn {Directive} %destructor @{ @var{code} @} @var{symbols}
@findex %destructor @findex %destructor
Invoke the braced @var{code} whenever the parser discards one of the Invoke the braced @var{code} whenever the parser discards one of the
@var{symbols}. @var{symbols}. Within @var{code}, @code{$$} (or @code{$<@var{tag}>$})
Within @var{code}, @code{$$} designates the semantic value associated designates the semantic value associated with the discarded symbol, and
with the discarded symbol, and @code{@@$} designates its location. @code{@@$} designates its location. The additional parser parameters are
The additional parser parameters are also available (@pxref{Parser Function, , also available (@pxref{Parser Function, , The Parser Function
The Parser Function @code{yyparse}}). @code{yyparse}}).
When a symbol is listed among @var{symbols}, its @code{%destructor} is called a When a symbol is listed among @var{symbols}, its @code{%destructor} is called a
per-symbol @code{%destructor}. per-symbol @code{%destructor}.
@@ -4734,10 +4734,11 @@ Decl, , Freeing Discarded Symbols}).
@c This is the same text as for %destructor. @c This is the same text as for %destructor.
Invoke the braced @var{code} whenever the parser displays one of the Invoke the braced @var{code} whenever the parser displays one of the
@var{symbols}. Within @var{code}, @code{yyoutput} denotes the output stream @var{symbols}. Within @var{code}, @code{yyoutput} denotes the output stream
(a @code{FILE*} in C, and an @code{std::ostream&} in C++), (a @code{FILE*} in C, and an @code{std::ostream&} in C++), @code{$$} (or
@code{$$} designates the semantic value associated with the symbol, and @code{$<@var{tag}>$}) designates the semantic value associated with the
@code{@@$} its location. The additional parser parameters are also symbol, and @code{@@$} its location. The additional parser parameters are
available (@pxref{Parser Function, , The Parser Function @code{yyparse}}). also available (@pxref{Parser Function, , The Parser Function
@code{yyparse}}).
The @var{symbols} are defined as for @code{%destructor} (@pxref{Destructor The @var{symbols} are defined as for @code{%destructor} (@pxref{Destructor
Decl, , Freeing Discarded Symbols}.): they can be per-type (e.g., Decl, , Freeing Discarded Symbols}.): they can be per-type (e.g.,
@@ -11704,8 +11705,8 @@ London, Department of Computer Science, TR-00-12 (December 2000).
@uref{http://www.cs.rhul.ac.uk/research/languages/publications/tomita_style_1.ps} @uref{http://www.cs.rhul.ac.uk/research/languages/publications/tomita_style_1.ps}
@end table @end table
@node Index @node Index of Terms
@unnumbered Index @unnumbered Index of Terms
@printindex cp @printindex cp
+1 -1
Submodule gnulib updated: cabce6b8f2...bd54a45e6e
+1
View File
@@ -268,3 +268,4 @@
/xmemdup0.c /xmemdup0.c
/xmemdup0.h /xmemdup0.h
/sys_types.in.h /sys_types.in.h
/obstack_printf.c
+1
View File
@@ -179,3 +179,4 @@
/xalloc.m4 /xalloc.m4
/xsize.m4 /xsize.m4
/xstrndup.m4 /xstrndup.m4
/obstack-printf.m4
+16 -16
View File
@@ -73,7 +73,7 @@ log_resolution (rule *r, symbol_number token,
{ {
case shift_resolution: case shift_resolution:
case right_resolution: case right_resolution:
obstack_fgrow2 (&solved_conflicts_obstack, obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s" _(" Conflict between rule %d and token %s"
" resolved as shift"), " resolved as shift"),
r->number, r->number,
@@ -82,7 +82,7 @@ log_resolution (rule *r, symbol_number token,
case reduce_resolution: case reduce_resolution:
case left_resolution: case left_resolution:
obstack_fgrow2 (&solved_conflicts_obstack, obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s" _(" Conflict between rule %d and token %s"
" resolved as reduce"), " resolved as reduce"),
r->number, r->number,
@@ -90,7 +90,7 @@ log_resolution (rule *r, symbol_number token,
break; break;
case nonassoc_resolution: case nonassoc_resolution:
obstack_fgrow2 (&solved_conflicts_obstack, obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s" _(" Conflict between rule %d and token %s"
" resolved as an error"), " resolved as an error"),
r->number, r->number,
@@ -102,33 +102,33 @@ log_resolution (rule *r, symbol_number token,
switch (resolution) switch (resolution)
{ {
case shift_resolution: case shift_resolution:
obstack_fgrow2 (&solved_conflicts_obstack, obstack_printf (&solved_conflicts_obstack,
" (%s < %s)", " (%s < %s)",
r->prec->tag, r->prec->tag,
symbols[token]->tag); symbols[token]->tag);
break; break;
case reduce_resolution: case reduce_resolution:
obstack_fgrow2 (&solved_conflicts_obstack, obstack_printf (&solved_conflicts_obstack,
" (%s < %s)", " (%s < %s)",
symbols[token]->tag, symbols[token]->tag,
r->prec->tag); r->prec->tag);
break; break;
case left_resolution: case left_resolution:
obstack_fgrow1 (&solved_conflicts_obstack, obstack_printf (&solved_conflicts_obstack,
" (%%left %s)", " (%%left %s)",
symbols[token]->tag); symbols[token]->tag);
break; break;
case right_resolution: case right_resolution:
obstack_fgrow1 (&solved_conflicts_obstack, obstack_printf (&solved_conflicts_obstack,
" (%%right %s)", " (%%right %s)",
symbols[token]->tag); symbols[token]->tag);
break; break;
case nonassoc_resolution: case nonassoc_resolution:
obstack_fgrow1 (&solved_conflicts_obstack, obstack_printf (&solved_conflicts_obstack,
" (%%nonassoc %s)", " (%%nonassoc %s)",
symbols[token]->tag); symbols[token]->tag);
break; break;
@@ -145,7 +145,7 @@ log_resolution (rule *r, symbol_number token,
{ {
case shift_resolution: case shift_resolution:
case right_resolution: case right_resolution:
obstack_fgrow2 (&solved_conflicts_xml_obstack, obstack_printf (&solved_conflicts_xml_obstack,
" <resolution rule=\"%d\" symbol=\"%s\"" " <resolution rule=\"%d\" symbol=\"%s\""
" type=\"shift\">", " type=\"shift\">",
r->number, r->number,
@@ -154,7 +154,7 @@ log_resolution (rule *r, symbol_number token,
case reduce_resolution: case reduce_resolution:
case left_resolution: case left_resolution:
obstack_fgrow2 (&solved_conflicts_xml_obstack, obstack_printf (&solved_conflicts_xml_obstack,
" <resolution rule=\"%d\" symbol=\"%s\"" " <resolution rule=\"%d\" symbol=\"%s\""
" type=\"reduce\">", " type=\"reduce\">",
r->number, r->number,
@@ -162,7 +162,7 @@ log_resolution (rule *r, symbol_number token,
break; break;
case nonassoc_resolution: case nonassoc_resolution:
obstack_fgrow2 (&solved_conflicts_xml_obstack, obstack_printf (&solved_conflicts_xml_obstack,
" <resolution rule=\"%d\" symbol=\"%s\"" " <resolution rule=\"%d\" symbol=\"%s\""
" type=\"error\">", " type=\"error\">",
r->number, r->number,
@@ -174,33 +174,33 @@ log_resolution (rule *r, symbol_number token,
switch (resolution) switch (resolution)
{ {
case shift_resolution: case shift_resolution:
obstack_fgrow2 (&solved_conflicts_xml_obstack, obstack_printf (&solved_conflicts_xml_obstack,
"%s &lt; %s", "%s &lt; %s",
xml_escape_n (0, r->prec->tag), xml_escape_n (0, r->prec->tag),
xml_escape_n (1, symbols[token]->tag)); xml_escape_n (1, symbols[token]->tag));
break; break;
case reduce_resolution: case reduce_resolution:
obstack_fgrow2 (&solved_conflicts_xml_obstack, obstack_printf (&solved_conflicts_xml_obstack,
"%s &lt; %s", "%s &lt; %s",
xml_escape_n (0, symbols[token]->tag), xml_escape_n (0, symbols[token]->tag),
xml_escape_n (1, r->prec->tag)); xml_escape_n (1, r->prec->tag));
break; break;
case left_resolution: case left_resolution:
obstack_fgrow1 (&solved_conflicts_xml_obstack, obstack_printf (&solved_conflicts_xml_obstack,
"%%left %s", "%%left %s",
xml_escape (symbols[token]->tag)); xml_escape (symbols[token]->tag));
break; break;
case right_resolution: case right_resolution:
obstack_fgrow1 (&solved_conflicts_xml_obstack, obstack_printf (&solved_conflicts_xml_obstack,
"%%right %s", "%%right %s",
xml_escape (symbols[token]->tag)); xml_escape (symbols[token]->tag));
break; break;
case nonassoc_resolution: case nonassoc_resolution:
obstack_fgrow1 (&solved_conflicts_xml_obstack, obstack_printf (&solved_conflicts_xml_obstack,
"%%nonassoc %s", "%%nonassoc %s",
xml_escape (symbols[token]->tag)); xml_escape (symbols[token]->tag));
break; break;
+53 -45
View File
@@ -177,10 +177,10 @@ static void
muscle_syncline_grow (char const *key, location loc) muscle_syncline_grow (char const *key, location loc)
{ {
char *extension = NULL; char *extension = NULL;
obstack_fgrow1 (&muscle_obstack, "]b4_syncline(%d, [[", loc.start.line); obstack_printf (&muscle_obstack, "]b4_syncline(%d, ", loc.start.line);
MUSCLE_OBSTACK_SGROW (&muscle_obstack, obstack_quote (&muscle_obstack,
quotearg_style (c_quoting_style, loc.start.file)); quotearg_style (c_quoting_style, loc.start.file));
obstack_sgrow (&muscle_obstack, "]])["); obstack_sgrow (&muscle_obstack, ")[");
obstack_1grow (&muscle_obstack, 0); obstack_1grow (&muscle_obstack, 0);
extension = obstack_finish (&muscle_obstack); extension = obstack_finish (&muscle_obstack);
muscle_grow (key, extension, ""); muscle_grow (key, extension, "");
@@ -205,11 +205,11 @@ void muscle_pair_list_grow (const char *muscle,
const char *a1, const char *a2) const char *a1, const char *a2)
{ {
char *pair; char *pair;
obstack_sgrow (&muscle_obstack, "[[["); obstack_sgrow (&muscle_obstack, "[");
MUSCLE_OBSTACK_SGROW (&muscle_obstack, a1); obstack_quote (&muscle_obstack, a1);
obstack_sgrow (&muscle_obstack, "]], [["); obstack_sgrow (&muscle_obstack, ", ");
MUSCLE_OBSTACK_SGROW (&muscle_obstack, a2); obstack_quote (&muscle_obstack, a2);
obstack_sgrow (&muscle_obstack, "]]]"); obstack_sgrow (&muscle_obstack, "]");
obstack_1grow (&muscle_obstack, 0); obstack_1grow (&muscle_obstack, 0);
pair = obstack_finish (&muscle_obstack); pair = obstack_finish (&muscle_obstack);
muscle_grow (muscle, pair, ",\n"); muscle_grow (muscle, pair, ",\n");
@@ -259,53 +259,61 @@ muscle_find (char const *key)
} }
void /* In the format `file_name:line.column', append BOUND to MUSCLE. Use
digraphs for special characters in the file name. */
static void
muscle_boundary_grow (char const *key, boundary bound) muscle_boundary_grow (char const *key, boundary bound)
{ {
char *extension; char *extension;
MUSCLE_OBSTACK_SGROW (&muscle_obstack, bound.file); obstack_sgrow (&muscle_obstack, "[[");
obstack_1grow (&muscle_obstack, ':'); obstack_escape (&muscle_obstack, bound.file);
obstack_fgrow1 (&muscle_obstack, "%d", bound.line); obstack_1grow (&muscle_obstack, ':');
obstack_1grow (&muscle_obstack, '.'); obstack_printf (&muscle_obstack, "%d", bound.line);
obstack_fgrow1 (&muscle_obstack, "%d", bound.column); obstack_1grow (&muscle_obstack, '.');
obstack_1grow (&muscle_obstack, '\0'); obstack_printf (&muscle_obstack, "%d", bound.column);
obstack_sgrow (&muscle_obstack, "]]");
obstack_1grow (&muscle_obstack, '\0');
extension = obstack_finish (&muscle_obstack); extension = obstack_finish (&muscle_obstack);
muscle_grow (key, extension, ""); muscle_grow (key, extension, "");
obstack_free (&muscle_obstack, extension); obstack_free (&muscle_obstack, extension);
} }
void
/* In the format `[[file_name:line.column]], [[file_name:line.column]]',
append LOC to MUSCLE. Use digraphs for special characters in each
file name. */
static void
muscle_location_grow (char const *key, location loc) muscle_location_grow (char const *key, location loc)
{ {
muscle_grow (key, "[[", "");
muscle_boundary_grow (key, loc.start); muscle_boundary_grow (key, loc.start);
muscle_grow (key, "]], [[", ""); muscle_grow (key, "", ", ");
muscle_boundary_grow (key, loc.end); muscle_boundary_grow (key, loc.end);
muscle_grow (key, "]]", "");
} }
#define MUSCLE_COMMON_DECODE(Value) \ #define COMMON_DECODE(Value) \
case '$': \ case '$': \
aver (*++(Value) == ']'); \ aver (*++(Value) == ']'); \
aver (*++(Value) == '['); \ aver (*++(Value) == '['); \
obstack_sgrow (&muscle_obstack, "$"); \ obstack_sgrow (&muscle_obstack, "$"); \
break; \ break; \
case '@': \ case '@': \
switch (*++(Value)) \ switch (*++(Value)) \
{ \ { \
case '@': obstack_sgrow (&muscle_obstack, "@" ); break; \ case '@': obstack_sgrow (&muscle_obstack, "@" ); break; \
case '{': obstack_sgrow (&muscle_obstack, "[" ); break; \ case '{': obstack_sgrow (&muscle_obstack, "[" ); break; \
case '}': obstack_sgrow (&muscle_obstack, "]" ); break; \ case '}': obstack_sgrow (&muscle_obstack, "]" ); break; \
default: aver (false); break; \ default: aver (false); break; \
} \ } \
break; \ break; \
default: \ default: \
obstack_1grow (&muscle_obstack, *(Value)); \ obstack_1grow (&muscle_obstack, *(Value)); \
break; break;
/* Reverse of MUSCLE_OBSTACK_SGROW. */ /* Reverse of obstack_escape. */
static char * static char *
muscle_string_decode (char const *key) string_decode (char const *key)
{ {
char const *value; char const *value;
char *value_decoded; char *value_decoded;
@@ -317,7 +325,7 @@ muscle_string_decode (char const *key)
do { do {
switch (*value) switch (*value)
{ {
MUSCLE_COMMON_DECODE (value) COMMON_DECODE (value)
case '[': case '[':
case ']': case ']':
aver (false); aver (false);
@@ -332,7 +340,7 @@ muscle_string_decode (char const *key)
/* Reverse of muscle_location_grow. */ /* Reverse of muscle_location_grow. */
static location static location
muscle_location_decode (char const *key) location_decode (char const *key)
{ {
location loc; location loc;
char const *value = muscle_find_const (key); char const *value = muscle_find_const (key);
@@ -342,7 +350,7 @@ muscle_location_decode (char const *key)
while (*++value) while (*++value)
switch (*value) switch (*value)
{ {
MUSCLE_COMMON_DECODE (value) COMMON_DECODE (value)
case '[': case '[':
aver (false); aver (false);
break; break;
@@ -455,7 +463,7 @@ muscle_percent_define_get (char const *variable)
variable, ")"); variable, ")");
muscle_insert (usage_name, ""); muscle_insert (usage_name, "");
value = muscle_string_decode (name); value = string_decode (name);
if (!value) if (!value)
value = xstrdup (""); value = xstrdup ("");
return value; return value;
@@ -469,7 +477,7 @@ muscle_percent_define_get_loc (char const *variable)
if (!muscle_find_const (loc_name)) if (!muscle_find_const (loc_name))
fatal(_("%s: undefined %%define variable %s"), fatal(_("%s: undefined %%define variable %s"),
"muscle_percent_define_get_loc", quote (variable)); "muscle_percent_define_get_loc", quote (variable));
return muscle_location_decode (loc_name); return location_decode (loc_name);
} }
char const * char const *
@@ -573,7 +581,7 @@ muscle_percent_define_check_values (char const * const *values)
name = UNIQSTR_CONCAT ("percent_define(", *variablep, ")"); name = UNIQSTR_CONCAT ("percent_define(", *variablep, ")");
value = muscle_string_decode (name); value = string_decode (name);
if (value) if (value)
{ {
for (++values; *values; ++values) for (++values; *values; ++values)
+37 -60
View File
@@ -35,62 +35,47 @@ void muscle_free (void);
/* An obstack dedicated to receive muscle keys and values. */ /* An obstack dedicated to receive muscle keys and values. */
extern struct obstack muscle_obstack; extern struct obstack muscle_obstack;
#define MUSCLE_INSERT_BOOL(Key, Value) \ #define MUSCLE_INSERT_BOOL(Key, Value) \
do { \ do { \
int v = Value; \ int v = Value; \
MUSCLE_INSERT_INT (Key, v); \ MUSCLE_INSERT_INT (Key, v); \
} while(0) } while (0)
#define MUSCLE_INSERT_INT(Key, Value) \ #define MUSCLE_INSERT_INT(Key, Value) \
do { \ do { \
obstack_fgrow1 (&muscle_obstack, "%d", Value); \ obstack_printf (&muscle_obstack, "%d", Value); \
obstack_1grow (&muscle_obstack, 0); \ obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \ muscle_insert (Key, obstack_finish (&muscle_obstack)); \
} while(0) } while (0)
#define MUSCLE_INSERT_LONG_INT(Key, Value) \ #define MUSCLE_INSERT_LONG_INT(Key, Value) \
do { \ do { \
obstack_fgrow1 (&muscle_obstack, "%ld", Value); \ obstack_printf (&muscle_obstack, "%ld", Value); \
obstack_1grow (&muscle_obstack, 0); \ obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \ muscle_insert (Key, obstack_finish (&muscle_obstack)); \
} while(0) } while (0)
#define MUSCLE_INSERT_STRING_RAW(Key, Value) \ #define MUSCLE_INSERT_STRING_RAW(Key, Value) \
do { \ do { \
obstack_sgrow (&muscle_obstack, Value); \ obstack_sgrow (&muscle_obstack, Value); \
obstack_1grow (&muscle_obstack, 0); \ obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \ muscle_insert (Key, obstack_finish (&muscle_obstack)); \
} while(0) } while (0)
#define MUSCLE_INSERT_STRING(Key, Value) \ #define MUSCLE_INSERT_STRING(Key, Value) \
do { \ do { \
MUSCLE_OBSTACK_SGROW (&muscle_obstack, Value); \ obstack_escape (&muscle_obstack, Value); \
obstack_1grow (&muscle_obstack, 0); \ obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \ muscle_insert (Key, obstack_finish (&muscle_obstack)); \
} while(0) } while (0)
#define MUSCLE_OBSTACK_SGROW(Obstack, Value) \ #define MUSCLE_INSERT_C_STRING(Key, Value) \
do { \ do { \
char const *p; \ obstack_escape (&muscle_obstack, \
for (p = Value; *p; p++) \ quotearg_style (c_quoting_style, Value)); \
switch (*p) \ obstack_1grow (&muscle_obstack, 0); \
{ \ muscle_insert (Key, obstack_finish (&muscle_obstack)); \
case '$': obstack_sgrow (Obstack, "$]["); break; \ } while (0)
case '@': obstack_sgrow (Obstack, "@@" ); break; \
case '[': obstack_sgrow (Obstack, "@{" ); break; \
case ']': obstack_sgrow (Obstack, "@}" ); break; \
default: obstack_1grow (Obstack, *p); break; \
} \
} while(0)
#define MUSCLE_INSERT_C_STRING(Key, Value) \
do { \
MUSCLE_OBSTACK_SGROW (&muscle_obstack, \
quotearg_style (c_quoting_style, \
Value)); \
obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \
} while(0)
/* Append VALUE to the current value of KEY. If KEY did not already /* Append VALUE to the current value of KEY. If KEY did not already
exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously
@@ -110,15 +95,7 @@ void muscle_code_grow (const char *key, const char *value, location loc);
muscle values are output *double* quoted, one needs to strip the first level muscle values are output *double* quoted, one needs to strip the first level
of quotes to reach the list itself. */ of quotes to reach the list itself. */
void muscle_pair_list_grow (const char *muscle, void muscle_pair_list_grow (const char *muscle,
const char *a1, const char *a2); const char *a1, const char *a2);
/* In the format `[[file_name:line.column]], [[file_name:line.column]]', append
LOC to MUSCLE. Use digraphs for special characters in each file name. */
void muscle_location_grow (char const *key, location loc);
/* In the format `file_name:line.column', append BOUND to MUSCLE. Use digraphs
for special characters in the file name. */
void muscle_boundary_grow (char const *key, boundary bound);
/* Grow KEY for the occurrence of the name USER_NAME at LOC appropriately for /* Grow KEY for the occurrence of the name USER_NAME at LOC appropriately for
use with b4_check_user_names in ../data/bison.m4. USER_NAME is not escaped use with b4_check_user_names in ../data/bison.m4. USER_NAME is not escaped
+30 -17
View File
@@ -70,7 +70,7 @@ Name (char const *name, \
int i; \ int i; \
int j = 1; \ int j = 1; \
\ \
obstack_fgrow1 (&format_obstack, "%6d", first); \ obstack_printf (&format_obstack, "%6d", first); \
for (i = begin; i < end; ++i) \ for (i = begin; i < end; ++i) \
{ \ { \
obstack_1grow (&format_obstack, ','); \ obstack_1grow (&format_obstack, ','); \
@@ -81,7 +81,7 @@ Name (char const *name, \
} \ } \
else \ else \
++j; \ ++j; \
obstack_fgrow1 (&format_obstack, "%6d", table_data[i]); \ obstack_printf (&format_obstack, "%6d", table_data[i]); \
if (table_data[i] < min) \ if (table_data[i] < min) \
min = table_data[i]; \ min = table_data[i]; \
if (max < table_data[i]) \ if (max < table_data[i]) \
@@ -93,10 +93,10 @@ Name (char const *name, \
lmin = min; \ lmin = min; \
lmax = max; \ lmax = max; \
/* Build `NAME_min' and `NAME_max' in the obstack. */ \ /* Build `NAME_min' and `NAME_max' in the obstack. */ \
obstack_fgrow1 (&format_obstack, "%s_min", name); \ obstack_printf (&format_obstack, "%s_min", name); \
obstack_1grow (&format_obstack, 0); \ obstack_1grow (&format_obstack, 0); \
MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin); \ MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin); \
obstack_fgrow1 (&format_obstack, "%s_max", name); \ obstack_printf (&format_obstack, "%s_max", name); \
obstack_1grow (&format_obstack, 0); \ obstack_1grow (&format_obstack, 0); \
MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax); \ MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax); \
} }
@@ -110,29 +110,39 @@ GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table, item_number)
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number) GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number)
/*--------------------------------------------------------------------. /*----------------------------------------------------------------.
| Print to OUT a representation of STRING escaped both for C and M4. | | Print to OUT a representation of CP quoted and escaped for M4. |
`--------------------------------------------------------------------*/ `----------------------------------------------------------------*/
static void static void
escaped_output (FILE *out, char const *string) quoted_output (FILE *out, char const *cp)
{ {
char const *p;
fprintf (out, "[["); fprintf (out, "[[");
for (p = quotearg_style (c_quoting_style, string); *p; p++) for (; *cp; cp++)
switch (*p) switch (*cp)
{ {
case '$': fputs ("$][", out); break; case '$': fputs ("$][", out); break;
case '@': fputs ("@@", out); break; case '@': fputs ("@@", out); break;
case '[': fputs ("@{", out); break; case '[': fputs ("@{", out); break;
case ']': fputs ("@}", out); break; case ']': fputs ("@}", out); break;
default: fputc (*p, out); break; default: fputc (*cp, out); break;
} }
fprintf (out, "]]"); fprintf (out, "]]");
} }
/*----------------------------------------------------------------.
| Print to OUT a representation of STRING quoted and escaped both |
| for C and M4. |
`----------------------------------------------------------------*/
static void
string_output (FILE *out, char const *string)
{
quoted_output (out, quotearg_style (c_quoting_style, string));
}
/*------------------------------------------------------------------. /*------------------------------------------------------------------.
| Prepare the muscles related to the symbols: translate, tname, and | | Prepare the muscles related to the symbols: translate, tname, and |
@@ -175,7 +185,7 @@ prepare_symbols (void)
if (i) if (i)
obstack_1grow (&format_obstack, ' '); obstack_1grow (&format_obstack, ' ');
MUSCLE_OBSTACK_SGROW (&format_obstack, cp); obstack_escape (&format_obstack, cp);
free (cp); free (cp);
obstack_1grow (&format_obstack, ','); obstack_1grow (&format_obstack, ',');
j += width; j += width;
@@ -299,7 +309,7 @@ user_actions_output (FILE *out)
{ {
fprintf (out, "b4_case(%d, [b4_syncline(%d, ", r + 1, fprintf (out, "b4_case(%d, [b4_syncline(%d, ", r + 1,
rules[r].action_location.start.line); rules[r].action_location.start.line);
escaped_output (out, rules[r].action_location.start.file); string_output (out, rules[r].action_location.start.file);
fprintf (out, ")\n[ %s]])\n\n", rules[r].action); fprintf (out, ")\n[ %s]])\n\n", rules[r].action);
} }
fputs ("])\n\n", out); fputs ("])\n\n", out);
@@ -405,12 +415,15 @@ symbol_code_props_output (FILE *out, char const *what,
code, optional typename. */ code, optional typename. */
fprintf (out, "%s[", sep); fprintf (out, "%s[", sep);
sep = ",\n"; sep = ",\n";
escaped_output (out, loc.start.file); string_output (out, loc.start.file);
fprintf (out, ", %d, ", loc.start.line); fprintf (out, ", %d, ", loc.start.line);
escaped_output (out, sym->tag); quoted_output (out, sym->tag);
fprintf (out, ", %d, [[%s]]", sym->number, code); fprintf (out, ", %d, [[%s]]", sym->number, code);
if (sym->type_name) if (sym->type_name)
fprintf (out, ", [[%s]]", sym->type_name); {
fputs (", ", out);
quoted_output (out, sym->type_name);
}
fputc (']', out); fputc (']', out);
} }
} }
+490 -428
View File
File diff suppressed because it is too large Load Diff
+5 -7
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 2.5.1.19-ced26-dirty. */ /* A Bison parser, made by GNU Bison 2.6.1.12-3153-dirty. */
/* Bison interface for Yacc-like parsers in C /* Bison interface for Yacc-like parsers in C
@@ -167,8 +167,7 @@ extern int gram_debug;
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE typedef union YYSTYPE
{ {
/* Line 2049 of yacc.c */
/* Line 2063 of yacc.c */
#line 114 "parse-gram.y" #line 114 "parse-gram.y"
symbol *symbol; symbol *symbol;
@@ -182,9 +181,8 @@ typedef union YYSTYPE
named_ref *named_ref; named_ref *named_ref;
/* Line 2049 of yacc.c */
/* Line 2063 of yacc.c */ #line 186 "parse-gram.h"
#line 188 "parse-gram.h"
} YYSTYPE; } YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -204,6 +202,7 @@ typedef struct YYLTYPE
# define YYLTYPE_IS_TRIVIAL 1 # define YYLTYPE_IS_TRIVIAL 1
#endif #endif
#ifdef YYPARSE_PARAM #ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus #if defined __STDC__ || defined __cplusplus
int gram_parse (void *YYPARSE_PARAM); int gram_parse (void *YYPARSE_PARAM);
@@ -218,5 +217,4 @@ int gram_parse ();
#endif #endif
#endif /* ! YYPARSE_PARAM */ #endif /* ! YYPARSE_PARAM */
#endif /* !GRAM__________SRC_PARSE_GRAM_H */ #endif /* !GRAM__________SRC_PARSE_GRAM_H */
+24 -12
View File
@@ -347,17 +347,27 @@ grammar_declaration:
} }
| "%destructor" "{...}" generic_symlist | "%destructor" "{...}" generic_symlist
{ {
symbol_list *list; code_props code;
for (list = $3; list; list = list->next) code_props_symbol_action_init (&code, $2, @2);
symbol_list_destructor_set (list, $2, @2); code_props_translate_code (&code);
symbol_list_free ($3); {
symbol_list *list;
for (list = $3; list; list = list->next)
symbol_list_destructor_set (list, &code);
symbol_list_free ($3);
}
} }
| "%printer" "{...}" generic_symlist | "%printer" "{...}" generic_symlist
{ {
symbol_list *list; code_props code;
for (list = $3; list; list = list->next) code_props_symbol_action_init (&code, $2, @2);
symbol_list_printer_set (list, $2, @2); code_props_translate_code (&code);
symbol_list_free ($3); {
symbol_list *list;
for (list = $3; list; list = list->next)
symbol_list_printer_set (list, &code);
symbol_list_free ($3);
}
} }
| "%default-prec" | "%default-prec"
{ {
@@ -724,11 +734,13 @@ add_param (char const *type, char *decl, location loc)
/* Strip the surrounding '{' and '}', and any blanks just inside /* Strip the surrounding '{' and '}', and any blanks just inside
the braces. */ the braces. */
while (*--p == ' ' || *p == '\t') --p;
continue; while (isspace ((unsigned char) *p))
--p;
p[1] = '\0'; p[1] = '\0';
while (*++decl == ' ' || *decl == '\t') ++decl;
continue; while (isspace ((unsigned char) *decl))
++decl;
if (! name_start) if (! name_start)
complain_at (loc, _("missing identifier in parameter declaration")); complain_at (loc, _("missing identifier in parameter declaration"));
+5 -5
View File
@@ -54,7 +54,7 @@ print_core (struct obstack *oout, state *s)
snritems = nitemset; snritems = nitemset;
} }
obstack_fgrow1 (oout, "%d", s->number); obstack_printf (oout, "%d", s->number);
for (i = 0; i < snritems; i++) for (i = 0; i < snritems; i++)
{ {
item_number *sp; item_number *sp;
@@ -68,15 +68,15 @@ print_core (struct obstack *oout, state *s)
r = item_number_as_rule_number (*sp); r = item_number_as_rule_number (*sp);
obstack_fgrow1 (oout, "\n%s -> ", rules[r].lhs->tag); obstack_printf (oout, "\n%s -> ", rules[r].lhs->tag);
for (sp = rules[r].rhs; sp < sp1; sp++) for (sp = rules[r].rhs; sp < sp1; sp++)
obstack_fgrow1 (oout, "%s ", symbols[*sp]->tag); obstack_printf (oout, "%s ", symbols[*sp]->tag);
obstack_1grow (oout, '.'); obstack_1grow (oout, '.');
for (/* Nothing */; *sp >= 0; ++sp) for (/* Nothing */; *sp >= 0; ++sp)
obstack_fgrow1 (oout, " %s", symbols[*sp]->tag); obstack_printf (oout, " %s", symbols[*sp]->tag);
/* Experimental feature: display the lookahead tokens. */ /* Experimental feature: display the lookahead tokens. */
if (report_flag & report_lookahead_tokens if (report_flag & report_lookahead_tokens
@@ -95,7 +95,7 @@ print_core (struct obstack *oout, state *s)
obstack_sgrow (oout, "["); obstack_sgrow (oout, "[");
BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0) BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0)
{ {
obstack_fgrow2 (oout, "%s%s", sep, symbols[k]->tag); obstack_printf (oout, "%s%s", sep, symbols[k]->tag);
sep = ", "; sep = ", ";
} }
obstack_sgrow (oout, "]"); obstack_sgrow (oout, "]");
+4 -1
View File
@@ -45,7 +45,10 @@ typedef struct code_props {
CODE_PROPS_SYMBOL_ACTION, CODE_PROPS_RULE_ACTION CODE_PROPS_SYMBOL_ACTION, CODE_PROPS_RULE_ACTION
} kind; } kind;
/** \c NULL iff \c code_props::kind is \c CODE_PROPS_NONE. */ /**
* \c NULL iff \c code_props::kind is \c CODE_PROPS_NONE.
* Memory is allocated in an obstack freed elsewhere.
*/
char const *code; char const *code;
/** Undefined iff \c code_props::code is \c NULL. */ /** Undefined iff \c code_props::code is \c NULL. */
location location; location location;
+88 -87
View File
@@ -46,6 +46,9 @@ YY_DECL;
#define YY_USER_ACTION location_compute (loc, &loc->end, yytext, yyleng); #define YY_USER_ACTION location_compute (loc, &loc->end, yytext, yyleng);
static char *fetch_type_name (char *cp, char const **type_name,
location dollar_loc);
static void handle_action_dollar (symbol_list *rule, char *cp, static void handle_action_dollar (symbol_list *rule, char *cp,
location dollar_loc); location dollar_loc);
static void handle_action_at (symbol_list *rule, char *cp, location at_loc); static void handle_action_at (symbol_list *rule, char *cp, location at_loc);
@@ -95,11 +98,15 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
int braces_level = 0; int braces_level = 0;
/* Whether a semicolon is probably needed. /* Whether a semicolon is probably needed.
The heuristic is that a semicolon is not needed after '{', '}', ';',
or a C preprocessor directive, and that whitespaces and comments The heuristic is that a semicolon is not needed after '{', '}',
do not affect this flag. ';', or a C preprocessor directive, and that whitespaces and
Note that '{' does not need a semicolon because of '{}'. comments do not affect this flag. Note that '{' does not need a
A semicolon may be needed before a cpp direcive, but don't bother. */ semicolon because of '{}'. A semicolon may be needed before a
cpp directive, but don't bother.
While it is maintained in several start-conditions (factoring
opportunities), it is meaningful only for SC_RULE_ACTION. */
bool need_semicolon = false; bool need_semicolon = false;
/* Whether in a C preprocessor directive. Don't use a start condition /* Whether in a C preprocessor directive. Don't use a start condition
@@ -157,7 +164,8 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
} }
<SC_RULE_ACTION,SC_SYMBOL_ACTION>{ <SC_RULE_ACTION,SC_SYMBOL_ACTION>
{
"'" { "'" {
STRING_GROW; STRING_GROW;
BEGIN SC_CHARACTER; BEGIN SC_CHARACTER;
@@ -176,42 +184,31 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
STRING_GROW; STRING_GROW;
BEGIN SC_LINE_COMMENT; BEGIN SC_LINE_COMMENT;
} }
[$@] {
warn_at (*loc, _("stray '%s'"), yytext);
obstack_escape (&obstack_for_string, yytext);
need_semicolon = true;
}
[\[\]] {
obstack_escape (&obstack_for_string, yytext);
need_semicolon = true;
}
} }
<SC_RULE_ACTION> <SC_RULE_ACTION>
{ {
"$"("<"{tag}">")?{ref} { "$"("<"{tag}">")?{ref} {
ref_tail_fields = 0; ref_tail_fields = NULL;
handle_action_dollar (self->rule, yytext, *loc); handle_action_dollar (self->rule, yytext, *loc);
if (ref_tail_fields) { if (ref_tail_fields)
obstack_sgrow (&obstack_for_string, ref_tail_fields); obstack_sgrow (&obstack_for_string, ref_tail_fields);
}
need_semicolon = true; need_semicolon = true;
} }
"@"{ref} { "@"{ref} {
ref_tail_fields = 0; ref_tail_fields = NULL;
handle_action_at (self->rule, yytext, *loc); handle_action_at (self->rule, yytext, *loc);
if (ref_tail_fields) { if (ref_tail_fields)
obstack_sgrow (&obstack_for_string, ref_tail_fields); obstack_sgrow (&obstack_for_string, ref_tail_fields);
}
need_semicolon = true;
}
"$" {
warn_at (*loc, _("stray '$'"));
obstack_sgrow (&obstack_for_string, "$][");
need_semicolon = true;
}
"@" {
warn_at (*loc, _("stray '@'"));
obstack_sgrow (&obstack_for_string, "@@");
need_semicolon = true;
}
"[" {
obstack_sgrow (&obstack_for_string, "@{");
need_semicolon = true;
}
"]" {
obstack_sgrow (&obstack_for_string, "@}");
need_semicolon = true; need_semicolon = true;
} }
@@ -263,8 +260,12 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
<SC_SYMBOL_ACTION> <SC_SYMBOL_ACTION>
{ {
"$$" { "$"("<"{tag}">")?"$" {
obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar["); const char *type_name = NULL;
fetch_type_name (yytext + 1, &type_name, *loc)[-1] = 0;
obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar(");
obstack_quote (&obstack_for_string, type_name);
obstack_sgrow (&obstack_for_string, ")[");
self->is_value_used = true; self->is_value_used = true;
} }
"@$" { "@$" {
@@ -274,30 +275,18 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
} }
/*-----------------------------------------.
| Escape M4 quoting characters in C code. |
`-----------------------------------------*/
<*> <*>
{ {
\$ obstack_sgrow (&obstack_for_string, "$]["); /* Escape M4 quoting characters in C code. */
\@ obstack_sgrow (&obstack_for_string, "@@"); [$@\[\]] obstack_escape (&obstack_for_string, yytext);
\[ obstack_sgrow (&obstack_for_string, "@{");
\] obstack_sgrow (&obstack_for_string, "@}"); /* By default, grow the string obstack with the input. */
.|\n STRING_GROW;
/* End of processing. */
<<EOF>> STRING_FINISH; return last_string;
} }
/*-----------------------------------------------------.
| By default, grow the string obstack with the input. |
`-----------------------------------------------------*/
<*>.|\n STRING_GROW;
/* End of processing. */
<*><<EOF>> {
STRING_FINISH;
return last_string;
}
%% %%
static inline bool static inline bool
@@ -345,7 +334,7 @@ typedef struct
not visible from current midrule. */ not visible from current midrule. */
#define VARIANT_NOT_VISIBLE_FROM_MIDRULE (1 << 2) #define VARIANT_NOT_VISIBLE_FROM_MIDRULE (1 << 2)
static variant *variant_table = 0; static variant *variant_table = NULL;
static unsigned variant_table_size = 0; static unsigned variant_table_size = 0;
static unsigned variant_count = 0; static unsigned variant_count = 0;
@@ -367,7 +356,7 @@ static void
variant_table_free (void) variant_table_free (void)
{ {
free (variant_table); free (variant_table);
variant_table = 0; variant_table = NULL;
variant_table_size = variant_count = 0; variant_table_size = variant_count = 0;
} }
@@ -410,7 +399,7 @@ variant_add (uniqstr id, location id_loc, unsigned symbol_index,
} }
static const char * static const char *
get_at_spec(unsigned symbol_index) get_at_spec (unsigned symbol_index)
{ {
static char at_buf[20]; static char at_buf[20];
if (symbol_index == 0) if (symbol_index == 0)
@@ -454,30 +443,30 @@ show_sub_messages (const char* cp, bool explicit_bracketing,
/* Create the explanation message. */ /* Create the explanation message. */
obstack_init (&msg_buf); obstack_init (&msg_buf);
obstack_fgrow1 (&msg_buf, _("possibly meant: %c"), dollar_or_at); obstack_printf (&msg_buf, _("possibly meant: %c"), dollar_or_at);
if (contains_dot_or_dash (id)) if (contains_dot_or_dash (id))
obstack_fgrow1 (&msg_buf, "[%s]", id); obstack_printf (&msg_buf, "[%s]", id);
else else
obstack_sgrow (&msg_buf, id); obstack_sgrow (&msg_buf, id);
obstack_sgrow (&msg_buf, tail); obstack_sgrow (&msg_buf, tail);
if (var->err & VARIANT_HIDDEN) if (var->err & VARIANT_HIDDEN)
{ {
obstack_fgrow1 (&msg_buf, _(", hiding %c"), dollar_or_at); obstack_printf (&msg_buf, _(", hiding %c"), dollar_or_at);
if (contains_dot_or_dash (var->id)) if (contains_dot_or_dash (var->id))
obstack_fgrow1 (&msg_buf, "[%s]", var->id); obstack_printf (&msg_buf, "[%s]", var->id);
else else
obstack_sgrow (&msg_buf, var->id); obstack_sgrow (&msg_buf, var->id);
obstack_sgrow (&msg_buf, tail); obstack_sgrow (&msg_buf, tail);
} }
obstack_fgrow1 (&msg_buf, _(" at %s"), at_spec); obstack_printf (&msg_buf, _(" at %s"), at_spec);
if (var->err & VARIANT_NOT_VISIBLE_FROM_MIDRULE) if (var->err & VARIANT_NOT_VISIBLE_FROM_MIDRULE)
{ {
const char *format = const char *format =
_(", cannot be accessed from mid-rule action at $%d"); _(", cannot be accessed from mid-rule action at $%d");
obstack_fgrow1 (&msg_buf, format, midrule_rhs_index); obstack_printf (&msg_buf, format, midrule_rhs_index);
} }
obstack_1grow (&msg_buf, '\0'); obstack_1grow (&msg_buf, '\0');
@@ -688,6 +677,31 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
int max_left_semantic_context = 0; int max_left_semantic_context = 0;
/* If CP points to a typename (i.e., <.*?>), set TYPE_NAME to its
beginning (i.e., after the opening "<", and return the pointer
immediately after it. */
static
char *
fetch_type_name (char *cp, char const **type_name,
location dollar_loc)
{
if (*cp == '<')
{
*type_name = ++cp;
while (*cp != '>')
++cp;
/* The '>' symbol will be later replaced by '\0'. Original
'text' is needed for error messages. */
++cp;
if (untyped_var_seen)
complain_at (dollar_loc, _("explicit type given in untyped grammar"));
tag_seen = true;
}
return cp;
}
/*------------------------------------------------------------------. /*------------------------------------------------------------------.
| TEXT is pointing to a wannabee semantic value (i.e., a '$'). | | TEXT is pointing to a wannabee semantic value (i.e., a '$'). |
| | | |
@@ -701,7 +715,6 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
{ {
char const *type_name = NULL; char const *type_name = NULL;
char *cp = text + 1; char *cp = text + 1;
char *gt_ptr = 0;
symbol_list *effective_rule; symbol_list *effective_rule;
int effective_rule_length; int effective_rule_length;
int n; int n;
@@ -718,26 +731,14 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
} }
/* Get the type name if explicit. */ /* Get the type name if explicit. */
if (*cp == '<') cp = fetch_type_name (cp, &type_name, dollar_loc);
{
type_name = ++cp;
while (*cp != '>')
++cp;
/* The '>' symbol will be later replaced by '\0'. Original
'text' is needed for error messages. */
gt_ptr = cp;
++cp;
if (untyped_var_seen)
complain_at (dollar_loc, _("explicit type given in untyped grammar"));
tag_seen = true;
}
n = parse_ref (cp, effective_rule, effective_rule_length, n = parse_ref (cp, effective_rule, effective_rule_length,
rule->midrule_parent_rhs_index, text, dollar_loc, '$'); rule->midrule_parent_rhs_index, text, dollar_loc, '$');
if (gt_ptr) /* End type_name. */
*gt_ptr = '\0'; if (type_name)
cp[-1] = '\0';
switch (n) switch (n)
{ {
@@ -764,11 +765,11 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
} }
else else
untyped_var_seen = true; untyped_var_seen = true;
type_name = "";
} }
obstack_fgrow1 (&obstack_for_string, obstack_sgrow (&obstack_for_string, "]b4_lhs_value(");
"]b4_lhs_value([%s])[", type_name); obstack_quote (&obstack_for_string, type_name);
obstack_sgrow (&obstack_for_string, ")[");
rule->action_props.is_value_used = true; rule->action_props.is_value_used = true;
break; break;
@@ -785,12 +786,12 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
cp, quote (effective_rule->content.sym->tag)); cp, quote (effective_rule->content.sym->tag));
else else
untyped_var_seen = true; untyped_var_seen = true;
type_name = "";
} }
obstack_fgrow3 (&obstack_for_string, obstack_printf (&obstack_for_string,
"]b4_rhs_value(%d, %d, [%s])[", "]b4_rhs_value(%d, %d, ", effective_rule_length, n);
effective_rule_length, n, type_name); obstack_quote (&obstack_for_string, type_name);
obstack_sgrow (&obstack_for_string, ")[");
if (n > 0) if (n > 0)
symbol_list_n_get (effective_rule, n)->action_props.is_value_used = symbol_list_n_get (effective_rule, n)->action_props.is_value_used =
true; true;
@@ -826,7 +827,7 @@ handle_action_at (symbol_list *rule, char *text, location at_loc)
locations_flag = true; locations_flag = true;
n = parse_ref (cp, effective_rule, effective_rule_length, n = parse_ref (cp, effective_rule, effective_rule_length,
rule->midrule_parent_rhs_index, text, at_loc, '@'); rule->midrule_parent_rhs_index, text, at_loc, '@');
switch (n) switch (n)
{ {
case INVALID_REF: case INVALID_REF:
@@ -837,7 +838,7 @@ handle_action_at (symbol_list *rule, char *text, location at_loc)
break; break;
default: default:
obstack_fgrow2 (&obstack_for_string, "]b4_rhs_location(%d, %d)[", obstack_printf (&obstack_for_string, "]b4_rhs_location(%d, %d)[",
effective_rule_length, n); effective_rule_length, n);
break; break;
} }
+20 -18
View File
@@ -72,8 +72,8 @@ static void fail_for_invalid_at (char const *at);
"@@" fputc ('@', yyout); "@@" fputc ('@', yyout);
"@{" fputc ('[', yyout); "@{" fputc ('[', yyout);
"@}" fputc (']', yyout); "@}" fputc (']', yyout);
"@`" /* Empty. Used by b4_cat in ../data/bison.m4. */ "@`" continue; /* Used by b4_cat in ../data/bison.m4. */
@\n /* Likewise. */ @\n continue;
"@oline@" fprintf (yyout, "%d", out_lineno + 1); "@oline@" fprintf (yyout, "%d", out_lineno + 1);
"@ofile@" QPUTS (outname); "@ofile@" QPUTS (outname);
@@ -87,9 +87,9 @@ static void fail_for_invalid_at (char const *at);
} }
/* This pattern must not match more than the previous @ patterns. */ /* This pattern must not match more than the previous @ patterns. */
@[^@{}`(\n]* fail_for_invalid_at (yytext); @[^@{}`(\n]* fail_for_invalid_at (yytext);
\n out_lineno++; ECHO; \n out_lineno++; ECHO;
[^@\n]+ ECHO; [^@\n]+ ECHO;
<INITIAL><<EOF>> { <INITIAL><<EOF>> {
if (outname) if (outname)
@@ -100,15 +100,15 @@ static void fail_for_invalid_at (char const *at);
return EOF; return EOF;
} }
<SC_AT_DIRECTIVE_ARGS>{ <SC_AT_DIRECTIVE_ARGS>
[^@]+ { STRING_GROW; } {
[^@]+ STRING_GROW;
"@@" { obstack_1grow (&obstack_for_string, '@'); } "@@" obstack_1grow (&obstack_for_string, '@');
"@{" { obstack_1grow (&obstack_for_string, '['); } "@{" obstack_1grow (&obstack_for_string, '[');
"@}" { obstack_1grow (&obstack_for_string, ']'); } "@}" obstack_1grow (&obstack_for_string, ']');
"@`" /* Empty. Useful for starting an argument "@`" continue; /* For starting an argument that begins with whitespace. */
that begins with whitespace. */ @\n continue;
@\n /* Empty. */
@[,)] { @[,)] {
if (at_directive_argc >= AT_DIRECTIVE_ARGC_MAX) if (at_directive_argc >= AT_DIRECTIVE_ARGC_MAX)
@@ -131,15 +131,17 @@ static void fail_for_invalid_at (char const *at);
} }
} }
@.? { fail_for_invalid_at (yytext); } @.? fail_for_invalid_at (yytext);
} }
<SC_AT_DIRECTIVE_SKIP_WS>{ <SC_AT_DIRECTIVE_SKIP_WS>
[ \t\r\n] {
. { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; } [ \t\r\n] continue;
. { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; }
} }
<SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>{ <SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>
{
<<EOF>> { <<EOF>> {
fatal (_("unclosed %s directive in skeleton"), at_directive_argv[0]); fatal (_("unclosed %s directive in skeleton"), at_directive_argv[0]);
} }
+10 -16
View File
@@ -223,49 +223,43 @@ symbol_list_null (symbol_list *node)
} }
void void
symbol_list_destructor_set (symbol_list *node, char const *code, location loc) symbol_list_destructor_set (symbol_list *node, code_props const *destructor)
{ {
code_props destructor;
code_props_symbol_action_init (&destructor, code, loc);
code_props_translate_code (&destructor);
switch (node->content_type) switch (node->content_type)
{ {
case SYMLIST_SYMBOL: case SYMLIST_SYMBOL:
symbol_destructor_set (node->content.sym, &destructor); symbol_destructor_set (node->content.sym, destructor);
break; break;
case SYMLIST_TYPE: case SYMLIST_TYPE:
semantic_type_destructor_set ( semantic_type_destructor_set (
semantic_type_get (node->content.type_name), &destructor); semantic_type_get (node->content.type_name), destructor);
break; break;
case SYMLIST_DEFAULT_TAGGED: case SYMLIST_DEFAULT_TAGGED:
default_tagged_destructor_set (&destructor); default_tagged_destructor_set (destructor);
break; break;
case SYMLIST_DEFAULT_TAGLESS: case SYMLIST_DEFAULT_TAGLESS:
default_tagless_destructor_set (&destructor); default_tagless_destructor_set (destructor);
break; break;
} }
} }
void void
symbol_list_printer_set (symbol_list *node, char const *code, location loc) symbol_list_printer_set (symbol_list *node, code_props const *printer)
{ {
code_props printer;
code_props_symbol_action_init (&printer, code, loc);
code_props_translate_code (&printer);
switch (node->content_type) switch (node->content_type)
{ {
case SYMLIST_SYMBOL: case SYMLIST_SYMBOL:
symbol_printer_set (node->content.sym, &printer); symbol_printer_set (node->content.sym, printer);
break; break;
case SYMLIST_TYPE: case SYMLIST_TYPE:
semantic_type_printer_set ( semantic_type_printer_set (
semantic_type_get (node->content.type_name), &printer); semantic_type_get (node->content.type_name), printer);
break; break;
case SYMLIST_DEFAULT_TAGGED: case SYMLIST_DEFAULT_TAGGED:
default_tagged_printer_set (&printer); default_tagged_printer_set (printer);
break; break;
case SYMLIST_DEFAULT_TAGLESS: case SYMLIST_DEFAULT_TAGLESS:
default_tagless_printer_set (&printer); default_tagless_printer_set (printer);
break; break;
} }
} }
+4 -4
View File
@@ -119,11 +119,11 @@ uniqstr symbol_list_n_type_name_get (symbol_list *l, location loc, int n);
bool symbol_list_null (symbol_list *node); bool symbol_list_null (symbol_list *node);
/** Set the \c \%destructor for \c node as \c code at \c loc. */ /** Set the \c \%destructor for \c node as \c code at \c loc. */
void symbol_list_destructor_set (symbol_list *node, char const *code, void symbol_list_destructor_set (symbol_list *node,
location loc); code_props const *destructor);
/** Set the \c \%printer for \c node as \c code at \c loc. */ /** Set the \c \%printer for \c node as \c code at \c loc. */
void symbol_list_printer_set (symbol_list *node, char const *code, void symbol_list_printer_set (symbol_list *node,
location loc); code_props const *printer);
#endif /* !SYMLIST_H_ */ #endif /* !SYMLIST_H_ */
+14 -7
View File
@@ -60,23 +60,30 @@ struct symbol
/** The location of its first occurrence. */ /** The location of its first occurrence. */
location location; location location;
/** Its \c \%type. */ /** Its \c \%type.
Beware that this is the type_name as was entered by the user,
including silly things such as "]" if she entered "%token <]> t".
Therefore, when outputting type_name to M4, be sure to escape it
into "@}". See quoted_output for instance. */
uniqstr type_name; uniqstr type_name;
/** Its \c \%type's location. */ /** Its \c \%type's location. */
location type_location; location type_location;
/** Any \c \%destructor declared specifically for this symbol. /** Any \c \%destructor declared specifically for this symbol.
Access this field only through <tt>symbol</tt>'s interface functions. For Access this field only through <tt>symbol</tt>'s interface
example, if <tt>symbol::destructor = NULL</tt>, a default \c \%destructor functions. For example, if <tt>symbol::destructor = NULL</tt>, a
or a per-type \c \%destructor might be appropriate, and default \c \%destructor or a per-type \c \%destructor might be
\c symbol_destructor_get will compute the correct one. */ appropriate, and \c symbol_destructor_get will compute the
correct one. */
code_props destructor; code_props destructor;
/** Any \c \%printer declared specifically for this symbol. /** Any \c \%printer declared specifically for this symbol.
Access this field only through <tt>symbol</tt>'s interface functions. Access this field only through <tt>symbol</tt>'s interface functions.
\sa symbol::destructor */ \sa symbol::destructor */
code_props printer; code_props printer;
symbol_number number; symbol_number number;
+48 -38
View File
@@ -160,36 +160,50 @@ typedef size_t uintptr_t;
# define obstack_chunk_free free # define obstack_chunk_free free
# include <obstack.h> # include <obstack.h>
# define obstack_sgrow(Obs, Str) \ # define obstack_sgrow(Obs, Str) \
obstack_grow (Obs, Str, strlen (Str)) obstack_grow (Obs, Str, strlen (Str))
# define obstack_fgrow1(Obs, Format, Arg1) \ /* Output Str escaped for our postprocessing (i.e., escape M4 special
do { \ characters).
char buf[4096]; \
sprintf (buf, Format, Arg1); \
obstack_grow (Obs, buf, strlen (buf)); \
} while (0)
# define obstack_fgrow2(Obs, Format, Arg1, Arg2) \ For instance "[foo]" -> "@{foo@}", "$$" -> "$][$][". */
do { \
char buf[4096]; \ # define obstack_escape(Obs, Str) \
sprintf (buf, Format, Arg1, Arg2); \ do { \
obstack_grow (Obs, buf, strlen (buf)); \ char const *p; \
} while (0) for (p = Str; *p; p++) \
switch (*p) \
{ \
case '$': obstack_sgrow (Obs, "$]["); break; \
case '@': obstack_sgrow (Obs, "@@" ); break; \
case '[': obstack_sgrow (Obs, "@{" ); break; \
case ']': obstack_sgrow (Obs, "@}" ); break; \
default: obstack_1grow (Obs, *p ); break; \
} \
} while (0)
/* Output Str both quoted for M4 (i.e., embed in [[...]]), and escaped
for our postprocessing (i.e., escape M4 special characters). If
Str is empty (or NULL), output "[]" instead of "[[]]" as it make M4
programming easier (m4_ifval can be used).
For instance "[foo]" -> "[[@{foo@}]]", "$$" -> "[[$][$][]]". */
# define obstack_quote(Obs, Str) \
do { \
char const* obstack_quote_p = Str; \
if (obstack_quote_p && obstack_quote_p[0]) \
{ \
obstack_sgrow (Obs, "[["); \
obstack_escape (Obs, obstack_quote_p); \
obstack_sgrow (Obs, "]]"); \
} \
else \
obstack_sgrow (Obs, "[]"); \
} while (0)
# define obstack_fgrow3(Obs, Format, Arg1, Arg2, Arg3) \
do { \
char buf[4096]; \
sprintf (buf, Format, Arg1, Arg2, Arg3); \
obstack_grow (Obs, buf, strlen (buf)); \
} while (0)
# define obstack_fgrow4(Obs, Format, Arg1, Arg2, Arg3, Arg4) \
do { \
char buf[4096]; \
sprintf (buf, Format, Arg1, Arg2, Arg3, Arg4); \
obstack_grow (Obs, buf, strlen (buf)); \
} while (0)
@@ -205,25 +219,21 @@ do { \
# define TAB_EXT ".tab" # define TAB_EXT ".tab"
# endif # endif
# ifndef DEFAULT_TMPDIR
# define DEFAULT_TMPDIR "/tmp"
# endif
/*---------------------. /*---------------------.
| Free a linked list. | | Free a linked list. |
`---------------------*/ `---------------------*/
# define LIST_FREE(Type, List) \ # define LIST_FREE(Type, List) \
do { \ do { \
Type *_node, *_next; \ Type *_node, *_next; \
for (_node = List; _node; _node = _next) \ for (_node = List; _node; _node = _next) \
{ \ { \
_next = _node->next; \ _next = _node->next; \
free (_node); \ free (_node); \
} \ } \
} while (0) } while (0)
/*---------------------------------------------. /*---------------------------------------------.
+136
View File
@@ -1230,6 +1230,142 @@ AT_CHECK_ACTION_LOCATIONS([[%destructor]])
AT_CHECK_ACTION_LOCATIONS([[%printer]]) AT_CHECK_ACTION_LOCATIONS([[%printer]])
## ------------------------- ##
## Qualified $$ in actions. ##
## ------------------------- ##
# Check that we can used qualified $$ (v.g., $<type>$) not only in
# rule actions, but also where $$ is valid: %printer and %destructor.
#
# FIXME: Not actually checking %desctructor, but it's the same code as
# %printer...
#
# To do that, use a semantic value that has two fields (sem_type),
# declare symbols to have only one of these types (INT, float), and
# use $<type>$ to get the other one. Including for symbols that are
# not typed (UNTYPED).
m4_pushdef([AT_TEST],
[AT_SETUP([[Qualified $$ in actions: $1]])
AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1"])
AT_DATA_GRAMMAR([[input.y]],
[[%skeleton "$1"
%defines // FIXME: Mandated by lalr1.cc in Bison 2.6.
%locations // FIXME: Mandated by lalr1.cc in Bison 2.6.
%debug
%code requires
{
typedef struct sem_type
{
int ival;
float fval;
} sem_type;
# define YYSTYPE sem_type
]AT_SKEL_CC_IF([[
# include <iostream>
static void
report (std::ostream& yyo, int ival, float fval)
{
yyo << "ival: " << ival << ", fval: " << fval;
}
]], [[
# include <stdio.h>
static void
report (FILE* yyo, int ival, float fval)
{
fprintf (yyo, "ival: %d, fval: %1.1f", ival, fval);
}
]])[
}
%code
{
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
}
%token UNTYPED
%token <ival> INT
%type <fval> float
%printer { report (yyo, $$, $<fval>$); } <ival>;
%printer { report (yyo, $<ival>$, $$ ); } <fval>;
%printer { report (yyo, $<ival>$, $<fval>$); } <>;
]AT_SKEL_CC_IF([[
/* The lalr1.cc skeleton, for backward compatibility, defines
a constructor for position that initializes the filename. The
glr.cc skeleton does not (and in fact cannot: location/position
are stored in a union, from which objects with constructors are
excluded in C++). */
%initial-action {
@$.initialize ();
}
]])[
%initial-action
{
$<ival>$ = 42;
$<fval>$ = 4.2;
}
%%
float: UNTYPED INT
{
$$ = $<fval>1 + $<fval>2;
$<ival>$ = $<ival>1 + $][2;
};
%%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE(AT_SKEL_CC_IF([[{yy::parser::token::UNTYPED,
yy::parser::token::INT,
EOF}]],
[[{UNTYPED, INT, EOF}]]),
[AT_VAL.ival = toknum * 10; AT_VAL.fval = toknum / 10.0;])[
int
main (void)
{]AT_SKEL_CC_IF([[
yy::parser p;
p.set_debug_level(1);
return p.parse ();]], [[
yydebug = 1;
return yyparse ();]])[
}
]])
AT_FULL_COMPILE([[input]])
AT_PARSER_CHECK([./input], 0, [], [stderr])
# Don't be too picky on the traces, GLR is not exactly the same. Keep
# only the lines from the printer.
#
# Don't care about locations. FIXME: remove their removal when Bison
# supports C++ without locations.
AT_CHECK([[sed -ne 's/([-0-9.]*: /(/;/ival:/p' stderr]], 0,
[[Reading a token: Next token is token UNTYPED (ival: 10, fval: 0.1)
Shifting token UNTYPED (ival: 10, fval: 0.1)
Reading a token: Next token is token INT (ival: 20, fval: 0.2)
Shifting token INT (ival: 20, fval: 0.2)
$][1 = token UNTYPED (ival: 10, fval: 0.1)
$][2 = token INT (ival: 20, fval: 0.2)
-> $$ = nterm float (ival: 30, fval: 0.3)
Cleanup: popping nterm float (ival: 30, fval: 0.3)
]])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
])
AT_TEST([yacc.c])
AT_TEST([glr.c])
AT_TEST([lalr1.cc])
AT_TEST([glr.cc])
m4_popdef([AT_TEST])
## ----------------------------------------------- ## ## ----------------------------------------------- ##
## Fix user actions without a trailing semicolon. ## ## Fix user actions without a trailing semicolon. ##
## ----------------------------------------------- ## ## ----------------------------------------------- ##
+20 -6
View File
@@ -288,16 +288,16 @@ static int power (int base, int exponent);
]AT_YYLEX_DECLARE_EXTERN[ ]AT_YYLEX_DECLARE_EXTERN[
} }
]AT_SKEL_CC_IF([AT_LOCATION_TYPE_IF([], [ ]AT_SKEL_CC_IF([AT_LOCATION_TYPE_IF([], [[
/* The lalr1.cc skeleton, for backward compatibility, defines /* The lalr1.cc skeleton, for backward compatibility, defines
a constructor for position that initializes the filename. The a constructor for position that initializes the filename. The
glr.cc skeleton does not (and in fact cannot: location/position glr.cc skeleton does not (and in fact cannot: location/position
are stored in a union, from which objects with constructors are are stored in a union, from which objects with constructors are
excluded in C++. */ excluded in C++). */
%initial-action { %initial-action {
@$.initialize (); @$.initialize ();
} }
])])[ ]])])[
/* Bison Declarations */ /* Bison Declarations */
%token CALC_EOF 0 "end of input" %token CALC_EOF 0 "end of input"
@@ -386,11 +386,9 @@ AT_YYERROR_SEES_LOC_IF([
fprintf (stderr, ": ");]) fprintf (stderr, ": ");])
fprintf (stderr, "%s\n", s); fprintf (stderr, "%s\n", s);
}])[ }])[
]AT_DEFINES_IF([], ]AT_DEFINES_IF([],
[AT_CALC_LEX [AT_CALC_LEX
AT_CALC_MAIN])[ AT_CALC_MAIN])])
]])
AT_DEFINES_IF([AT_DATA_SOURCE([[calc-lex.c]AT_SKEL_CC_IF([[c]])], AT_DEFINES_IF([AT_DATA_SOURCE([[calc-lex.c]AT_SKEL_CC_IF([[c]])],
[[#include "calc.h]AT_SKEL_CC_IF([[h]])[" [[#include "calc.h]AT_SKEL_CC_IF([[h]])["
@@ -500,6 +498,20 @@ AT_CHECK([cat stderr], 0, [expout])
]) ])
# AT_CHECK_SPACES([FILE])
# -----------------------
# Make sure we did not introduce bad spaces. Checked here because all
# the skeletons are (or should be) exercized here.
m4_define([AT_CHECK_SPACES],
[# No initial empty lines.
AT_CHECK([sed -ne '/./q;=;p;' $1])
# No trailing spaces.
# FIXME: For 2.7: AT_CHECK([sed -ne '/[ ]$/{=;p;}' $1])
# No final empty lines.
AT_CHECK([sed -ne '${/^$/{=;p;};}' $1])
])
# AT_CHECK_CALC([BISON-OPTIONS]) # AT_CHECK_CALC([BISON-OPTIONS])
# ------------------------------ # ------------------------------
# Start a testing chunk which compiles `calc' grammar with # Start a testing chunk which compiles `calc' grammar with
@@ -514,6 +526,8 @@ AT_BISON_OPTION_PUSHDEFS([$1])
AT_DATA_CALC_Y([$1]) AT_DATA_CALC_Y([$1])
AT_FULL_COMPILE([calc], AT_DEFINES_IF([[lex], [main]])) AT_FULL_COMPILE([calc], AT_DEFINES_IF([[lex], [main]]))
AT_CHECK_SPACES([calc.AT_SKEL_CC_IF([cc], [c])])
AT_DEFINES_IF([AT_CHECK_SPACES([calc.AT_SKEL_CC_IF([hh], [h])])])
# Test the priorities. # Test the priorities.
_AT_CHECK_CALC([$1], _AT_CHECK_CALC([$1],
+97
View File
@@ -1369,3 +1369,100 @@ AT_TEST([%define api.prefix foo], [-p bar], [input.y:1.9-18])
m4_popdef([AT_TEST]) m4_popdef([AT_TEST])
AT_CLEANUP AT_CLEANUP
## -------------- ##
## Stray $ or @. ##
## -------------- ##
AT_SETUP([[Stray $ or @]])
# Give %printer and %destructor "<*> exp TOK" instead of "<*>" to
# check that the warnings are reported once, not three times.
AT_DATA_GRAMMAR([[input.y]],
[[%token TOK
%destructor { $%; @%; } <*> exp TOK;
%initial-action { $%; @%; };
%printer { $%; @%; } <*> exp TOK;
%%
exp: TOK { $%; @%; $$ = $1; };
]])
AT_BISON_CHECK([[input.y]], 0, [],
[[input.y:10.19: warning: stray '$'
input.y:10.23: warning: stray '@'
input.y:11.19: warning: stray '$'
input.y:11.23: warning: stray '@'
input.y:12.19: warning: stray '$'
input.y:12.23: warning: stray '@'
input.y:14.19: warning: stray '$'
input.y:14.23: warning: stray '@'
]])
AT_CLEANUP
## ---------------- ##
## Code injection. ##
## ---------------- ##
AT_SETUP([[Code injection]])
m4_pattern_allow([^m4_errprintn$])
# AT_TEST([MACRO])
# ----------------
# Try to have MACRO be run by bison.
m4_pushdef([AT_TEST],
[AT_DATA([[input.y]],
[[%type <$1(DEAD %type)> exp
%token <$1(DEAD %token)> a
%initial-action
{
$$;
$<$1(DEAD %initial-action)>$
};
%printer
{
$$
$<$1(DEAD %printer)>$
} <> <*>;
%lex-param
{
$1(DEAD %lex-param)
};
%parse-param
{
$1(DEAD %parse-param)
};
%%
exp:
a a[last]
{
$$;
$][1;
$<$1(DEAD action 1)>$
$<$1(DEAD action 2)>1
$<$1(DEAD action 3)>last
$<$1(DEAD action 4)>0
;
};
]])
# FIXME: Provide a means to iterate over all the skeletons.
AT_BISON_CHECK([[-d input.y]])
AT_BISON_CHECK([[-d -S glr.c input.y]])
AT_BISON_CHECK([[-d -S lalr1.cc input.y]])
AT_BISON_CHECK([[-d -S glr.cc input.y]])
AT_BISON_CHECK([[ -S lalr1.java input.y]])
])
AT_TEST([m4_errprintn])
AT_TEST([@:>@m4_errprintn])
m4_popdef([AT_TEST])
AT_CLEANUP
+1 -1
View File
@@ -333,7 +333,7 @@ static
static size_t toknum = 0; static size_t toknum = 0;
int res; int res;
]AT_USE_LEX_ARGS[; ]AT_USE_LEX_ARGS[;
assert (toknum < sizeof input); assert (toknum < sizeof input / sizeof input[0]);
res = input[toknum++]; res = input[toknum++];
]$2[;]AT_LOCATION_IF([[ ]$2[;]AT_LOCATION_IF([[
]AT_LOC_FIRST_LINE[ = ]AT_LOC_LAST_LINE[ = 1; ]AT_LOC_FIRST_LINE[ = ]AT_LOC_LAST_LINE[ = 1;
+84 -2
View File
@@ -917,7 +917,6 @@ m4_define([AT_CHECK_DANCER],
[AT_SETUP([Dancer $1]) [AT_SETUP([Dancer $1])
AT_BISON_OPTION_PUSHDEFS([$1]) AT_BISON_OPTION_PUSHDEFS([$1])
_AT_DATA_DANCER_Y([$1]) _AT_DATA_DANCER_Y([$1])
AT_BISON_CHECK([-o dancer.c dancer.y])
AT_FULL_COMPILE([dancer]) AT_FULL_COMPILE([dancer])
AT_PARSER_CHECK([./dancer], 1, [], AT_PARSER_CHECK([./dancer], 1, [],
[syntax error, unexpected ':' [syntax error, unexpected ':'
@@ -1002,7 +1001,6 @@ m4_define([AT_CHECK_EXPECT2],
[AT_SETUP([Expecting two tokens $1]) [AT_SETUP([Expecting two tokens $1])
AT_BISON_OPTION_PUSHDEFS([$1]) AT_BISON_OPTION_PUSHDEFS([$1])
_AT_DATA_EXPECT2_Y([$1]) _AT_DATA_EXPECT2_Y([$1])
AT_BISON_CHECK([-o expect2.c expect2.y])
AT_FULL_COMPILE([expect2]) AT_FULL_COMPILE([expect2])
AT_PARSER_CHECK([./expect2], 1, [], AT_PARSER_CHECK([./expect2], 1, [],
[syntax error, unexpected '+', expecting A or B [syntax error, unexpected '+', expecting A or B
@@ -1585,3 +1583,87 @@ Stack now 0
m4_popdef([AT_LAC_CHECK]) m4_popdef([AT_LAC_CHECK])
AT_CLEANUP AT_CLEANUP
## ---------------------- ##
## Lex and parse params. ##
## ---------------------- ##
# AT_TEST(SKELETON)
# -----------------
# Check that the identifier of the params is properly fetched
# even when there are trailing blanks.
m4_pushdef([AT_TEST],
[AT_SETUP([[Lex and parse params: $1]])
AT_BISON_OPTION_PUSHDEFS([%locations %skeleton $1])
## FIXME: Improve parsing of parse-param and use the generated
## yyerror.
AT_DATA_GRAMMAR([input.y],
[[%defines
%locations
%skeleton $1
%union { int ival; }
%parse-param { int x }
// Spaces, tabs, and new lines.
%parse-param { @&t@
int y @&t@
@&t@
@&t@
}
%{
#include <stdio.h>
#include <stdlib.h>
]AT_SKEL_CC_IF([], [[
static
void
yyerror (int x, int y, const char *msg)
{
fprintf (stderr, "x: %d, y: %d, %s\n", x, y, msg);
}]])[
]AT_YYLEX_DECLARE[
%}
%%
exp: 'a' { fprintf (stdout, "x: %d, y: %d\n", x, y); };
%%
]AT_YYLEX_DEFINE(["a"])[
]AT_SKEL_CC_IF(
[AT_YYERROR_DEFINE
int
yyparse (int x, int y)
{
yy::parser parser(x, y);
return parser.parse ();
}
])[
int
main (void)
{
return !!yyparse(1, 2);
}
]])
AT_FULL_COMPILE([input])
AT_CHECK([./input], 0, [[x: 1, y: 2
]])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
])
## FIXME: test Java, and iterate over skeletons.
AT_TEST("yacc.c")
AT_TEST("glr.c")
AT_TEST("lalr1.cc")
AT_TEST("glr.cc")
m4_popdef([AT_TEST])
+44 -29
View File
@@ -27,6 +27,11 @@ AT_BANNER([[User Actions.]])
# errors. # errors.
m4_define([AT_SYNCLINES_COMPILE], m4_define([AT_SYNCLINES_COMPILE],
[AT_CHECK([$CC $CFLAGS $CPPFLAGS -c $1], [ignore], [], [stderr]) [AT_CHECK([$CC $CFLAGS $CPPFLAGS -c $1], [ignore], [], [stderr])
# Transform stderr into something like this:
#
# input.y:4: #error "4"
#
# In case GCC displays column information, strip it down. # In case GCC displays column information, strip it down.
# #
# input.y:4:2: #error "4" or # input.y:4:2: #error "4" or
@@ -42,6 +47,11 @@ m4_define([AT_SYNCLINES_COMPILE],
# => # =>
# input.y:4: #error "8" # input.y:4: #error "8"
# #
# The message may include a caret-error:
#
# input.y:1:2: error: #error "1"
# #error "1"
# ^
# #
# And possibly distcc adds its bits. # And possibly distcc adds its bits.
# #
@@ -54,19 +64,22 @@ m4_define([AT_SYNCLINES_COMPILE],
# distcc[35882] (dcc_connect_by_name) ERROR: failed to look up host "chrisimac": Unknown host # distcc[35882] (dcc_connect_by_name) ERROR: failed to look up host "chrisimac": Unknown host
# distcc[35882] Warning: failed to distribute input.c to chrisimac/4, running locally instead # distcc[35882] Warning: failed to distribute input.c to chrisimac/4, running locally instead
AT_CHECK([[sed -e '/^distcc\[[0-9]*\] /d' \ AT_CHECK([[perl -p -0777 - stderr <<\EOF
-e 's/^\([^:]*:[^:.]*\)[.:][^:]*:\(.*\)$/\1:\2/' \ s/^distcc\[\d+\] .*\n//gm;
-e 's/^\([^:]*:[^:]*:\)[^@%:@]*\( @%:@error\)/\1\2/' \ s/^([^:]+:\d+)[.:][^:]+:(.+)$/$][1:$][2/gm;
-e "/^[^:]*: In function '[^\']*':$/d" \ s/^([^:]+:\d+):[^#]*( #error)/$][1:$][2/gm;
stderr]], s/^[^:]*: In function '[^']+':\n//gm;
0, [stdout]) s/^\ +#error.*\n\ *\^\n//gm;
EOF
]],
0, [stdout])
]) ])
# AT_TEST_SYNCLINE(TITLE, INPUT, ERROR-MSG) # AT_TEST(TITLE, INPUT, ERROR-MSG)
# ----------------------------------------- # --------------------------------
# Check that compiling the parser produced from INPUT cause GCC # Check that compiling the parser produced from INPUT cause GCC
# to issue ERROR-MSG. # to issue ERROR-MSG.
m4_define([AT_TEST_SYNCLINE], m4_pushdef([AT_TEST],
[AT_SETUP([$1]) [AT_SETUP([$1])
AT_BISON_OPTION_PUSHDEFS AT_BISON_OPTION_PUSHDEFS
# It seems impossible to find a generic scheme to check the location # It seems impossible to find a generic scheme to check the location
@@ -103,12 +116,12 @@ AT_CLEANUP
]) ])
## --------------------- ## ## ------------------- ##
## Prologue synch line. ## ## Prologue syncline. ##
## --------------------- ## ## ------------------- ##
AT_TEST_SYNCLINE([Prologue synch line], AT_TEST([Prologue syncline],
[[%{ [[%{
#error "2" #error "2"
]AT_YYERROR_DECLARE_EXTERN[ ]AT_YYERROR_DECLARE_EXTERN[
@@ -122,11 +135,11 @@ exp: '0';
]) ])
## ------------------- ## ## ----------------- ##
## %union synch line. ## ## %union syncline. ##
## ------------------- ## ## ----------------- ##
AT_TEST_SYNCLINE([%union synch line], AT_TEST([%union syncline],
[[%union { [[%union {
#error "2" #error "2"
char dummy; char dummy;
@@ -143,11 +156,11 @@ exp: '0';
]) ])
## ------------------------- ## ## ----------------------- ##
## Postprologue synch line. ## ## Postprologue syncline. ##
## ------------------------- ## ## ----------------------- ##
AT_TEST_SYNCLINE([Postprologue synch line], AT_TEST([Postprologue syncline],
[[%{ [[%{
]AT_YYERROR_DECLARE_EXTERN[ ]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[ ]AT_YYLEX_DECLARE_EXTERN[
@@ -167,11 +180,11 @@ exp: '0';
]) ])
## ------------------- ## ## ----------------- ##
## Action synch line. ## ## Action syncline. ##
## ------------------- ## ## ----------------- ##
AT_TEST_SYNCLINE([Action synch line], AT_TEST([Action syncline],
[[%{ [[%{
]AT_YYERROR_DECLARE_EXTERN[ ]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[ ]AT_YYLEX_DECLARE_EXTERN[
@@ -186,11 +199,11 @@ exp:
]) ])
## --------------------- ## ## ------------------- ##
## Epilogue synch line. ## ## Epilogue syncline. ##
## --------------------- ## ## ------------------- ##
AT_TEST_SYNCLINE([Epilogue synch line], AT_TEST([Epilogue syncline],
[[%{ [[%{
]AT_YYERROR_DECLARE_EXTERN[ ]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[ ]AT_YYLEX_DECLARE_EXTERN[
@@ -202,3 +215,5 @@ exp: '0';
]], ]],
[input.y:8: #error "8" [input.y:8: #error "8"
]) ])
m4_popdef([AT_TEST])