Compare commits

...
31 Commits
Author SHA1 Message Date
Yijun Yu 1d8565537b b4_yaxx macro enables saving parsing trees into XML, tested on 1.875-3.0.4, see https://github.com/yijunyu/yaxx 2017-03-11 17:33:40 +00:00
Akim Demaille d6445ec10b Merge remote-tracking branch 'origin/maint'
* origin/maint:
  maint: post-release administrivia
  version 3.0.4
  gnulib: update
  build: re-enable compiler warnings, and fix them
  tests: c++: fix a C++03 conformance issue
  tests: fix a title
  c++: reserve 200 slots in the parser's stack
  tests: be more robust to unrecognized synclines, and try to recognize xlc
  tests: fix C++ conformance
  build: fix some warnings
  build: avoid infinite recursions on include_next
2015-01-23 15:17:35 +01:00
Akim Demaille 7ca7a3abf3 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2015-01-23 14:13:40 +01:00
Akim Demaille c4e686a1ab version 3.0.4
* NEWS: Record release date.
2015-01-23 13:53:53 +01:00
Akim Demaille 2646fd012d gnulib: update 2015-01-23 11:27:10 +01:00
Akim Demaille a2c525b34c build: re-enable compiler warnings, and fix them
There are warnings (-Wextra) in generated C++ code:

  ltlparse.cc: In member function 'ltlyy::parser::symbol_number_type
  ltlyy::parser::by_state::type_get() const':
  ltlparse.cc:452:33: warning: enumeral and non-enumeral type in
  conditional expression
      return state == empty_state ? empty_symbol : yystos_[state];

Reported by Alexandre Duret-Lutz.

It turns out that -Wall and -Wextra were disabled because of a stupid
typo.

* configure.ac: Fix the stupid typo.
* data/lalr1.cc, src/AnnotationList.c, src/InadequacyList.c,
* src/ielr.c, src/print.c, src/scan-code.l, src/symlist.c,
* src/symlist.h, src/symtab.c, src/tables.c, tests/actions.at,
* tests/calc.at, tests/cxx-type.at, tests/glr-regression.at,
* tests/named-refs.at, tests/torture.at:
Fix warnings, mostly issues about variables used only with assertions,
which are disabled with -DNDEBUG.
2015-01-23 07:52:50 +01:00
Akim Demaille 658b189348 tests: c++: fix a C++03 conformance issue
This fixes test 241 on xLC:

"input.y", line 42.11: 1540-0274 (S) The name lookup for "report" did not find a declaration.
"input.y", line 42.11: 1540-1292 (I) Static declarations are not considered for a function call if the function is not qualified.

where report is:

  static void
  report (std::ostream& yyo, int ival, float fval)
  {
    yyo << "ival: " << ival << ", fval: " <<  fval;
  }

and line 42 is:

  %printer { report (yyo, $$,       $<fval>$); } <ival>;

It turns out that indeed this function must not be declared static,
<http://stackoverflow.com/a/17662745/1353549>.  Let's put it into an
anonymous namespace.

Reported by Thomas Jahns.
http://lists.gnu.org/archive/html/bug-bison/2015-01/msg00059.html

* tests/actions.at (Qualified $$ in actions): Don't use "static",
prefer anonymous namespace.
2015-01-22 08:45:44 +01:00
Akim Demaille a06344172a tests: fix a title
* tests/conflicts.at: De-overquote.
2015-01-20 20:47:02 +01:00
Akim Demaille 573654ca9e c++: reserve 200 slots in the parser's stack
This is consistent with what is done with yacc.c and glr.c.  Because
it also avoids that the stack needs to be resized very soon, it should
help keeping tests about destructors more reliable.

Indeed, if the stack is created too small, very soon the C++ library
needs to enlarge it, which means creating a new one, copying the
elements from the initial one onto it, and then destroy the elements
of the initial stack: that would be a spurious call to a destructor.

Reported by Thomas Jahns.
http://lists.gnu.org/archive/html/bug-bison/2015-01/msg00059.html

* data/stack.hh (stack::stack): Reserve 200 slots.
* tests/c++.at: Remove traces of stack expansions.
2015-01-20 20:45:48 +01:00
Akim Demaille 0b0370ff42 tests: be more robust to unrecognized synclines, and try to recognize xlc
Reported by Thomas Jahns.
http://lists.gnu.org/archive/html/bug-bison/2015-01/msg00059.html

* tests/synclines.at (AT_SYNCLINES_COMPILE): Rename as...
(_AT_SYNCLINES_COMPILE): this.
Try to recognize xlc locations.
(AT_SYNCLINES_COMPILE): New.  Skips the test if we can't read the
synclines.
2015-01-20 18:16:09 +01:00
Akim Demaille eaa476a7e9 tests: fix C++ conformance
Reported by Thomas Jahns.
http://lists.gnu.org/archive/html/bug-bison/2015-01/msg00059.html

* tests/c++.at (Exception safety): Add missing include.
Don't use const_iterator for erase.
2015-01-20 18:04:24 +01:00
Akim Demaille 16832bf546 build: fix some warnings
Reported by John Horigan.
http://lists.gnu.org/archive/html/bug-bison/2015-01/msg00034.html

* src/graphviz.c, src/symtab.h: Address compiler warnings.
2015-01-18 15:41:15 +01:00
Akim Demaille eabb3df7aa Merge remote-tracking branch 'origin/maint' into origin/master
* origin/maint:
  doc: minor fixes
  gnulib: strtoul is considered obsolete and now useless
  c++: avoid warnings when destructors don't use $$
  maint: post-release administrivia
  version 3.0.3
  gnulib: update
2015-01-16 15:14:41 +01:00
Akim Demaille 0ab29b7c20 build: avoid infinite recursions on include_next
On MacOS X 10.5 PPC with Apple's GCC 4.0.1:

  % uname -a
  Darwin aria.cielonegro.org 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:57:0
  1 PDT 2009; root:xnu-1228.15.4~1/RELEASE_PPC Power Macintosh
  % gcc --version
  powerpc-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5493)
  Copyright (C) 2005 Free Software Foundation, Inc.
  This is free software; see the source for copying conditions.  There is NO
  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

