Compare commits

...
48 Commits
Author SHA1 Message Date
Akim Demaille f0942df01a version 3.5.91
* NEWS: Record release date.
2020-04-29 08:47:35 +02:00
Akim Demaille 52ababbc89 build: fix syntax-check issues
* cfg.mk: We do want to gettextize the examples.
* po/POTFILES.in: Adjust.
2020-04-29 08:47:04 +02:00
Akim Demaille 8e11933e41 gnulib: update 2020-04-29 08:32:25 +02:00
Akim Demaille 99efa35369 doc: document YYEOF, YYUNDEF and YYerror
* doc/bison.texi (Special Tokens): New.
* examples/c/bistromathic/parse.y: Formatting changes.
2020-04-29 08:23:55 +02:00
Akim Demaille 547545a795 package: fix distcheck
Bison emits strings to translate in the generated code, for builtin
tokens.  So they appear only in generated parsers, which are not
shipped, so they are not in the src tree, so we cannot use them in our
POTFILE.

Except src/parse-gram.c, which is in the source tree.  And even in the
git repo.  But to avoid useless diffs in the repo, we do not keep the
src/parse-gram.c _with_ the #lines.  This is done in a dist-hook which
regenerates src/parse-gram.c when we run "make dist".

Unfortunately, then, update-po traverses the whole tree and sees that
the location of the strings to translate in src/parse-gram.c have
changed, so the bison.pot is to be updated.  And that is not possible
in the "make dist" which is run within "make distcheck"
(not the one preparing the dist for distcheck, the one run by
distcheck to check that a distributed tarball can build a tarball)
because then the src tree is read-only.

So let's not put src/parse-gram.c in the POTFILE, and expose these
strings to gettextize by hand.

* src/i18n-strings.c: New.
* po/POTFILES.in: Add it, and remove src/parse-gram.c.
2020-04-29 07:01:22 +02:00
Akim Demaille 1b5cf80e32 style: avoid gettextize warnings
* src/scan-gram.l, src/scan-skel.l: Help it see the start and end of
"character literals".
2020-04-29 07:01:22 +02:00
Akim Demaille 4c641c5189 tests: beware of portability of readline
* examples/test: here.
2020-04-29 07:01:22 +02:00
Akim Demaille 3b05de2d05 yacc.c: install backward compatibility for YYERRCODE
Some people have been using that symbol.  Some even have #defined it
themselves.
https://lists.gnu.org/r/bison-patches/2020-04/msg00138.html

Let's provide backward compatibility, having it point to YYUNDEF, so
that an error message is generated.

* data/skeletons/yacc.c (YYERRCODE): New, at the exact same location
it was defined before.
2020-04-28 08:26:49 +02:00
Akim Demaille 902a235ad3 style: c++: s/type/kind/ where appropriate
These are internal details.  `type_get ()` is still there to ensure
backward compatibility, `kind ()` being the modern way.