building in place enters into an infinite recursion on "#include_next":

  % gmake V=1
  [snip]
  depbase=`echo lib/math.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
  gcc -std=gnu99    -I. -Ilib -I. -I./lib   -g -O2 -MT lib/math.o -MD -MP -MF $depbase.Tpo -c -o lib/math.o lib/math.c &&\
  mv -f $depbase.Tpo $depbase.Po
  In file included from lib/math.h:27,
                   from lib/math.h:27,
                   from lib/math.h:27,
                   from lib/math.h:27,
  [snip]
                   from lib/math.h:27,
                   from lib/math.h:27,
                   from lib/math.c:3:
  lib/math.h:27:23: error: #include nested too deeply
  Makefile:3414: recipe for target 'lib/math.o' failed
  gmake[2]: *** [lib/math.o] Error 1

Using -I./lib instead of -Ilib fixes the problem.

Reported by Pho.
<https://lists.gnu.org/archive/html/bison-patches/2014-01/msg00000.html>

* Makefile.am (AM_CPPFLAGS): Use -I./lib instead of -Ilib.
2015-01-16 10:52:17 +01:00
Akim Demaille 559b30881d doc: minor fixes
* doc/bison.texi: Fix warnings about colon in reference names.
* data/bison.m4, src/files.h: Fix comments.
* doc/Doxyfile.in: update.
2015-01-16 10:52:17 +01:00
Akim Demaille 88ffc4b907 gnulib: strtoul is considered obsolete and now useless
* bootstrap.conf: here.
2015-01-15 17:26:32 +01:00
Akim Demaille 3e82dfaa0d c++: avoid warnings when destructors don't use $$
* data/c++.m4: here.
2015-01-15 14:29:22 +01:00
Akim Demaille 11d820174f maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2015-01-15 10:24:34 +01:00
Akim Demaille 875ef1b90c symbol: use the first occurrence as an LHS as defining location
Currently on the following grammar:

    %type <foo> foo
    %%
    start: foo | bar | "baz"
    foo: foo
    bar: bar

bison reports:

    warning: 2 nonterminals useless in grammar [-Wother]
    warning: 4 rules useless in grammar [-Wother]
    1.13-15: warning: nonterminal useless in grammar: foo [-Wother]
     %type <foo> foo
                 ^^^
    3.14-16: warning: nonterminal useless in grammar: bar [-Wother]
     start: foo | bar | "baz"
                  ^^^
    [...]

i.e., the location of the first occurrence of a symbol is taken as its
definition point.  In the case of nonterminals, the first occurrence
as a left-hand side of a rule makes more sense:

    warning: 2 nonterminals useless in grammar [-Wother]
    warning: 4 rules useless in grammar [-Wother]
    4.1-3: warning: nonterminal useless in grammar: foo [-Wother]
     foo: foo
     ^^^
    5.1-3: warning: nonterminal useless in grammar: bar [-Wother]
     bar: bar
     ^^^
    [...]

* src/symtab.h, src/symtab.c (symbol::location_of_lhs): New.
(symbol_location_as_lhs_set): New.
* src/parse-gram.y (current_lhs): Use it.
* tests/reduce.at: Update locations.
2015-01-14 17:05:35 +01:00
Akim Demaille 650af77812 reduce: don't complain about rules whose lhs is useless
In the following grammar, the 'exp' nonterminal is trivially useless.
So, of course, its rules are useless too.

    %%
    input: '0' | exp
    exp: exp '+' exp | exp '-' exp | '(' exp ')'

Previously all the useless rules were reported, including those whose
left-hand side is the 'exp' nonterminal:

    warning: 1 nonterminal useless in grammar [-Wother]
    warning: 4 rules useless in grammar [-Wother]
    2.14-16: warning: nonterminal useless in grammar: exp [-Wother]
     input: '0' | exp
                  ^^^
    2.14-16: warning: rule useless in grammar [-Wother]
     input: '0' | exp
                  ^^^
  ! 3.6-16: warning: rule useless in grammar [-Wother]
  !  exp: exp '+' exp | exp '-' exp | '(' exp ')'
  !       ^^^^^^^^^^^
  ! 3.20-30: warning: rule useless in grammar [-Wother]
  !  exp: exp '+' exp | exp '-' exp | '(' exp ')'
  !                     ^^^^^^^^^^^
  ! 3.34-44: warning: rule useless in grammar [-Wother]
  !  exp: exp '+' exp | exp '-' exp | '(' exp ')'
  !                                   ^^^^^^^^^^^

The interest of being so verbose is dubious.  I suspect most of the
time nonterminals are not expected to be useless, so the user wants to
fix the nonterminal, not remove its rules.  And even if the user
wanted to get rid of its rules, the position of these rules probably
does not help more that just having the name of the nonterminal.

This commit discard these messages, marked with '!', and keep the
others.  In particular, we still report:

    2.14-16: warning: rule useless in grammar [-Wother]
     input: '0' | exp
                  ^^^

All the useless rules (including the '!' ones) are still reported in
the reports (xml, text, etc.); only the diagnostics on stderr change.

* src/gram.c (grammar_rules_useless_report): Don't complain about
useless rules whose lhs is useless.
* src/reduce.h, src/reduce.c (reduce_nonterminal_useless_in_grammar):
Take a sym_content as argument.
Adjust callers.
* tests/reduce.at (Useless Rules, Underivable Rules, Reduced Automaton):
Adjust.
2015-01-14 13:59:53 +01:00
Akim Demaille c03a8db0cc style: reduce: use unsigned to count a number of objects
* src/reduce.h, src/reduce.c (nuseful_productions, nuseless_productions)
(nuseful_nonterminals, nuseless_nonterminals): Declare as unsigned.
Simplify "0 <" tests into non-zero tests.
2015-01-14 10:13:49 +01:00
Akim Demaille 8b06c6b871 style: reduce: introduce and use a swap for bitset
* src/reduce.c (bitset_swap): New.
Use it.
2015-01-14 10:13:49 +01:00
Akim Demaille c5da1a2adc style: reduce: reduce scopes and other stylistic changes
* src/reduce.c: Various stylistic changes:
Reduce scopes.
Prefer ++i to i++.
Prefer < to >.
2015-01-14 10:13:30 +01:00
Akim Demaille dfd5b89d01 Merge remote-tracking branch 'origin/maint'
* origin/maint:
  tests: split a large test case into several smaller ones
  package: a bit of trouble shooting indications
  doc: liby's main arms the internationalization
  bison: avoid warnings from static code analysis
  c++: fix the use of destructors when variants are enabled
  style: tests: simplify the handling of some C++ tests
  c++: symbols can be empty, so use it
  c++: variants: don't leak the lookahead in error recovery
  c++: provide a means to clear symbols
  c++: clean up the handling of empty symbols
  c++: comment and style changes
  c++: variants: comparing addresses of typeid.name() is undefined
  c++: locations: complete the API and fix comments
  build: do not clean figure sources in make clean
2015-01-13 14:45:15 +01:00
Akim Demaille 13e294ee55 Merge remote-tracking branch 'origin/maint'
* origin/maint:
  build: don't try to generate docs when cross-compiling
  package: fix a reporter's name
  %union: fix the support for named %union
  package: bump to 2015
  flex: don't trust YY_USER_INIT
  yacc.c: fix broken union when api.value.type=union and %defines are used
  doc: fix missing xref
  gnulib: update
  location: remove some ugly debugging code traces
  build: use abort to pacify compiler errors
  package: bump to 2014
  doc: specify documentation encoding
2015-01-05 13:51:30 +01:00
Akim Demaille 8044fda634 symbols: properly fuse the properties of two symbol aliases
This completes and fixes a728075710.
Reported by Valentin Tolmer.

Before it Bison used to put the properties of the symbols
(associativity, printer, etc.) in the 'symbol' structure.  An
identifier-named token (FOO) and its string-named alias ("foo")
duplicated these properties, and symbol_check_alias_consistency()
checked that both had compatible properties and fused them, at the end
of the parsing of the grammar.

The commit a728075710 introduces a
sym_content structure that keeps all these properties, and ensures
that both aliases point to the same sym_content (instead of
duplicating).  However, it removed symbol_check_alias_consistency,
which resulted in the non-fusion of *existing* properties:

  %token FOO "foo"
  %left FOO %left "foo"

was properly diagnosed as a redeclaration, but

  %left FOO %left "foo"
  %token FOO "foo"

was not, as the properties of FOO and "foo" were not checked before
fusion.  It certainly also means that

  %left "foo"
  %token FOO "foo"

did not transfer properly the associativity to FOO.

The fix is simple: reintroduce symbol_check_alias_consistency (under a
better name, symbol_merge_properties) and call it where appropriate.

Also, that commit made USER_NUMBER_HAS_STRING_ALIAS useless, but left
it.

* src/symtab.h (USER_NUMBER_HAS_STRING_ALIAS): Remove, unused.
Adjust dependencies.
* src/symtab.c (symbol_merge_properties): New, based on the former
symbol_check_alias_consistency.
* tests/input.at: Re-enable tests that we now pass.
2013-12-10 09:43:33 +01:00
Akim Demaille b7d4c48e55 Merge remote-tracking branch 'origin/maint'
* origin/maint:
  package: install the examples
  package: install README and the like in docdir
  diagnostics: fix the order of multiple declarations reports
  symbol: provide an easy means to compare them in source order

Conflicts:
  src/symtab.c
  tests/input.at

* tests/input.at: Comment out a test that master currently does not
pass (because of a728075710).
2013-12-10 08:53:07 +01:00
Akim Demaille fc6c85664a Merge remote-tracking branch 'origin/maint'
* origin/maint: (43 commits)
  maint: post-release administrivia
  version 3.0.2
  gnulib: update
  output: do not generate source files when late errors are caught
  output: record what generated files are source or report files
  output: do not generate source files when early errors are caught
  xml: also use "%empty" with html output
  style: formatting changes
  xml: also display %empty for empty right-hand sides
  reports: display %empty in the generated pointed-rules
  news: YYERROR vs variants
  style: scope reduction in lalr.cc
  lalr1.cc: formatting changes
  lalr1.cc: fix the support of YYERROR with variants
  tests: check $$'s destruction with variant, YYERROR, and no error recovery
  tests: simplify useless obfuscation
  skeletons: use better names when computing a "goto"
  maint: post-release administrivia
  version 3.0.1
  aver: it is no longer "protected against NDEBUG"
  ...

Conflicts:
  data/glr.c
2013-12-09 10:43:37 +01:00
Akim Demaille 4f3cc9c21b Merge remote-tracking branch 'origin/maint'
* origin/maint:
  glr: more assertions
  glr: shorten scopes
  glr: formatting changes
  glr: better use of tracing macros
  examples: improve the output of the "variant" example
  variant: remove useless assertion
  tests: remove stray debugging traces
  tests: do not use grep -q
  build: don't require flex for ordinary builds
  maint: update .gitignore
  build: port to pre-5.8.7 perl
  tests: minor change to make it easier to test other skeletons
  uniqstr: fix assertion
2013-09-19 16:33:20 +02:00
Akim Demaille 55a2063005 glr: simplify the invocation of YYLLOC_DEFAULT
The commit which introduces yyresolveLocations (commit
8710fc41aa) saves and restores the
look-ahead (type, value and location) for no clear reason.  This
appears to be useless.

* data/glr.c (yyresolveLocations): Don't save/restore the current
look-ahead to call YYLLOC_DEFAULT.
Minor style changes.
2013-09-19 16:14:07 +02:00
Valentin TolmerandAkim Demaille a728075710 symbols: improve symbol aliasing
Rather than having duplicate info in the symbol and the alias that has
to be resolved later on, both the symbol and the alias have a common
pointer to a separate structure containing this info.

* src/symtab.h (sym_content): New structure.
* src/symtab.c (sym_content_new, sym_content_free, symbol_free): New

* src/AnnotationList.c, src/conflicts.c, src/gram.c, src/gram.h,
* src/graphviz.c, src/ielr.c, src/output.c, src/parse-gram.y, src/print.c
* src/print-xml.c, src/print_graph.c, src/reader.c, src/reduce.c,
* src/state.h, src/symlist.c, src/symtab.c, src/symtab.h, src/tables.c:
Adjust.

* tests/input.at: Fix expectations (order changes).
2013-08-01 12:49:51 +02:00
52 changed files with 2303 additions and 1437 deletions
+1 -1
View File
@@ -1 +1 @@
3.0.2 3.0.4
+3 -2
View File
@@ -39,8 +39,9 @@ AM_YFLAGS = -d -v -Werror -Wall -Wno-yacc --report=all
# Initialization before completion by local.mk's. # Initialization before completion by local.mk's.
AM_CFLAGS = $(WARN_CFLAGS) AM_CFLAGS = $(WARN_CFLAGS)
# Find builddir/src/scan-code.c etc. # Find builddir/src/scan-code.c etc. For some reason "-I./lib"
AM_CPPFLAGS = -I. -Ilib -I$(top_srcdir) -I$(top_srcdir)/lib # instead of "-Ilib" avoids infinite recursions on #include_next.
AM_CPPFLAGS = -I. -I./lib -I$(top_srcdir) -I$(top_srcdir)/lib
BUILT_SOURCES = BUILT_SOURCES =
CLEANFILES = CLEANFILES =
DISTCLEANFILES = DISTCLEANFILES =
+57
View File
@@ -1,5 +1,62 @@
GNU Bison NEWS GNU Bison NEWS
* Noteworthy changes in release ?.? (????-??-??) [?]
** Diagnostics about useless rules
In the following grammar, the 'exp' nonterminal is trivially useless. So,
of course, its rules are useless too.
%%
input: '0' | exp
exp: exp '+' exp | exp '-' exp | '(' exp ')'
Previously all the useless rules were reported, including those whose
left-hand side is the 'exp' nonterminal:
warning: 1 nonterminal useless in grammar [-Wother]
warning: 4 rules useless in grammar [-Wother]
2.14-16: warning: nonterminal useless in grammar: exp [-Wother]
input: '0' | exp
^^^
2.14-16: warning: rule useless in grammar [-Wother]
input: '0' | exp
^^^
3.6-16: warning: rule useless in grammar [-Wother]
exp: exp '+' exp | exp '-' exp | '(' exp ')'
^^^^^^^^^^^
3.20-30: warning: rule useless in grammar [-Wother]
exp: exp '+' exp | exp '-' exp | '(' exp ')'
^^^^^^^^^^^
3.34-44: warning: rule useless in grammar [-Wother]
exp: exp '+' exp | exp '-' exp | '(' exp ')'
^^^^^^^^^^^
Now, rules whose left-hand side symbol is useless are no longer reported
as useless. The locations of the errors have also been adjusted to point
to the first use of the nonterminal as a left-hand side of a rule:
warning: 1 nonterminal useless in grammar [-Wother]
warning: 4 rules useless in grammar [-Wother]
3.1-3: warning: nonterminal useless in grammar: exp [-Wother]
exp: exp '+' exp | exp '-' exp | '(' exp ')'
^^^
2.14-16: warning: rule useless in grammar [-Wother]
input: '0' | exp
^^^
* Noteworthy changes in release 3.0.4 (2015-01-23) [stable]
** Bug fixes
*** C++ with Variants (lalr1.cc)
Fix a compiler warning when no %destructor use $$.
*** Test suites
Several portability issues in tests were fixed.
* Noteworthy changes in release 3.0.3 (2015-01-15) [stable] * Noteworthy changes in release 3.0.3 (2015-01-15) [stable]
** Bug fixes ** Bug fixes
+2
View File
@@ -66,6 +66,7 @@ Jim Kent [email protected]
Jim Meyering [email protected] Jim Meyering [email protected]
Joel E. Denny [email protected] Joel E. Denny [email protected]
Johan van Selst [email protected] Johan van Selst [email protected]
John Horigan [email protected]
Jonathan Fabrizio [email protected] Jonathan Fabrizio [email protected]
Jonathan Nieder [email protected] Jonathan Nieder [email protected]
Juan Manuel Guerrero [email protected] Juan Manuel Guerrero [email protected]
@@ -113,6 +114,7 @@ Peter Fales [email protected]
Peter Hamorsky [email protected] Peter Hamorsky [email protected]
Peter Simons [email protected] Peter Simons [email protected]
Petr Machata [email protected] Petr Machata [email protected]
Pho [email protected]
Piotr Gackiewicz [email protected] Piotr Gackiewicz [email protected]
Quentin Hocquet [email protected] Quentin Hocquet [email protected]
Quoc Peyrot [email protected] Quoc Peyrot [email protected]
+1 -1
View File
@@ -33,7 +33,7 @@ gnulib_modules='
quote quotearg quote quotearg
readme-release readme-release
realloc-posix realloc-posix
spawn-pipe stdbool stpcpy strdup-posix strerror strtoul strverscmp spawn-pipe stdbool stpcpy strdup-posix strerror strverscmp
unistd unistd-safer unlink unlocked-io unistd unistd-safer unlink unlocked-io
update-copyright unsetenv verify update-copyright unsetenv verify
warnings warnings
+1 -1
View File
@@ -81,7 +81,7 @@ AC_ARG_ENABLE([gcc-warnings],
[enable_gcc_warnings=no]) [enable_gcc_warnings=no])
AM_CONDITIONAL([ENABLE_GCC_WARNINGS], [test "$enable_gcc_warnings" = yes]) AM_CONDITIONAL([ENABLE_GCC_WARNINGS], [test "$enable_gcc_warnings" = yes])
if test "$enable_gcc_warnings" = yes; then if test "$enable_gcc_warnings" = yes; then
warn_common='-Wall-Wextra -Wno-sign-compare -Wcast-align -Wdocumentation warn_common='-Wall -Wextra -Wno-sign-compare -Wcast-align -Wdocumentation
-Wformat -Wpointer-arith -Wwrite-strings' -Wformat -Wpointer-arith -Wwrite-strings'
warn_c='-Wbad-function-cast -Wshadow -Wstrict-prototypes' warn_c='-Wbad-function-cast -Wshadow -Wstrict-prototypes'
warn_cxx='-Wnoexcept' warn_cxx='-Wnoexcept'
-1
View File
@@ -437,7 +437,6 @@ m4_define([b4_symbol_action_location],
# b4_symbol_action(SYMBOL-NUM, KIND) # b4_symbol_action(SYMBOL-NUM, KIND)
# ---------------------------------- # ----------------------------------
# Run the action KIND (destructor or printer) for SYMBOL-NUM. # Run the action KIND (destructor or printer) for SYMBOL-NUM.
# Same as in C, but using references instead of pointers.
m4_define([b4_symbol_action], m4_define([b4_symbol_action],
[b4_symbol_if([$1], [has_$2], [b4_symbol_if([$1], [has_$2],
[b4_dollar_pushdef([(*yyvaluep)], [b4_dollar_pushdef([(*yyvaluep)],
+1
View File
@@ -347,6 +347,7 @@ m4_define([b4_public_types_define],
// User destructor. // User destructor.
symbol_number_type yytype = this->type_get (); symbol_number_type yytype = this->type_get ();
basic_symbol<Base>& yysym = *this; basic_symbol<Base>& yysym = *this;
(void) yysym;
switch (yytype) switch (yytype)
{ {
]b4_symbol_foreach([b4_symbol_destructor])dnl ]b4_symbol_foreach([b4_symbol_destructor])dnl
+4 -15
View File
@@ -1692,7 +1692,7 @@ yyreportAmbiguity (yySemanticOption* yyx0,
* ending at YYS1. Has no effect on previously resolved states. * ending at YYS1. Has no effect on previously resolved states.
* The first semantic option of a state is always chosen. */ * The first semantic option of a state is always chosen. */
static void static void
yyresolveLocations (yyGLRState* yys1, int yyn1, yyresolveLocations (yyGLRState *yys1, int yyn1,
yyGLRStack *yystackp]b4_user_formals[) yyGLRStack *yystackp]b4_user_formals[)
{ {
if (0 < yyn1) if (0 < yyn1)
@@ -1703,9 +1703,9 @@ yyresolveLocations (yyGLRState* yys1, int yyn1,
yyGLRStackItem yyrhsloc[1 + YYMAXRHS]; yyGLRStackItem yyrhsloc[1 + YYMAXRHS];
int yynrhs; int yynrhs;
yySemanticOption *yyoption = yys1->yysemantics.yyfirstVal; yySemanticOption *yyoption = yys1->yysemantics.yyfirstVal;
YYASSERT (yyoption != YY_NULLPTR); YYASSERT (yyoption);
yynrhs = yyrhsLength (yyoption->yyrule); yynrhs = yyrhsLength (yyoption->yyrule);
if (yynrhs > 0) if (0 < yynrhs)
{ {
yyGLRState *yys; yyGLRState *yys;
int yyn; int yyn;
@@ -1728,18 +1728,7 @@ yyresolveLocations (yyGLRState* yys1, int yyn1,
yyGLRState *yyprevious = yyoption->yystate; yyGLRState *yyprevious = yyoption->yystate;
yyrhsloc[0].yystate.yyloc = yyprevious->yyloc; yyrhsloc[0].yystate.yyloc = yyprevious->yyloc;
} }
{ YYLLOC_DEFAULT ((yys1->yyloc), yyrhsloc, yynrhs);
int yychar_current = yychar;
YYSTYPE yylval_current = yylval;
YYLTYPE yylloc_current = yylloc;
yychar = yyoption->yyrawchar;
yylval = yyoption->yyval;
yylloc = yyoption->yyloc;
YYLLOC_DEFAULT ((yys1->yyloc), yyrhsloc, yynrhs);
yychar = yychar_current;
yylval = yylval_current;
yylloc = yylloc_current;
}
} }
} }
}]])[ }]])[
+11 -3
View File
@@ -149,10 +149,11 @@ b4_variant_if([m4_include(b4_pkgdatadir/[variant.hh])])
m4_define([b4_shared_declarations], m4_define([b4_shared_declarations],
[b4_percent_code_get([[requires]])[ [b4_percent_code_get([[requires]])[
]b4_parse_assert_if([# include <cassert>])[ ]b4_parse_assert_if([# include <cassert>])[
# include <vector> # include <cstdlib> // std::abort
# include <iostream> # include <iostream>
# include <stdexcept> # include <stdexcept>
# include <string>]b4_defines_if([[ # include <string>
# include <vector>]b4_defines_if([[
# include "stack.hh" # include "stack.hh"
]b4_bison_locations_if([[# include "location.hh"]])])[ ]b4_bison_locations_if([[# include "location.hh"]])])[
]b4_variant_if([b4_variant_includes])[ ]b4_variant_if([b4_variant_includes])[
@@ -569,7 +570,10 @@ m4_if(b4_prefix, [yy], [],
]b4_parser_class_name[::symbol_number_type ]b4_parser_class_name[::symbol_number_type
]b4_parser_class_name[::by_state::type_get () const ]b4_parser_class_name[::by_state::type_get () const
{ {
return state == empty_state ? empty_symbol : yystos_[state]; if (state == empty_state)
return empty_symbol;
else
return yystos_[state];
} }
inline inline
@@ -622,6 +626,10 @@ m4_if(b4_prefix, [yy], [],
std::ostream& yyoutput = yyo; std::ostream& yyoutput = yyo;
YYUSE (yyoutput); YYUSE (yyoutput);
symbol_number_type yytype = yysym.type_get (); symbol_number_type yytype = yysym.type_get ();
// Avoid a (spurious) G++ 4.8 warning about "array subscript is
// below array bounds".
if (yysym.empty ())
std::abort ();
yyo << (yytype < yyntokens_ ? "token" : "nterm") yyo << (yytype < yyntokens_ ? "token" : "nterm")
<< ' ' << yytname_[yytype] << " ("]b4_locations_if([ << ' ' << yytname_[yytype] << " ("]b4_locations_if([
<< yysym.location << ": "])[; << yysym.location << ": "])[;
+3 -4
View File
@@ -32,12 +32,12 @@ m4_define([b4_stack_define],
stack () stack ()
: seq_ () : seq_ ()
{ {
seq_.reserve (200);
} }
stack (unsigned int n) stack (unsigned int n)
: seq_ (n) : seq_ (n)
{ {}
}
inline inline
T& T&
@@ -114,8 +114,7 @@ m4_define([b4_stack_define],
slice (const S& stack, unsigned int range) slice (const S& stack, unsigned int range)
: stack_ (stack) : stack_ (stack)
, range_ (range) , range_ (range)
{ {}
}
inline inline
const T& const T&
+319 -12
View File
@@ -52,6 +52,8 @@ m4_define([b4_lac_flag],
[none], [[0]], [[1]])]) [none], [[0]], [[1]])])
m4_include(b4_pkgdatadir/[c.m4]) m4_include(b4_pkgdatadir/[c.m4])
m4_define([b4_yaxx],[$1])
m4_define([b4_not_yaxx],[])
## ---------------- ## ## ---------------- ##
## Default values. ## ## Default values. ##
@@ -331,7 +333,11 @@ m4_if(b4_api_prefix, [yy], [],
#define yydebug ]b4_prefix[debug #define yydebug ]b4_prefix[debug
#define yynerrs ]b4_prefix[nerrs #define yynerrs ]b4_prefix[nerrs
]]b4_pure_if([], [[ ]]b4_pure_if([], [[
#define yylval ]b4_prefix[lval #define yylval ]b4_prefix[lval]b4_yaxx([
#define yytext ]b4_prefix[text
#define YYYAXX_XML "b4_prefix[]yaxx.xml"
#define YYYAXX_DTD "b4_prefix[]yaxx.dtd"
])[
#define yychar ]b4_prefix[char]b4_locations_if([[ #define yychar ]b4_prefix[char]b4_locations_if([[
#define yylloc ]b4_prefix[lloc]])]))[ #define yylloc ]b4_prefix[lloc]])]))[
@@ -420,6 +426,10 @@ typedef short int yytype_int16;
/* The parser invokes alloca or malloc; define the necessary symbols. */]dnl /* The parser invokes alloca or malloc; define the necessary symbols. */]dnl
b4_push_if([], [b4_lac_if([], [[ b4_push_if([], [b4_lac_if([], [[
]b4_yaxx([
#define XML_ALLOC(X) malloc(X)
#define XML_FREE(X) free(X)
])[
# ifdef YYSTACK_USE_ALLOCA # ifdef YYSTACK_USE_ALLOCA
# if YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA
# ifdef __GNUC__ # ifdef __GNUC__
@@ -494,7 +504,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
union yyalloc union yyalloc
{ {
yytype_int16 yyss_alloc; yytype_int16 yyss_alloc;
YYSTYPE yyvs_alloc;]b4_locations_if([ YYSTYPE yyvs_alloc;]b4_yaxx([char *yyxs_alloc;])[]b4_locations_if([
YYLTYPE yyls_alloc;])[ YYLTYPE yyls_alloc;])[
}; };
@@ -505,10 +515,10 @@ union yyalloc
N elements. */ N elements. */
]b4_locations_if( ]b4_locations_if(
[# define YYSTACK_BYTES(N) \ [# define YYSTACK_BYTES(N) \
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE) ]b4_yaxx([+ sizeof(char*) ])[) \
+ 2 * YYSTACK_GAP_MAXIMUM)], + 2 * YYSTACK_GAP_MAXIMUM)],
[# define YYSTACK_BYTES(N) \ [# define YYSTACK_BYTES(N) \
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) ]b4_yaxx([+ sizeof(char*) ])[) \
+ YYSTACK_GAP_MAXIMUM)])[ + YYSTACK_GAP_MAXIMUM)])[
# define YYCOPY_NEEDED 1 # define YYCOPY_NEEDED 1
@@ -580,19 +590,27 @@ static const ]b4_int_type_for([b4_translate])[ yytranslate[] =
]b4_translate[ ]b4_translate[
}; };
]b4_not_yaxx([
#if ]b4_api_PREFIX[DEBUG #if ]b4_api_PREFIX[DEBUG
])[
]b4_integral_parser_table_define([rline], [b4_rline], ]b4_integral_parser_table_define([rline], [b4_rline],
[[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[ [[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
]b4_not_yaxx([
#endif #endif
])[
]b4_not_yaxx([
#if ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[ #if ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[
])[
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at YYNTOKENS, nonterminals. */ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] = static const char *const yytname[] =
{ {
]b4_tname[ ]b4_tname[
}; };
]b4_not_yaxx([
#endif #endif
])
# ifdef YYPRINT # ifdef YYPRINT
/* YYTOKNUM[NUM] -- (External) token number corresponding to the /* YYTOKNUM[NUM] -- (External) token number corresponding to the
@@ -1366,7 +1384,194 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
[[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([, [[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([,
[[[YYLTYPE *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [, [[[YYLTYPE *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
b4_parse_param]))], [[ b4_parse_param]))], [[
]b4_yaxx([
extern char *b4_prefix[]text;
// Yijun Yu: utility functions -----------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
/// replace character terminals into symbolic terminals
static char *YYTNAME(int r)
{
static char yytname_buf[[8]];
if (strlen(yytname[[r]])==3 && yytname[[r]][[0]] == '\'' && yytname[[r]][[2]] == '\'')
{
sprintf(yytname_buf, "CHAR%d", (int)yytname[[r]][[1]]);
return yytname_buf;
}
else if (strlen(yytname[[r]])>=2 && yytname[[r]][[0]] == 64 )
{
strcpy(yytname_buf,"ACTION");
strcat(yytname_buf,&(yytname[[r]][[1]]));
return yytname_buf;
}
return (char *)yytname[[r]];
}
#include <stdio.h>
#include <stddef.h>
static char *yytext_buf = NULL;
/// replace a special character in the text into an entity
static
void replace_entity(char c, char *s)
{
char *buf;
char *i;
int len, l;
i = yytext_buf;
do {
i = (char *)index(i, c);
if (i) {
l = i - yytext_buf;
len = strlen(yytext_buf) + strlen(s) - 1;
//buf = (char*)YYSTACK_ALLOC(1000000);
buf = (char*)YYSTACK_ALLOC(len + 1); // Myo M Thein
if (l>0) {
#if 1 // Myo M Thein
strncpy(buf, yytext_buf, l);
#else
int t = 0;
while (t < l) {
buf[t] = yytext_buf[t];
t++;
}
buf[t] = 0;
#endif
} else {
buf[[0]] = 0;
}
strcat(buf, s);
strncat(buf, yytext_buf + l + 1, strlen(yytext_buf) - l);
buf[[len]] = 0;
YYSTACK_FREE(yytext_buf);
//yytext_buf = buf;
memcpy(yytext_buf,buf,len+1);
i++;
if (*i=='\0')
i=NULL;
}
} while (i);
}
/// replace the special characters in the text into entities
static
char* xml_encode( char ch)
{
static char text[[2]];
switch(ch)
{
case '&':
return ( "&amp;");
break;
case '>':
return ( "&gt;");
break;
case '<' :
return ( "&lt;" );
break;
case '\"':
return ( "&quot;");
break;
case '\'':
return ( "&apos;");
break;
default:
text[[0]]=ch;
text[[1]]=0;
return text;
break;
}
}
static
void replace_special_entities(char *text,char *text_out)
{
int i,lg;
if (!text) { strcpy(text_out,"??");return ; }
lg = strlen(text);
strcpy(text_out,"");
for (i=0;i<lg;i++)
{
strcat(text_out,xml_encode(text[[i]]));
}
}
static
void generate_xml_output(char **yyxsp,char **yyxs)
{
#ifndef YYYAXX_XML
#define YYYAXX_XML "yaxx.xml"
#endif
#ifndef YYYAXX_DTD
#define YYYAXX_DTD "yaxx.dtd"
#endif
int r, i, j;
char buf[[2000]];
int old_rule = 0;
FILE *stdout = fopen(YYYAXX_XML, "w");
char *p = *yyxsp + 6;
#if 0
char *v = strsep(&p, ">");
strcpy(buf, v);
#else
i = 0;
while (p[[i]]!='>') {
buf[[i]] = p[[i]];
i++;
}
buf[[i]] = 0;
#endif
/// Generating the XML document
/// version
fprintf(stdout,"<?xml version=\"1.0\"?>\n");
/// DTD reference
fprintf(stdout,"<?xml-stylesheet type=\"text/xsl\" href=\"yaxx.xsl\"?>");
fprintf(stdout,"<!DOCTYPE %s SYSTEM \"" YYYAXX_DTD "\">\n", buf);
/// inserting name space before the XML data
fprintf(stdout,"<yaxx:%s xmlns:yaxx=\"urn:YAcc-Xml-eXtension\"%s\n", buf,
yyxs[[1]]+i+6); //ffprintf(stdout,f, "%s\n", yyxs[[1]]);
/// Generating the document type definition (DTD)
stdout = fopen(YYYAXX_DTD , "w");
/// DTD for non-terminals
for (r = 2; r < sizeof(yyr1)/sizeof(unsigned short); r++)
{
j = yyr1[[r]];
if (j != old_rule) {
if (old_rule!=0)
fprintf(stdout,")>\n");
fprintf(stdout,"<!ELEMENT %s (", YYTNAME(yyr1[[r]]));
} else
fprintf(stdout," | ");
if (yyr2[[r]]==0)
fprintf(stdout,"EMPTY");
else {
/*
int multiple = 0;
for (i = yyprhs[[r]]; yyrhs[[i]] > 0 ; i++)
if (i!=yyprhs[[r]]) {
multiple = 1; break;
}
if (multiple) fprintf(stdout,"(");
for (i = yyprhs[[r]]; yyrhs[[i]] > 0 ; i++) {
if (i!=yyprhs[[r]])
fprintf(stdout,",");
fprintf(stdout,"%s", YYTNAME(yyrhs[[i]]));
}
if (multiple) fprintf(stdout,")");
*/
}
old_rule = j;
}
fprintf(stdout,")>\n");
/// DTD for terminals
for (r = 3; r < YYNTOKENS; r++)
{
fprintf(stdout,"<!ELEMENT %s (#PCDATA)>\n", YYTNAME(r));
}
}
])[
/*----------. /*----------.
| yyparse. | | yyparse. |
@@ -1398,7 +1603,26 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
YYSIZE_T yymsg_alloc = sizeof yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif #endif
]b4_yaxx([
/* The tags stack. */
char *yyxsa[[YYINITDEPTH]];
char **yyxs = yyxsa;
char **yyxsp;
])[
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp -= (N)])[) #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp -= (N)])[)
]b4_yaxx([
#include <stdio.h>
#include <string.h>
#undef __GNUC_PREREQ
#define __GNUC_PREREQ(maj, min) (maj < 4)
#include <stdlib.h>
#include <stddef.h>
static char * yyxml_str=NULL; // for XML
// for id attribute generation (by William Candillon)
int _id = 0;
char str[[256]];
])[
/* The number of symbols on the RHS of the reduced rule. /* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */ Keep to zero when no symbol should be popped. */
@@ -1410,7 +1634,9 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
goto yyread_pushed_token; goto yyread_pushed_token;
}]])[ }]])[
yyssp = yyss = yyssa; yyssp = yyss = yyssa;]b4_yaxx([
yyxsp = yyxs = yyxsa;
])[
yyvsp = yyvs = yyvsa;]b4_locations_if([[ yyvsp = yyvs = yyvsa;]b4_locations_if([[
yylsp = yyls = yylsa;]])[ yylsp = yyls = yylsa;]])[
yystacksize = YYINITDEPTH;]b4_lac_if([[ yystacksize = YYINITDEPTH;]b4_lac_if([[
@@ -1460,7 +1686,7 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
these so that the &'s don't force the real ones into these so that the &'s don't force the real ones into
memory. */ memory. */
YYSTYPE *yyvs1 = yyvs; YYSTYPE *yyvs1 = yyvs;
yytype_int16 *yyss1 = yyss;]b4_locations_if([ yytype_int16 *yyss1 = yyss;]b4_yaxx([ char **yyxs1 = yyxs;])[]b4_locations_if([
YYLTYPE *yyls1 = yyls;])[ YYLTYPE *yyls1 = yyls;])[
/* Each stack pointer address is followed by the size of the /* Each stack pointer address is followed by the size of the
@@ -1469,9 +1695,9 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
be undefined if yyoverflow is a macro. */ be undefined if yyoverflow is a macro. */
yyoverflow (YY_("memory exhausted"), yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp), &yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),]b4_locations_if([ &yyvs1, yysize * sizeof (*yyvsp),]b4_yaxx([&yyxs1, yysize * sizeof (*yyxsp),])[]b4_locations_if([
&yyls1, yysize * sizeof (*yylsp),])[ &yyls1, yysize * sizeof (*yylsp),])[
&yystacksize); &yystacksize);]b4_yaxx([yyxs = yyxs1;])[
]b4_locations_if([ ]b4_locations_if([
yyls = yyls1;])[ yyls = yyls1;])[
yyss = yyss1; yyss = yyss1;
@@ -1495,7 +1721,7 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
if (! yyptr) if (! yyptr)
goto yyexhaustedlab; goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([ YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_yaxx([YYSTACK_RELOCATE (yyxs_alloc, yyxs);])[]b4_locations_if([
YYSTACK_RELOCATE (yyls_alloc, yyls);])[ YYSTACK_RELOCATE (yyls_alloc, yyls);])[
# undef YYSTACK_RELOCATE # undef YYSTACK_RELOCATE
if (yyss1 != yyssa) if (yyss1 != yyssa)
@@ -1505,7 +1731,7 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
#endif /* no yyoverflow */ #endif /* no yyoverflow */
yyssp = yyss + yysize - 1; yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;]b4_locations_if([ yyvsp = yyvs + yysize - 1;]b4_yaxx([yyxsp = yyxs + yysize - 1;])[]b4_locations_if([
yylsp = yyls + yysize - 1;])[ yylsp = yyls + yysize - 1;])[
YYDPRINTF ((stderr, "Stack size increased to %lu\n", YYDPRINTF ((stderr, "Stack size increased to %lu\n",
@@ -1570,7 +1796,33 @@ yyread_pushed_token:]])[
} }
else else
{ {
yytoken = YYTRANSLATE (yychar); yytoken = YYTRANSLATE (yychar);]b4_yaxx([
{ // Yijun Yu: process the terminal
yyxml_str = (char *) XML_ALLOC(200);
strcpy(yyxml_str, "<yaxx:");
strcat(yyxml_str, YYTNAME(yytoken));
#if 1 //William Candillon
strcat(yyxml_str, " id=\"");
sprintf(str, "%x", _id);
strcat(yyxml_str, str);
strcat(yyxml_str, "\"");
_id++;
#endif
strcat(yyxml_str, ">");
if (yytoken < YYNTOKENS) {
if (yytext) {
char *tmp;
tmp=(char *)YYSTACK_ALLOC(6*strlen(yytext)+1);
replace_special_entities(yytext,tmp);
strcat(yyxml_str, tmp);
YYSTACK_FREE(tmp);
}
}
strcat(yyxml_str, "</yaxx:");
strcat(yyxml_str, YYTNAME(yytoken));
strcat(yyxml_str, ">\n");
}
])[
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
} }
@@ -1607,6 +1859,10 @@ yyread_pushed_token:]])[
yystate = yyn; yystate = yyn;
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
]b4_yaxx([
*++yyxsp = yyxml_str;
yyxml_str = 0;
])[
*++yyvsp = yylval; *++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END YY_IGNORE_MAYBE_UNINITIALIZED_END
]b4_locations_if([ *++yylsp = yylloc;])[ ]b4_locations_if([ *++yylsp = yylloc;])[
@@ -1654,6 +1910,53 @@ yyreduce:
if (yychar_backup != yychar) if (yychar_backup != yychar)
YY_LAC_DISCARD ("yychar change"); YY_LAC_DISCARD ("yychar change");
}]], [[ }]], [[
]b4_yaxx([
{
int len = 0;
int alloc_len=0;
int n = 0;
int yyi;
for (yyi = 0; yyi < yylen; yyi++)
{
int l;
char * yyxml_str = yyxsp[[yyi+1-yylen]];
if (yyxml_str==NULL) {
l = 0;
} else
l = strlen(yyxml_str);
len += l;
n++;
}
alloc_len =len+100+2*strlen(YYTNAME(yyr1[[yyn]]));
yyxml_str = (char *) XML_ALLOC(alloc_len);
strcpy(yyxml_str, "<yaxx:");
strcat(yyxml_str, YYTNAME(yyr1[[yyn]]));
#if 1 //William Candillon
strcat(yyxml_str, " id=\"");
sprintf(str, "%x", _id);
strcat(yyxml_str, str);
strcat(yyxml_str, "\"");
_id++;
#endif
strcat(yyxml_str, ">\n");
for (yyi = 0; yyi < yylen; yyi++)
{
char * xml_str = yyxsp[[yyi+1-yylen]];
if (xml_str) {
strcat(yyxml_str, xml_str);
XML_FREE(xml_str);
yyxsp[[yyi+1-yylen]] = NULL;
} else {
fprintf(stderr, "Warning! the %d-th argument is empty", yyi+1);
}
}
strcat(yyxml_str, "</yaxx:");
strcat(yyxml_str, YYTNAME(yyr1[[yyn]]));
strcat(yyxml_str, ">\n");
yyxsp -= n;
*++yyxsp = yyxml_str;
yyxml_str = NULL;
}])[
switch (yyn) switch (yyn)
{ {
]b4_user_actions[ ]b4_user_actions[
@@ -1829,6 +2132,10 @@ yyerrlab1:
YY_LAC_DISCARD ("error recovery");]])[ YY_LAC_DISCARD ("error recovery");]])[
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
]b4_yaxx([
*++yyxsp = yyxml_str;
yyxml_str = 0;
])[
*++yyvsp = yylval; *++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END YY_IGNORE_MAYBE_UNINITIALIZED_END
]b4_locations_if([[ ]b4_locations_if([[
@@ -1848,7 +2155,7 @@ yyerrlab1:
/*-------------------------------------. /*-------------------------------------.
| yyacceptlab -- YYACCEPT comes here. | | yyacceptlab -- YYACCEPT comes here. |
`-------------------------------------*/ `-------------------------------------*/
yyacceptlab: yyacceptlab:]b4_yaxx([generate_xml_output(--yyxsp,yyxs);])[
yyresult = 0; yyresult = 0;
goto yyreturn; goto yyreturn;
+1405 -960
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -7550,7 +7550,7 @@ in an associativity related conflict, which can be specified as follows.
The unary-minus is another typical example where associativity is The unary-minus is another typical example where associativity is
usually over-specified, see @ref{Infix Calc, , Infix Notation usually over-specified, see @ref{Infix Calc, , Infix Notation
Calculator: @code{calc}}. The @code{%left} directive is traditionally Calculator - @code{calc}}. The @code{%left} directive is traditionally
used to declare the precedence of @code{NEG}, which is more than needed used to declare the precedence of @code{NEG}, which is more than needed
since it also defines its associativity. While this is harmless in the since it also defines its associativity. While this is harmless in the
traditional example, who knows how @code{NEG} might be used in future traditional example, who knows how @code{NEG} might be used in future
@@ -10748,8 +10748,8 @@ it must be copyable;
in order to compute the (default) value of @code{@@$} in a reduction, the in order to compute the (default) value of @code{@@$} in a reduction, the
parser basically runs parser basically runs
@example @example
@@$.begin = @@$1.begin; @@$.begin = @@1.begin;
@@$.end = @@$@var{N}.end; // The location of last right-hand side symbol. @@$.end = @@@var{N}.end; // The location of last right-hand side symbol.
@end example @end example
@noindent @noindent
so there must be copyable @code{begin} and @code{end} members; so there must be copyable @code{begin} and @code{end} members;
@@ -11337,7 +11337,7 @@ regular destructors. All the values are printed using their
@noindent @noindent
The grammar itself is straightforward (@pxref{Location Tracking Calc, , The grammar itself is straightforward (@pxref{Location Tracking Calc, ,
Location Tracking Calculator: @code{ltcalc}}). Location Tracking Calculator - @code{ltcalc}}).
@comment file: calc++-parser.yy @comment file: calc++-parser.yy
@example @example
+1 -1
Submodule gnulib updated: 7585eb3f16...ea6cb044ca
-2
View File
@@ -211,8 +211,6 @@
/stripslash.c /stripslash.c
/strndup.c /strndup.c
/strnlen.c /strnlen.c
/strtol.c
/strtoul.c
/strverscmp.c /strverscmp.c
/sys /sys
/sys_ioctl.h /sys_ioctl.h
-2
View File
@@ -144,8 +144,6 @@
/string_h.m4 /string_h.m4
/strndup.m4 /strndup.m4
/strnlen.m4 /strnlen.m4
/strtol.m4
/strtoul.m4
/strverscmp.m4 /strverscmp.m4
/sys_ioctl_h.m4 /sys_ioctl_h.m4
/sys_socket_h.m4 /sys_socket_h.m4
+10 -9
View File
@@ -242,7 +242,7 @@ AnnotationList__computePredecessorAnnotations (AnnotationList *self, state *s,
{ {
symbol_number contribution_token = symbol_number contribution_token =
InadequacyList__getContributionToken (self->inadequacyNode, ci) InadequacyList__getContributionToken (self->inadequacyNode, ci)
->number; ->content->number;
if (AnnotationList__isContributionAlways (self, ci)) if (AnnotationList__isContributionAlways (self, ci))
{ {
annotation_node->contributions[ci] = NULL; annotation_node->contributions[ci] = NULL;
@@ -546,14 +546,14 @@ AnnotationList__compute_from_inadequacies (
AnnotationList__insertInto (annotation_node, AnnotationList__insertInto (annotation_node,
&annotation_lists[s->number], &annotation_lists[s->number],
s->nitems); s->nitems);
aver (b); aver (b); (void) b;
} }
/* This aver makes sure the /* This aver makes sure the
AnnotationList__computeDominantContribution check above AnnotationList__computeDominantContribution check above
does discard annotations in the simplest case of a S/R does discard annotations in the simplest case of a S/R
conflict with no token precedence. */ conflict with no token precedence. */
aver (!bitset_test (shift_tokens, conflicted_token) aver (!bitset_test (shift_tokens, conflicted_token)
|| symbols[conflicted_token]->prec); || symbols[conflicted_token]->content->prec);
++annotation_counts[s->number]; ++annotation_counts[s->number];
if (contribution_count > *max_contributionsp) if (contribution_count > *max_contributionsp)
*max_contributionsp = contribution_count; *max_contributionsp = contribution_count;
@@ -599,7 +599,7 @@ AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces)
{ {
symbol_number token = symbol_number token =
InadequacyList__getContributionToken (a->inadequacyNode, ci) InadequacyList__getContributionToken (a->inadequacyNode, ci)
->number; ->content->number;
{ {
int j; int j;
for (j = 0; j < spaces+2; ++j) for (j = 0; j < spaces+2; ++j)
@@ -648,7 +648,7 @@ AnnotationList__computeLookaheadFilter (AnnotationList const *self,
Sbitset biter; Sbitset biter;
symbol_number token = symbol_number token =
InadequacyList__getContributionToken (self->inadequacyNode, ci) InadequacyList__getContributionToken (self->inadequacyNode, ci)
->number; ->content->number;
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item) SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
bitset_set (lookahead_filter[item], token); bitset_set (lookahead_filter[item], token);
} }
@@ -683,7 +683,8 @@ AnnotationList__stateMakesContribution (AnnotationList const *self,
return false; return false;
{ {
symbol_number token = symbol_number token =
InadequacyList__getContributionToken (self->inadequacyNode, ci)->number; InadequacyList__getContributionToken (self->inadequacyNode, ci)
->content->number;
Sbitset__Index item; Sbitset__Index item;
Sbitset biter; Sbitset biter;
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item) SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
@@ -713,7 +714,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
ContributionIndex ci; ContributionIndex ci;
int actioni; int actioni;
ContributionIndex ci_rr_dominator = ContributionIndex__none; ContributionIndex ci_rr_dominator = ContributionIndex__none;
int shift_precedence = token->prec; int shift_precedence = token->content->prec;
/* If the token has no precedence set, shift is always chosen. */ /* If the token has no precedence set, shift is always chosen. */
if (!shift_precedence) if (!shift_precedence)
@@ -743,7 +744,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
if (reduce_precedence if (reduce_precedence
&& (reduce_precedence < shift_precedence && (reduce_precedence < shift_precedence
|| (reduce_precedence == shift_precedence || (reduce_precedence == shift_precedence
&& token->assoc == right_assoc))) && token->content->assoc == right_assoc)))
continue; continue;
if (!AnnotationList__stateMakesContribution (self, nitems, ci, if (!AnnotationList__stateMakesContribution (self, nitems, ci,
lookaheads)) lookaheads))
@@ -751,7 +752,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
/* This uneliminated reduction contributes, so see if it can cause /* This uneliminated reduction contributes, so see if it can cause
an error action. */ an error action. */
if (reduce_precedence == shift_precedence if (reduce_precedence == shift_precedence
&& token->assoc == non_assoc) && token->content->assoc == non_assoc)
{ {
/* It's not possible to find split-stable domination over /* It's not possible to find split-stable domination over
shift after a potential %nonassoc. */ shift after a potential %nonassoc. */
+1 -1
View File
@@ -66,7 +66,7 @@ symbol *
InadequacyList__getContributionToken (InadequacyList const *self, InadequacyList__getContributionToken (InadequacyList const *self,
ContributionIndex i) ContributionIndex i)
{ {
aver (0 <= i && i < self->contributionCount); aver (0 <= i && i < self->contributionCount); (void) i;
return self->inadequacy.conflict.token; return self->inadequacy.conflict.token;
} }
+8 -8
View File
@@ -104,7 +104,7 @@ log_resolution (rule *r, symbol_number token,
case shift_resolution: case shift_resolution:
obstack_printf (&solved_conflicts_obstack, obstack_printf (&solved_conflicts_obstack,
" (%s < %s)", " (%s < %s)",
r->prec->tag, r->prec->symbol->tag,
symbols[token]->tag); symbols[token]->tag);
break; break;
@@ -112,7 +112,7 @@ log_resolution (rule *r, symbol_number token,
obstack_printf (&solved_conflicts_obstack, obstack_printf (&solved_conflicts_obstack,
" (%s < %s)", " (%s < %s)",
symbols[token]->tag, symbols[token]->tag,
r->prec->tag); r->prec->symbol->tag);
break; break;
case left_resolution: case left_resolution:
@@ -176,7 +176,7 @@ log_resolution (rule *r, symbol_number token,
case shift_resolution: case shift_resolution:
obstack_printf (&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->symbol->tag),
xml_escape_n (1, symbols[token]->tag)); xml_escape_n (1, symbols[token]->tag));
break; break;
@@ -184,7 +184,7 @@ log_resolution (rule *r, symbol_number token,
obstack_printf (&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->symbol->tag));
break; break;
case left_resolution: case left_resolution:
@@ -269,18 +269,18 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
for (i = 0; i < ntokens; i++) for (i = 0; i < ntokens; i++)
if (bitset_test (lookahead_tokens, i) if (bitset_test (lookahead_tokens, i)
&& bitset_test (lookahead_set, i) && bitset_test (lookahead_set, i)
&& symbols[i]->prec) && symbols[i]->content->prec)
{ {
/* Shift-reduce conflict occurs for token number i /* Shift-reduce conflict occurs for token number i
and it has a precedence. and it has a precedence.
The precedence of shifting is that of token i. */ The precedence of shifting is that of token i. */
if (symbols[i]->prec < redprec) if (symbols[i]->content->prec < redprec)
{ {
register_precedence (redrule->prec->number, i); register_precedence (redrule->prec->number, i);
log_resolution (redrule, i, reduce_resolution); log_resolution (redrule, i, reduce_resolution);
flush_shift (s, i); flush_shift (s, i);
} }
else if (symbols[i]->prec > redprec) else if (symbols[i]->content->prec > redprec)
{ {
register_precedence (i, redrule->prec->number); register_precedence (i, redrule->prec->number);
log_resolution (redrule, i, shift_resolution); log_resolution (redrule, i, shift_resolution);
@@ -294,7 +294,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
For right associativity, keep only the shift. For right associativity, keep only the shift.
For nonassociativity, keep neither. */ For nonassociativity, keep neither. */
switch (symbols[i]->assoc) switch (symbols[i]->content->assoc)
{ {
case undef_assoc: case undef_assoc:
abort (); abort ();
+3 -1
View File
@@ -64,7 +64,9 @@ extern char *all_but_ext;
void compute_output_file_names (void); void compute_output_file_names (void);
void output_file_names_free (void); void output_file_names_free (void);
/** Record that we generate file \a file_name. /** Record that we generate a file.
*
* \param file_name the name of file being generated.
* \param source whether this is a source file (*c, *.java...) * \param source whether this is a source file (*c, *.java...)
* as opposed to a report (*.output, *.dot...). * as opposed to a report (*.output, *.dot...).
*/ */
+12 -9
View File
@@ -65,19 +65,19 @@ rule_useless_in_parser_p (rule const *r)
} }
void void
rule_lhs_print (rule const *r, symbol const *previous_lhs, FILE *out) rule_lhs_print (rule const *r, sym_content const *previous_lhs, FILE *out)
{ {
fprintf (out, " %3d ", r->number); fprintf (out, " %3d ", r->number);
if (previous_lhs != r->lhs) if (previous_lhs != r->lhs)
fprintf (out, "%s:", r->lhs->tag); fprintf (out, "%s:", r->lhs->symbol->tag);
else else
fprintf (out, "%*s|", (int) strlen (previous_lhs->tag), ""); fprintf (out, "%*s|", (int) strlen (previous_lhs->symbol->tag), "");
} }
void void
rule_lhs_print_xml (rule const *r, FILE *out, int level) rule_lhs_print_xml (rule const *r, FILE *out, int level)
{ {
xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->tag); xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->symbol->tag);
} }
size_t size_t
@@ -158,7 +158,7 @@ grammar_rules_partial_print (FILE *out, const char *title,
{ {
rule_number r; rule_number r;
bool first = true; bool first = true;
symbol *previous_lhs = NULL; sym_content *previous_lhs = NULL;
/* rule # : LHS -> RHS */ /* rule # : LHS -> RHS */
for (r = 0; r < nrules + nuseless_productions; r++) for (r = 0; r < nrules + nuseless_productions; r++)
@@ -209,7 +209,7 @@ grammar_rules_print_xml (FILE *out, int level)
rules[r].number, usefulness); rules[r].number, usefulness);
if (rules[r].precsym) if (rules[r].precsym)
fprintf (out, " percent_prec=\"%s\"", fprintf (out, " percent_prec=\"%s\"",
xml_escape (rules[r].precsym->tag)); xml_escape (rules[r].precsym->symbol->tag));
fputs (">\n", out); fputs (">\n", out);
} }
rule_lhs_print_xml (&rules[r], out, level + 3); rule_lhs_print_xml (&rules[r], out, level + 3);
@@ -239,7 +239,7 @@ grammar_dump (FILE *out, const char *title)
for (i = ntokens; i < nsyms; i++) for (i = ntokens; i < nsyms; i++)
fprintf (out, "%5d %5d %5d %s\n", fprintf (out, "%5d %5d %5d %s\n",
i, i,
symbols[i]->prec, symbols[i]->assoc, symbols[i]->content->prec, symbols[i]->content->assoc,
symbols[i]->tag); symbols[i]->tag);
fprintf (out, "\n\n"); fprintf (out, "\n\n");
} }
@@ -280,7 +280,7 @@ grammar_dump (FILE *out, const char *title)
rule_number r; rule_number r;
for (r = 0; r < nrules + nuseless_productions; r++) for (r = 0; r < nrules + nuseless_productions; r++)
{ {
fprintf (out, "%-5d %s:", r, rules[r].lhs->tag); fprintf (out, "%-5d %s:", r, rules[r].lhs->symbol->tag);
rule_rhs_print (&rules[r], out); rule_rhs_print (&rules[r], out);
fprintf (out, "\n"); fprintf (out, "\n");
} }
@@ -293,7 +293,10 @@ grammar_rules_useless_report (const char *message)
{ {
rule_number r; rule_number r;
for (r = 0; r < nrules ; ++r) for (r = 0; r < nrules ; ++r)
if (!rules[r].useful) /* Don't complain about rules whose LHS is useless, we already
complained about it. */
if (!reduce_nonterminal_useless_in_grammar (rules[r].lhs)
&& !rules[r].useful)
complain (&rules[r].location, Wother, "%s", message); complain (&rules[r].location, Wother, "%s", message);
} }
+5 -4
View File
@@ -180,17 +180,17 @@ typedef struct
except if some rules are useless. */ except if some rules are useless. */
rule_number number; rule_number number;
symbol *lhs; sym_content *lhs;
item_number *rhs; item_number *rhs;
/* This symbol provides both the associativity, and the precedence. */ /* This symbol provides both the associativity, and the precedence. */
symbol *prec; sym_content *prec;
int dprec; int dprec;
int merger; int merger;
/* This symbol was attached to the rule via %prec. */ /* This symbol was attached to the rule via %prec. */
symbol *precsym; sym_content *precsym;
location location; location location;
bool useful; bool useful;
@@ -220,7 +220,8 @@ bool rule_useless_in_parser_p (rule const *r);
/* Print this rule's number and lhs on OUT. If a PREVIOUS_LHS was /* Print this rule's number and lhs on OUT. If a PREVIOUS_LHS was
already displayed (by a previous call for another rule), avoid already displayed (by a previous call for another rule), avoid
useless repetitions. */ useless repetitions. */
void rule_lhs_print (rule const *r, symbol const *previous_lhs, FILE *out); void rule_lhs_print (rule const *r, sym_content const *previous_lhs,
FILE *out);
void rule_lhs_print_xml (rule const *r, FILE *out, int level); void rule_lhs_print_xml (rule const *r, FILE *out, int level);
/* Return the length of the RHS. */ /* Return the length of the RHS. */
+3 -3
View File
@@ -93,7 +93,7 @@ no_reduce_bitset_init (state const *s, bitset *no_reduce_set)
bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n)); bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n));
for (n = 0; n < s->errs->num; ++n) for (n = 0; n < s->errs->num; ++n)
if (s->errs->symbols[n]) if (s->errs->symbols[n])
bitset_set (*no_reduce_set, s->errs->symbols[n]->number); bitset_set (*no_reduce_set, s->errs->symbols[n]->content->number);
} }
static void static void
@@ -113,8 +113,8 @@ conclude_red (struct obstack *out, int source, rule_number ruleno,
with n the source state and m the rule number. This is because we with n the source state and m the rule number. This is because we
don't want all the reductions bearing a same rule number to point to don't want all the reductions bearing a same rule number to point to
the same state, since that is not the desired format. */ the same state, since that is not the desired format. */
fprintf (fout, " %1$d -> \"%1$dR%2$d%3$s\" [", fprintf (fout, " %d -> \"%dR%d%s\" [",
source, ruleno, ed); source, source, ruleno, ed);
/* (The lookahead tokens have been added to the beginning of the /* (The lookahead tokens have been added to the beginning of the
obstack, in the caller function.) */ obstack, in the caller function.) */
+6 -3
View File
@@ -424,7 +424,7 @@ ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
if (item_number_is_rule_number (ritem[s->items[item] - 2])) if (item_number_is_rule_number (ritem[s->items[item] - 2]))
{ {
state **predecessor; state **predecessor;
aver (lhs != accept->number); aver (lhs != accept->content->number);
for (predecessor = predecessors[s->number]; for (predecessor = predecessors[s->number];
*predecessor; *predecessor;
++predecessor) ++predecessor)
@@ -580,7 +580,7 @@ typedef struct state_list {
static void static void
ielr_compute_goto_follow_set (bitsetv follow_kernel_items, ielr_compute_goto_follow_set (bitsetv follow_kernel_items,
bitsetv always_follows, state_list *s, bitsetv always_follows, state_list *s,
symbol *n, bitset follow_set) sym_content *n, bitset follow_set)
{ {
goto_number n_goto = map_goto (s->lr0Isocore->state->number, n->number); goto_number n_goto = map_goto (s->lr0Isocore->state->number, n->number);
bitset_copy (follow_set, always_follows[n_goto]); bitset_copy (follow_set, always_follows[n_goto]);
@@ -1102,7 +1102,10 @@ ielr (void)
else if (STREQ (type, "canonical-lr")) else if (STREQ (type, "canonical-lr"))
lr_type = LR_TYPE__CANONICAL_LR; lr_type = LR_TYPE__CANONICAL_LR;
else else
aver (false); {
aver (false);
abort ();
}
free (type); free (type);
} }
+12 -10
View File
@@ -149,7 +149,7 @@ prepare_symbols (void)
MUSCLE_INSERT_INT ("tokens_number", ntokens); MUSCLE_INSERT_INT ("tokens_number", ntokens);
MUSCLE_INSERT_INT ("nterms_number", nvars); MUSCLE_INSERT_INT ("nterms_number", nvars);
MUSCLE_INSERT_INT ("symbols_number", nsyms); MUSCLE_INSERT_INT ("symbols_number", nsyms);
MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number); MUSCLE_INSERT_INT ("undef_token_number", undeftoken->content->number);
MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number); MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
muscle_insert_symbol_number_table ("translate", muscle_insert_symbol_number_table ("translate",
@@ -197,7 +197,7 @@ prepare_symbols (void)
int i; int i;
int *values = xnmalloc (ntokens, sizeof *values); int *values = xnmalloc (ntokens, sizeof *values);
for (i = 0; i < ntokens; ++i) for (i = 0; i < ntokens; ++i)
values[i] = symbols[i]->user_token_number; values[i] = symbols[i]->content->user_token_number;
muscle_insert_int_table ("toknum", values, muscle_insert_int_table ("toknum", values,
values[0], 1, ntokens); values[0], 1, ntokens);
free (values); free (values);
@@ -283,9 +283,9 @@ prepare_states (void)
static int static int
symbol_type_name_cmp (const symbol **lhs, const symbol **rhs) symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
{ {
int res = uniqstr_cmp ((*lhs)->type_name, (*rhs)->type_name); int res = uniqstr_cmp ((*lhs)->content->type_name, (*rhs)->content->type_name);
if (!res) if (!res)
res = (*lhs)->number - (*rhs)->number; res = (*lhs)->content->number - (*rhs)->content->number;
return res; return res;
} }
@@ -320,8 +320,9 @@ type_names_output (FILE *out)
/* The index of the first symbol of the current type-name. */ /* The index of the first symbol of the current type-name. */
int i0 = i; int i0 = i;
fputs (i ? ",\n[" : "[", out); fputs (i ? ",\n[" : "[", out);
for (; i < nsyms && syms[i]->type_name == syms[i0]->type_name; ++i) for (; i < nsyms
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->number); && syms[i]->content->type_name == syms[i0]->content->type_name; ++i)
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->content->number);
fputs ("]", out); fputs ("]", out);
} }
fputs ("])\n\n", out); fputs ("])\n\n", out);
@@ -428,20 +429,21 @@ prepare_symbol_definitions (void)
MUSCLE_INSERT_STRING (key, sym->tag); MUSCLE_INSERT_STRING (key, sym->tag);
SET_KEY ("user_number"); SET_KEY ("user_number");
MUSCLE_INSERT_INT (key, sym->user_token_number); MUSCLE_INSERT_INT (key, sym->content->user_token_number);
SET_KEY ("is_token"); SET_KEY ("is_token");
MUSCLE_INSERT_INT (key, MUSCLE_INSERT_INT (key,
i < ntokens && sym != errtoken && sym != undeftoken); i < ntokens && sym != errtoken && sym != undeftoken);
SET_KEY ("number"); SET_KEY ("number");
MUSCLE_INSERT_INT (key, sym->number); MUSCLE_INSERT_INT (key, sym->content->number);
SET_KEY ("has_type"); SET_KEY ("has_type");
MUSCLE_INSERT_INT (key, !!sym->type_name); MUSCLE_INSERT_INT (key, !!sym->content->type_name);
SET_KEY ("type"); SET_KEY ("type");
MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : ""); MUSCLE_INSERT_STRING (key, sym->content->type_name
? sym->content->type_name : "");
{ {
int j; int j;
+4 -2
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.0.2.13-975bb-dirty. */ /* A Bison parser, made by GNU Bison 3.0.2.29-9a91e. */
/* Bison implementation for Yacc-like parsers in C /* Bison implementation for Yacc-like parsers in C
@@ -44,7 +44,7 @@
#define YYBISON 1 #define YYBISON 1
/* Bison version. */ /* Bison version. */
#define YYBISON_VERSION "3.0.2.13-975bb-dirty" #define YYBISON_VERSION "3.0.2.29-9a91e"
/* Skeleton name. */ /* Skeleton name. */
#define YYSKELETON_NAME "yacc.c" #define YYSKELETON_NAME "yacc.c"
@@ -3118,6 +3118,8 @@ current_lhs (symbol *sym, location loc, named_ref *ref)
{ {
current_lhs_symbol = sym; current_lhs_symbol = sym;
current_lhs_location = loc; current_lhs_location = loc;
if (sym)
symbol_location_as_lhs_set (sym, loc);
/* In order to simplify memory management, named references for lhs /* In order to simplify memory management, named references for lhs
are always assigned by deep copy into the current symbol_list are always assigned by deep copy into the current symbol_list
node. This is because a single named-ref in the grammar may node. This is because a single named-ref in the grammar may
+1 -1
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.0.2.13-975bb-dirty. */ /* A Bison parser, made by GNU Bison 3.0.2.29-9a91e. */
/* Bison interface for Yacc-like parsers in C /* Bison interface for Yacc-like parsers in C
+2
View File
@@ -865,6 +865,8 @@ current_lhs (symbol *sym, location loc, named_ref *ref)
{ {
current_lhs_symbol = sym; current_lhs_symbol = sym;
current_lhs_location = loc; current_lhs_location = loc;
if (sym)
symbol_location_as_lhs_set (sym, loc);
/* In order to simplify memory management, named references for lhs /* In order to simplify memory management, named references for lhs
are always assigned by deep copy into the current symbol_list are always assigned by deep copy into the current symbol_list
node. This is because a single named-ref in the grammar may node. This is because a single named-ref in the grammar may
+5 -5
View File
@@ -259,7 +259,7 @@ print_reductions (FILE *out, int level, state *s)
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i)); bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
for (i = 0; i < s->errs->num; ++i) for (i = 0; i < s->errs->num; ++i)
if (s->errs->symbols[i]) if (s->errs->symbols[i])
bitset_set (no_reduce_set, s->errs->symbols[i]->number); bitset_set (no_reduce_set, s->errs->symbols[i]->content->number);
if (default_reduction) if (default_reduction)
report = true; report = true;
@@ -388,11 +388,11 @@ print_grammar (FILE *out, int level)
/* Terminals */ /* Terminals */
xml_puts (out, level + 1, "<terminals>"); xml_puts (out, level + 1, "<terminals>");
for (i = 0; i < max_user_token_number + 1; i++) for (i = 0; i < max_user_token_number + 1; i++)
if (token_translations[i] != undeftoken->number) if (token_translations[i] != undeftoken->content->number)
{ {
char const *tag = symbols[token_translations[i]]->tag; char const *tag = symbols[token_translations[i]]->tag;
int precedence = symbols[token_translations[i]]->prec; int precedence = symbols[token_translations[i]]->content->prec;
assoc associativity = symbols[token_translations[i]]->assoc; assoc associativity = symbols[token_translations[i]]->content->assoc;
xml_indent (out, level + 2); xml_indent (out, level + 2);
fprintf (out, fprintf (out,
"<terminal symbol-number=\"%d\" token-number=\"%d\"" "<terminal symbol-number=\"%d\" token-number=\"%d\""
@@ -417,7 +417,7 @@ print_grammar (FILE *out, int level)
"<nonterminal symbol-number=\"%d\" name=\"%s\"" "<nonterminal symbol-number=\"%d\" name=\"%s\""
" usefulness=\"%s\"/>", " usefulness=\"%s\"/>",
i, xml_escape (tag), i, xml_escape (tag),
reduce_nonterminal_useless_in_grammar (i) reduce_nonterminal_useless_in_grammar (symbols[i]->content)
? "useless-in-grammar" : "useful"); ? "useless-in-grammar" : "useful");
} }
xml_puts (out, level + 1, "</nonterminals>"); xml_puts (out, level + 1, "</nonterminals>");
+6 -4
View File
@@ -72,7 +72,7 @@ print_core (FILE *out, state *s)
size_t i; size_t i;
item_number *sitems = s->items; item_number *sitems = s->items;
size_t snritems = s->nitems; size_t snritems = s->nitems;
symbol *previous_lhs = NULL; sym_content *previous_lhs = NULL;
/* Output all the items of a state, not only its kernel. */ /* Output all the items of a state, not only its kernel. */
if (report_flag & report_itemsets) if (report_flag & report_itemsets)
@@ -226,7 +226,8 @@ print_reduction (FILE *out, size_t width,
if (!enabled) if (!enabled)
fputc ('[', out); fputc ('[', out);
if (r->number) if (r->number)
fprintf (out, _("reduce using rule %d (%s)"), r->number, r->lhs->tag); fprintf (out, _("reduce using rule %d (%s)"), r->number,
r->lhs->symbol->tag);
else else
fprintf (out, _("accept")); fprintf (out, _("accept"));
if (!enabled) if (!enabled)
@@ -260,7 +261,7 @@ print_reductions (FILE *out, state *s)
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i)); bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
for (i = 0; i < s->errs->num; ++i) for (i = 0; i < s->errs->num; ++i)
if (s->errs->symbols[i]) if (s->errs->symbols[i])
bitset_set (no_reduce_set, s->errs->symbols[i]->number); bitset_set (no_reduce_set, s->errs->symbols[i]->content->number);
/* Compute the width of the lookahead token column. */ /* Compute the width of the lookahead token column. */
if (default_reduction) if (default_reduction)
@@ -343,6 +344,7 @@ print_reductions (FILE *out, state *s)
|| (STREQ (default_reductions, "consistent") || (STREQ (default_reductions, "consistent")
&& default_reduction_only) && default_reduction_only)
|| (reds->num == 1 && reds->rules[0]->number == 0)); || (reds->num == 1 && reds->rules[0]->number == 0));
(void) default_reduction_only;
free (default_reductions); free (default_reductions);
} }
} }
@@ -411,7 +413,7 @@ print_grammar (FILE *out)
/* TERMINAL (type #) : rule #s terminal is on RHS */ /* TERMINAL (type #) : rule #s terminal is on RHS */
fprintf (out, "%s\n\n", _("Terminals, with rules where they appear")); fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
for (i = 0; i < max_user_token_number + 1; i++) for (i = 0; i < max_user_token_number + 1; i++)
if (token_translations[i] != undeftoken->number) if (token_translations[i] != undeftoken->content->number)
{ {
const char *tag = symbols[token_translations[i]]->tag; const char *tag = symbols[token_translations[i]]->tag;
rule_number r; rule_number r;
+5 -4
View File
@@ -46,7 +46,7 @@ static void
print_core (struct obstack *oout, state *s) print_core (struct obstack *oout, state *s)
{ {
item_number const *sitems = s->items; item_number const *sitems = s->items;
symbol *previous_lhs = NULL; sym_content *previous_lhs = NULL;
size_t i; size_t i;
size_t snritems = s->nitems; size_t snritems = s->nitems;
@@ -72,11 +72,12 @@ print_core (struct obstack *oout, state *s)
r = &rules[item_number_as_rule_number (*sp)]; r = &rules[item_number_as_rule_number (*sp)];
obstack_printf (oout, "%3d ", r->number); obstack_printf (oout, "%3d ", r->number);
if (previous_lhs && UNIQSTR_EQ (previous_lhs->tag, r->lhs->tag)) if (previous_lhs && UNIQSTR_EQ (previous_lhs->symbol->tag,
r->lhs->symbol->tag))
obstack_printf (oout, "%*s| ", obstack_printf (oout, "%*s| ",
(int) strlen (previous_lhs->tag), ""); (int) strlen (previous_lhs->symbol->tag), "");
else else
obstack_printf (oout, "%s: ", escape (r->lhs->tag)); obstack_printf (oout, "%s: ", escape (r->lhs->symbol->tag));
previous_lhs = r->lhs; previous_lhs = r->lhs;
for (sp = r->rhs; sp < sp1; sp++) for (sp = r->rhs; sp < sp1; sp++)
+27 -26
View File
@@ -240,13 +240,13 @@ grammar_current_rule_begin (symbol *lhs, location loc,
current_rule = grammar_end; current_rule = grammar_end;
/* Mark the rule's lhs as a nonterminal if not already so. */ /* Mark the rule's lhs as a nonterminal if not already so. */
if (lhs->class == unknown_sym) if (lhs->content->class == unknown_sym)
{ {
lhs->class = nterm_sym; lhs->content->class = nterm_sym;
lhs->number = nvars; lhs->content->number = nvars;
++nvars; ++nvars;
} }
else if (lhs->class == token_sym) else if (lhs->content->class == token_sym)
complain (&loc, complaint, _("rule given for %s, which is a token"), complain (&loc, complaint, _("rule given for %s, which is a token"),
lhs->tag); lhs->tag);
} }
@@ -292,15 +292,15 @@ grammar_rule_check (const symbol_list *r)
Don't worry about the default action if $$ is untyped, since $$'s Don't worry about the default action if $$ is untyped, since $$'s
value can't be used. */ value can't be used. */
if (!r->action_props.code && r->content.sym->type_name) if (!r->action_props.code && r->content.sym->content->type_name)
{ {
symbol *first_rhs = r->next->content.sym; symbol *first_rhs = r->next->content.sym;
/* If $$ is being set in default way, report if any type mismatch. */ /* If $$ is being set in default way, report if any type mismatch. */
if (first_rhs) if (first_rhs)
{ {
char const *lhs_type = r->content.sym->type_name; char const *lhs_type = r->content.sym->content->type_name;
const char *rhs_type = const char *rhs_type =
first_rhs->type_name ? first_rhs->type_name : ""; first_rhs->content->type_name ? first_rhs->content->type_name : "";
if (!UNIQSTR_EQ (lhs_type, rhs_type)) if (!UNIQSTR_EQ (lhs_type, rhs_type))
complain (&r->location, Wother, complain (&r->location, Wother,
_("type clash on default action: <%s> != <%s>"), _("type clash on default action: <%s> != <%s>"),
@@ -350,7 +350,8 @@ grammar_rule_check (const symbol_list *r)
it for char literals and strings, which are always tokens. */ it for char literals and strings, which are always tokens. */
if (r->ruleprec if (r->ruleprec
&& r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"' && r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
&& r->ruleprec->status != declared && !r->ruleprec->prec) && r->ruleprec->content->status != declared
&& !r->ruleprec->content->prec)
complain (&r->location, Wother, complain (&r->location, Wother,
_("token for %%prec is not defined: %s"), r->ruleprec->tag); _("token for %%prec is not defined: %s"), r->ruleprec->tag);
} }
@@ -517,8 +518,8 @@ grammar_current_rule_symbol_append (symbol *sym, location loc,
p = grammar_symbol_append (sym, loc); p = grammar_symbol_append (sym, loc);
if (name) if (name)
assign_named_ref (p, name); assign_named_ref (p, name);
if (sym->status == undeclared || sym->status == used) if (sym->content->status == undeclared || sym->content->status == used)
sym->status = needed; sym->content->status = needed;
} }
/* Attach an ACTION to the current rule. */ /* Attach an ACTION to the current rule. */
@@ -558,11 +559,11 @@ packgram (void)
for (p = grammar; p; p = p->next) for (p = grammar; p; p = p->next)
{ {
symbol *ruleprec = p->ruleprec; symbol *ruleprec = p->ruleprec;
record_merge_function_type (p->merger, p->content.sym->type_name, record_merge_function_type (p->merger, p->content.sym->content->type_name,
p->merger_declaration_location); p->merger_declaration_location);
rules[ruleno].user_number = ruleno; rules[ruleno].user_number = ruleno;
rules[ruleno].number = ruleno; rules[ruleno].number = ruleno;
rules[ruleno].lhs = p->content.sym; rules[ruleno].lhs = p->content.sym->content;
rules[ruleno].rhs = ritem + itemno; rules[ruleno].rhs = ritem + itemno;
rules[ruleno].prec = NULL; rules[ruleno].prec = NULL;
rules[ruleno].dprec = p->dprec; rules[ruleno].dprec = p->dprec;
@@ -604,11 +605,11 @@ packgram (void)
/* item_number = symbol_number. /* item_number = symbol_number.
But the former needs to contain more: negative rule numbers. */ But the former needs to contain more: negative rule numbers. */
ritem[itemno++] = ritem[itemno++] =
symbol_number_as_item_number (p->content.sym->number); symbol_number_as_item_number (p->content.sym->content->number);
/* A rule gets by default the precedence and associativity /* A rule gets by default the precedence and associativity
of its last token. */ of its last token. */
if (p->content.sym->class == token_sym && default_prec) if (p->content.sym->content->class == token_sym && default_prec)
rules[ruleno].prec = p->content.sym; rules[ruleno].prec = p->content.sym->content;
} }
} }
@@ -616,8 +617,8 @@ packgram (void)
the specified symbol's precedence replaces the default. */ the specified symbol's precedence replaces the default. */
if (ruleprec) if (ruleprec)
{ {
rules[ruleno].precsym = ruleprec; rules[ruleno].precsym = ruleprec->content;
rules[ruleno].prec = ruleprec; rules[ruleno].prec = ruleprec->content;
} }
/* An item ends by the rule number (negated). */ /* An item ends by the rule number (negated). */
ritem[itemno++] = rule_number_as_item_number (ruleno); ritem[itemno++] = rule_number_as_item_number (ruleno);
@@ -647,19 +648,19 @@ reader (void)
/* Construct the accept symbol. */ /* Construct the accept symbol. */
accept = symbol_get ("$accept", empty_location); accept = symbol_get ("$accept", empty_location);
accept->class = nterm_sym; accept->content->class = nterm_sym;
accept->number = nvars++; accept->content->number = nvars++;
/* Construct the error token */ /* Construct the error token */
errtoken = symbol_get ("error", empty_location); errtoken = symbol_get ("error", empty_location);
errtoken->class = token_sym; errtoken->content->class = token_sym;
errtoken->number = ntokens++; errtoken->content->number = ntokens++;
/* Construct a token that represents all undefined literal tokens. /* Construct a token that represents all undefined literal tokens.
It is always token number 2. */ It is always token number 2. */
undeftoken = symbol_get ("$undefined", empty_location); undeftoken = symbol_get ("$undefined", empty_location);
undeftoken->class = token_sym; undeftoken->content->class = token_sym;
undeftoken->number = ntokens++; undeftoken->content->number = ntokens++;
gram_in = xfopen (grammar_file, "r"); gram_in = xfopen (grammar_file, "r");
@@ -721,10 +722,10 @@ check_and_convert_grammar (void)
if (!endtoken) if (!endtoken)
{ {
endtoken = symbol_get ("$end", empty_location); endtoken = symbol_get ("$end", empty_location);
endtoken->class = token_sym; endtoken->content->class = token_sym;
endtoken->number = 0; endtoken->content->number = 0;
/* Value specified by POSIX. */ /* Value specified by POSIX. */
endtoken->user_token_number = 0; endtoken->content->user_token_number = 0;
} }
/* Report any undefined symbols and consider them nonterminals. */ /* Report any undefined symbols and consider them nonterminals. */
+79 -82
View File
@@ -39,7 +39,7 @@
#include "reduce.h" #include "reduce.h"
#include "symtab.h" #include "symtab.h"
/* Set of all nonterminals which are not useless. */ /* Set of all nonterminals whose language is not empty. */
static bitset N; static bitset N;
/* Set of all rules which have no useless nonterminals in their RHS. */ /* Set of all rules which have no useless nonterminals in their RHS. */
@@ -52,11 +52,18 @@ static bitset V;
'useless', but no warning should be issued). */ 'useless', but no warning should be issued). */
static bitset V1; static bitset V1;
static rule_number nuseful_productions; static unsigned nuseful_productions;
rule_number nuseless_productions; unsigned nuseless_productions;
static int nuseful_nonterminals; static unsigned nuseful_nonterminals;
symbol_number nuseless_nonterminals; unsigned nuseless_nonterminals;
#define bitset_swap(Lhs, Rhs) \
do { \
bitset lhs__ = Lhs; \
Lhs = Rhs; \
Rhs = lhs__; \
} while (0)
/*-------------------------------------------------------------------. /*-------------------------------------------------------------------.
| Another way to do this would be with a set for each production and | | Another way to do this would be with a set for each production and |
| then do subset tests against N0, but even for the C grammar the | | then do subset tests against N0, but even for the C grammar the |
@@ -71,7 +78,7 @@ useful_production (rule_number r, bitset N0)
/* A production is useful if all of the nonterminals in its appear /* A production is useful if all of the nonterminals in its appear
in the set of useful nonterminals. */ in the set of useful nonterminals. */
for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp) for (rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
if (ISVAR (*rhsp) && !bitset_test (N0, *rhsp - ntokens)) if (ISVAR (*rhsp) && !bitset_test (N0, *rhsp - ntokens))
return false; return false;
return true; return true;
@@ -85,14 +92,10 @@ useful_production (rule_number r, bitset N0)
static void static void
useless_nonterminals (void) useless_nonterminals (void)
{ {
bitset Np, Ns;
rule_number r;
/* N is set as built. Np is set being built this iteration. P is /* N is set as built. Np is set being built this iteration. P is
set of all productions which have a RHS all in N. */ set of all productions which have a RHS all in N. */
Np = bitset_create (nvars, BITSET_FIXED); bitset Np = bitset_create (nvars, BITSET_FIXED);
/* The set being computed is a set of nonterminals which can derive /* The set being computed is a set of nonterminals which can derive
the empty string or strings consisting of all terminals. At each the empty string or strings consisting of all terminals. At each
@@ -112,8 +115,9 @@ useless_nonterminals (void)
while (1) while (1)
{ {
rule_number r;
bitset_copy (Np, N); bitset_copy (Np, N);
for (r = 0; r < nrules; r++) for (r = 0; r < nrules; ++r)
if (!bitset_test (P, r) if (!bitset_test (P, r)
&& useful_production (r, N)) && useful_production (r, N))
{ {
@@ -122,9 +126,7 @@ useless_nonterminals (void)
} }
if (bitset_equal_p (N, Np)) if (bitset_equal_p (N, Np))
break; break;
Ns = Np; bitset_swap (N, Np);
Np = N;
N = Ns;
} }
bitset_free (N); bitset_free (N);
N = Np; N = Np;
@@ -134,8 +136,6 @@ useless_nonterminals (void)
static void static void
inaccessable_symbols (void) inaccessable_symbols (void)
{ {
bitset Vp, Vs, Pp;
/* Find out which productions are reachable and which symbols are /* Find out which productions are reachable and which symbols are
used. Starting with an empty set of productions and a set of used. Starting with an empty set of productions and a set of
symbols which only has the start symbol in it, iterate over all symbols which only has the start symbol in it, iterate over all
@@ -159,46 +159,43 @@ inaccessable_symbols (void)
terminals are printed (if running in verbose mode) so that the terminals are printed (if running in verbose mode) so that the
user can know. */ user can know. */
Vp = bitset_create (nsyms, BITSET_FIXED); bitset Vp = bitset_create (nsyms, BITSET_FIXED);
Pp = bitset_create (nrules, BITSET_FIXED); bitset Pp = bitset_create (nrules, BITSET_FIXED);
/* If the start symbol isn't useful, then nothing will be useful. */ /* If the start symbol isn't useful, then nothing will be useful. */
if (bitset_test (N, accept->number - ntokens)) if (bitset_test (N, accept->content->number - ntokens))
{ {
bitset_set (V, accept->number); bitset_set (V, accept->content->number);
while (1) while (1)
{ {
rule_number r; rule_number r;
bitset_copy (Vp, V); bitset_copy (Vp, V);
for (r = 0; r < nrules; r++) for (r = 0; r < nrules; ++r)
{ if (!bitset_test (Pp, r)
if (!bitset_test (Pp, r) && bitset_test (P, r)
&& bitset_test (P, r) && bitset_test (V, rules[r].lhs->number))
&& bitset_test (V, rules[r].lhs->number)) {
{ item_number *rhsp;
item_number *rhsp; for (rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++) if (ISTOKEN (*rhsp) || bitset_test (N, *rhsp - ntokens))
if (ISTOKEN (*rhsp) || bitset_test (N, *rhsp - ntokens)) bitset_set (Vp, *rhsp);
bitset_set (Vp, *rhsp); bitset_set (Pp, r);
bitset_set (Pp, r); }
}
}
if (bitset_equal_p (V, Vp)) if (bitset_equal_p (V, Vp))
break; break;
Vs = Vp; bitset_swap (V, Vp);
Vp = V;
V = Vs;
} }
} }
bitset_free (V); bitset_free (V);
V = Vp; V = Vp;
/* Tokens 0, 1, and 2 are internal to Bison. Consider them useful. */ /* These tokens (numbered 0, 1, and 2) are internal to Bison.
bitset_set (V, endtoken->number); /* end-of-input token */ Consider them useful. */
bitset_set (V, errtoken->number); /* error token */ bitset_set (V, endtoken->content->number); /* end-of-input token */
bitset_set (V, undeftoken->number); /* some undefined token */ bitset_set (V, errtoken->content->number); /* error token */
bitset_set (V, undeftoken->content->number); /* some undefined token */
bitset_free (P); bitset_free (P);
P = Pp; P = Pp;
@@ -209,9 +206,8 @@ inaccessable_symbols (void)
nuseful_nonterminals = 0; nuseful_nonterminals = 0;
{ {
symbol_number i; symbol_number i;
for (i = ntokens; i < nsyms; i++) for (i = ntokens; i < nsyms; ++i)
if (bitset_test (V, i)) nuseful_nonterminals += bitset_test (V, i);
nuseful_nonterminals++;
} }
nuseless_nonterminals = nvars - nuseful_nonterminals; nuseless_nonterminals = nvars - nuseful_nonterminals;
@@ -236,7 +232,7 @@ reduce_grammar_tables (void)
/* Report and flag useless productions. */ /* Report and flag useless productions. */
{ {
rule_number r; rule_number r;
for (r = 0; r < nrules; r++) for (r = 0; r < nrules; ++r)
rules[r].useful = bitset_test (P, r); rules[r].useful = bitset_test (P, r);
grammar_rules_useless_report (_("rule useless in grammar")); grammar_rules_useless_report (_("rule useless in grammar"));
} }
@@ -257,8 +253,8 @@ reduce_grammar_tables (void)
for (r = 0; r < nrules; ++r) for (r = 0; r < nrules; ++r)
{ {
item_number *rhsp = rules[r].rhs; item_number *rhsp = rules[r].rhs;
for (/* Nothing. */; *rhsp >= 0; ++rhsp) for (/* Nothing. */; 0 <= *rhsp; ++rhsp)
/* Nothing. */; continue;
*rhsp = rule_number_as_item_number (r); *rhsp = rule_number_as_item_number (r);
rules[r].number = r; rules[r].number = r;
} }
@@ -289,31 +285,33 @@ nonterminals_reduce (void)
afterwards. Kept for later report. */ afterwards. Kept for later report. */
symbol_number *nontermmap = xnmalloc (nvars, sizeof *nontermmap); symbol_number *nontermmap = xnmalloc (nvars, sizeof *nontermmap);
symbol_number n = ntokens; {
symbol_number i; symbol_number n = ntokens;
for (i = ntokens; i < nsyms; i++) symbol_number i;
if (bitset_test (V, i)) for (i = ntokens; i < nsyms; ++i)
nontermmap[i - ntokens] = n++; if (bitset_test (V, i))
for (i = ntokens; i < nsyms; i++)
if (!bitset_test (V, i))
{
nontermmap[i - ntokens] = n++; nontermmap[i - ntokens] = n++;
if (symbols[i]->status != used) for (i = ntokens; i < nsyms; ++i)
complain (&symbols[i]->location, Wother, if (!bitset_test (V, i))
_("nonterminal useless in grammar: %s"), {
symbols[i]->tag); nontermmap[i - ntokens] = n++;
} if (symbols[i]->content->status != used)
complain (&symbols[i]->location, Wother,
_("nonterminal useless in grammar: %s"),
symbols[i]->tag);
}
}
/* Shuffle elements of tables indexed by symbol number. */ /* Shuffle elements of tables indexed by symbol number. */
{ {
symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted); symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted);
symbol_number i;
for (i = ntokens; i < nsyms; i++) for (i = ntokens; i < nsyms; ++i)
symbols[i]->number = nontermmap[i - ntokens]; symbols[i]->content->number = nontermmap[i - ntokens];
for (i = ntokens; i < nsyms; i++) for (i = ntokens; i < nsyms; ++i)
symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i]; symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i];
for (i = ntokens; i < nsyms; i++) for (i = ntokens; i < nsyms; ++i)
symbols[i] = symbols_sorted[i - ntokens]; symbols[i] = symbols_sorted[i - ntokens];
free (symbols_sorted); free (symbols_sorted);
} }
@@ -323,12 +321,12 @@ nonterminals_reduce (void)
for (r = 0; r < nrules; ++r) for (r = 0; r < nrules; ++r)
{ {
item_number *rhsp; item_number *rhsp;
for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp) for (rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
if (ISVAR (*rhsp)) if (ISVAR (*rhsp))
*rhsp = symbol_number_as_item_number (nontermmap[*rhsp *rhsp = symbol_number_as_item_number (nontermmap[*rhsp
- ntokens]); - ntokens]);
} }
accept->number = nontermmap[accept->number - ntokens]; accept->content->number = nontermmap[accept->content->number - ntokens];
} }
nsyms -= nuseless_nonterminals; nsyms -= nuseless_nonterminals;
@@ -345,7 +343,7 @@ nonterminals_reduce (void)
void void
reduce_output (FILE *out) reduce_output (FILE *out)
{ {
if (nuseless_nonterminals > 0) if (nuseless_nonterminals)
{ {
int i; int i;
fprintf (out, "%s\n\n", _("Nonterminals useless in grammar")); fprintf (out, "%s\n\n", _("Nonterminals useless in grammar"));
@@ -357,7 +355,7 @@ reduce_output (FILE *out)
{ {
bool b = false; bool b = false;
int i; int i;
for (i = 0; i < ntokens; i++) for (i = 0; i < ntokens; ++i)
if (reduce_token_unused_in_grammar (i)) if (reduce_token_unused_in_grammar (i))
{ {
if (!b) if (!b)
@@ -369,7 +367,7 @@ reduce_output (FILE *out)
fputs ("\n\n", out); fputs ("\n\n", out);
} }
if (nuseless_productions > 0) if (nuseless_productions)
grammar_rules_partial_print (out, _("Rules useless in grammar"), grammar_rules_partial_print (out, _("Rules useless in grammar"),
rule_useless_in_grammar_p); rule_useless_in_grammar_p);
} }
@@ -382,12 +380,12 @@ reduce_output (FILE *out)
static void static void
reduce_print (void) reduce_print (void)
{ {
if (nuseless_nonterminals > 0) if (nuseless_nonterminals)
complain (NULL, Wother, ngettext ("%d nonterminal useless in grammar", complain (NULL, Wother, ngettext ("%d nonterminal useless in grammar",
"%d nonterminals useless in grammar", "%d nonterminals useless in grammar",
nuseless_nonterminals), nuseless_nonterminals),
nuseless_nonterminals); nuseless_nonterminals);
if (nuseless_productions > 0) if (nuseless_productions)
complain (NULL, Wother, ngettext ("%d rule useless in grammar", complain (NULL, Wother, ngettext ("%d rule useless in grammar",
"%d rules useless in grammar", "%d rules useless in grammar",
nuseless_productions), nuseless_productions),
@@ -397,8 +395,6 @@ reduce_print (void)
void void
reduce_grammar (void) reduce_grammar (void)
{ {
bool reduced;
/* Allocate the global sets used to compute the reduced grammar */ /* Allocate the global sets used to compute the reduced grammar */
N = bitset_create (nvars, BITSET_FIXED); N = bitset_create (nvars, BITSET_FIXED);
@@ -409,13 +405,13 @@ reduce_grammar (void)
useless_nonterminals (); useless_nonterminals ();
inaccessable_symbols (); inaccessable_symbols ();
reduced = (nuseless_nonterminals + nuseless_productions > 0); /* Did we reduce something? */
if (!reduced) if (!nuseless_nonterminals && !nuseless_productions)
return; return;
reduce_print (); reduce_print ();
if (!bitset_test (N, accept->number - ntokens)) if (!bitset_test (N, accept->content->number - ntokens))
complain (&startsymbol_location, fatal, complain (&startsymbol_location, fatal,
_("start symbol %s does not derive any sentence"), _("start symbol %s does not derive any sentence"),
startsymbol->tag); startsymbol->tag);
@@ -423,9 +419,9 @@ reduce_grammar (void)
/* First reduce the nonterminals, as they renumber themselves in the /* First reduce the nonterminals, as they renumber themselves in the
whole grammar. If you change the order, nonterms would be whole grammar. If you change the order, nonterms would be
renumbered only in the reduced grammar. */ renumbered only in the reduced grammar. */
if (nuseless_nonterminals > 0) if (nuseless_nonterminals)
nonterminals_reduce (); nonterminals_reduce ();
if (nuseless_productions > 0) if (nuseless_productions)
reduce_grammar_tables (); reduce_grammar_tables ();
if (trace_flag & trace_grammar) if (trace_flag & trace_grammar)
@@ -446,10 +442,11 @@ reduce_token_unused_in_grammar (symbol_number i)
} }
bool bool
reduce_nonterminal_useless_in_grammar (symbol_number i) reduce_nonterminal_useless_in_grammar (const sym_content *sym)
{ {
aver (ntokens <= i && i < nsyms + nuseless_nonterminals); symbol_number n = sym->number;
return nsyms <= i; aver (ntokens <= n && n < nsyms + nuseless_nonterminals);
return nsyms <= n;
} }
/*-----------------------------------------------------------. /*-----------------------------------------------------------.
+8 -3
View File
@@ -24,9 +24,14 @@
void reduce_grammar (void); void reduce_grammar (void);
void reduce_output (FILE *out); void reduce_output (FILE *out);
bool reduce_token_unused_in_grammar (symbol_number i); bool reduce_token_unused_in_grammar (symbol_number i);
bool reduce_nonterminal_useless_in_grammar (symbol_number i);
/** Whether symbol \a i is useless in the grammar.
* \pre reduce_grammar was called before.
*/
bool reduce_nonterminal_useless_in_grammar (const sym_content *sym);
void reduce_free (void); void reduce_free (void);
extern symbol_number nuseless_nonterminals; extern unsigned nuseless_nonterminals;
extern rule_number nuseless_productions; extern unsigned nuseless_productions;
#endif /* !REDUCE_H_ */ #endif /* !REDUCE_H_ */
+2 -3
View File
@@ -664,7 +664,7 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
case LHS_REF: case LHS_REF:
if (!type_name) if (!type_name)
type_name = symbol_list_n_type_name_get (rule, dollar_loc, 0); type_name = symbol_list_n_type_name_get (rule, 0);
if (!type_name) if (!type_name)
{ {
@@ -695,8 +695,7 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
if (max_left_semantic_context < 1 - n) if (max_left_semantic_context < 1 - n)
max_left_semantic_context = 1 - n; max_left_semantic_context = 1 - n;
if (!type_name && 0 < n) if (!type_name && 0 < n)
type_name = type_name = symbol_list_n_type_name_get (effective_rule, n);
symbol_list_n_type_name_get (effective_rule, dollar_loc, n);
if (!type_name) if (!type_name)
{ {
if (union_seen | tag_seen) if (union_seen | tag_seen)
+1 -1
View File
@@ -135,7 +135,7 @@ typedef struct
/* Is the TRANSITIONS->states[Num] labelled by the error token? */ /* Is the TRANSITIONS->states[Num] labelled by the error token? */
# define TRANSITION_IS_ERROR(Transitions, Num) \ # define TRANSITION_IS_ERROR(Transitions, Num) \
(TRANSITION_SYMBOL (Transitions, Num) == errtoken->number) (TRANSITION_SYMBOL (Transitions, Num) == errtoken->content->number)
/* When resolving a SR conflicts, if the reduction wins, the shift is /* When resolving a SR conflicts, if the reduction wins, the shift is
disabled. */ disabled. */
+4 -4
View File
@@ -190,9 +190,9 @@ symbol_list_n_get (symbol_list *l, int n)
`--------------------------------------------------------------*/ `--------------------------------------------------------------*/
uniqstr uniqstr
symbol_list_n_type_name_get (symbol_list *l, location loc, int n) symbol_list_n_type_name_get (symbol_list *l, int n)
{ {
return symbol_list_n_get (l, n)->content.sym->type_name; return symbol_list_n_get (l, n)->content.sym->content->type_name;
} }
bool bool
@@ -210,8 +210,8 @@ symbol_list_code_props_set (symbol_list *node, code_props_type kind,
{ {
case SYMLIST_SYMBOL: case SYMLIST_SYMBOL:
symbol_code_props_set (node->content.sym, kind, cprops); symbol_code_props_set (node->content.sym, kind, cprops);
if (node->content.sym->status == undeclared) if (node->content.sym->content->status == undeclared)
node->content.sym->status = used; node->content.sym->content->status = used;
break; break;
case SYMLIST_TYPE: case SYMLIST_TYPE:
semantic_type_code_props_set semantic_type_code_props_set
+1 -1
View File
@@ -124,7 +124,7 @@ symbol_list *symbol_list_n_get (symbol_list *l, int n);
/* Get the data type (alternative in the union) of the value for /* Get the data type (alternative in the union) of the value for
symbol N in rule RULE. */ symbol N in rule RULE. */
uniqstr symbol_list_n_type_name_get (symbol_list *l, location loc, int n); uniqstr symbol_list_n_type_name_get (symbol_list *l, int n);
/* Check whether the node is a border element of a rule. */ /* Check whether the node is a border element of a rule. */
bool symbol_list_null (symbol_list *node); bool symbol_list_null (symbol_list *node);
+186 -160
View File
@@ -58,6 +58,35 @@ static symgraph **prec_nodes;
bool *used_assoc = NULL; bool *used_assoc = NULL;
/*--------------------------.
| Create a new sym_content. |
`--------------------------*/
static sym_content *
sym_content_new (symbol *s)
{
sym_content *res = xmalloc (sizeof *res);
res->symbol = s;
res->type_name = NULL;
{
int i;
for (i = 0; i < CODE_PROPS_SIZE; ++i)
code_props_none_init (&res->props[i]);
}
res->number = NUMBER_UNDEFINED;
res->prec = 0;
res->assoc = undef_assoc;
res->user_token_number = USER_NUMBER_UNDEFINED;
res->class = unknown_sym;
res->status = undeclared;
return res;
}
/*---------------------------------. /*---------------------------------.
| Create a new symbol, named TAG. | | Create a new symbol, named TAG. |
`---------------------------------*/ `---------------------------------*/
@@ -76,22 +105,10 @@ symbol_new (uniqstr tag, location loc)
res->tag = tag; res->tag = tag;
res->location = loc; res->location = loc;
res->location_of_lhs = false;
res->type_name = NULL;
{
int i;
for (i = 0; i < CODE_PROPS_SIZE; ++i)
code_props_none_init (&res->props[i]);
}
res->number = NUMBER_UNDEFINED;
res->prec = 0;
res->assoc = undef_assoc;
res->user_token_number = USER_NUMBER_UNDEFINED;
res->alias = NULL; res->alias = NULL;
res->class = unknown_sym; res->content = sym_content_new (res);
res->status = undeclared; res->is_alias = false;
if (nsyms == SYMBOL_NUMBER_MAXIMUM) if (nsyms == SYMBOL_NUMBER_MAXIMUM)
complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"), complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"),
@@ -100,6 +117,31 @@ symbol_new (uniqstr tag, location loc)
return res; return res;
} }
/*--------------------.
| Free a sym_content. |
`--------------------*/
static void
sym_content_free (sym_content *sym)
{
free (sym);
}
/*---------------------------------------------------------.
| Free a symbol and its associated content if appropriate. |
`---------------------------------------------------------*/
static void
symbol_free (void *ptr)
{
symbol *sym = (symbol *)ptr;
if (!sym->is_alias)
sym_content_free (sym->content);
free (sym);
}
/* If needed, swap first and second so that first has the earliest /* If needed, swap first and second so that first has the earliest
location (according to location_cmp). location (according to location_cmp).
@@ -145,9 +187,10 @@ code_props_type_string (code_props_type kind)
case printer: case printer:
return "%printer"; return "%printer";
} }
assert (0); abort ();
} }
/*----------------------------------------. /*----------------------------------------.
| Create a new semantic type, named TAG. | | Create a new semantic type, named TAG. |
`----------------------------------------*/ `----------------------------------------*/
@@ -176,12 +219,12 @@ semantic_type_new (uniqstr tag, const location *loc)
`-----------------*/ `-----------------*/
#define SYMBOL_ATTR_PRINT(Attr) \ #define SYMBOL_ATTR_PRINT(Attr) \
if (s->Attr) \ if (s->content->Attr) \
fprintf (f, " %s { %s }", #Attr, s->Attr) fprintf (f, " %s { %s }", #Attr, s->content->Attr)
#define SYMBOL_CODE_PRINT(Attr) \ #define SYMBOL_CODE_PRINT(Attr) \
if (s->props[Attr].code) \ if (s->content->props[Attr].code) \
fprintf (f, " %s { %s }", #Attr, s->props[Attr].code) fprintf (f, " %s { %s }", #Attr, s->content->props[Attr].code)
void void
symbol_print (symbol const *s, FILE *f) symbol_print (symbol const *s, FILE *f)
@@ -228,7 +271,6 @@ is_identifier (uniqstr s)
uniqstr uniqstr
symbol_id_get (symbol const *sym) symbol_id_get (symbol const *sym)
{ {
aver (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS);
if (sym->alias) if (sym->alias)
sym = sym->alias; sym = sym->alias;
return is_identifier (sym->tag) ? sym->tag : 0; return is_identifier (sym->tag) ? sym->tag : 0;
@@ -267,6 +309,13 @@ semantic_type_redeclaration (semantic_type *s, const char *what, location first,
} }
void
symbol_location_as_lhs_set (symbol *sym, location loc)
{
if (!sym->location_of_lhs)
sym->location = loc;
}
/*-----------------------------------------------------------------. /*-----------------------------------------------------------------.
| Set the TYPE_NAME associated with SYM. Does nothing if passed 0 | | Set the TYPE_NAME associated with SYM. Does nothing if passed 0 |
@@ -278,13 +327,13 @@ symbol_type_set (symbol *sym, uniqstr type_name, location loc)
{ {
if (type_name) if (type_name)
{ {
if (sym->type_name) if (sym->content->type_name)
symbol_redeclaration (sym, "%type", sym->type_location, loc); symbol_redeclaration (sym, "%type", sym->content->type_location, loc);
else else
{ {
uniqstr_assert (type_name); uniqstr_assert (type_name);
sym->type_name = type_name; sym->content->type_name = type_name;
sym->type_location = loc; sym->content->type_location = loc;
} }
} }
} }
@@ -297,12 +346,12 @@ void
symbol_code_props_set (symbol *sym, code_props_type kind, symbol_code_props_set (symbol *sym, code_props_type kind,
code_props const *code) code_props const *code)
{ {
if (sym->props[kind].code) if (sym->content->props[kind].code)
symbol_redeclaration (sym, code_props_type_string (kind), symbol_redeclaration (sym, code_props_type_string (kind),
sym->props[kind].location, sym->content->props[kind].location,
code->location); code->location);
else else
sym->props[kind] = *code; sym->content->props[kind] = *code;
} }
/*-----------------------------------------------------. /*-----------------------------------------------------.
@@ -330,14 +379,14 @@ code_props *
symbol_code_props_get (symbol *sym, code_props_type kind) symbol_code_props_get (symbol *sym, code_props_type kind)
{ {
/* Per-symbol code props. */ /* Per-symbol code props. */
if (sym->props[kind].code) if (sym->content->props[kind].code)
return &sym->props[kind]; return &sym->content->props[kind];
/* Per-type code props. */ /* Per-type code props. */
if (sym->type_name) if (sym->content->type_name)
{ {
code_props *code = code_props *code =
&semantic_type_get (sym->type_name, NULL)->props[kind]; &semantic_type_get (sym->content->type_name, NULL)->props[kind];
if (code->code) if (code->code)
return code; return code;
} }
@@ -345,8 +394,8 @@ symbol_code_props_get (symbol *sym, code_props_type kind)
/* Apply default code props's only to user-defined symbols. */ /* Apply default code props's only to user-defined symbols. */
if (sym->tag[0] != '$' && sym != errtoken) if (sym->tag[0] != '$' && sym != errtoken)
{ {
code_props *code = code_props *code = &semantic_type_get (sym->content->type_name ? "*" : "",
&semantic_type_get (sym->type_name ? "*" : "", NULL)->props[kind]; NULL)->props[kind];
if (code->code) if (code->code)
return code; return code;
} }
@@ -361,16 +410,17 @@ symbol_code_props_get (symbol *sym, code_props_type kind)
void void
symbol_precedence_set (symbol *sym, int prec, assoc a, location loc) symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
{ {
sym_content *s = sym->content;
if (a != undef_assoc) if (a != undef_assoc)
{ {
if (sym->prec) if (s->prec)
symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location, symbol_redeclaration (sym, assoc_to_string (a),
loc); s->prec_location, loc);
else else
{ {
sym->prec = prec; s->prec = prec;
sym->assoc = a; s->assoc = a;
sym->prec_location = loc; s->prec_location = loc;
} }
} }
@@ -387,26 +437,26 @@ void
symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring) symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
{ {
bool warned = false; bool warned = false;
if (sym->class != unknown_sym && sym->class != class) if (sym->content->class != unknown_sym && sym->content->class != class)
{ {
complain (&loc, complaint, _("symbol %s redefined"), sym->tag); complain (&loc, complaint, _("symbol %s redefined"), sym->tag);
/* Don't report both "redefined" and "redeclared". */ /* Don't report both "redefined" and "redeclared". */
warned = true; warned = true;
} }
if (class == nterm_sym && sym->class != nterm_sym) if (class == nterm_sym && sym->content->class != nterm_sym)
sym->number = nvars++; sym->content->number = nvars++;
else if (class == token_sym && sym->number == NUMBER_UNDEFINED) else if (class == token_sym && sym->content->number == NUMBER_UNDEFINED)
sym->number = ntokens++; sym->content->number = ntokens++;
sym->class = class; sym->content->class = class;
if (declaring) if (declaring)
{ {
if (sym->status == declared && !warned) if (sym->content->status == declared && !warned)
complain (&loc, Wother, _("symbol %s redeclared"), sym->tag); complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
else else
sym->status = declared; sym->content->status = declared;
} }
} }
@@ -420,10 +470,7 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
{ {
int *user_token_numberp; int *user_token_numberp;
if (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS) user_token_numberp = &sym->content->user_token_number;
user_token_numberp = &sym->user_token_number;
else
user_token_numberp = &sym->alias->user_token_number;
if (*user_token_numberp != USER_NUMBER_UNDEFINED if (*user_token_numberp != USER_NUMBER_UNDEFINED
&& *user_token_numberp != user_token_number) && *user_token_numberp != user_token_number)
complain (&loc, complaint, _("redefining user token number of %s"), complain (&loc, complaint, _("redefining user token number of %s"),
@@ -433,12 +480,12 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
/* User defined $end token? */ /* User defined $end token? */
if (user_token_number == 0) if (user_token_number == 0)
{ {
endtoken = sym; endtoken = sym->content->symbol;
/* It is always mapped to 0, so it was already counted in /* It is always mapped to 0, so it was already counted in
NTOKENS. */ NTOKENS. */
if (endtoken->number != NUMBER_UNDEFINED) if (endtoken->content->number != NUMBER_UNDEFINED)
--ntokens; --ntokens;
endtoken->number = 0; endtoken->content->number = 0;
} }
} }
@@ -451,16 +498,17 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
static inline bool static inline bool
symbol_check_defined (symbol *sym) symbol_check_defined (symbol *sym)
{ {
if (sym->class == unknown_sym) sym_content *s = sym->content;
if (s->class == unknown_sym)
{ {
assert (sym->status != declared); assert (s->status != declared);
complain (&sym->location, complain (&sym->location,
sym->status == needed ? complaint : Wother, s->status == needed ? complaint : Wother,
_("symbol %s is used, but is not defined as a token" _("symbol %s is used, but is not defined as a token"
" and has no rules"), " and has no rules"),
sym->tag); sym->tag);
sym->class = nterm_sym; s->class = nterm_sym;
sym->number = nvars++; s->number = nvars++;
} }
{ {
@@ -471,9 +519,9 @@ symbol_check_defined (symbol *sym)
/* Set the semantic type status associated to the current symbol to /* Set the semantic type status associated to the current symbol to
'declared' so that we could check semantic types unnecessary uses. */ 'declared' so that we could check semantic types unnecessary uses. */
if (sym->type_name) if (s->type_name)
{ {
semantic_type *sem_type = semantic_type_get (sym->type_name, NULL); semantic_type *sem_type = semantic_type_get (s->type_name, NULL);
if (sem_type) if (sem_type)
sem_type->status = declared; sem_type->status = declared;
} }
@@ -519,6 +567,45 @@ semantic_type_check_defined_processor (void *sem_type,
} }
/*-------------------------------------------------------------------.
| Merge the properties (precedence, associativity, etc.) of SYM, and |
| its string-named alias STR; check consistency. |
`-------------------------------------------------------------------*/
static void
symbol_merge_properties (symbol *sym, symbol *str)
{
if (str->content->type_name != sym->content->type_name)
{
if (str->content->type_name)
symbol_type_set (sym,
str->content->type_name, str->content->type_location);
else
symbol_type_set (str,
sym->content->type_name, sym->content->type_location);
}
{
int i;
for (i = 0; i < CODE_PROPS_SIZE; ++i)
if (str->content->props[i].code)
symbol_code_props_set (sym, i, &str->content->props[i]);
else if (sym->content->props[i].code)
symbol_code_props_set (str, i, &sym->content->props[i]);
}
if (sym->content->prec || str->content->prec)
{
if (str->content->prec)
symbol_precedence_set (sym, str->content->prec, str->content->assoc,
str->content->prec_location);
else
symbol_precedence_set (str, sym->content->prec, sym->content->assoc,
sym->content->prec_location);
}
}
void void
symbol_make_alias (symbol *sym, symbol *str, location loc) symbol_make_alias (symbol *sym, symbol *str, location loc)
{ {
@@ -530,71 +617,17 @@ symbol_make_alias (symbol *sym, symbol *str, location loc)
_("symbol %s given more than one literal string"), sym->tag); _("symbol %s given more than one literal string"), sym->tag);
else else
{ {
str->class = token_sym; symbol_merge_properties (sym, str);
str->user_token_number = sym->user_token_number; sym_content_free (str->content);
sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS; str->content = sym->content;
str->content->symbol = str;
str->is_alias = true;
str->alias = sym; str->alias = sym;
sym->alias = str; sym->alias = str;
str->number = sym->number;
symbol_type_set (str, sym->type_name, loc);
} }
} }
/*---------------------------------------------------------.
| Check that THIS, and its alias, have same precedence and |
| associativity. |
`---------------------------------------------------------*/
static inline void
symbol_check_alias_consistency (symbol *this)
{
symbol *sym = this;
symbol *str = this->alias;
/* Check only the symbol in the symbol-string pair. */
if (!(this->alias
&& this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
return;
if (str->type_name != sym->type_name)
{
if (str->type_name)
symbol_type_set (sym, str->type_name, str->type_location);
else
symbol_type_set (str, sym->type_name, sym->type_location);
}
{
int i;
for (i = 0; i < CODE_PROPS_SIZE; ++i)
if (str->props[i].code)
symbol_code_props_set (sym, i, &str->props[i]);
else if (sym->props[i].code)
symbol_code_props_set (str, i, &sym->props[i]);
}
if (sym->prec || str->prec)
{
if (str->prec)
symbol_precedence_set (sym, str->prec, str->assoc,
str->prec_location);
else
symbol_precedence_set (str, sym->prec, sym->assoc,
sym->prec_location);
}
}
static bool
symbol_check_alias_consistency_processor (void *this,
void *null ATTRIBUTE_UNUSED)
{
symbol_check_alias_consistency (this);
return true;
}
/*-------------------------------------------------------------------. /*-------------------------------------------------------------------.
| Assign a symbol number, and write the definition of the token name | | Assign a symbol number, and write the definition of the token name |
| into FDEFINES. Put in SYMBOLS. | | into FDEFINES. Put in SYMBOLS. |
@@ -603,13 +636,11 @@ symbol_check_alias_consistency_processor (void *this,
static inline bool static inline bool
symbol_pack (symbol *this) symbol_pack (symbol *this)
{ {
aver (this->number != NUMBER_UNDEFINED); aver (this->content->number != NUMBER_UNDEFINED);
if (this->class == nterm_sym) if (this->content->class == nterm_sym)
this->number += ntokens; this->content->number += ntokens;
else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
return true;
symbols[this->number] = this; symbols[this->content->number] = this->content->symbol;
return true; return true;
} }
@@ -619,7 +650,6 @@ symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
return symbol_pack (this); return symbol_pack (this);
} }
static void static void
user_token_number_redeclaration (int num, symbol *first, symbol *second) user_token_number_redeclaration (int num, symbol *first, symbol *second)
{ {
@@ -642,17 +672,18 @@ static inline bool
symbol_translation (symbol *this) symbol_translation (symbol *this)
{ {
/* Non-terminal? */ /* Non-terminal? */
if (this->class == token_sym if (this->content->class == token_sym
&& this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS) && !this->is_alias)
{ {
/* A token which translation has already been set? */ /* A token which translation has already been set?*/
if (token_translations[this->user_token_number] != undeftoken->number) if (token_translations[this->content->user_token_number]
!= undeftoken->content->number)
user_token_number_redeclaration user_token_number_redeclaration
(this->user_token_number, (this->content->user_token_number,
symbols[token_translations[this->user_token_number]], symbols[token_translations[this->content->user_token_number]], this);
this);
else else
token_translations[this->user_token_number] = this->number; token_translations[this->content->user_token_number]
= this->content->number;
} }
return true; return true;
@@ -738,7 +769,7 @@ symbols_new (void)
NULL, NULL,
hash_symbol_hasher, hash_symbol_hasher,
hash_symbol_comparator, hash_symbol_comparator,
free); symbol_free);
semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY, semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
NULL, NULL,
hash_semantic_type_hasher, hash_semantic_type_hasher,
@@ -838,8 +869,8 @@ dummy_symbol_get (location loc)
sprintf (buf, "$@%d", ++dummy_count); sprintf (buf, "$@%d", ++dummy_count);
sym = symbol_get (buf, loc); sym = symbol_get (buf, loc);
sym->class = nterm_sym; sym->content->class = nterm_sym;
sym->number = nvars++; sym->content->number = nvars++;
return sym; return sym;
} }
@@ -929,7 +960,7 @@ symbols_token_translations_init (void)
max_user_token_number = 0; max_user_token_number = 0;
for (i = 0; i < ntokens; ++i) for (i = 0; i < ntokens; ++i)
{ {
symbol *this = symbols[i]; sym_content *this = symbols[i]->content;
if (this->user_token_number != USER_NUMBER_UNDEFINED) if (this->user_token_number != USER_NUMBER_UNDEFINED)
{ {
if (this->user_token_number > max_user_token_number) if (this->user_token_number > max_user_token_number)
@@ -941,8 +972,8 @@ symbols_token_translations_init (void)
/* If 256 is not used, assign it to error, to follow POSIX. */ /* If 256 is not used, assign it to error, to follow POSIX. */
if (num_256_available_p if (num_256_available_p
&& errtoken->user_token_number == USER_NUMBER_UNDEFINED) && errtoken->content->user_token_number == USER_NUMBER_UNDEFINED)
errtoken->user_token_number = 256; errtoken->content->user_token_number = 256;
/* Set the missing user numbers. */ /* Set the missing user numbers. */
if (max_user_token_number < 256) if (max_user_token_number < 256)
@@ -950,7 +981,7 @@ symbols_token_translations_init (void)
for (i = 0; i < ntokens; ++i) for (i = 0; i < ntokens; ++i)
{ {
symbol *this = symbols[i]; sym_content *this = symbols[i]->content;
if (this->user_token_number == USER_NUMBER_UNDEFINED) if (this->user_token_number == USER_NUMBER_UNDEFINED)
this->user_token_number = ++max_user_token_number; this->user_token_number = ++max_user_token_number;
if (this->user_token_number > max_user_token_number) if (this->user_token_number > max_user_token_number)
@@ -963,7 +994,7 @@ symbols_token_translations_init (void)
/* Initialize all entries for literal tokens to the internal token /* Initialize all entries for literal tokens to the internal token
number for $undefined, which represents all invalid inputs. */ number for $undefined, which represents all invalid inputs. */
for (i = 0; i < max_user_token_number + 1; i++) for (i = 0; i < max_user_token_number + 1; i++)
token_translations[i] = undeftoken->number; token_translations[i] = undeftoken->content->number;
symbols_do (symbol_translation_processor, NULL, symbols_do (symbol_translation_processor, NULL,
symbol_table, &symbols_sorted); symbol_table, &symbols_sorted);
} }
@@ -977,9 +1008,6 @@ symbols_token_translations_init (void)
void void
symbols_pack (void) symbols_pack (void)
{ {
symbols_do (symbol_check_alias_consistency_processor, NULL,
symbol_table, &symbols_sorted);
symbols = xcalloc (nsyms, sizeof *symbols); symbols = xcalloc (nsyms, sizeof *symbols);
symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted); symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted);
@@ -998,9 +1026,7 @@ symbols_pack (void)
else else
{ {
symbols[writei] = symbols[readi]; symbols[writei] = symbols[readi];
symbols[writei]->number = writei; symbols[writei]->content->number = writei;
if (symbols[writei]->alias)
symbols[writei]->alias->number = writei;
writei += 1; writei += 1;
} }
} }
@@ -1009,11 +1035,11 @@ symbols_pack (void)
symbols_token_translations_init (); symbols_token_translations_init ();
if (startsymbol->class == unknown_sym) if (startsymbol->content->class == unknown_sym)
complain (&startsymbol_location, fatal, complain (&startsymbol_location, fatal,
_("the start symbol %s is undefined"), _("the start symbol %s is undefined"),
startsymbol->tag); startsymbol->tag);
else if (startsymbol->class == token_sym) else if (startsymbol->content->class == token_sym)
complain (&startsymbol_location, fatal, complain (&startsymbol_location, fatal,
_("the start symbol %s is a token"), _("the start symbol %s is a token"),
startsymbol->tag); startsymbol->tag);
@@ -1150,9 +1176,9 @@ static inline bool
is_assoc_useless (symbol *s) is_assoc_useless (symbol *s)
{ {
return s return s
&& s->assoc != undef_assoc && s->content->assoc != undef_assoc
&& s->assoc != precedence_assoc && s->content->assoc != precedence_assoc
&& !used_assoc[s->number]; && !used_assoc[s->content->number];
} }
/*-------------------------------. /*-------------------------------.
@@ -1184,19 +1210,19 @@ print_precedence_warnings (void)
{ {
symbol *s = symbols[i]; symbol *s = symbols[i];
if (s if (s
&& s->prec != 0 && s->content->prec != 0
&& !prec_nodes[i]->pred && !prec_nodes[i]->pred
&& !prec_nodes[i]->succ) && !prec_nodes[i]->succ)
{ {
if (is_assoc_useless (s)) if (is_assoc_useless (s))
complain (&s->prec_location, Wprecedence, complain (&s->content->prec_location, Wprecedence,
_("useless precedence and associativity for %s"), s->tag); _("useless precedence and associativity for %s"), s->tag);
else if (s->assoc == precedence_assoc) else if (s->content->assoc == precedence_assoc)
complain (&s->prec_location, Wprecedence, complain (&s->content->prec_location, Wprecedence,
_("useless precedence for %s"), s->tag); _("useless precedence for %s"), s->tag);
} }
else if (is_assoc_useless (s)) else if (is_assoc_useless (s))
complain (&s->prec_location, Wprecedence, complain (&s->content->prec_location, Wprecedence,
_("useless associativity for %s, use %%precedence"), s->tag); _("useless associativity for %s, use %%precedence"), s->tag);
} }
free (used_assoc); free (used_assoc);
+32 -14
View File
@@ -50,6 +50,7 @@ typedef int symbol_number;
typedef struct symbol symbol; typedef struct symbol symbol;
typedef struct sym_content sym_content;
/* Declaration status of a symbol. /* Declaration status of a symbol.
@@ -73,24 +74,45 @@ typedef enum
declared, declared,
} status; } status;
typedef enum code_props_type code_props_type;
enum code_props_type enum code_props_type
{ {
destructor = 0, destructor = 0,
printer = 1, printer = 1,
}; };
typedef enum code_props_type code_props_type;
enum { CODE_PROPS_SIZE = 2 }; enum { CODE_PROPS_SIZE = 2 };
/* When extending this structure, be sure to complete
symbol_check_alias_consistency. */
struct symbol struct symbol
{ {
/** The key, name of the symbol. */ /** The key, name of the symbol. */
uniqstr tag; uniqstr tag;
/** The location of its first occurrence. */
/** The "defining" location. */
location location; location location;
/** Whether \a location is about the first uses as left-hand side
symbol of a rule (true), or simply the first occurrence (e.g.,
in a %type, or as a rhs symbol of a rule). The former type of
location is more natural in error messages. This Boolean helps
moving from location of the first occurrence to first use as
lhs. */
bool location_of_lhs;
/** Points to the other in the symbol-string pair for an alias. */
symbol *alias;
/** Whether this symbol is the alias of another or not. */
bool is_alias;
/** All the info about the pointed symbol is there. */
sym_content *content;
};
struct sym_content
{
symbol *symbol;
/** Its \c \%type. /** Its \c \%type.
Beware that this is the type_name as was entered by the user, Beware that this is the type_name as was entered by the user,
@@ -117,10 +139,6 @@ struct symbol
assoc assoc; assoc assoc;
int user_token_number; int user_token_number;
/* Points to the other in the symbol-string pair for an alias.
Special value USER_NUMBER_HAS_STRING_ALIAS in the symbol half of the
symbol-string pair for an alias. */
symbol *alias;
symbol_class class; symbol_class class;
status status; status status;
}; };
@@ -128,12 +146,6 @@ struct symbol
/** Undefined user number. */ /** Undefined user number. */
# define USER_NUMBER_UNDEFINED -1 # define USER_NUMBER_UNDEFINED -1
/* 'symbol->user_token_number == USER_NUMBER_HAS_STRING_ALIAS' means
this symbol has a literal string alias. For instance, '%token foo
"foo"' has '"foo"' numbered regularly, and 'foo' numbered as
USER_NUMBER_HAS_STRING_ALIAS. */
# define USER_NUMBER_HAS_STRING_ALIAS -9991
/* Undefined internal token number. */ /* Undefined internal token number. */
# define NUMBER_UNDEFINED (-1) # define NUMBER_UNDEFINED (-1)
@@ -174,6 +186,12 @@ uniqstr symbol_id_get (symbol const *sym);
*/ */
void symbol_make_alias (symbol *sym, symbol *str, location loc); void symbol_make_alias (symbol *sym, symbol *str, location loc);
/**
* This symbol is used as the lhs of a rule. Record this location
* as definition point, if not already done.
*/
void symbol_location_as_lhs_set (symbol *sym, location loc);
/** Set the \c type_name associated with \c sym. /** Set the \c type_name associated with \c sym.
Do nothing if passed 0 as \c type_name. */ Do nothing if passed 0 as \c type_name. */
+3 -3
View File
@@ -290,7 +290,7 @@ action_row (state *s)
/* Do not use any default reduction if there is a shift for /* Do not use any default reduction if there is a shift for
error */ error */
if (sym == errtoken->number) if (sym == errtoken->content->number)
nodefault = true; nodefault = true;
} }
@@ -300,7 +300,7 @@ action_row (state *s)
for (i = 0; i < errp->num; i++) for (i = 0; i < errp->num; i++)
{ {
symbol *sym = errp->symbols[i]; symbol *sym = errp->symbols[i];
actrow[sym->number] = ACTION_NUMBER_MINIMUM; actrow[sym->content->number] = ACTION_NUMBER_MINIMUM;
} }
/* Turn off default reductions where requested by the user. See /* Turn off default reductions where requested by the user. See
@@ -698,7 +698,7 @@ pack_vector (vector_number vector)
if (ok) if (ok)
{ {
int loc; int loc PACIFY_CC (= -1);
int k; int k;
for (k = 0; k < t; k++) for (k = 0; k < t; k++)
{ {
+7 -4
View File
@@ -633,7 +633,7 @@ main (int argc, const char *argv[])
{ {
int status; int status;
yydebug = !!getenv ("YYDEBUG"); yydebug = !!getenv ("YYDEBUG");
assert (argc == 2); assert (argc == 2); (void) argc;
source = argv[1]; source = argv[1];
status = yyparse (); status = yyparse ();
switch (status) switch (status)
@@ -1530,10 +1530,13 @@ AT_DATA_GRAMMAR([[input.y]],
]AT_SKEL_CC_IF([[ ]AT_SKEL_CC_IF([[
# include <iostream> # include <iostream>
static void namespace
report (std::ostream& yyo, int ival, float fval)
{ {
yyo << "ival: " << ival << ", fval: " << fval; void
report (std::ostream& yyo, int ival, float fval)
{
yyo << "ival: " << ival << ", fval: " << fval;
}
} }
]], [[ ]], [[
# include <stdio.h> # include <stdio.h>
+2 -2
View File
@@ -342,7 +342,6 @@ AT_PARSER_CHECK([./list], 0,
]], ]],
[[Destroy: "" [[Destroy: ""
Destroy: "0" Destroy: "0"
Destroy: (0)
Destroy: 1 Destroy: 1
Destroy: "1" Destroy: "1"
Destroy: () Destroy: ()
@@ -719,6 +718,7 @@ $1
#include <cstdlib> // size_t and getenv. #include <cstdlib> // size_t and getenv.
#include <iostream> #include <iostream>
#include <set> #include <set>
#include <string>
bool debug = false; bool debug = false;
@@ -751,7 +751,7 @@ $1
~Object () ~Object ()
{ {
log (this, "Object::~Object"); log (this, "Object::~Object");
objects::const_iterator i = instances.find (this); objects::iterator i = instances.find (this);
// Make sure this object is alive. // Make sure this object is alive.
assert (i != instances.end ()); assert (i != instances.end ());
Object::instances.erase (i); Object::instances.erase (i);
+2 -2
View File
@@ -94,8 +94,8 @@ main (int argc, const char **argv)
status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count]])[); status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count]])[);
if (fclose (input)) if (fclose (input))
perror ("fclose"); perror ("fclose");
assert (global_result == result); assert (global_result == result); (void) result;
assert (global_count == count); assert (global_count == count); (void) count;
return status; return status;
} }
]]) ]])
+1 -1
View File
@@ -395,7 +395,7 @@ AT_CLEANUP
m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [ m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [
AT_SETUP([[parse.error=verbose and consistent errors: $1]]) AT_SETUP([[parse.error=verbose and consistent errors: ]$1])
AT_BISON_OPTION_PUSHDEFS([$1]) AT_BISON_OPTION_PUSHDEFS([$1])
+1 -1
View File
@@ -127,7 +127,7 @@ declarator : ID
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
assert (argc == 2); assert (argc == 2); (void) argc;
if (!freopen (argv[1], "r", stdin)) if (!freopen (argv[1], "r", stdin))
return 3; return 3;
return yyparse (); return yyparse ();
+1 -1
View File
@@ -72,7 +72,7 @@ const char *input = YY_NULLPTR;
int int
main (int argc, const char* argv[]) main (int argc, const char* argv[])
{ {
assert (argc == 2); assert (argc == 2); (void) argc;
input = argv[1]; input = argv[1];
return yyparse (); return yyparse ();
} }
+2 -2
View File
@@ -162,8 +162,8 @@ int main (int argc, const char **argv)
} }
status = yyparse (); status = yyparse ();
fclose (input); fclose (input);
assert (global_result == result); assert (global_result == result); (void) global_result; (void) result;
assert (global_count == count); assert (global_count == count); (void) global_count; (void) count;
return status; return status;
} }
]]) ]])
+12 -41
View File
@@ -172,33 +172,6 @@ input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother] input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
useless9: '9'; useless9: '9';
^^^^^^^^ ^^^^^^^^
input.y:6.11-13: warning: rule useless in grammar [-Wother]
useless1: '1';
^^^
input.y:7.11-13: warning: rule useless in grammar [-Wother]
useless2: '2';
^^^
input.y:8.11-13: warning: rule useless in grammar [-Wother]
useless3: '3';
^^^
input.y:9.11-13: warning: rule useless in grammar [-Wother]
useless4: '4';
^^^
input.y:10.11-13: warning: rule useless in grammar [-Wother]
useless5: '5';
^^^
input.y:11.11-13: warning: rule useless in grammar [-Wother]
useless6: '6';
^^^
input.y:12.11-13: warning: rule useless in grammar [-Wother]
useless7: '7';
^^^
input.y:13.11-13: warning: rule useless in grammar [-Wother]
useless8: '8';
^^^
input.y:14.11-13: warning: rule useless in grammar [-Wother]
useless9: '9';
^^^
]]) ]])
@@ -281,18 +254,12 @@ not-reduced.y: warning: 3 rules useless in grammar [-Wother]
not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother] not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
not_reachable: useful { /* A not reachable action. */ } not_reachable: useful { /* A not reachable action. */ }
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother] not-reduced.y:17.1-14: warning: nonterminal useless in grammar: non_productive [-Wother]
| non_productive { /* A non productive action. */ } non_productive: non_productive useless_token
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother] not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother]
| non_productive { /* A non productive action. */ } | non_productive { /* A non productive action. */ }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
not-reduced.y:14.16-56: warning: rule useless in grammar [-Wother]
not_reachable: useful { /* A not reachable action. */ }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
not-reduced.y:17.17-18.63: warning: rule useless in grammar [-Wother]
non_productive: non_productive useless_token
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
]]) ]])
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0, AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
@@ -360,14 +327,18 @@ underivable: indirection;
indirection: underivable; indirection: underivable;
]]) ]])
AT_BISON_CHECK([[input.y]], 0, [], AT_BISON_CHECK([[-fcaret input.y]], 0, [],
[[input.y: warning: 2 nonterminals useless in grammar [-Wother] [[input.y: warning: 2 nonterminals useless in grammar [-Wother]
input.y: warning: 3 rules useless in grammar [-Wother] input.y: warning: 3 rules useless in grammar [-Wother]
input.y:5.15-25: warning: nonterminal useless in grammar: underivable [-Wother] input.y:6.1-11: warning: nonterminal useless in grammar: underivable [-Wother]
input.y:6.14-24: warning: nonterminal useless in grammar: indirection [-Wother] underivable: indirection;
^^^^^^^^^^^
input.y:7.1-11: warning: nonterminal useless in grammar: indirection [-Wother]
indirection: underivable;
^^^^^^^^^^^
input.y:5.15-25: warning: rule useless in grammar [-Wother] input.y:5.15-25: warning: rule useless in grammar [-Wother]
input.y:6.14-24: warning: rule useless in grammar [-Wother] exp: useful | underivable;
input.y:7.14-24: warning: rule useless in grammar [-Wother] ^^^^^^^^^^^
]]) ]])
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0, AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
+35 -12
View File
@@ -19,13 +19,13 @@
AT_BANNER([[User Actions.]]) AT_BANNER([[User Actions.]])
# AT_SYNCLINES_COMPILE(FILE) # _AT_SYNCLINES_COMPILE(FILE)
# -------------------------- # ---------------------------
# Compile FILE expecting an error, and save in the file stdout the # Compile FILE expecting an error, and save in the file stdout the
# normalized output. Ignore the exit status, since some compilers # normalized output. Ignore the exit status, since some compilers
# (e.g. c89 on IRIX 6.5) trigger warnings on '#error', instead of # (e.g. c89 on IRIX 6.5) trigger warnings on '#error', instead of
# 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: # Transform stderr into something like this:
@@ -75,6 +75,12 @@ m4_define([AT_SYNCLINES_COMPILE],
# When c++ is used to compiler C, we might have more messages (Clang 3.2): # When c++ is used to compiler C, we might have more messages (Clang 3.2):
# #
# clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated # clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
#
#
# xlc reports things like:
#
# "input.yy", line 80.21: 1540-0218 (S) The call does not match any parameter list for "operator<<".
# "/usr/vacpp/include/iosfwd", line 32.6: 1506-205 (S) #error This file to be used only with IBM VisualAge C++ v4 and later compilers
AT_CHECK([[$PERL -p -0777 - stderr <<\EOF AT_CHECK([[$PERL -p -0777 - stderr <<\EOF
# 1. Remove useless lines. # 1. Remove useless lines.
@@ -92,6 +98,8 @@ AT_CHECK([[$PERL -p -0777 - stderr <<\EOF
# 2. Normalize the lines we kept. # 2. Normalize the lines we kept.
# xlc messages. Remove also error identifier (e.g., "1540-0218 (S)").
s/^"(.*?)", line ([\w.]*): \d+-\d+ \(.\) /$][1:$][2: /gm;
# Remove column. # Remove column.
s/^([^:]+:\d+)[.:][^:]+:(.+)$/$][1:$][2/gm; s/^([^:]+:\d+)[.:][^:]+:(.+)$/$][1:$][2/gm;
# Map all combinations of "error: " and "#error: " to "#error ". # Map all combinations of "error: " and "#error: " to "#error ".
@@ -101,13 +109,14 @@ EOF
0, [stdout]) 0, [stdout])
]) ])
# AT_TEST(TITLE, INPUT, ERROR-MSG)
# --------------------------------
# Check that compiling the parser produced from INPUT cause GCC # AT_SYNCLINES_COMPILE(FILE)
# to issue ERROR-MSG. # --------------------------
m4_pushdef([AT_TEST], # Compile FILE expecting an error, and save in the file stdout the
[AT_SETUP([$1]) # normalized output. If we can't get a trustable location
AT_BISON_OPTION_PUSHDEFS # from the compiler, just skip the test.
#
# It seems impossible to find a generic scheme to check the location # It seems impossible to find a generic scheme to check the location
# of an error. Even requiring GCC is not sufficient, since for instance # of an error. Even requiring GCC is not sufficient, since for instance
# the version modified by Apple: # the version modified by Apple:
@@ -124,15 +133,29 @@ AT_BISON_OPTION_PUSHDEFS
# #
# | input.y:2: "2" # | input.y:2: "2"
# | cpp-precomp: warning: errors during smart preprocessing, retrying in basic mode # | cpp-precomp: warning: errors during smart preprocessing, retrying in basic mode
m4_define([AT_SYNCLINES_COMPILE],
[# Check if we can trust location translation.
AT_DATA([syncline.c], AT_DATA([syncline.c],
[[#error "1" [[#error "1"
int i; /* avoids -pedantic warning about an empty translation unit. */ int i; /* avoids -pedantic warning about an empty translation unit. */
]]) ]])
AT_SYNCLINES_COMPILE([syncline.c]) _AT_SYNCLINES_COMPILE([syncline.c])
AT_CHECK([[test "`cat stdout`" = 'syncline.c:1: @%:@error "1"' || exit 77]]) AT_CHECK([[test "`cat stdout`" = 'syncline.c:1: @%:@error "1"' || exit 77]])
# Then work for real.
_AT_SYNCLINES_COMPILE([$1])
])
# AT_TEST(TITLE, INPUT, ERROR-MSG)
# --------------------------------
# Check that compiling the parser produced from INPUT cause GCC
# to issue ERROR-MSG.
m4_pushdef([AT_TEST],
[AT_SETUP([$1])
AT_BISON_OPTION_PUSHDEFS
AT_DATA([[input.y]], [$2]) AT_DATA([[input.y]], [$2])
AT_BISON_CHECK([-o input.c input.y]) AT_BISON_CHECK([-o input.c input.y])
AT_SYNCLINES_COMPILE([input.c]) AT_SYNCLINES_COMPILE([input.c])
+1 -1
View File
@@ -403,7 +403,7 @@ get_args (int argc, const char **argv)
{ {
int res; int res;
char *endp; char *endp;
assert (argc == 2); assert (argc == 2); (void) argc;
res = strtol (argv[1], &endp, 10); res = strtol (argv[1], &endp, 10);
assert (argv[1] != endp); assert (argv[1] != endp);
assert (0 <= res); assert (0 <= res);