* data/skeletons/c++.m4 (by_type, by_type::type): Rename as...
(by_kind, by_kind::kind_): this.
Adjust dependencies.
2020-04-28 08:16:05 +02:00
Akim Demaille 11027558c8 java: clean up the definition of token kinds
From

    public interface Lexer {
      /* Token kinds.  */
      /** Token number, to be returned by the scanner.  */
      static final int YYEOF = 0;
      /** Token number, to be returned by the scanner.  */
      static final int YYERRCODE = 256;
      /** Token number, to be returned by the scanner.  */
      static final int YYUNDEF = 257;
      /** Token number, to be returned by the scanner.  */
      static final int BANG = 258;
    ...
      /** Deprecated, use b4_symbol(0, id) instead.  */
      public static final int EOF = YYEOF;

to

    public interface Lexer {
      /* Token kinds.  */
      /** Token "end of file", to be returned by the scanner.  */
      static final int YYEOF = 0;
      /** Token error, to be returned by the scanner.  */
      static final int YYerror = 256;
      /** Token "invalid token", to be returned by the scanner.  */
      static final int YYUNDEF = 257;
      /** Token "!", to be returned by the scanner.  */
      static final int BANG = 258;
    ...
      /** Deprecated, use YYEOF instead.  */
      public static final int EOF = YYEOF;

* data/skeletons/java.m4 (b4_token_enum): Display the symbol's tag in
comment.
* data/skeletons/lalr1.java: Address overquotation issue.
* examples/java/calc/Calc.y, examples/java/simple/Calc.y: Use YYEOF,
not EOF.
2020-04-28 07:56:00 +02:00
Akim Demaille cd4e799da4 error: rename the error token from YYERRCODE to YYerror
See https://lists.gnu.org/r/bison-patches/2020-04/msg00162.html.

* data/skeletons/bison.m4, data/skeletons/c.m4, data/skeletons/glr.cc,
* data/skeletons/lalr1.java, doc/bison.texi,
* examples/c/bistromathic/parse.y, src/scan-gram.l, src/symtab.c
(YYERRCODE): Rename as...
(YYerror): this.
Adjust dependencies.
2020-04-28 07:54:07 +02:00
Akim Demaille 7346163840 dogfooding: use YYERRCODE in our scanner
* src/scan-gram.l: Use it.
* tests/input.at: Adjust.
2020-04-27 08:21:50 +02:00
Akim Demaille 89c4e1becf scanner: avoid spurious errors about empty character literals
On an invalid character literal such as "'\777'" we used to produce
two errors:

    input.y:2.9-12: error: invalid number after \-escape: 777
    input.y:2.8-13: error: empty character literal

Get rid of the second one.

* src/scan-gram.l (STRING_GROW_ESCAPE): New.
* tests/input.at: Adjust.
2020-04-27 08:06:49 +02:00
Akim Demaille 3262747c5b scanner: bad character literals are errors
* src/scan-gram.l: These are errors, not warnings.
* tests/input.at: Adjust.
2020-04-27 07:17:04 +02:00
Akim Demaille 5f3cd49acc regen 2020-04-27 07:08:55 +02:00
Akim Demaille e6d928c4e8 todo: update 2020-04-26 19:55:52 +02:00
Akim Demaille b254b36db8 all: don't emit an error message when the scanner returns YYERRCODE
I'm quite pleased to see that the tricky case of glr.c was already
prepared by the changes to support syntax_error exceptions.  Better
yet, it is actually syntax_error that becomes a special case of the
general pattern: make yytoken be YYERRCODE.

* data/skeletons/glr.c (YYFAULTYTOK): Remove the now useless (Basil)
Faulty token.
Instead, use the error token.
* data/skeletons/lalr1.d, data/skeletons/lalr1.java: When computing
the action, first check the case of the error token.

* tests/calc.at: Check cases for the error token symbols before and
after it.
2020-04-26 19:55:52 +02:00
Akim Demaille 58e79539fc c: don't emit an error message when the scanner returns YYERRCODE
* data/skeletons/yacc.c (yyparse): When the scanner returns YYERRCODE,
go directly to error recovery (yyerrlab1).
However, don't keep the error token as lookahead, that token is too
special.
* data/skeletons/lalr1.cc: Likewise.

* examples/c/bistromathic/parse.y (yylex): Use that feature to report
nicely invalid characters.
* examples/c/bistromathic/bistromathic.test: Check that.
* examples/test: Neutralize gratuitous differences such as rule
position.

* tests/calc.at: Check that case in C only.
The other case seem to be working, but that's an illusion that the
next commit will address (in fact, they can enter endless loops, and
report the error several times anyway).
2020-04-26 18:05:30 +02:00
Akim Demaille 60366b152b examples: bistromathic: demonstrate error recovery
* examples/c/bistromathic/parse.y: here.
* examples/c/bistromathic/bistromathic.test: Check it.
Included a stupid case where the error is actually ignored.
2020-04-26 16:08:47 +02:00
Akim Demaille c90110efd3 examples: bistromathic: when quitting, close the current line
When the user ctrl-d the line, we left the cursor not at col 0.
Let's fix that.
This revealed a few short-comings in the testing framework.

* examples/test (run): Also display the diffs.
And support -n.
* examples/c/bistromathic/bistromathic.test
* examples/c/bistromathic/parse.y
2020-04-26 16:08:47 +02:00
Akim Demaille 3b50adf7f4 examples: bistromathic: comment changes
* examples/c/bistromathic/parse.y: here.
2020-04-26 16:08:47 +02:00
Akim Demaille 3aaa971096 doc: hacking tricks
* README-hacking.md: Here.
2020-04-26 16:08:42 +02:00
Akim Demaille 7eabe1c70b c++: make valid to print the empty symbol
* data/skeletons/lalr1.cc (yy_print_): here.
2020-04-26 15:09:52 +02:00
Akim Demaille 7fec669e42 c++: always define symbol_name
* data/skeletons/lalr1.cc (symbol_name): Always define it, even when
it's actually yytname which is used.
2020-04-26 15:09:52 +02:00
Akim Demaille cbbbe12e02 c++: fix a few style issues
* data/skeletons/lalr1.cc (yystack_print_, yy_reduce_print_): Add
missing const.
(yystack_print_): Rename as...
(yy_stack_print_): this.
* data/skeletons/glr.cc (yy_symbol_value_print_, yy_symbol_print_):
Add missing const.
2020-04-26 15:09:52 +02:00
Akim Demaille 286d0755f8 all: prefer YYERRCODE to YYERROR
We will not keep YYERRCODE anyway, it causes backward compatibility
issues.  So as a first step, let all the skeletons use that name,
until we have a better one.

* data/skeletons/bison.m4, data/skeletons/glr.c,
* data/skeletons/glr.cc, data/skeletons/lalr1.cc,
* data/skeletons/lalr1.d, data/skeletons/lalr1.java,
* data/skeletons/yacc.c, doc/bison.texi, tests/headers.at,
* tests/input.at:
here.
2020-04-26 15:09:51 +02:00
Akim Demaille 1c3d79b871 style: glr.c: clarify
* data/skeletons/glr.c: Make the code a bit clearer.
2020-04-26 14:49:26 +02:00
Akim Demaille 9c72d3c5a8 style: prefer b4_has_translations_if
* data/skeletons/glr.c, data/skeletons/yacc.c: here.
2020-04-26 13:34:30 +02:00
Akim Demaille bc083be055 style: glr.c: fix indentation issue
* data/skeletons/glr.c (yyparse): here.
2020-04-26 10:57:23 +02:00
Akim Demaille 22eeb1ab8a style: fix a few remaining 'type' instead of 'kind'
* data/skeletons/glr.c, data/skeletons/yacc.c (YY_SYMBOL_PRINT):
Here.
2020-04-26 10:57:22 +02:00
Akim Demaille c4dbc1776c skeletons: make the warning about implementation details clearer
* data/skeletons/bison.m4 (b4_disclaimer): Here.
* data/skeletons/lalr1.d, data/skeletons/lalr1.java: Use it.
2020-04-26 10:57:02 +02:00
Akim Demaille b74fc07d21 style: c: fix a few minor issues about indentation of cpp directives
* README-hacking.md: More about cpp.
* data/skeletons/c.m4, data/skeletons/yacc.c: Style changes.
2020-04-25 12:16:57 +02:00
Akim Demaille 3ab12c1036 bench: store in benches/012 rather than in benches/12
* etc/bench.pl.in ($basedir): New.
Format $count with a least three digits.
2020-04-25 11:34:06 +02:00
Akim Demaille 30ce43b2b5 bench: minor improvements
* etc/bench.pl.in: Don't force parse.error=detailed
Use a simpler way to display the pseudo %bison directive.
(&bench_with_gbenchmark): Give details about the compiler.
2020-04-25 11:06:16 +02:00
Akim Demaille 150dc95395 style: clarify #endif
We could try to avoid the weird "#if 1", but then the indentation of
the inner #if would be wrong.  Let' keep it this way.

* data/skeletons/yacc.c: here.
Also, avoid sticking the comment to the directive.
2020-04-25 11:06:16 +02:00
Akim Demaille bb7c4a5508 style: minor fixes
* data/skeletons/bison.m4, doc/bison.texi: Spell check.
* examples/c/bistromathic/parse.y (N_): Remove, now useless.
2020-04-25 08:00:08 +02:00
Akim Demaille 5c9f50b545 examples: bistromathic: shorten token description
* examples/c/bistromathic/parse.y: "number" is enough.
* doc/bison.texi: Likewise.
2020-04-24 19:03:12 +02:00
Akim Demaille b42702d738 examples: bistromathic: demonstrate internationalization
Currently it was only using stubs.  Let's actually translate the
strings using gettext.

* examples/c/bistromathic/local.mk: Define LOCALEDIR, BISON_LOCALEDIR
and link with libintl.
* examples/c/bistromathic/parse.y: Use them.
Remove useless includes.
Take ENABLE_NLS into account.
(error_format_string): New.
(yyreport_syntax_error): Rewrite to rely on a format string, which is
more appropriate for internationalization.
* examples/c/bistromathic/Makefile: We no longer use Flex.
We need readline and intl.

* doc/bison.texi: Point to bistromathic for a better option for
internationalization.
* po/POTFILES.in: Add bistromathic.
2020-04-24 19:03:12 +02:00
Akim Demaille 401e7c5c36 todo: update for YYERRCODE 2020-04-24 19:03:12 +02:00
Akim Demaille 93fec67c46 regen 2020-04-24 08:23:27 +02:00
Akim Demaille 4378e2dc3c diagnostics: fix a typo
* src/complain.c: here.
2020-04-24 08:22:22 +02:00
Akim Demaille 81334eb5a0 c, c++: provide a default definition for N_
In C/C++, N_ is a no-op.  Define it if the user didn't.
Suggested by Frank Heckenbach.
https://lists.gnu.org/r/bug-bison/2020-04/msg00010.html

* src/output.c (prepare_symbol_names): Rename has_translations as
has_translations_flag.
* data/skeletons/bison.m4 (b4_has_translations_if): New.
* data/skeletons/java.m4 (b4_trans): Use it.

* data/skeletons/glr.c, data/skeletons/lalr1.cc, data/skeletons/yacc.c
(N_): Provide a default definition.
2020-04-20 07:37:45 +02:00
Akim Demaille df373f1ea1 i18n: also look in src/parse-gram.c
Some strings appears in the generated file only, e.g., translation of
"end of file".  So don't forget to go and see there.
2020-04-19 15:40:12 +02:00
Akim Demaille 9b7e7077dd style: fix comments
* data/skeletons/glr.c, data/skeletons/lalr1.cc,
* data/skeletons/yacc.c: here.
2020-04-19 15:40:12 +02:00
Akim Demaille 5ab0086157 tokens: clean up the translation of special symbols
* src/output.c (prepare_symbol_names): Don't play tricks with the
symbols, it's quite too late.
(has_translations): Move to...
* src/symtab.c: here.
(symbols_pack): Use it to enable translation for special symbols.
2020-04-19 15:40:12 +02:00
Akim Demaille 2831bd376f news: fix typo
Reported by Frank Heckenbach.
2020-04-19 08:20:57 +02:00
Akim Demaille 1d0e3ee896 tests: beware of portability issues with wc
On macOS, wc -l always prepends the result with a tab, even when fed
by stdin.  But anyway, we should have used `grep -c -v`, which appears
to be portable according to Autoconf's "Limitations of Usual Tools"
section.
Reported by Denis Excoffier.
https://lists.gnu.org/r/bug-bison/2020-04/msg00009.html

* tests/calc.at (_AT_CHECK_CALC): Use grep's -c instead.
2020-04-19 08:12:31 +02:00
Akim Demaille 0a64b76430 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2020-04-18 10:59:05 +02:00
43 changed files with 1112 additions and 493 deletions
+1 -1
View File
@@ -1 +1 @@
3.5.4
3.5.90
+32 -5
View File
@@ -1,5 +1,26 @@
GNU Bison NEWS
* Noteworthy changes in release 3.5.91 (2020-04-29) [stable]
** New features
*** Returning the error token
When the scanner returns an invalid token or the undefined token
(YYUNDEF), the parser generates an error message and enters error
recovery. Because of that error message, most scanners that find lexical
errors generate an error message, and then ignore the invalid input
without entering the error-recovery.
The scanners may now return YYerror, the error token, to enter the
error-recovery mode without triggering an additional error message. See
the bistromathic for an example.
*** The bistromathic features internationalization
Its way to build the error message is more general and is easy to use in
other projects.
* Noteworthy changes in release 3.5.90 (2020-04-18) [beta]
** Backward incompatible changes
@@ -14,6 +35,12 @@ GNU Bison NEWS
(2013-07-25), "%error-verbose" is deprecated in favor of "%define
parse.error verbose".
** Deprecated features
The YYPRINT macro, which works only with yacc.c and only for tokens, was
obsoleted long ago by %printer, introduced in Bison 1.50 (November 2002).
It is deprecated and its support will be removed eventually.
** New features
*** Improved syntax error messages
@@ -80,7 +107,7 @@ GNU Bison NEWS
PLUS "+"
MINUS "-"
<double>
NUM _("double precision number")
NUM _("number")
<symrec*>
FUN _("function")
VAR _("variable")
@@ -117,10 +144,10 @@ GNU Bison NEWS
"yytoken_kind_t".
This type now also includes tokens that were previously hidden: YYEOF (end
of input), YYUNDEF (undefined token), and YYERRCODE (error token). They
of input), YYUNDEF (undefined token), and YYerror (error token). They
now have string aliases, internationalized when internationalization is
enabled. Therefore, by default, error messages now refer to "end of file"
(internationalized) rather than the cryptic "$end", or to "invaid token"
(internationalized) rather than the cryptic "$end", or to "invalid token"
rather than "$undefined".
Therefore in most cases it is now useless to define the end-of-line token
@@ -4113,8 +4140,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
LocalWords: fsanitize Vogelsgesang lis redeclared stdint automata yytname
LocalWords: yysymbol yytnamerr yyreport ctx ARGMAX yysyntax stderr LPAREN
LocalWords: symrec yypcontext TOKENMAX yyexpected YYEMPTY yypstate YYEOF
LocalWords: autocompletion bistromathic submessages Cayuela lexcalc
LocalWords: yytoken YYUNDEF YYERRCODE
LocalWords: autocompletion bistromathic submessages Cayuela lexcalc hoc
LocalWords: yytoken YYUNDEF YYerror
Local Variables:
ispell-dictionary: "american"
+39
View File
@@ -37,6 +37,14 @@ Only user visible strings are to be translated: error messages, bits of the
assert/abort), and all the --trace output which is meant for the maintainers
only.
## Syntax highlighting
It's quite nice to be in C++ mode when editing lalr1.cc for instance.
However tools such as Emacs will be fooled by the fact that braces and
parens do not nest, as in `[[}]]`. As a consequence you might be misguided
by its visual pairing to parens. The m4-mode is safer. Unfortunately the
m4-mode is also fooled by `#` which is sees as a comment, stops pairing with
parens/brackets that are inside...
## Coding Style
Do not add horizontal tab characters to any file in Bison's repository
except where required. For example, do not use tabs to format C code.
@@ -57,6 +65,31 @@ Actually, Bison has legacy code that we should replace with gnulib modules
### Skeletons
We try to use the "typical" coding style for each language.
#### CPP
We indent the CPP directives this way:
```
#if FOO
# if BAR
# define BAZ
# endif
#endif
```
Don't indent with leading spaces in the skeletons (it's ok in the grammar
files though, e.g., in `%code {...}` blocks).
On occasions, use `cppi -c` to see where we stand. We don't aim at full
correctness: depending `-d`, some bits can be in the *.c file, or the *.h
file within the double-inclusion cpp-guards. In that case, favor the case
of the *.h file, but don't waste time on this.
Don't hesitate to leave a comment on the `#endif` (e.g., `#endif /* FOO
*/`), especially for long blocks.
There is no conistency on `! defined` vs. `!defined`. The day gnulib
decides, we'll follow them.
#### C/C++
Follow the GNU Coding Standards.
@@ -370,6 +403,12 @@ again, since some early failures may stop latter tests from being run. Yet
at some point, you'll have to fix remaining issues by hand...
## Running Java parsers
Use the `javaexec.sh` script. For instance to run the parser of test case
504:
$ sh ./_build/javaexec.sh -cp ./_build/tests/testsuite.dir/504 Calc
## make maintainer-check-valgrind
This target uses valgrind both to check bison, and the generated parsers.
+32 -28
View File
@@ -7,6 +7,10 @@
- is there a migration path that would allow to use TokenKinds in
yylex?
- define the tokens as an enum too.
- promote YYEOF rather than EOF.
*** D
- is there a way to attach yysymbol_name to the enum itself? As we did
in Java.
@@ -14,9 +18,11 @@
- It would be better to have TokenKind as return value. Can we use
reflection to support both output types?
** Documentation
- YYERRCODE, YYUNDEF, YYEOF
- YYERRCODE and translation
** YYerror
https://git.savannah.gnu.org/gitweb/?p=gettext.git;a=blob;f=gettext-runtime/intl/plural.y;h=a712255af4f2f739c93336d4ff6556d932a426a5;hb=HEAD
should be updated to not use YYERRCODE. Returning an undef token is good
enough.
** Java
*** Examples
@@ -25,6 +31,28 @@ Have an example with a push parser. Use autocompletion in that case.
*** calc.at
Stop hard-coding "Calc". Adjust local.at (look for FIXME).
* Bison 3.7
** Counter example generation
See https://github.com/akimd/bison/pull/15.
** Clean up
Rename user_token_number for tokens as "code". It's not a "user number",
it's the token code, and the user can control it, but this code always
exists.
See also USER_NUMBER_UNDEFINED and NUMBER_UNDEFINED.
Rename endtoken as eoftoken.
Also do it in data/skeletons.
Don't rename in Bison 3.6 (it would be logical to do so) because that
would probably create many conflicts in Vincent's work (see previous point).
** A dev warning for b4_
Maybe we should check for m4_ and b4_ leaking out of the m4 processing, as
Autoconf does. It would have caught overquotation issues.
** doc
I feel it's ugly to use the GNU style to declare functions in the doc. It
generates tons of white space in the page, and may contribute to bad page
@@ -35,7 +63,7 @@ token vs terminal, variable vs non terminal.
** api.token.raw
The YYUNDEFTOK could be assigned a semantic value so that yyerror could be
used to report invalid lexemes. See also the item "$undefined" below.
used to report invalid lexemes.
** push parsers
Consider deprecating impure push parsers. They add a lot of complexity, for
@@ -43,21 +71,6 @@ a bad feature. On the other hand, that would make it much harder to sit
push parsers on top of pull parser. Which is currently not relevant, since
push parsers are measurably slower.
* Bison 3.7
** Counter example generation
See https://github.com/akimd/bison/pull/15.
** Clean up
Rename user_token_number for tokens as "code". It's not a "user number",
it's the token code, and the user can control it, but this code always
exists.
Rename endtoken as eoftoken.
Also do it in data/skeletons.
Don't rename in Bison 3.6 (it would be logical to do so) because that
would probably create many conflicts in Vincent's work (see previous point).
* Bison 3.8
** Unit rules / Injection rules (Akim Demaille)
@@ -460,15 +473,6 @@ move to partial orders (sounds like series/parallel orders to me).
This is a prerequisite for modules.
* $undefined
From Hans:
- If the Bison generated parser experiences an undefined number in the
character range, that character is written out in diagnostic messages, an
addition to the $undefined value.
Suggest: Change the name $undefined to undefined; looks better in outputs.
* Pre and post actions.
From: Florian Krohm <[email protected]>
Subject: YYACT_EPILOGUE
+1 -1
View File
@@ -156,7 +156,7 @@ exclude = \
$(call exclude, \
bindtextdomain=^lib/main.c$$ \
cast_of_argument_to_free=^src/muscle-tab.c$$ \
po_check=^(examples|tests)/|(^po/POTFILES.in|.md)$$ \
po_check=^tests|(^po/POTFILES.in|.md)$$ \
preprocessor_indentation=^data/|^lib/|^src/parse-gram.[ch]$$ \
program_name=^lib/main.c$$ \
prohibit_always-defined_macros=^data/skeletons/yacc.c$$ \
+5 -3
View File
@@ -72,8 +72,9 @@ version 2.2 of Bison.])
# -------------
# Issue a warning about private implementation details.
m4_define([b4_disclaimer],
[b4_comment([Undocumented macros, especially those whose name start with YY_,
are private implementation details. Do not rely on them.])
[b4_comment([DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed.])
])
@@ -369,6 +370,7 @@ m4_define([b4_$3_if],
# Expand IF-TRUE, if FLAG is true, IF-FALSE otherwise.
b4_define_flag_if([defines]) # Whether headers are requested.
b4_define_flag_if([glr]) # Whether a GLR parser is requested.
b4_define_flag_if([has_translations]) # Whether some tokens are internationalized.
b4_define_flag_if([nondeterministic]) # Whether conflicts should be handled.
b4_define_flag_if([token_table]) # Whether yytoken_table is demanded.
b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
@@ -425,7 +427,7 @@ m4_define([b4_symbol_kind],
m4_case([$1],
[-2], [[YYEMPTY]],
[0], [[YYEOF]],
[1], [[YYERROR]],
[1], [[YYerror]],
[2], [[YYUNDEF]],
[m4_case(b4_symbol([$1], [tag]),
[$accept], [[YYACCEPT]],
+25 -25
View File
@@ -352,7 +352,7 @@ m4_define([b4_symbol_type_define],
break;
}
// Type destructor.
// Value type destructor.
]b4_symbol_variant([[yykind]], [[value]], [[template destroy]])])[
Base::clear ();
}
@@ -380,30 +380,30 @@ m4_define([b4_symbol_type_define],
};
/// Type access provider for token (enum) based symbols.
struct by_type
struct by_kind
{
/// Default constructor.
by_type ();
by_kind ();
#if 201103L <= YY_CPLUSPLUS
/// Move constructor.
by_type (by_type&& that);
by_kind (by_kind&& that);
#endif
/// Copy constructor.
by_type (const by_type& that);
by_kind (const by_kind& that);
/// The symbol kind as needed by the constructor.
typedef token_kind_type kind_type;
/// Constructor from (external) token numbers.
by_type (kind_type t);
by_kind (kind_type t);
/// Record that this symbol is empty.
void clear ();
/// Steal the symbol kind from \a that.
void move (by_type& that);
void move (by_kind& that);
/// The (internal) type number (corresponding to \a type).
/// \a empty when empty.
@@ -411,14 +411,14 @@ m4_define([b4_symbol_type_define],
/// The symbol kind.
/// \a ]b4_symbol_prefix[YYEMPTY when empty.
symbol_kind_type type;
symbol_kind_type kind_;
};
/// "External" symbols: returned by the scanner.
struct symbol_type : basic_symbol<by_type>
struct symbol_type : basic_symbol<by_kind>
{]b4_variant_if([[
/// Superclass.
typedef basic_symbol<by_type> super_type;
typedef basic_symbol<by_kind> super_type;
/// Empty symbol.
symbol_type () {}
@@ -492,44 +492,44 @@ m4_define([b4_public_types_define],
location = YY_MOVE (s.location);])[
}
// by_type.
]b4_inline([$1])b4_parser_class[::by_type::by_type ()
: type (symbol_kind::]b4_symbol_prefix[YYEMPTY)
// by_kind.
]b4_inline([$1])b4_parser_class[::by_kind::by_kind ()
: kind_ (symbol_kind::]b4_symbol_prefix[YYEMPTY)
{}
#if 201103L <= YY_CPLUSPLUS
]b4_inline([$1])b4_parser_class[::by_type::by_type (by_type&& that)
: type (that.type)
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (by_kind&& that)
: kind_ (that.kind_)
{
that.clear ();
}
#endif
]b4_inline([$1])b4_parser_class[::by_type::by_type (const by_type& that)
: type (that.type)
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (const by_kind& that)
: kind_ (that.kind_)
{}
]b4_inline([$1])b4_parser_class[::by_type::by_type (token_kind_type t)
: type (yytranslate_ (t))
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (token_kind_type t)
: kind_ (yytranslate_ (t))
{}
]b4_inline([$1])[void
]b4_parser_class[::by_type::clear ()
]b4_parser_class[::by_kind::clear ()
{
type = symbol_kind::]b4_symbol_prefix[YYEMPTY;
kind_ = symbol_kind::]b4_symbol_prefix[YYEMPTY;
}
]b4_inline([$1])[void
]b4_parser_class[::by_type::move (by_type& that)
]b4_parser_class[::by_kind::move (by_kind& that)
{
type = that.type;
kind_ = that.kind_;
that.clear ();
}
]b4_inline([$1])[]b4_parser_class[::symbol_kind_type
]b4_parser_class[::by_type::kind () const YY_NOEXCEPT
]b4_parser_class[::by_kind::kind () const YY_NOEXCEPT
{
return type;
return kind_;
}
]])
+11 -11
View File
@@ -439,7 +439,7 @@ m4_define([b4_symbol(-2, tag)], [[No symbol.]])
m4_if(b4_symbol(0, id), [YYEOF],
[m4_define([b4_symbol(0, id)], [b4_api_PREFIX[][EOF]])])
m4_define([b4_symbol(1, id)], [b4_api_PREFIX[][ERRCODE]])
m4_define([b4_symbol(1, id)], [b4_api_PREFIX[][error]])
m4_define([b4_symbol(2, id)], [b4_api_PREFIX[][UNDEF]])
@@ -965,8 +965,8 @@ m4_define([b4_yy_location_print_define],
This macro was not mandated originally: define only if we know
we won't break user code: when these are the locations we know. */
#ifndef YY_LOCATION_PRINT
# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
# ifndef YY_LOCATION_PRINT
# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
@@ -996,17 +996,17 @@ yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
return res;
}
# define YY_LOCATION_PRINT(File, Loc) \
# define YY_LOCATION_PRINT(File, Loc) \
yy_location_print_ (File, &(Loc))
# else
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
#endif]],
# else
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
# endif /* !defined YY_LOCATION_PRINT */]],
[[/* This macro is provided for backward compatibility. */
#ifndef YY_LOCATION_PRINT
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
#endif]])
# ifndef YY_LOCATION_PRINT
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif]])
])
# b4_yyloc_default
+33 -24
View File
@@ -261,6 +261,11 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
# define YY_(Msgid) Msgid
# endif
#endif
]b4_has_translations_if([
#ifndef N_
# define N_(Msgid) Msgid
#endif
])[
#ifndef YYFREE
# define YYFREE free
@@ -329,10 +334,7 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
#define YYMAXLEFT ]b4_max_left_semantic_context[
/* YYMAXUTOK -- Last valid token number (for yychar). */
#define YYMAXUTOK ]b4_user_token_number_max[]b4_glr_cc_if([[
/* YYFAULTYTOK -- Token number (for yychar) that denotes a
syntax_error thrown from the scanner. */
#define YYFAULTYTOK (YYMAXUTOK + 1)]])[
#define YYMAXUTOK ]b4_user_token_number_max[
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
as returned by yylex, with out-of-bounds checking. */
@@ -621,8 +623,8 @@ yysymbol_name (yysymbol_kind_t yysymbol)
static const char *const yy_sname[] =
{
]b4_symbol_names[
};]m4_ifdef([b4_translatable], [[
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YYTNAME[SYMBOL-NUM] is
};]b4_has_translations_if([[
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
internationalizable. */
static ]b4_int_type_for([b4_translatable])[ yytranslatable[] =
{
@@ -664,12 +666,12 @@ yysymbol_name (yysymbol_kind_t yysymbol)
]b4_yy_symbol_print_define[
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
do { \
if (yydebug) \
{ \
YY_FPRINTF ((stderr, "%s ", Title)); \
yy_symbol_print (stderr, Type, Value]b4_locuser_args([Location])[); \
yy_symbol_print (stderr, Kind, Value]b4_locuser_args([Location])[); \
YY_FPRINTF ((stderr, "\n")); \
} \
} while (0)
@@ -686,7 +688,7 @@ static void yypdumpstack (yyGLRStack* yystackp)
#else /* !]b4_api_PREFIX[DEBUG */
# define YY_DPRINTF(Args) do {} while (yyfalse)
# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
#endif /* !]b4_api_PREFIX[DEBUG */
@@ -825,7 +827,7 @@ yygetToken (int *yycharp][]b4_pure_if([, yyGLRStack* yystackp])[]b4_user_formals
// Map errors caught in the scanner to the undefined token,
// so that error handling is started. However, record this
// with this special value of yychar.
*yycharp = YYFAULTYTOK;
*yycharp = ]b4_symbol(1, id)[;
}
#endif // YY_EXCEPTIONS]], [[
*yycharp = ]b4_lex[;]])[
@@ -1030,8 +1032,14 @@ static inline int
yygetLRActions (yy_state_t yystate, yysymbol_kind_t yytoken, const short** yyconflicts)
{
int yyindex = yypact[yystate] + yytoken;
if (yyisDefaultedState (yystate)
|| yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken)
if (yytoken == ]b4_symbol(1, kind)[)
{
// This is the error token.
*yyconflicts = yyconfl;
return 0;
}
else if (yyisDefaultedState (yystate)
|| yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken)
{
*yyconflicts = yyconfl;
return -yydefact[yystate];
@@ -2029,7 +2037,7 @@ yyprocessOneStack (yyGLRStack* yystackp, ptrdiff_t yyk,
const int yyaction = yygetLRActions (yystate, yytoken, &yyconflicts);
yystackp->yytops.yylookaheadNeeds[yyk] = yytrue;
while (*yyconflicts != 0)
for (/* nothing */; *yyconflicts; yyconflicts += 1)
{
YYRESULTTAG yyflag;
ptrdiff_t yynewStack = yysplitStack (yystackp, yyk);
@@ -2048,7 +2056,6 @@ yyprocessOneStack (yyGLRStack* yystackp, ptrdiff_t yyk,
}
else
return yyflag;
yyconflicts += 1;
}
if (yyisShiftAction (yyaction))
@@ -2103,7 +2110,7 @@ yypcontext_expected_tokens (const yyGLRStack* yystackp,
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yyx;
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol_prefix[YYERROR
if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[
&& !yytable_value_is_error (yytable[yyx + yyn]))
{
if (!yyarg)
@@ -2361,8 +2368,8 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
int yyj = yypact[yys->yylrState];
if (! yypact_value_is_default (yyj))
{
yyj += ]b4_symbol_prefix[YYERROR;
if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == ]b4_symbol_prefix[YYERROR
yyj += ]b4_symbol(1, kind)[;
if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == ]b4_symbol(1, kind)[
&& yyisShiftAction (yytable[yyj]))
{
/* Shift the error token. */
@@ -2445,7 +2452,7 @@ b4_dollar_popdef])[]dnl
/* For efficiency, we have two loops, the first of which is
specialized to deterministic operation (single stack, no
potential ambiguity). */
/* Standard mode */
/* Standard mode. */
while (yytrue)
{
yy_state_t yystate = yystack.yytops.yystates[0]->yylrState;
@@ -2468,7 +2475,8 @@ b4_dollar_popdef])[]dnl
yysymbol_kind_t yytoken = ]b4_yygetToken_call;[
const short* yyconflicts;
int yyaction = yygetLRActions (yystate, yytoken, &yyconflicts);
if (*yyconflicts != 0)
if (*yyconflicts)
/* Enter nondeterministic mode. */
break;
if (yyisShiftAction (yyaction))
{
@@ -2481,11 +2489,11 @@ b4_dollar_popdef])[]dnl
}
else if (yyisErrorAction (yyaction))
{]b4_locations_if([[
yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[]b4_glr_cc_if([[
/* Don't issue an error message again for exceptions
thrown from the scanner. */
if (yychar != YYFAULTYTOK)
]])[ yyreportSyntaxError (&yystack]b4_user_args[);
yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
/* Issue an error message unless the scanner already
did. */
if (yychar != ]b4_symbol(1, id)[)
yyreportSyntaxError (&yystack]b4_user_args[);
goto yyuser_error;
}
else
@@ -2493,6 +2501,7 @@ b4_dollar_popdef])[]dnl
}
}
/* Nondeterministic mode. */
while (yytrue)
{
yysymbol_kind_t yytoken_to_shift;
+11 -9
View File
@@ -167,7 +167,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
void
]b4_parser_class[::yy_symbol_value_print_ (symbol_kind_type yykind,
const semantic_type* yyvaluep]b4_locations_if([[,
const location_type* yylocationp]])[)
const location_type* yylocationp]])[) const
{]b4_locations_if([[
YYUSE (yylocationp);]])[
YYUSE (yyvaluep);
@@ -181,7 +181,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
void
]b4_parser_class[::yy_symbol_print_ (symbol_kind_type yykind,
const semantic_type* yyvaluep]b4_locations_if([[,
const location_type* yylocationp]])[)
const location_type* yylocationp]])[) const
{
*yycdebug_ << (yykind < YYNTOKENS ? "token" : "nterm")
<< ' ' << yytname[yykind] << " ("]b4_locations_if([[
@@ -317,16 +317,16 @@ b4_percent_code_get([[requires]])[
/// \param yylocationp Its location.]])[
virtual void yy_symbol_value_print_ (symbol_kind_type yykind,
const semantic_type* yyvaluep]b4_locations_if([[,
const location_type* yylocationp]])[);
const location_type* yylocationp]])[) const;
/// \brief Report a symbol on the debug stream.
/// \param yykind The symbol kind.
/// \param yyvaluep Its semantic value.]b4_locations_if([[
/// \param yylocationp Its location.]])[
virtual void yy_symbol_print_ (symbol_kind_type yykind,
const semantic_type* yyvaluep]b4_locations_if([[,
const location_type* yylocationp]])[);
const location_type* yylocationp]])[) const;
private:
// Debugging.
/// Debug stream.
std::ostream* yycdebug_;
#endif
@@ -344,6 +344,8 @@ b4_percent_define_flag_if([[global_tokens_and_yystype]],
#define ]b4_symbol(-2, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(-2, [id])[
#undef ]b4_symbol(0, [id])[
#define ]b4_symbol(0, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(0, [id])[
#undef ]b4_symbol(1, [id])[
#define ]b4_symbol(1, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(1, [id])[
#ifndef ]b4_api_PREFIX[STYPE
# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type
@@ -354,10 +356,10 @@ b4_percent_define_flag_if([[global_tokens_and_yystype]],
]m4_define([b4_declare_symbol_enum],
[[typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type yysymbol_kind_t;
#define ]b4_symbol_prefix[YYEMPTY ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEMPTY
#define ]b4_symbol_prefix[YYERROR ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYERROR
#define ]b4_symbol_prefix[YYEOF ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEOF
#define ]b4_symbol_prefix[YYUNDEF ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYUNDEF
#define ]b4_symbol_prefix[YYEMPTY ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEMPTY
#define ]b4_symbol_prefix[YYerror ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYerror
#define ]b4_symbol_prefix[YYEOF ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEOF
#define ]b4_symbol_prefix[YYUNDEF ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYUNDEF
]])[
]b4_percent_code_get([[provides]])[
]m4_popdef([b4_parse_param])dnl
+9 -4
View File
@@ -137,9 +137,14 @@ m4_define([b4_integral_parser_table_define],
# ------------------------
# Output the definition of this token as an enum.
m4_define([b4_token_enum],
[b4_token_format([ /** Token number, to be returned by the scanner. */
static final int %s = %s;
], [$1])])
[b4_token_visible_if([$1],
[m4_format([[ /** Token %s, to be returned by the scanner. */
static final int %s = %s%s;
]],
b4_symbol([$1], [tag]),
b4_symbol([$1], [id]),
b4_symbol([$1], b4_api_token_raw_if([[number]], [[user_number]])))])])
# b4_token_enums
# --------------
@@ -344,7 +349,7 @@ m4_define([b4_symbol_translate],
# ----------------
# Translate a string if i18n is enabled. Avoid collision with b4_translate.
m4_define([b4_trans],
[m4_if(b4_has_translations, 0, [$1], [i18n($1)])])
[b4_has_translations_if([i18n($1)], [$1])])
+93 -58
View File
@@ -305,35 +305,44 @@ m4_define([b4_shared_declarations],
/// In theory \a t should be a token_kind_type, but character literals
/// are valid, yet not members of the token_type enum.
static symbol_kind_type yytranslate_ (int t);
]b4_parse_error_bmatch([custom\|detailed], [[
/// The user-facing name of the symbol whose (internal) number is
/// YYSYMBOL. No bounds checking.
static const char *symbol_name (symbol_kind_type yysymbol);
]b4_parse_error_bmatch(
[custom\|detailed],
[[ /// The user-facing name of the symbol whose (internal) number is
/// YYSYMBOL. No bounds checking.
static const char *symbol_name (symbol_kind_type yysymbol);]],
[simple],
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
/// The user-facing name of the symbol whose (internal) number is
/// YYSYMBOL. No bounds checking.
static const char *symbol_name (symbol_kind_type yysymbol);
/// For a symbol, its name in clear.
static const char* const yytname_[];
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
]],
[verbose],
[[ /// The user-facing name of the symbol whose (internal) number is
/// YYSYMBOL. No bounds checking.
static std::string symbol_name (symbol_kind_type yysymbol);
/// Convert the symbol name \a n to a form suitable for a diagnostic.
static std::string yytnamerr_ (const char *yystr);
/// For a symbol, its name in clear.
static const char* const yytname_[];
]])[
// Tables.
]b4_parser_tables_declare[
]b4_parse_error_case([verbose], [[
/// Convert the symbol name \a n to a form suitable for a diagnostic.
static std::string yytnamerr_ (const char *n);
/// For a symbol, its name in clear.
static const char* const yytname_[];
]],
[b4_token_table_if([], [[
#if ]b4_api_PREFIX[DEBUG
/// For a symbol, its name in clear.
static const char* const yytname_[];
#endif
]])])[
#if ]b4_api_PREFIX[DEBUG
]b4_integral_parser_table_declare([rline], [b4_rline],
[[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
/// Report on the debug stream that the rule \a r is going to be reduced.
virtual void yy_reduce_print_ (int r);
virtual void yy_reduce_print_ (int r) const;
/// Print the state stack on the debug stream.
virtual void yystack_print_ ();
virtual void yy_stack_print_ () const;
/// Debugging level.
int yydebug_;
@@ -523,6 +532,11 @@ m4_if(b4_prefix, [yy], [],
# define YY_(msgid) msgid
# endif
#endif
]b4_has_translations_if([
#ifndef N_
# define N_(Msgid) Msgid
#endif
])[
// Whether we are compiled with exception support.
#ifndef YY_EXCEPTIONS
@@ -562,7 +576,7 @@ m4_if(b4_prefix, [yy], [],
# define YY_STACK_PRINT() \
do { \
if (yydebug_) \
yystack_print_ (); \
yy_stack_print_ (); \
} while (false)
#else // !]b4_api_PREFIX[DEBUG
@@ -582,17 +596,16 @@ m4_if(b4_prefix, [yy], [],
#define YYERROR goto yyerrorlab
#define YYRECOVERING() (!!yyerrstatus_)
]b4_namespace_open[]b4_parse_error_bmatch([custom\|detailed], [[
/* The user-facing name of the symbol whose (internal) number is
YYSYMBOL. No bounds checking. */
const char *
]b4_namespace_open[
]b4_parse_error_bmatch([custom\|detailed],
[[ const char *
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
{
static const char *const yy_sname[] =
{
]b4_symbol_names[
};]m4_ifdef([b4_translatable], [[
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YYTNAME[SYMBOL-NUM] is
};]b4_has_translations_if([[
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
internationalizable. */
static ]b4_int_type_for([b4_translatable])[ yytranslatable[] =
{
@@ -603,10 +616,18 @@ m4_if(b4_prefix, [yy], [],
: yy_sname[yysymbol]);]], [[
return yy_sname[yysymbol];]])[
}
]])
b4_parse_error_case([verbose], [[
/* Return YYSTR after stripping away unnecessary quotes and
]],
[simple],
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
const char *
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
{
return yytname_[yysymbol];
}
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
]],
[verbose],
[[ /* Return YYSTR after stripping away unnecessary quotes and
backslashes, so that it's suitable for yyerror. The heuristic is
that double-quoting is unnecessary unless the string contains an
apostrophe, a comma, or backslash (other than backslash-backslash).
@@ -645,6 +666,12 @@ b4_parse_error_case([verbose], [[
return yystr;
}
std::string
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
{
return yytnamerr_ (yytname_[yysymbol]);
}
]])[
/// Build a parser object.
@@ -725,7 +752,7 @@ b4_parse_error_case([verbose], [[
b4_symbol_variant([that.kind ()],
[value], [move], [YY_MOVE (that.value)])])[
// that is emptied.
that.type = symbol_kind::]b4_symbol(-2, kind)[;
that.kind_ = symbol_kind::]b4_symbol(-2, kind)[;
}
#if YY_CPLUSPLUS < 201103L
@@ -768,23 +795,21 @@ b4_parse_error_case([verbose], [[
#if ]b4_api_PREFIX[DEBUG
template <typename Base>
void
]b4_parser_class[::yy_print_ (std::ostream& yyo,
const basic_symbol<Base>& yysym) const
]b4_parser_class[::yy_print_ (std::ostream& yyo, const basic_symbol<Base>& yysym) const
{
std::ostream& yyoutput = yyo;
YYUSE (yyoutput);
symbol_kind_type yykind = yysym.kind ();
#if defined __GNUC__ && ! defined __clang__ && ! defined __ICC && __GNUC__ * 100 + __GNUC_MINOR__ <= 408
// Avoid a (spurious) G++ 4.8 warning about "array subscript is
// below array bounds".
if (yysym.empty ())
std::abort ();
#endif
yyo << (yykind < YYNTOKENS ? "token" : "nterm")
<< ' ' << yytname_[yykind] << " ("]b4_locations_if([
<< yysym.location << ": "])[;
]b4_symbol_actions([printer])[
yyo << ')';
yyo << "empty symbol";
else
{
symbol_kind_type yykind = yysym.kind ();
yyo << (yykind < YYNTOKENS ? "token" : "nterm")
<< ' ' << symbol_name (yykind) << " ("]b4_locations_if([
<< yysym.location << ": "])[;
]b4_symbol_actions([printer])[
yyo << ')';
}
}
#endif
@@ -943,7 +968,7 @@ b4_dollar_popdef])[]dnl
{]b4_token_ctor_if([[
symbol_type yylookahead (]b4_lex[);
yyla.move (yylookahead);]], [[
yyla.type = yytranslate_ (]b4_lex[);]])[
yyla.kind_ = yytranslate_ (]b4_lex[);]])[
}
#if YY_EXCEPTIONS
catch (const syntax_error& yyexc)
@@ -956,6 +981,16 @@ b4_dollar_popdef])[]dnl
}
YY_SYMBOL_PRINT ("Next token is", yyla);
if (yyla.kind () == ]symbol_kind::b4_symbol(1, kind)[)
{
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
yyla.kind_ = ]symbol_kind::b4_symbol(2, kind)[;
goto yyerrlab1;
}
/* If the proper action on seeing token YYLA.TYPE is to reduce or
to detect an error, take that action. */
yyn += yyla.kind ();
@@ -1130,9 +1165,9 @@ b4_dollar_popdef])[]dnl
yyn = yypact_[+yystack_[0].state];
if (!yy_pact_value_is_default_ (yyn))
{
yyn += symbol_kind::]b4_symbol_prefix[YYERROR;
yyn += symbol_kind::]b4_symbol(1, kind)[;
if (0 <= yyn && yyn <= yylast_
&& yycheck_[yyn] == symbol_kind::]b4_symbol_prefix[YYERROR)
&& yycheck_[yyn] == symbol_kind::]b4_symbol(1, kind)[)
{
yyn = yytable_[yyn];
if (0 < yyn)
@@ -1246,7 +1281,7 @@ b4_dollar_popdef])[]dnl
for (int yyx = 0; yyx < YYNTOKENS; ++yyx)
{
symbol_kind_type yysym = YY_CAST (symbol_kind_type, yyx);
if (yysym != symbol_kind::]b4_symbol_prefix[YYERROR
if (yysym != symbol_kind::]b4_symbol(1, kind)[
&& yysym != symbol_kind::]b4_symbol_prefix[YYUNDEF
&& yyparser_.yy_lac_check_ (yysym))
{
@@ -1269,7 +1304,7 @@ b4_dollar_popdef])[]dnl
int yychecklim = yylast_ - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck_[yyx + yyn] == yyx && yyx != symbol_kind::]b4_symbol_prefix[YYERROR
if (yycheck_[yyx + yyn] == yyx && yyx != symbol_kind::]b4_symbol(1, kind)[
&& !yy_table_value_is_error_ (yytable_[yyx + yyn]))
{
if (!yyarg)
@@ -1293,7 +1328,7 @@ b4_dollar_popdef])[]dnl
yylac_stack_.clear ();
// Reduce until we encounter a shift and thereby accept the token.
#if ]b4_api_PREFIX[DEBUG
YYCDEBUG << "LAC: checking lookahead " << yytname_[yytoken] << ':';
YYCDEBUG << "LAC: checking lookahead " << symbol_name (yytoken) << ':';
#endif
std::ptrdiff_t lac_top = 0;
while (true)
@@ -1393,7 +1428,7 @@ b4_dollar_popdef])[]dnl
{
#if ]b4_api_PREFIX[DEBUG
YYCDEBUG << "LAC: initial context established for "
<< yytname_[yytoken] << '\n';
<< symbol_name (yytoken) << '\n';
#endif
yy_lac_established_ = true;
return yy_lac_check_ (yytoken);
@@ -1502,9 +1537,7 @@ b4_dollar_popdef])[]dnl
for (char const* yyp = yyformat; *yyp; ++yyp)
if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
{
yyres += ]b4_parse_error_case([verbose],
[[yytnamerr_ (yytname_[yyarg[yyi++]])]],
[[symbol_name (yyarg[yyi++])]])[;
yyres += symbol_name (yyarg[yyi++]);
++yyp;
}
else
@@ -1519,7 +1552,8 @@ b4_dollar_popdef])[]dnl
]b4_parser_tables_define[
]b4_tname_if([], [[#if ]b4_api_PREFIX[DEBUG]])[
]b4_parse_error_bmatch([simple\|verbose],
[[#if ]b4_api_PREFIX[DEBUG]b4_tname_if([[ || 1]])[
// YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
// First, the terminals, then, starting at \a YYNTOKENS, nonterminals.
const char*
@@ -1527,13 +1561,14 @@ b4_dollar_popdef])[]dnl
{
]b4_tname[
};
]b4_tname_if([], [[#endif]])[
#endif
]])[
#if ]b4_api_PREFIX[DEBUG][
]b4_integral_parser_table_define([rline], [b4_rline])[
void
]b4_parser_class[::yystack_print_ ()
]b4_parser_class[::yy_stack_print_ () const
{
*yycdebug_ << "Stack now";
for (stack_type::const_iterator
@@ -1545,7 +1580,7 @@ b4_dollar_popdef])[]dnl
}
void
]b4_parser_class[::yy_reduce_print_ (int yyrule)
]b4_parser_class[::yy_reduce_print_ (int yyrule) const
{
int yylno = yyrline_[yyrule];
int yynrhs = yyr2_[yyrule];
+47 -33
View File
@@ -21,7 +21,7 @@ m4_include(b4_skeletonsdir/[d.m4])
b4_output_begin([b4_parser_file_name])
b4_copyright([Skeleton implementation for Bison LALR(1) parsers in D],
[2007-2012, 2019-2020])[
]b4_disclaimer[
]b4_percent_define_ifdef([package], [module b4_percent_define_get([package]);
])[
version(D_Version2) {
@@ -509,39 +509,53 @@ m4_popdef([b4_at_dollar])])dnl
yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
yy_symbol_print ("Next token is", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
/* If the proper action on seeing token YYTOKEN is to reduce or to
detect an error, take that action. */
yyn += yytoken;
if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken)
label = YYDEFAULT;
/* <= 0 means reduce or error. */
else if ((yyn = yytable_[yyn]) <= 0)
if (yytoken == SymbolKind.]b4_symbol(1, kind)[)
{
if (yy_table_value_is_error_ (yyn))
label = YYERRLAB;
else
{
yyn = -yyn;
label = YYREDUCE;
}
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
yychar = TokenKind.YYUNDEF;
yytoken = SymbolKind.]b4_symbol_prefix[YYUNDEF;]b4_locations_if([[
yyerrloc = yylloc;]])[
label = YYERRLAB1;
}
else
{
/* Shift the lookahead token. */]b4_parse_trace_if([[
yy_symbol_print ("Shifting", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
/* If the proper action on seeing token YYTOKEN is to reduce or to
detect an error, take that action. */
yyn += yytoken;
if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken)
label = YYDEFAULT;
/* Discard the token being shifted. */
yychar = TokenKind.YYEMPTY;
/* <= 0 means reduce or error. */
else if ((yyn = yytable_[yyn]) <= 0)
{
if (yy_table_value_is_error_ (yyn))
label = YYERRLAB;
else
{
yyn = -yyn;
label = YYREDUCE;
}
}
else
{
/* Shift the lookahead token. */]b4_parse_trace_if([[
yy_symbol_print ("Shifting", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
/* Count tokens shifted since error; after three, turn off error
* status. */
if (yyerrstatus_ > 0)
--yyerrstatus_;
/* Discard the token being shifted. */
yychar = TokenKind.YYEMPTY;
yystate = yyn;
yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
label = YYNEWSTATE;
/* Count tokens shifted since error; after three, turn off error
* status. */
if (yyerrstatus_ > 0)
--yyerrstatus_;
yystate = yyn;
yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
label = YYNEWSTATE;
}
}
break;
@@ -577,8 +591,8 @@ m4_popdef([b4_at_dollar])])dnl
yytoken = SymbolKind.]b4_symbol(-2, kind)[;
yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
}
]b4_locations_if([ yyerrloc = yylloc;])[
]b4_locations_if([
yyerrloc = yylloc;])[
if (yyerrstatus_ == 3)
{
/* If just tried and failed to reuse lookahead token after an
@@ -624,8 +638,8 @@ m4_popdef([b4_at_dollar])])dnl
yyn = yypact_[yystate];
if (!yy_pact_value_is_default_ (yyn))
{
yyn += SymbolKind.]b4_symbol_prefix[YYERROR;
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == SymbolKind.]b4_symbol_prefix[YYERROR)
yyn += SymbolKind.]b4_symbol(1, kind)[;
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == SymbolKind.]b4_symbol(1, kind)[)
{
yyn = yytable_[yyn];
if (0 < yyn)
@@ -731,14 +745,14 @@ m4_popdef([b4_at_dollar])])dnl
int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
int count = 0;
for (int x = yyxbegin; x < yyxend; ++x)
if (yycheck_[x + yyn] == x && x != SymbolKind.]b4_symbol_prefix[YYERROR
if (yycheck_[x + yyn] == x && x != SymbolKind.]b4_symbol(1, kind)[
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
++count;
if (count < 5)
{
count = 0;
for (int x = yyxbegin; x < yyxend; ++x)
if (yycheck_[x + yyn] == x && x != SymbolKind.]b4_symbol_prefix[YYERROR
if (yycheck_[x + yyn] == x && x != SymbolKind.]b4_symbol(1, kind)[
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
{
res ~= count++ == 0 ? ", expecting " : " or ";
+50 -36
View File
@@ -78,6 +78,7 @@ m4_define([b4_define_state],[[
]b4_output_begin([b4_parser_file_name])[
]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
[2007-2015, 2018-2020])[
]b4_disclaimer[
]b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);[
]])[
]b4_user_pre_prologue[
@@ -163,12 +164,12 @@ import java.text.MessageFormat;
}
}
private ]b4_location_type[ yylloc (YYStack rhs, int n)
private ]b4_location_type[ yylloc(YYStack rhs, int n)
{
if (0 < n)
return new ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
return new ]b4_location_type[(rhs.locationAt(n-1).begin, rhs.locationAt(0).end);
else
return new ]b4_location_type[ (rhs.locationAt (0).end);
return new ]b4_location_type[(rhs.locationAt(0).end);
}]])[
]b4_declare_symbol_enum[
@@ -179,7 +180,7 @@ import java.text.MessageFormat;
*/
public interface Lexer {
]b4_token_enums[
/** Deprecated, use b4_symbol(0, id) instead. */
/** Deprecated, use ]b4_symbol(0, id)[ instead. */
public static final int EOF = ]b4_symbol(0, id)[;
]b4_locations_if([[
@@ -614,41 +615,55 @@ b4_dollar_popdef[]dnl
yySymbolPrint ("Next token is", yytoken,
yylval]b4_locations_if([, yylloc])[);]])[
/* If the proper action on seeing token YYTOKEN is to reduce or to
detect an error, take that action. */
yyn += yytoken.getCode ();
if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode ())
label = YYDEFAULT;
/* <= 0 means reduce or error. */
else if ((yyn = yytable_[yyn]) <= 0)
if (yytoken == SymbolKind.]b4_symbol_prefix[YYerror)
{
if (yyTableValueIsError (yyn))
label = YYERRLAB;
else
{
yyn = -yyn;
label = YYREDUCE;
}
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
yychar = Lexer.]b4_percent_define_get([api.token.prefix])[YYUNDEF;
yytoken = SymbolKind.]b4_symbol_prefix[YYUNDEF;]b4_locations_if([[
yyerrloc = yylloc;]])[
label = YYERRLAB1;
}
else
{
/* Shift the lookahead token. */]b4_parse_trace_if([[
yySymbolPrint ("Shifting", yytoken,
yylval]b4_locations_if([, yylloc])[);
/* If the proper action on seeing token YYTOKEN is to reduce or to
detect an error, take that action. */
yyn += yytoken.getCode ();
if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode ())
label = YYDEFAULT;
/* <= 0 means reduce or error. */
else if ((yyn = yytable_[yyn]) <= 0)
{
if (yyTableValueIsError (yyn))
label = YYERRLAB;
else
{
yyn = -yyn;
label = YYREDUCE;
}
}
else
{
/* Shift the lookahead token. */]b4_parse_trace_if([[
yySymbolPrint ("Shifting", yytoken,
yylval]b4_locations_if([, yylloc])[);
]])[
/* Discard the token being shifted. */
yychar = YYEMPTY_;
/* Discard the token being shifted. */
yychar = YYEMPTY_;
/* Count tokens shifted since error; after three, turn off error
status. */
if (yyerrstatus_ > 0)
--yyerrstatus_;
/* Count tokens shifted since error; after three, turn off error
status. */
if (yyerrstatus_ > 0)
--yyerrstatus_;
yystate = yyn;
yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
label = YYNEWSTATE;
yystate = yyn;
yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
label = YYNEWSTATE;
}
}
break;
@@ -684,7 +699,6 @@ b4_dollar_popdef[]dnl
yytoken = null;
yyreportSyntaxError (new Context (yystack, yytoken]b4_locations_if([[, yylloc]])[));
}
]b4_locations_if([[
yyerrloc = yylloc;]])[
if (yyerrstatus_ == 3)
@@ -732,9 +746,9 @@ b4_dollar_popdef[]dnl
yyn = yypact_[yystate];
if (!yyPactValueIsDefault (yyn))
{
yyn += SymbolKind.]b4_symbol_prefix[YYERROR.getCode ();
yyn += SymbolKind.]b4_symbol(1, kind)[.getCode ();
if (0 <= yyn && yyn <= YYLAST_
&& yycheck_[yyn] == SymbolKind.]b4_symbol_prefix[YYERROR.getCode ())
&& yycheck_[yyn] == SymbolKind.]b4_symbol(1, kind)[.getCode ())
{
yyn = yytable_[yyn];
if (0 < yyn)
@@ -925,7 +939,7 @@ b4_dollar_popdef[]dnl
int yychecklim = YYLAST_ - yyn + 1;
int yyxend = yychecklim < NTOKENS ? yychecklim : NTOKENS;
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck_[yyx + yyn] == yyx && yyx != SymbolKind.]b4_symbol_prefix[YYERROR.getCode ()
if (yycheck_[yyx + yyn] == yyx && yyx != SymbolKind.]b4_symbol(1, kind)[.getCode ()
&& !yyTableValueIsError (yytable_[yyx + yyn]))
{
if (yyarg == null)
+38 -20
View File
@@ -358,6 +358,7 @@ b4_output_begin([b4_parser_file_name])[
/* C LALR(1) parser skeleton written by Richard Stallman, by
simplifying the original so-called "semantic" parser. */
]b4_disclaimer[
/* All symbols defined below should begin with yy or YY, to avoid
infringing on user name space. This should be done even for local
variables, as they might otherwise be expanded by user macros.
@@ -365,7 +366,6 @@ b4_output_begin([b4_parser_file_name])[
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */
]b4_disclaimer[
]b4_identification[
]b4_percent_code_get([[top]])[]dnl
m4_if(b4_api_prefix, [yy], [],
@@ -463,6 +463,11 @@ typedef int yy_state_fast_t;
# define YY_(Msgid) Msgid
# endif
#endif
]b4_has_translations_if([
#ifndef N_
# define N_(Msgid) Msgid
#endif
])[
]b4_attribute_define[
@@ -542,7 +547,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
# endif]b4_lac_if([[
# define YYCOPY_NEEDED 1]])[
#endif]b4_lac_if([], [b4_parse_error_case([simple], [[/* !defined yyoverflow */]])])[
#endif /* ]b4_lac_if([[1]], [b4_parse_error_case([simple], [[!defined yyoverflow]], [[1]])])[ */
#if (! defined yyoverflow \
&& (! defined __cplusplus \
@@ -676,8 +681,8 @@ yysymbol_name (yysymbol_kind_t yysymbol)
static const char *const yy_sname[] =
{
]b4_symbol_names[
};]m4_ifdef([b4_translatable], [[
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YYTNAME[SYMBOL-NUM] is
};]b4_has_translations_if([[
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
internationalizable. */
static ]b4_int_type_for([b4_translatable])[ yytranslatable[] =
{
@@ -690,14 +695,14 @@ yysymbol_name (yysymbol_kind_t yysymbol)
}]])[
#endif
# ifdef YYPRINT
#ifdef YYPRINT
/* YYTOKNUM[NUM] -- (External) token number corresponding to the
(internal) symbol number NUM (which must be that of a token). */
static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
{
]b4_toknum[
};
# endif
#endif
#define YYPACT_NINF (]b4_pact_ninf[)
@@ -741,6 +746,9 @@ enum { YYENOMEM = -2 };
} \
while (0)
/* Backward compatibility with an undocumented macro.
Use ]b4_symbol(1, id)[ or ]b4_symbol(2, id)[. */
#define YYERRCODE ]b4_symbol(2, id)[
]b4_locations_if([[
]b4_yylloc_default_define[
#define YYRHSLOC(Rhs, K) ((Rhs)[K])
@@ -762,13 +770,13 @@ do { \
]b4_yy_location_print_define[
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
do { \
if (yydebug) \
{ \
YYFPRINTF (stderr, "%s ", Title); \
yy_symbol_print (stderr, \
Type, Value]b4_locations_if([, Location])[]b4_user_args[); \
Kind, Value]b4_locations_if([, Location])[]b4_user_args[); \
YYFPRINTF (stderr, "\n"); \
} \
} while (0)
@@ -836,7 +844,7 @@ do { \
int yydebug;
#else /* !]b4_api_PREFIX[DEBUG */
# define YYDPRINTF(Args) ((void) 0)
# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif /* !]b4_api_PREFIX[DEBUG */
@@ -1149,7 +1157,7 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
for (yyx = 0; yyx < YYNTOKENS; ++yyx)
{
yysymbol_kind_t yysym = YY_CAST (yysymbol_kind_t, yyx);
if (yysym != ]b4_symbol_prefix[YYERROR && yysym != ]b4_symbol_prefix[YYUNDEF)
if (yysym != ]b4_symbol(1, kind)[ && yysym != ]b4_symbol_prefix[YYUNDEF)
switch (yy_lac (]b4_push_if([[yyps->yyesa, &yyps->yyes, &yyps->yyes_capacity, yyps->yyssp, yysym]],
[[yyctx->yyesa, yyctx->yyes, yyctx->yyes_capacity, yyctx->yyssp, yysym]])[))
{
@@ -1178,7 +1186,7 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yyx;
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol_prefix[YYERROR
if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[
&& !yytable_value_is_error (yytable[yyx + yyn]))
{
if (!yyarg)
@@ -1400,10 +1408,10 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
switch (yycount)
{
# define YYCASE_(N, S) \
#define YYCASE_(N, S) \
case N: \
yyformat = S; \
break
break
default: /* Avoid compiler warnings. */
YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s"));
@@ -1411,7 +1419,7 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
# undef YYCASE_
#undef YYCASE_
}
/* Compute error message size. Don't count the "%s"s, but reserve
@@ -1693,7 +1701,7 @@ yysetstate:
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([
YYSTACK_RELOCATE (yyls_alloc, yyls);])[
# undef YYSTACK_RELOCATE
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
@@ -1765,6 +1773,17 @@ yyread_pushed_token:]])[
yytoken = ]b4_symbol(0, [kind])[;
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
else if (yychar == ]b4_symbol(1, [id])[)
{
/* The scanner already issued an error message, process directly
to error recovery. But do not keep the error token as
lookahead, it is too special and may lead us to an endless
loop in error recovery. */
yychar = ]b4_symbol(2, [id])[;
yytoken = ]b4_symbol(1, [kind])[;]b4_locations_if([[
yyerror_range[1] = yylloc;]])[
goto yyerrlab1;
}
else
{
yytoken = YYTRANSLATE (yychar);
@@ -1947,9 +1966,8 @@ yyerrlab:
goto yyexhaustedlab;
}]])[
}
]b4_locations_if([[ yyerror_range[1] = yylloc;]])[
]b4_locations_if([[
yyerror_range[1] = yylloc;]])[
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse lookahead token after an
@@ -2004,8 +2022,8 @@ yyerrlab1:
yyn = yypact[yystate];
if (!yypact_value_is_default (yyn))
{
yyn += ]b4_symbol_prefix[YYERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == ]b4_symbol_prefix[YYERROR)
yyn += ]b4_symbol(1, kind)[;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == ]b4_symbol(1, kind)[)
{
yyn = yytable[yyn];
if (0 < yyn)
+67 -12
View File
@@ -314,6 +314,7 @@ Parser C-Language Interface
The Lexical Analyzer Function @code{yylex}
* Calling Convention:: How @code{yyparse} calls @code{yylex}.
* Special Tokens:: Signaling end-of-file and errors to the parser.
* Tokens from Literals:: Finding token kinds from string aliases.
* Token Values:: How @code{yylex} must return the semantic value
of the token it has read.
@@ -7115,6 +7116,7 @@ that need it. @xref{Invocation}.
@menu
* Calling Convention:: How @code{yyparse} calls @code{yylex}.
* Special Tokens:: Signaling end-of-file and errors to the parser.
* Tokens from Literals:: Finding token kinds from string aliases.
* Token Values:: How @code{yylex} must return the semantic value
of the token it has read.
@@ -7168,6 +7170,49 @@ This interface has been designed so that the output from the @code{lex}
utility can be used without change as the definition of @code{yylex}.
@node Special Tokens
@subsection Special Tokens
In addition to the user defined tokens, Bison generates a few special tokens
that @code{yylex} may return.
The @code{YYEOF} token denotes the end of file, and signals to the parser
that there is nothing left afterwards. @xref{Calling Convention}, for an
example.
Returning @code{YYUNDEF} tells the parser that some lexical error was found.
It will emit an error message about an ``invalid token'', and enter
error-recovery (@pxref{Error Recovery}). Returning an unknown token kind
results in the exact same behavior.
Returning @code{YYerror} requires the parser to enter error-recovery
@emph{without} emitting an error message. This way the lexical analyzer can
produce an accurate error messages about the invalid input (something the
parser cannot do), and yet benefit from the error-recovery features of the
parser.
@example
int
yylex (void)
@{
@dots{}
switch (c)
@{
@dots{}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
@dots{}
return TOK_NUM;
@dots{}
case EOF:
return YYEOF;
default:
yyerror ("syntax error: invalid character: %c", c);
return YYerror;
@}
@}
@end example
@node Tokens from Literals
@subsection Finding Tokens by String Literals
@@ -7471,7 +7516,7 @@ enum yysymbol_kind_t
@{
YYSYMBOL_YYEMPTY = -2, /* No symbol. */
YYSYMBOL_YYEOF = 0, /* "end of file" */
YYSYMBOL_YYERROR = 1, /* error */
YYSYMBOL_YYerror = 1, /* error */
YYSYMBOL_YYUNDEF = 2, /* "invalid token" */
YYSYMBOL_PLUS = 3, /* "+" */
YYSYMBOL_MINUS = 4, /* "-" */
@@ -7497,7 +7542,7 @@ The location of the syntax error (that of the unexpected token).
@deftypefun int yypcontext_expected_tokens (@code{const yypcontext_t *}ctx, @code{yysymbol_kind_t} @var{argv}@code{[]}, @code{int} @var{argc})
Fill @var{argv} with the expected tokens, which never includes
@code{YYSYMBOL_YYEMPTY}, @code{YYSYMBOL_YYERROR}, or
@code{YYSYMBOL_YYEMPTY}, @code{YYSYMBOL_YYerror}, or
@code{YYSYMBOL_YYUNDEF}.
Never put more than @var{argc} elements into @var{argv}, and on success
@@ -7510,11 +7555,15 @@ If @var{argv} is null, return the size needed to store all the possible
values, which is always less than @code{YYNTOKENS}.
@end deftypefun
@deftypefun {const char *} yysymbol_name (@code{symbol_kind_t} @var{symbol})
@deftypefun {@r{string type}} yysymbol_name (@code{symbol_kind_t} @var{symbol})
The name of the symbol whose kind is @var{symbol}, possibly translated.
Depending on the options, may return a @code{const char*} or a
@code{std::string}.
@end deftypefun
A custom syntax error function looks as follows.
A custom syntax error function looks as follows. This implementation is
inappropriate for internationalization, see the @file{c/bistromathic}
example for a better alternative.
@example
int
@@ -7802,7 +7851,7 @@ or @code{detailed}, token aliases can be internationalized:
%token
'\n' _("end of line")
<double>
NUM _("double precision number")
NUM _("number")
<symrec*>
FUN _("function")
VAR _("variable")
@@ -8253,7 +8302,7 @@ the lookahead token has no precedence, then the default is to shift.
@subsection Using Precedence For Non Operators
Using properly precedence and associativity directives can help fixing
shift/reduce conflicts that do not involve arithmetics-like operators. For
shift/reduce conflicts that do not involve arithmetic-like operators. For
instance, the ``dangling @code{else}'' problem (@pxref{Shift/Reduce}) can be
solved elegantly in two different ways.
@@ -10601,7 +10650,7 @@ Print the version number of Bison and exit.
Print the name of the directory containing locale-dependent data.
@item --print-datadir
Print the name of the directory containing skeletons and XSLT.
Print the name of the directory containing skeletons, CSS and XSLT.
@item -u
@item --update
@@ -11545,7 +11594,7 @@ struct token
@{
YYEMPTY = -2, // No token.
YYEOF = 0, // "end of file"
YYERRCODE = 256, // error
YYerror = 256, // error
YYUNDEF = 257, // "invalid token"
PLUS = 258, // "+"
MINUS = 259, // "-"
@@ -12074,7 +12123,9 @@ values, which is always less than @code{YYNTOKENS}.
The name of the symbol whose kind is @var{symbol}, possibly translated.
@end deftypemethod
A custom syntax error function looks as follows.
A custom syntax error function looks as follows. This implementation is
inappropriate for internationalization, see the @file{c/bistromathic}
example for a better alternative.
@example
void
@@ -12330,7 +12381,7 @@ interactions. A hand-written scanner is actually easier to interface with.
@node Calc++ --- C++ Calculator
@subsubsection Calc++ --- C++ Calculator
Of course the grammar is dedicated to arithmetics, a single expression,
Of course the grammar is dedicated to arithmetic, a single expression,
possibly preceded by variable assignments. An environment containing
possibly predefined variables such as @code{one} and @code{two}, is
exchanged with the parser. An example of valid input follows.
@@ -13327,6 +13378,10 @@ public void reportSyntaxError(YYParser.Context ctx) @{
System.err.println("");
@}
@end example
@noindent
This implementation is inappropriate for internationalization, see the
@file{c/bistromathic} example for a better alternative.
@end deftypemethod
@node Java Action Features
@@ -15116,7 +15171,7 @@ London, Department of Computer Science, TR-00-12 (December 2000).
@c LocalWords: redeclare automata Dparse localedir datadir XSLT midrule Wno
@c LocalWords: multitable headitem hh basename Doxygen fno filename gdef de
@c LocalWords: doxygen ival sval deftypemethod deallocate pos deftypemethodx
@c LocalWords: Ctor defcv defcvx arg accessors arithmetics CPP ifndef CALCXX
@c LocalWords: Ctor defcv defcvx arg accessors CPP ifndef CALCXX YYerror
@c LocalWords: lexer's calcxx bool LPAREN RPAREN deallocation cerrno climits
@c LocalWords: cstdlib Debian undef yywrap unput noyywrap nounput zA yyleng
@c LocalWords: errno strtol ERANGE str strerror iostream argc argv Javadoc PSLR
@@ -15150,7 +15205,7 @@ London, Department of Computer Science, TR-00-12 (December 2000).
@c LocalWords: Wdangling yytoken erreur syntaxe inattendu attendait nombre
@c LocalWords: YYUNDEF SymbolKind yypcontext YYENOMEM TOKENMAX getBundle
@c LocalWords: ResourceBundle myResources getString getName getToken
@c LocalWords: getLocation getExpectedTokens reportSyntaxError
@c LocalWords: getLocation getExpectedTokens reportSyntaxError bistromathic
@c Local Variables:
@c ispell-dictionary: "american"
+26 -16
View File
@@ -252,7 +252,6 @@ sub generate_grammar_triangular ($$@)
my $out = new IO::File ">$base.y"
or die;
print $out <<EOF;
%define parse.error detailed
%{
#include <stdio.h>
#include <stdlib.h>
@@ -388,7 +387,6 @@ sub generate_grammar_calc ($$@)
%}
%define api.value.type union
%define parse.error detailed
$directives
%{
@@ -812,7 +810,8 @@ sub compile ($)
my ($base) = @_;
my $compiler = compiler ($base);
my $my_bison = `sed -ne '/%bison "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
my $my_bison = `sed -ne '/[/][/] %bison "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
chop $my_bison;
run ((length $my_bison ? $my_bison : $bison) . " $base.y -o $base.c");
if ($gbench)
{
@@ -902,8 +901,13 @@ directive list.
sub bench_with_gbenchmark ($@)
{
my ($grammar, @directive) = @_;
my $compiler = compiler ("y0");
my $readme = new IO::File ">README.md";
print $readme <<EOF;
compiler: $compiler $cflags
EOF
my @obj = ();
for my $i (0 .. $#directive)
{
@@ -923,7 +927,6 @@ sub bench_with_gbenchmark ($@)
BENCHMARK_MAIN();
EOF
my $compiler = compiler ("y0");
run "$compiler -o main $cflags main.c @obj -lbenchmark";
run "./main | tee -a README.md";
}
@@ -1121,7 +1124,7 @@ sub parse_dir ()
elsif ($token[0] eq '%b')
{
shift @token;
@res = ("/*\n%bison \"$token[0]\"\\\n*/");
@res = ("// %bison \"$token[0]\"");
}
else
{
@@ -1160,19 +1163,26 @@ sub getopt ()
getopt;
my $basedir = 'benches';
# Create the directory we work in.
mkdir "benches" or die "cannot create benches"
unless -d "benches";
my $count = 1;
++$count
while -d "benches/$count";
my $dir = "benches/$count";
mkdir $basedir or die "cannot create directory $basedir"
unless -d $basedir;
my $count = 0;
my $dir;
while (!$dir || -d $dir)
{
++$count;
$dir = sprintf "%s/%03d", $basedir, $count;
}
mkdir $dir
or die "cannot create $dir";
unlink "benches/latest"
or die "cannot unlink benches/latest"
if -l "benches/latest";
symlink $count, "benches/latest"
or die "cannot create directory $dir";
unlink "$basedir/latest"
or die "cannot unlink $basedir/latest"
if -l "$basedir/latest";
symlink sprintf("%03d", $count), "$basedir/latest"
or die "cannot create symlink";
chdir $dir
or die "cannot chdir $dir";
+3
View File
@@ -53,10 +53,13 @@ push-parser model.
This example demonstrates best practices when using Bison.
- Its hand-written scanner tracks locations.
- Its interface is pure.
- It uses the `error` token to get error recovery.
- Its interface is "incremental", well suited for interaction: it uses the
push-parser API to feed the parser with the incoming tokens.
- It features an interactive command line with completion based on the
parser state, based on `yyexpected_tokens`.
- It uses Bison's standard catalogue for internationalization of generated
messages.
- It uses a custom syntax error with location, lookahead correction and
token internationalization.
- It supports debug traces with semantic values.
+14 -9
View File
@@ -3,20 +3,26 @@
BASE = bistromathic
BISON = bison
FLEX = flex
XSLTPROC = xsltproc
# We need to find the headers and libs for readline and intl.
# You probably need to customize this for your own environment.
CPPFLAGS = -I/opt/local/include
LDFLAGS = -L/opt/local/lib
# Find the translation catalogue for Bison's generated messagess.
BISON_LOCALEDIR = $(shell $(BISON) $(BISON_FLAGS) --print-localedir)
CPPFLAGS += -DENABLE_NLS -DBISON_LOCALEDIR='"$(BISON_LOCALEDIR)"'
LIBS = -lreadline -lintl
all: $(BASE)
%.c %.h %.xml %.gv: %.y
$(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
%.c: %.l
$(FLEX) $(FLEXFLAGS) -o$*.c $<
scan.o: parse.h
$(BASE): parse.o scan.o
$(CC) $(CFLAGS) -o $@ $^
$(BASE): parse.o
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
run: $(BASE)
@echo "Type bistromathic expressions. Quit with ctrl-d."
@@ -28,8 +34,7 @@ html: $(BASE).html
CLEANFILES = \
$(BASE) *.o \
parse.[ch] parse.output parse.xml parse.html parse.gv \
scan.c
parse.[ch] parse.output parse.xml parse.html parse.gv
clean:
rm -f $(CLEANFILES)
+3
View File
@@ -2,10 +2,13 @@
This example demonstrates best practices when using Bison.
- Its hand-written scanner tracks locations.
- Its interface is pure.
- It uses the `error` token to get error recovery.
- Its interface is "incremental", well suited for interaction: it uses the
push-parser API to feed the parser with the incoming tokens.
- It features an interactive command line with completion based on the
parser state, based on `yyexpected_tokens`.
- It uses Bison's standard catalogue for internationalization of generated
messages.
- It uses a custom syntax error with location, lookahead correction and
token internationalization.
- It supports debug traces with semantic values.
+152 -18
View File
@@ -17,7 +17,7 @@
# macOS' version of readline does not repeat stdin on stdout in
# non-interactive mode.
if ! echo '1-1' | prog | grep '1-1'; then
if ! echo '1-1' | prog | grep '1-1' >/dev/null; then
strip_prompt=true
fi
@@ -65,26 +65,159 @@ cat >input <<EOF
*
EOF
run 0 '> *
> err: 1.1: syntax error: expected end of file or - or ( or exit or double precision number or function or variable before *'
> ''
err: 1.1: syntax error: expected end of file or - or ( or exit or number or function or variable before *'
cat >input <<EOF
1 + 2 * * 3
EOF
run 0 '> 1 + 2 * * 3
> err: 1.9: syntax error: expected - or ( or double precision number or function or variable before *'
cat >input <<EOF
100%
EOF
run 0 '> 100%
100
> err: 1.4: error: invalid character'
> ''
err: 1.9: syntax error: expected - or ( or number or function or variable before *'
cat >input <<EOF
1 / 0
EOF
run 0 '> 1 / 0
> err: 1.1-5: error: division by zero'
> ''
err: 1.1-5: error: division by zero'
## ---------------- ##
## Error recovery. ##
## ---------------- ##
cat >input <<EOF
((1 ++ 2) ** 3)
(1 ++ 2) + (3 ** 4)
EOF
run 0 '> ((1 ++ 2) ** 3)
666
> (1 ++ 2) + (3 ** 4)
1332
> ''
err: 1.6: syntax error: expected - or ( or number or function or variable before +
err: 2.5: syntax error: expected - or ( or number or function or variable before +
err: 2.16: syntax error: expected - or ( or number or function or variable before *'
# The rule "( error )" should work even if there are no tokens between "(" and ")".
cat >input <<EOF
()
EOF
run 0 '> ()
666
> ''
err: 1.2: syntax error: expected - or ( or number or function or variable before )'
cat >input <<EOF
100% + 10
EOF
run 0 '> 100% + 10
> ''
err: 1.4: syntax error: invalid character: %'
# Traces. This allows to check the location of the error. If we
# forget to map YYerror to YYUNDEF, error recovery enters an endless
# loop with this input.
cat >input <<EOF
(+_)
EOF
run 0 '> (+_)
666
> ''
err: Starting parse
err: Entering state 0
err: Stack now 0
err: Reading a token
err: Next token is token ( (1.1: )
err: Shifting token ( (1.1: )
err: Entering state 2
err: Stack now 0 2
err: Return for a new token:
err: Reading a token
err: Next token is token + (1.2: )
err: LAC: initial context established for +
err: LAC: checking lookahead +: Err
err: LAC: checking lookahead end of file: Err
err: LAC: checking lookahead +: Err
err: LAC: checking lookahead -: S1
err: LAC: checking lookahead *: Err
err: LAC: checking lookahead /: Err
err: LAC: checking lookahead ^: Err
err: LAC: checking lookahead (: S2
err: LAC: checking lookahead ): Err
err: LAC: checking lookahead =: Err
err: LAC: checking lookahead exit: Err
err: LAC: checking lookahead number: S4
err: LAC: checking lookahead function: S5
err: LAC: checking lookahead variable: S6
err: LAC: checking lookahead NEG: Err
err: 1.2: syntax error: expected - or ( or number or function or variable before +
err: LAC: initial context discarded due to error recovery
err: Shifting token error (1.2: )
err: Entering state 10
err: Stack now 0 2 10
err: Next token is token + (1.2: )
err: LAC: initial context established for +
err: LAC: checking lookahead +: Err
err: Error: discarding token + (1.2: )
err: Error: popping token error (1.2: )
err: Stack now 0 2
err: LAC: initial context discarded due to error recovery
err: Shifting token error (1.2: )
err: Entering state 10
err: Stack now 0 2 10
err: Return for a new token:
err: 1.3: syntax error: invalid character: _
err: Reading a token
err: Error: popping token error (1.2: )
err: Stack now 0 2
err: Shifting token error (1.2-3: )
err: Entering state 10
err: Stack now 0 2 10
err: Next token is token invalid token (1.3: )
err: LAC: initial context established for invalid token
err: LAC: checking lookahead invalid token: Always Err
err: Error: discarding token invalid token (1.3: )
err: Error: popping token error (1.2-3: )
err: Stack now 0 2
err: LAC: initial context discarded due to error recovery
err: Shifting token error (1.2-3: )
err: Entering state 10
err: Stack now 0 2 10
err: Return for a new token:
err: Reading a token
err: Next token is token ) (1.4: )
err: Shifting token ) (1.4: )
err: Entering state 20
err: Stack now 0 2 10 20
err: Reducing stack by rule 15 (line 151):
err: $1 = token ( (1.1: )
err: $2 = token error (1.2-3: )
err: $3 = token ) (1.4: )
err: -> $$ = nterm exp (1.1-4: 666)
err: Entering state 7
err: Stack now 0 7
err: Return for a new token:
err: Reading a token
err: Now at end of input.
err: LAC: initial context established for end of file
err: LAC: checking lookahead end of file: R2 G8 S19
err: Reducing stack by rule 2 (line 126):
err: $1 = nterm exp (1.1-4: 666)
err: -> $$ = nterm input (1.1-4: )
err: Entering state 8
err: Stack now 0 8
err: Now at end of input.
err: Shifting token end of file (1.5: )
err: LAC: initial context discarded due to shift
err: Entering state 19
err: Stack now 0 8 19
err: Stack now 0 8 19
err: Cleanup: popping token end of file (1.5: )
err: Cleanup: popping nterm input (1.1-4: )' -p
## ------------ ##
@@ -107,25 +240,26 @@ sed -e 's/\\t/ /g' >input <<EOF
(1+\t\t
EOF
run 0 '> (1+
( cos ln
- double precision number sin
atan exp sqrt
( - atan cos exp ln number sin sqrt
> (1+
> err: 1.4: syntax error: expected - or ( or double precision number or function or variable before end of file'
> ''
err: 1.4: syntax error: expected - or ( or number or function or variable before end of file'
# Check the completion of a word.
sed -e 's/\\t/ /g' >input <<EOF
(at\t\t
EOF
run 0 '> (atan ( ''
> err: 1.9: syntax error: expected - or ( or double precision number or function or variable before end of file'
> ''
err: 1.9: syntax error: expected - or ( or number or function or variable before end of file'
# Check the completion at the very beginning.
sed -e 's/\\t/ /g' >input <<EOF
e\t\t
EOF
run 0 '> e
run -n 0 '> e
end of file exit exp ''
> e
0
> err: '
> ''
err: '
+5 -2
View File
@@ -26,8 +26,11 @@ nodist_%C%_bistromathic_SOURCES = %D%/parse.y %D%/parse.h
%D%/parse.c: $(dependencies)
# Don't use gnulib's system headers.
%C%_bistromathic_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
%C%_bistromathic_LDADD = -lm -lreadline
%C%_bistromathic_CPPFLAGS = \
-DBISON_LOCALEDIR='"$(localdir)"' \
-DLOCALEDIR='"$(localdir)"' \
-I$(top_srcdir)/%D% -I$(top_builddir)/%D%
%C%_bistromathic_LDADD = -lm -lreadline $(LIBINTL)
dist_bistromathic_DATA = %D%/parse.y %D%/Makefile %D%/README.md
CLEANFILES += %D%/parse.[ch] %D%/parse.output
+123 -38
View File
@@ -3,13 +3,24 @@
%code top {
#include <ctype.h> // isdigit
#include <math.h> // cos, sin, etc.
#include <stddef.h> // ptrdiff_t
#include <stdarg.h> // va_start
#include <stdio.h> // printf
#include <stdlib.h> // calloc.
#include <stdlib.h> // calloc
#include <string.h> // strcmp
#include <readline/readline.h>
#include <readline/history.h>
#if defined ENABLE_NLS && ENABLE_NLS
// Unable the translation of Bison's generated messages.
# define YYENABLE_NLS 1
# include <libintl.h>
// Unless specified otherwise, we expect bistromathic's own
// catalogue to be installed in the same tree as Bison's catalogue.
# ifndef LOCALEDIR
# define LOCALEDIR BISON_LOCALEDIR
# endif
#endif
}
%code requires {
@@ -35,13 +46,22 @@
}
%code provides {
# ifndef __attribute__
# ifndef __GNUC__
# define __attribute__(Spec) /* empty */
# endif
# endif
int yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc);
void yyerror (YYLTYPE *yylloc, char const *msg);
void yyerror (YYLTYPE *loc, char const *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
}
%code {
#define N_
#define _
#if defined ENABLE_NLS && ENABLE_NLS
# define _(Msgid) gettext (Msgid)
#else
# define _(Msgid) (Msgid)
#endif
// Whether to quit.
int done = 0;
@@ -82,7 +102,7 @@
EQUAL "="
EXIT "exit"
<double>
NUM _("double precision number")
NUM _("number")
<symrec*>
FUN _("function")
VAR _("variable")
@@ -133,6 +153,7 @@ exp:
| "-" exp %prec NEG { $$ = -$2; }
| exp[l] "^" exp[r] { $$ = pow ($l, $r); }
| "(" exp ")" { $$ = $2; }
| "(" error ")" { $$ = 666; }
;
// End of grammar.
@@ -235,6 +256,8 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
case '(': return TOK_LPAREN;
case ')': return TOK_RPAREN;
case '!': return TOK_YYUNDEF;
case '\0': return TOK_YYEOF;
// Numbers.
@@ -244,9 +267,9 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
{
int nchars = 0;
sscanf (*line - 1, "%lf%n", &yylval->TOK_NUM, &nchars);
*line += nchars - 1;
yylloc->last_column += nchars - 1;
return TOK_NUM;
*line += nchars - 1;
yylloc->last_column += nchars - 1;
return TOK_NUM;
}
// Identifiers.
@@ -276,8 +299,8 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
// Stray characters.
default:
yyerror (yylloc, "error: invalid character");
return yylex (line, yylval, yylloc);
yyerror (yylloc, "syntax error: invalid character: %c", c);
return TOK_YYerror;
}
}
@@ -286,40 +309,86 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
| Parser. |
`---------*/
const char *
error_format_string (int argc)
{
switch (argc)
{
default: /* Avoid compiler warnings. */
case 0: return _("%@: syntax error");
case 1: return _("%@: syntax error: unexpected %u");
// TRANSLATORS: '%@' is a location in a file, '%u' is an
// "unexpected token", and '%0e', '%1e'... are expected tokens
// at this point.
//
// For instance on the expression "1 + * 2", you'd get
//
// 1.5: syntax error: expected - or ( or number or function or variable before *
case 2: return _("%@: syntax error: expected %0e before %u");
case 3: return _("%@: syntax error: expected %0e or %1e before %u");
case 4: return _("%@: syntax error: expected %0e or %1e or %2e before %u");
case 5: return _("%@: syntax error: expected %0e or %1e or %2e or %3e before %u");
case 6: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e before %u");
case 7: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e before %u");
case 8: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e or %6e before %u");
}
}
int
yyreport_syntax_error (const yypcontext_t *ctx)
{
int res = 0;
YY_LOCATION_PRINT (stderr, *yypcontext_location (ctx));
fprintf (stderr, ": syntax error");
// Report the tokens expected at this point.
{
enum { TOKENMAX = 10 };
yysymbol_kind_t expected[TOKENMAX];
int n = yypcontext_expected_tokens (ctx, expected, TOKENMAX);
if (n < 0)
// Forward errors to yyparse.
res = n;
enum { ARGS_MAX = 7 };
yysymbol_kind_t arg[ARGS_MAX];
int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
if (argsize < 0)
return argsize;
const char *format = error_format_string (1 + argsize);
while (*format)
// %@: location.
if (format[0] == '%' && format[1] == '@')
{
YY_LOCATION_PRINT (stderr, *yypcontext_location (ctx));
format += 2;
}
// %u: unexpected token.
else if (format[0] == '%' && format[1] == 'u')
{
fputs (yysymbol_name (yypcontext_token (ctx)), stderr);
format += 2;
}
// %0e, %1e...: expected token.
else if (format[0] == '%'
&& isdigit (format[1])
&& format[2] == 'e'
&& (format[1] - '0') < argsize)
{
int i = format[1] - '0';
fputs (yysymbol_name (arg[i]), stderr);
format += 3;
}
else
for (int i = 0; i < n; ++i)
fprintf (stderr, "%s %s",
i == 0 ? ": expected" : " or", yysymbol_name (expected[i]));
}
// Report the unexpected token.
{
yysymbol_kind_t lookahead = yypcontext_token (ctx);
if (lookahead != YYSYMBOL_YYEMPTY)
fprintf (stderr, " before %s", yysymbol_name (lookahead));
}
fprintf (stderr, "\n");
return res;
{
fputc (*format, stderr);
++format;
}
fputc ('\n', stderr);
return 0;
}
// Called by yyparse on error.
void yyerror (YYLTYPE *loc, char const *msg)
void yyerror (YYLTYPE *loc, char const *format, ...)
{
YY_LOCATION_PRINT (stderr, *loc);
fprintf (stderr, ": %s\n", msg);
fputs (": ", stderr);
va_list args;
va_start (args, format);
vfprintf (stderr, format, args);
va_end (args);
putc ('\n', stderr);
}
@@ -467,8 +536,20 @@ void init_readline (void)
int main (int argc, char const* argv[])
{
#if defined ENABLE_NLS && ENABLE_NLS
// Set up internationalization.
setlocale (LC_ALL, "");
// Use Bison's standard translation catalogue for error messages
// (the generated messages).
bindtextdomain ("bison-runtime", BISON_LOCALEDIR);
// The translation catalogue of bistromathic is actually included in
// Bison's. In your own project, use the name of your project.
bindtextdomain ("bison", LOCALEDIR);
textdomain ("bison");
#endif
// Enable parse traces on option -p.
if (argc == 2 && strcmp (argv[1], "-p") == 0)
if (1 < argc && strcmp (argv[1], "-p") == 0)
yydebug = 1;
init_table ();
init_readline ();
@@ -477,7 +558,11 @@ int main (int argc, char const* argv[])
{
char *line = readline ("> ");
if (!line)
return 0;
{
// Finish the line started by the prompt.
putchar ('\n');
break;
}
if (*line)
add_history (line);
process_line (&lloc, line);
+1 -1
View File
@@ -150,7 +150,7 @@ class CalcLexer implements Calc.Lexer {
end.set(reader.getPosition());
switch (ttype) {
case StreamTokenizer.TT_EOF:
return EOF;
return YYEOF;
case StreamTokenizer.TT_EOL:
end.line += 1;
end.column = 0;
+1 -1
View File
@@ -93,7 +93,7 @@ class CalcLexer implements Calc.Lexer {
int ttype = st.nextToken();
switch (ttype) {
case StreamTokenizer.TT_EOF:
return EOF;
return YYEOF;
case StreamTokenizer.TT_EOL:
return (int) '\n';
case StreamTokenizer.TT_WORD:
+32 -14
View File
@@ -68,26 +68,35 @@ trap cleanup 0 1 2 13 15
mkdir $$.dir
cd $$.dir
# run [-noerr] EXPECTED-EXIT-STATUS EXPECTED-OUTPUT [PARSER-OPTIONS]
# ------------------------------------------------------------------
# run [-noerr, -n] EXPECTED-EXIT-STATUS EXPECTED-OUTPUT [PARSER-OPTIONS]
# ----------------------------------------------------------------------
# -noerr: ignore stderr, otherwise merge it into effective output.
# -n: not final end-of-line in expected-output
run ()
{
noerr=false
case $1 in
(-noerr) noerr=true; shift;;
esac
echo=echo
while true; do
case $1 in
(-noerr) noerr=true; shift;;
(-n) echo=printf; shift;;
(*) break;;
esac
done
# Expected exit status.
sta_exp=$1
shift
# Expected output.
if $strip_prompt; then
out_exp=$(echo "$1" | sed -e 's/^> err:/err:/;/^> /d')
else
out_exp=$1
fi
$echo "$1" |
sed -e 's/Reducing stack by rule .* (line .*):/Reducing stack by rule XX (line XXX):/g' |
if $strip_prompt; then
# An extra EOL added in bistromathic's main. Keep that empty line.
sed -e '/^> ./d;s/^> $//g'
else
cat
fi >exp
shift
# Effective exit status.
@@ -96,19 +105,28 @@ run ()
prog "$@" - <input >out_eff 2>err_eff || sta_eff=$?
# Combine effective output and error streams.
out_eff=$(cat out_eff && $noerr || sed -e 's/^/err: /g' err_eff)
{
cat out_eff
if ! $noerr; then
sed -e 's/^/err: /g' \
-e 's/Reducing stack by rule .* (line .*):/Reducing stack by rule XX (line XXX):/g' \
err_eff
fi
} >eff
if test $sta_eff -eq $sta_exp; then
if test "$out_eff" = "$out_exp"; then
if cmp eff exp 2>/dev/null; then
echo "$me: PASS: $number"
else
echo "$me: FAIL: $number"
echo "$me: input:"
sed -e 's/^/ /' input
echo "$me: expected output:"
echo "$out_exp" | sed -e 's/^/ /'
sed -e 's/^/ /' exp
echo "$me: effective output:"
echo "$out_eff" | sed -e 's/^/ /'
sed -e 's/^/ /' eff
echo "$me: diff:"
diff -u exp eff | sed -e 's/^/ /'
exit=false
fi
else
+1 -1
Submodule gnulib updated: 64e1ff019f...5ec4d920e4
+1
View File
@@ -1,3 +1,4 @@
/remove-potcdate.sin~
/*.gmo
/*.po
/LINGUAS
+1
View File
@@ -1,3 +1,4 @@
/extern-inline.m4~
/*~
/00gnulib.m4
/__inline.m4
+3
View File
@@ -1,3 +1,5 @@
examples/c/bistromathic/parse.y
examples/java/calc/Calc.y
src/complain.c
src/conflicts.c
src/files.c
@@ -5,6 +7,7 @@ src/fixits.c
src/getargs.c
src/gram.c
src/graphviz.c
src/i18n-strings.c
src/location.c
src/main.c
src/muscle-tab.c
+1 -1
View File
@@ -600,7 +600,7 @@ syntax_error (location loc,
CASE (2, _("expected %1$s before %0$s"));
CASE (3, _("expected %1$s or %2$s before %0$s"));
CASE (4, _("expected %1$s or %2$s or %3$s before %0$s"));
CASE (5, _("expected %1$s or %2$s or %4$s or %5$s before %0$s"));
CASE (5, _("expected %1$s or %2$s or %3$s or %4$s before %0$s"));
#undef CASE
}
location_print (loc, stderr);
+37
View File
@@ -0,0 +1,37 @@
/* This file is not compiled in, it is used only to expose more
strings to gettextize.
Why is this needed?
Bison emits strings to translate in the generated code, for builtin
tokens. So they appear only in generated parsers, which are not
shipped, so they are not in the src tree, so we cannot use them in
our POTFILE.
Except src/parse-gram.c, which is in the source tree. And even in
the git repo. But to avoid useless diffs in the repo, we do not
keep the #line directives in the src tree. Yet, for the user, we
ship a src/parse-gram.c _with_ the #lines. This is done in a
dist-hook which regenerates src/parse-gram.c when we run "make
dist".
Unfortunately, then, update-po traverses the whole tree and sees
that the location of the strings to translate in src/parse-gram.c
have changed, so the bison.pot is to be updated. And that is not
possible in the "make dist" which is run within "make distcheck"
(not the one preparing the dist for distcheck, the one run by
distcheck to check that a distributed tarball can build a tarball)
because then the src tree is read-only.
So let's not put src/parse-gram.c in the POTFILE, and expose these
strings to gettextize by hand.
*/
// Please syntax-check.
#include <config.h>
static const char *const msgid[] =
{
N_("end of file"),
N_("invalid token")
}
+1
View File
@@ -130,6 +130,7 @@ src_bison_LDADD = \
lib/libbison.a
EXTRA_DIST += %D%/i18n-strings.c
## ------ ##
+6 -21
View File
@@ -186,16 +186,6 @@ xescape_trigraphs (const char *src)
return buf;
}
/* Whether some symbol requires internationalization. */
static bool
has_translations (void)
{
for (int i = 0; i < nsyms; i++)
if (symbols[i]->translatable)
return true;
return false;
}
/* The tag to show in the generated parsers. Use "end of file" rather
than "$end". But keep "$end" in the reports, it's shorter and more
consistent. Support i18n if the user already uses it. */
@@ -219,11 +209,9 @@ symbol_tag (const symbol *sym)
static void
prepare_symbol_names (char const *muscle_name)
{
const bool eof_is_user_defined
= !endtoken->alias || STRNEQ (endtoken->alias->tag, "$end");
// Whether to add a pair of quotes around the name.
const bool quote = STREQ (muscle_name, "tname");
const bool with_translations = !quote && has_translations ();
bool has_translations = false;
/* We assume that the table will be output starting at column 2. */
int col = 2;
@@ -233,11 +221,9 @@ prepare_symbol_names (char const *muscle_name)
for (int i = 0; i < nsyms; i++)
{
const char *tag = symbol_tag (symbols[i]);
bool translatable =
with_translations
&& (symbols[i]->translatable
|| (!eof_is_user_defined && symbols[i]->content == endtoken->content)
|| symbols[i]->content == undeftoken->content);
bool translatable = !quote && symbols[i]->translatable;
if (translatable)
has_translations = true;
char *cp
= tag[0] == '"' && !quote
@@ -273,8 +259,7 @@ prepare_symbol_names (char const *muscle_name)
muscle_insert (muscle_name, obstack_finish0 (&format_obstack));
/* Announce whether translation support is needed. */
if (!quote)
MUSCLE_INSERT_BOOL ("has_translations", with_translations);
MUSCLE_INSERT_BOOL ("has_translations_flag", has_translations);
}
+47 -28
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.5.4.236-8d75. */
/* A Bison parser, made by GNU Bison 3.5.90. */
/* Bison implementation for Yacc-like parsers in C
@@ -34,6 +34,10 @@
/* C LALR(1) parser skeleton written by Richard Stallman, by
simplifying the original so-called "semantic" parser. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed. */
/* All symbols defined below should begin with yy or YY, to avoid
infringing on user name space. This should be done even for local
variables, as they might otherwise be expanded by user macros.
@@ -41,14 +45,11 @@
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */
/* Undocumented macros, especially those whose name start with YY_,
are private implementation details. Do not rely on them. */
/* Identify Bison output. */
#define YYBISON 1
/* Bison version. */
#define YYBISON_VERSION "3.5.4.236-8d75"
#define YYBISON_VERSION "3.5.90"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -105,7 +106,7 @@ enum yysymbol_kind_t
{
YYSYMBOL_YYEMPTY = -2,
YYSYMBOL_YYEOF = 0, /* "end of file" */
YYSYMBOL_YYERROR = 1, /* error */
YYSYMBOL_YYerror = 1, /* error */
YYSYMBOL_YYUNDEF = 2, /* "invalid token" */
YYSYMBOL_STRING = 3, /* "string" */
YYSYMBOL_TSTRING = 4, /* "translatable string" */
@@ -425,6 +426,11 @@ typedef int yy_state_fast_t;
# endif
#endif
#ifndef N_
# define N_(Msgid) Msgid
#endif
#ifndef YY_ATTRIBUTE_PURE
# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
@@ -524,7 +530,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# define YYCOPY_NEEDED 1
#endif
#endif /* 1 */
#if (! defined yyoverflow \
&& (! defined __cplusplus \
@@ -643,7 +649,7 @@ yysymbol_name (yysymbol_kind_t yysymbol)
{
static const char *const yy_sname[] =
{
N_("end of file"), "error", N_("invalid token"), N_("string"),
N_("end of file"), N_("error"), N_("invalid token"), N_("string"),
N_("translatable string"), "%token", "%nterm", "%type", "%destructor",
"%printer", "%left", "%right", "%nonassoc", "%precedence", "%prec",
"%dprec", "%merge", "%code", "%default-prec", "%define", "%defines",
@@ -666,11 +672,11 @@ yysymbol_name (yysymbol_kind_t yysymbol)
"named_ref.opt", "variable", "value", "id", "id_colon", "symbol",
"string_as_id", "epilogue.opt", YY_NULLPTR
};
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YYTNAME[SYMBOL-NUM] is
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
internationalizable. */
static yytype_int8 yytranslatable[] =
{
0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -684,7 +690,7 @@ yysymbol_name (yysymbol_kind_t yysymbol)
}
#endif
# ifdef YYPRINT
#ifdef YYPRINT
/* YYTOKNUM[NUM] -- (External) token number corresponding to the
(internal) symbol number NUM (which must be that of a token). */
static const yytype_int16 yytoknum[] =
@@ -697,7 +703,7 @@ static const yytype_int16 yytoknum[] =
305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315
};
# endif
#endif
#define YYPACT_NINF (-80)
@@ -925,6 +931,9 @@ enum { YYENOMEM = -2 };
} \
while (0)
/* Backward compatibility with an undocumented macro.
Use GRAM_error or GRAM_UNDEF. */
#define YYERRCODE GRAM_UNDEF
/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
If N is 0, then set CURRENT to the empty location which ends
@@ -972,8 +981,8 @@ do { \
This macro was not mandated originally: define only if we know
we won't break user code: when these are the locations we know. */
#ifndef YY_LOCATION_PRINT
# if defined GRAM_LTYPE_IS_TRIVIAL && GRAM_LTYPE_IS_TRIVIAL
# ifndef YY_LOCATION_PRINT
# if defined GRAM_LTYPE_IS_TRIVIAL && GRAM_LTYPE_IS_TRIVIAL
/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
@@ -1003,22 +1012,22 @@ yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
return res;
}
# define YY_LOCATION_PRINT(File, Loc) \
# define YY_LOCATION_PRINT(File, Loc) \
yy_location_print_ (File, &(Loc))
# else
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
#endif
# else
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
# endif /* !defined YY_LOCATION_PRINT */
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
do { \
if (yydebug) \
{ \
YYFPRINTF (stderr, "%s ", Title); \
yy_symbol_print (stderr, \
Type, Value, Location); \
Kind, Value, Location); \
YYFPRINTF (stderr, "\n"); \
} \
} while (0)
@@ -1312,7 +1321,7 @@ do { \
int yydebug;
#else /* !GRAM_DEBUG */
# define YYDPRINTF(Args) ((void) 0)
# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif /* !GRAM_DEBUG */
@@ -1606,7 +1615,7 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
for (yyx = 0; yyx < YYNTOKENS; ++yyx)
{
yysymbol_kind_t yysym = YY_CAST (yysymbol_kind_t, yyx);
if (yysym != YYSYMBOL_YYERROR && yysym != YYSYMBOL_YYUNDEF)
if (yysym != YYSYMBOL_YYerror && yysym != YYSYMBOL_YYUNDEF)
switch (yy_lac (yyctx->yyesa, yyctx->yyes, yyctx->yyes_capacity, yyctx->yyssp, yysym))
{
case YYENOMEM:
@@ -1901,7 +1910,7 @@ yysetstate:
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
YYSTACK_RELOCATE (yyls_alloc, yyls);
# undef YYSTACK_RELOCATE
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
@@ -1954,6 +1963,17 @@ yybackup:
yytoken = YYSYMBOL_YYEOF;
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
else if (yychar == GRAM_error)
{
/* The scanner already issued an error message, process directly
to error recovery. But do not keep the error token as
lookahead, it is too special and may lead us to an endless
loop in error recovery. */
yychar = GRAM_UNDEF;
yytoken = YYSYMBOL_YYerror;
yyerror_range[1] = yylloc;
goto yyerrlab1;
}
else
{
yytoken = YYTRANSLATE (yychar);
@@ -2619,7 +2639,6 @@ yyerrlab:
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = yychar == GRAM_EMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar);
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
@@ -2635,7 +2654,6 @@ yyerrlab:
}
yyerror_range[1] = yylloc;
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse lookahead token after an
@@ -2684,13 +2702,14 @@ yyerrorlab:
yyerrlab1:
yyerrstatus = 3; /* Each real token shifted decrements this. */
// Pop stack until we find a state that shifts the error token.
for (;;)
{
yyn = yypact[yystate];
if (!yypact_value_is_default (yyn))
{
yyn += YYSYMBOL_YYERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYERROR)
yyn += YYSYMBOL_YYerror;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
{
yyn = yytable[yyn];
if (0 < yyn)
+5 -4
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.5.4.236-8d75. */
/* A Bison parser, made by GNU Bison 3.5.90. */
/* Bison interface for Yacc-like parsers in C
@@ -31,8 +31,9 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Undocumented macros, especially those whose name start with YY_,
are private implementation details. Do not rely on them. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed. */
#ifndef YY_GRAM_SRC_PARSE_GRAM_H_INCLUDED
# define YY_GRAM_SRC_PARSE_GRAM_H_INCLUDED
@@ -79,7 +80,7 @@ extern int gram_debug;
{
GRAM_EMPTY = -2,
GRAM_EOF = 0, /* "end of file" */
GRAM_ERRCODE = 1, /* error */
GRAM_error = 1, /* error */
GRAM_UNDEF = 2, /* "invalid token" */
STRING = 3, /* "string" */
TSTRING = 4, /* "translatable string" */
+53 -32
View File
@@ -83,6 +83,23 @@ static boundary scanner_cursor;
unput (Msg[i - 1]); \
} while (0)
#define STRING_GROW_ESCAPE(Char) \
do { \
long c = Char; \
if (0 < c && c <= UCHAR_MAX) \
obstack_1grow (&obstack_for_string, c); \
else \
{ \
complain (loc, complaint, \
_("invalid number after \\-escape: %s"), \
yytext + 1); \
/* Avoid additional errors about empty char literal. */ \
obstack_1grow (&obstack_for_string, '?'); \
} \
} while (0)
/* The current file name. Might change with #line. */
static uniqstr current_file = NULL;
@@ -290,6 +307,7 @@ eqopt ({sp}=)?
"%"{id} {
complain (loc, complaint, _("invalid directive: %s"), quote (yytext));
return GRAM_error;
}
":" return COLON;
@@ -311,6 +329,7 @@ eqopt ({sp}=)?
accept "1FOO" as "1 FOO". */
{int}{id} {
complain (loc, complaint, _("invalid identifier: %s"), quote (yytext));
return GRAM_error;
}
/* Characters. */
@@ -361,10 +380,11 @@ eqopt ({sp}=)?
BEGIN SC_BRACKETED_ID;
}
[^\[%A-Za-z0-9_<>{}\"\'*;|=/, \f\r\n\t\v]+|. {
[^\[%A-Za-z0-9_<>{}""''*;|=/, \f\r\n\t\v]+|. {
complain (loc, complaint, "%s: %s",
ngettext ("invalid character", "invalid characters", yyleng),
quote_mem (yytext, yyleng));
return GRAM_error;
}
<<EOF>> {
@@ -381,7 +401,11 @@ eqopt ({sp}=)?
<SC_ESCAPED_CHARACTER,SC_ESCAPED_STRING,SC_ESCAPED_TSTRING,SC_TAG>
{
\0 complain (loc, complaint, _("invalid null character"));
\0 {
complain (loc, complaint, _("invalid null character"));
STRING_FREE;
return GRAM_error;
}
}
@@ -437,6 +461,7 @@ eqopt ({sp}=)?
complain (loc, complaint,
_("unexpected identifier in bracketed name: %s"),
quote (yytext));
return GRAM_error;
}
else
{
@@ -457,7 +482,10 @@ eqopt ({sp}=)?
}
}
else
complain (loc, complaint, _("an identifier expected"));
{
complain (loc, complaint, _("an identifier expected"));
return GRAM_error;
}
}
[^\].A-Za-z0-9_/ \f\r\n\t\v]+|. {
@@ -465,6 +493,7 @@ eqopt ({sp}=)?
ngettext ("invalid character in bracketed name",
"invalid characters in bracketed name", yyleng),
quote_mem (yytext, yyleng));
return GRAM_error;
}
<<EOF>> {
@@ -563,22 +592,27 @@ eqopt ({sp}=)?
{
"'" {
STRING_FINISH;
BEGIN INITIAL;
loc->start = token_start;
val->CHAR = last_string[0];
/* FIXME: Eventually, make these errors. */
if (last_string[0] == '\0')
{
complain (loc, Wother, _("empty character literal"));
/* '\0' seems dangerous even if we are about to complain. */
val->CHAR = '\'';
}
{
complain (loc, complaint, _("empty character literal"));
STRING_FREE;
return GRAM_error;
}
else if (last_string[1] != '\0')
complain (loc, Wother,
_("extra characters in character literal"));
STRING_FREE;
BEGIN INITIAL;
return CHAR;
{
complain (loc, complaint, _("extra characters in character literal"));
STRING_FREE;
return GRAM_error;
}
else
{
STRING_FREE;
return CHAR;
}
}
{eol} unexpected_newline (token_start, "'");
<<EOF>> unexpected_eof (token_start, "'");
@@ -620,22 +654,12 @@ eqopt ({sp}=)?
{
\\[0-7]{1,3} {
verify (UCHAR_MAX < ULONG_MAX);
long c = strtol (yytext + 1, NULL, 8);
if (0 < c && c <= UCHAR_MAX)
obstack_1grow (&obstack_for_string, c);
else
complain (loc, complaint, _("invalid number after \\-escape: %s"),
yytext+1);
STRING_GROW_ESCAPE (strtol (yytext + 1, NULL, 8));
}
\\x[0-9abcdefABCDEF]+ {
verify (UCHAR_MAX < ULONG_MAX);
long c = strtol (yytext + 2, NULL, 16);
if (0 < c && c <= UCHAR_MAX)
obstack_1grow (&obstack_for_string, c);
else
complain (loc, complaint, _("invalid number after \\-escape: %s"),
yytext+1);
STRING_GROW_ESCAPE (strtol (yytext + 2, NULL, 16));
}
\\a obstack_1grow (&obstack_for_string, '\a');
@@ -650,13 +674,9 @@ eqopt ({sp}=)?
\\("\""|"'"|"?"|"\\") obstack_1grow (&obstack_for_string, yytext[1]);
\\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {
int c = convert_ucn_to_byte (yytext);
if (c <= 0)
complain (loc, complaint, _("invalid number after \\-escape: %s"),
yytext+1);
else
obstack_1grow (&obstack_for_string, c);
STRING_GROW_ESCAPE (convert_ucn_to_byte (yytext));
}
\\(.|{eol}) {
char const *p = yytext + 1;
/* Quote only if escaping won't make the character visible. */
@@ -666,6 +686,7 @@ eqopt ({sp}=)?
p = quotearg_style_mem (escape_quoting_style, p, 1);
complain (loc, complaint, _("invalid character after \\-escape: %s"),
p);
obstack_1grow (&obstack_for_string, '?');
}
}
+1 -1
View File
@@ -84,7 +84,7 @@ static void fail_for_invalid_at (char const *at);
"@output(" at_init (&argc, argv, &at_ptr, &at_output);
/* This pattern must not match more than the previous @ patterns. */
@[^@{}\'(\n]* fail_for_invalid_at (yytext);
@[^@{}''(\n]* fail_for_invalid_at (yytext);
\n out_lineno++; ECHO;
[^@\n]+ ECHO;
+29 -2
View File
@@ -847,8 +847,8 @@ symbols_new (void)
accept->content->class = nterm_sym;
accept->content->number = nvars++;
/* Construct the YYERRCODE/"error" token */
errtoken = symbol_get ("YYERRCODE", empty_loc);
/* Construct the YYerror/"error" token */
errtoken = symbol_get ("YYerror", empty_loc);
errtoken->content->class = token_sym;
errtoken->content->number = ntokens++;
{
@@ -1095,6 +1095,21 @@ symbols_token_translations_init (void)
}
/* Whether some symbol requires internationalization. */
static bool
has_translations (void)
{
for (const void *entry = hash_get_first (symbol_table);
entry;
entry = hash_get_next (symbol_table, entry))
{
const symbol *sym = (const symbol *) entry;
if (sym->translatable)
return true;
}
return false;
}
/*----------------------------------------------------------------.
| Assign symbol numbers, and write definition of token names into |
| FDEFINES. Set up vectors SYMBOL_TABLE, TAGS of symbols. |
@@ -1137,6 +1152,18 @@ symbols_pack (void)
complain (&startsymbol_loc, fatal,
_("the start symbol %s is a token"),
startsymbol->tag);
// If some user tokens are internationalized, the internal ones
// should be too.
if (has_translations ())
{
const bool eof_is_user_defined
= !endtoken->alias || STRNEQ (endtoken->alias->tag, "$end");
if (!eof_is_user_defined)
endtoken->alias->translatable = true;
undeftoken->alias->translatable = true;
errtoken->alias->translatable = true;
}
}
/*---------------------------------.
+58 -9
View File
@@ -201,8 +201,8 @@ read_integer (]AT_YYLEX_FORMALS[)
/* Skip white spaces. */
do
{
]AT_LOCATION_IF(
[ AT_LOC_FIRST_COLUMN = AT_LOC_LAST_COLUMN;
]AT_LOCATION_IF([
AT_LOC_FIRST_COLUMN = AT_LOC_LAST_COLUMN;
AT_LOC_FIRST_LINE = AT_LOC_LAST_LINE;
])[
}
@@ -220,6 +220,15 @@ read_integer (]AT_YYLEX_FORMALS[)
if (c == EOF)
return ]AT_TOKEN_PREFIX[CALC_EOF;
/* An explicit error raised by the scanner. */
if (c == '#')
{]AT_LOCATION_IF([
fprintf (stderr, "%d.%d: ",
AT_LOC_FIRST_LINE, AT_LOC_FIRST_COLUMN);])[
fputs ("syntax error: invalid character: '#'\n", stderr);
return ]AT_TOKEN_PREFIX[]AT_API_PREFIX[error;
}
/* Return single chars. */
return c;
}
@@ -304,7 +313,7 @@ class CalcLexer(R) : Lexer
location.end.column += 1;]])[
}
// Handle EOF.
// EOF.
if (input.empty)
return TokenKind.CALC_EOF;
@@ -325,6 +334,14 @@ class CalcLexer(R) : Lexer
else
location.end.column += 1;]])[
input.popFront;
// An explicit error raised by the scanner. */
if (c == '#')
{
stderr.writeln (]AT_LOCATION_IF([location, ": ", ])["syntax error: invalid character: '#'");
return TokenKind.YYerror;
}
return c;
}
}
@@ -370,12 +387,12 @@ m4_define([AT_CALC_YYLEX(java)],
public int yylex () throws IOException {;]AT_LOCATION_IF([[
start.set (reader.getPosition ());]])[
int ttype = st.nextToken ();]AT_LOCATION_IF([[
int tkind = st.nextToken ();]AT_LOCATION_IF([[
end.set (reader.getPosition ());]])[
switch (ttype)
switch (tkind)
{
case StreamTokenizer.TT_EOF:
return EOF;
return CALC_EOF;
case StreamTokenizer.TT_EOL:;]AT_LOCATION_IF([[
end.line += 1;
end.column = 0;]])[
@@ -386,8 +403,11 @@ m4_define([AT_CALC_YYLEX(java)],
return NUM;
case ' ': case '\t':
return yylex ();
case '#':
System.err.println(]AT_LOCATION_IF([[start + ": " + ]])["syntax error: invalid character: '#'");
return YYerror;
default:
return ttype;
return tkind;
}
}
]AT_LEXPARAM_IF([], [[}]])[
@@ -763,8 +783,8 @@ AT_JAVA_IF(
[AT_PARSER_CHECK([calc input], 0, [AT_PARAM_IF([m4_n([$3])])], [stderr])])
AT_LANG_MATCH([c\|c++\|java],
[AT_GLR_IF([],
[AT_CHECK([grep -v 'Return for a new token:' stderr | wc -l],
[0],
[AT_CHECK([grep -c -v 'Return for a new token:' stderr],
[ignore],
[m4_n([AT_DEBUG_IF([$4], [0])])])])])
])
@@ -1004,6 +1024,35 @@ _AT_CHECK_CALC_ERROR([$1], [0], [(* *) + (*) + (*)],
]AT_JAVA_IF([1.10-1.11], [1.10])[: syntax error on token ['*'] (expected: [number] ['-'] ['('] ['!'])
]AT_JAVA_IF([1.16-1.17], [1.16])[: syntax error on token ['*'] (expected: [number] ['-'] ['('] ['!'])]])
# YYerror.
# --------
# Check that returning YYerror from the scanner properly enters
# error-recovery without issuing a second error message.
_AT_CHECK_CALC_ERROR([$1], [0], [(#) + (#) = 2222],
[[final: 2222 0 0]],
[102],
[[1.2: syntax error: invalid character: '#'
1.8: syntax error: invalid character: '#']])
_AT_CHECK_CALC_ERROR([$1], [0], [(1 + #) = 1111],
[[final: 1111 0 0]],
[102],
[[1.6: syntax error: invalid character: '#']])
_AT_CHECK_CALC_ERROR([$1], [0], [(# + 1) = 1111],
[[final: 1111 0 0]],
[102],
[[1.2: syntax error: invalid character: '#']])
_AT_CHECK_CALC_ERROR([$1], [0], [(1 + # + 1) = 1111],
[[final: 1111 0 0]],
[102],
[[1.6: syntax error: invalid character: '#']])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
+1 -1
View File
@@ -323,7 +323,7 @@ AT_PERL_CHECK([[-n -0777 -e '
|YYChar
|YYNTOKENS # This is actual scoped in a C++ class.
|YYPUSH_MORE(?:_DEFINED)?
|S_(YY(ACCEPT|EMPTY|EOF|ERROR|UNDEF)) # These guys are scoped.
|S_(YY(ACCEPT|EMPTY|EOF|error|UNDEF)) # These guys are scoped.
|YYUSE
|YY_ATTRIBUTE(?:_PURE|_UNUSED)
|YY(?:_REINTERPRET)?_CAST
+12 -23
View File
@@ -102,7 +102,6 @@ input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
input.y:7.1: error: invalid character: '%'
input.y:7.2: error: invalid character: '-'
input.y:8.1-9.0: error: missing '%}' at end of file
input.y:8.1-9.0: error: unexpected %{...%}
]])
AT_CLEANUP
@@ -343,9 +342,9 @@ exp:
%%
int main (void)
{
assert (YYERRCODE == 123);
assert (YYerror == 123);
assert (YYTRANSLATE (YYEOF) == YYSYMBOL_YYEOF);
assert (YYTRANSLATE (YYERRCODE) == YYSYMBOL_YYERROR);
assert (YYTRANSLATE (YYerror) == YYSYMBOL_YYerror);
assert (YYTRANSLATE (YYUNDEF) == YYSYMBOL_YYUNDEF);
return 0;
}
@@ -432,7 +431,7 @@ AT_BISON_CHECK([-Wno-other -S./dump-symbols.m4 input.y])
AT_CHECK([cat symbols.csv], [],
[[number, class, tag, id, user_number, type,
0, Token, "end of file", YYEOF, 0, ,
1, Token, error, YYERRCODE, 256, ,
1, Token, error, YYerror, 256, ,
2, Token, "invalid token", YYUNDEF, 257, ,
3, Token, 'a', , 97, ,
4, Token, "A1", A1, 1, ,
@@ -2339,19 +2338,19 @@ start: '
start: ']])
AT_BISON_CHECK([-fcaret empty.y], [1], [],
[[empty.y:2.8-9: warning: empty character literal [-Wother]
[[empty.y:2.8-9: error: empty character literal
2 | start: '';
| ^~
empty.y:3.8-4.0: error: missing "'" at end of line
3 | start: '
| ^
empty.y:3.8-4.0: warning: empty character literal [-Wother]
empty.y:3.8-4.0: error: empty character literal
3 | start: '
| ^
empty.y:4.8: error: missing "'" at end of file
4 | start: '
| ^
empty.y:4.8: warning: empty character literal [-Wother]
empty.y:4.8: error: empty character literal
4 | start: '
| ^
]])
@@ -2363,11 +2362,11 @@ start: 'ab
start: 'ab]])
AT_BISON_CHECK([two.y], [1], [],
[[two.y:2.8-11: warning: extra characters in character literal [-Wother]
[[two.y:2.8-11: error: extra characters in character literal
two.y:3.8-4.0: error: missing "'" at end of line
two.y:3.8-4.0: warning: extra characters in character literal [-Wother]
two.y:3.8-4.0: error: extra characters in character literal
two.y:4.8-10: error: missing "'" at end of file
two.y:4.8-10: warning: extra characters in character literal [-Wother]
two.y:4.8-10: error: extra characters in character literal
]])
AT_DATA_NO_FINAL_EOL([three.y],
@@ -2377,11 +2376,11 @@ start: 'abc
start: 'abc]])
AT_BISON_CHECK([three.y], [1], [],
[[three.y:2.8-12: warning: extra characters in character literal [-Wother]
[[three.y:2.8-12: error: extra characters in character literal
three.y:3.8-4.0: error: missing "'" at end of line
three.y:3.8-4.0: warning: extra characters in character literal [-Wother]
three.y:3.8-4.0: error: extra characters in character literal
three.y:4.8-11: error: missing "'" at end of file
three.y:4.8-11: warning: extra characters in character literal [-Wother]
three.y:4.8-11: error: extra characters in character literal
]])
AT_CLEANUP
@@ -2408,25 +2407,15 @@ AT_PERL_REQUIRE([[-e 'print "start: \"\\\t\\\f\\\0\\\1\" ;";' >> input.y]])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:2.9-12: error: invalid number after \-escape: 777
input.y:2.8-13: warning: empty character literal [-Wother]
input.y:2.16-17: error: invalid number after \-escape: 0
input.y:2.15-18: warning: empty character literal [-Wother]
input.y:2.21-25: error: invalid number after \-escape: xfff
input.y:2.20-26: warning: empty character literal [-Wother]
input.y:2.29-31: error: invalid number after \-escape: x0
input.y:2.28-32: warning: empty character literal [-Wother]
input.y:3.9-14: error: invalid number after \-escape: uffff
input.y:3.8-15: warning: empty character literal [-Wother]
input.y:3.18-23: error: invalid number after \-escape: u0000
input.y:3.17-24: warning: empty character literal [-Wother]
input.y:3.27-36: error: invalid number after \-escape: Uffffffff
input.y:3.26-37: warning: empty character literal [-Wother]
input.y:3.40-49: error: invalid number after \-escape: U00000000
input.y:3.39-50: warning: empty character literal [-Wother]
input.y:4.9-10: error: invalid character after \-escape: ' '
input.y:4.8-11: warning: empty character literal [-Wother]
input.y:4.14-15: error: invalid character after \-escape: A
input.y:4.13-16: warning: empty character literal [-Wother]
input.y:5.9-16: error: invalid character after \-escape: \t
input.y:5.17: error: invalid character after \-escape: \f
input.y:5.18: error: invalid character after \-escape: \0
+1 -1
View File
@@ -1601,7 +1601,7 @@ $9
# (C90 and C++98) guarantee: 32767. In that case, GCC's -pedantic
# will issue an error.
#
# There is no "" around `wc` since some indent the result.
# There is no "" around `wc` since some wc indent the result.
m4_bmatch([$4], [%define lr.type canonical-lr],
[if test 32767 -lt `wc -l < input.c`; then
CFLAGS=`echo " $CFLAGS " | sed -e 's/ -pedantic / /'`