Compare commits

...
21 Commits
Author SHA1 Message Date
Akim Demaille 307fcdee00 version 3.6
* NEWS: Record release date.
2020-05-08 09:57:14 +02:00
Akim Demaille d26d10ad6c examples: beware of portability issue on Windows
Reported by Jannick.
https://lists.gnu.org/r/bug-bison/2020-05/msg00040.html
https://lists.gnu.org/r/bug-bison/2020-05/msg00066.html

* examples/test (diff_opts): Use --strip-trailing-cr if supported, to
avoid \n vs. \r\n issues.
* examples/c/bistromathic/bistromathic.test: When on MSYS, don't try
to check autocompletion.
2020-05-08 09:45:29 +02:00
Akim Demaille 1b4108da3e regen 2020-05-08 09:45:29 +02:00
Akim Demaille 53bfc7df94 doc: fix the generation of the man page
When there is no bison.1 at all, the procedure fails.

* doc/local.mk (bison.1): Be robust to cold starts.
2020-05-08 09:02:45 +02:00
Akim Demaille a5fb4a88ef news: prepare for 3.6 2020-05-08 07:34:30 +02:00
Akim Demaille 54df196d49 doc: complete the table of symbols
* doc/bison.texi: Add YYEMPTY, YYEOF and YYUNDEF.
2020-05-08 07:34:30 +02:00
Akim Demaille 52bb6f0525 doc: clarify the glossary item about kinds
* doc/bison.texi (Glossary): here.
2020-05-07 08:38:58 +02:00
Akim Demaille 76dab18af3 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2020-05-06 08:48:05 +02:00
Akim Demaille c982974f33 version 3.5.94
* NEWS: Record release date.
2020-05-06 08:28:36 +02:00
Akim Demaille dc2a3578b7 doc: document yypstate_expected_tokens
* doc/bison.texi (Push Parser Interface): Here.
2020-05-06 08:11:52 +02:00
Akim Demaille 9661b2fcbc doc: restructure the push parser documentation
I don't think it's fair to have yypstate_new, yypstate_delete,
yypush_parse and yypull_parse to have their own section, on par with
yyparse and yylex.  Let them be in a single section about push
parsers.  And show new/delete first.

* doc/bison.texi (Push Parser Interface): New.
Fuse the aforementioned sections into it.
2020-05-06 08:11:52 +02:00
Akim DemailleandAkim Demaille d9a9b054ae all: fix the interface of yyexpected_tokens
The user gives yyexpected_tokens a limit: the max number of tokens she
wants to hear about.  That's because an error message that reports a
bazillion of possible tokens is useless.

In that case yyexpected_tokens returned 0, so the user would not know
if there are too many expected tokens or none (yes, that's possible).

There are several ways to tell the user in which situation she's in:

- return some E2MANY, a negative value.  Then it makes the pattern

    int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
    if (argsize < 0)
      return argsize;

  no longer valid, as for E2MANY (i) the user must generate the error
  message anyway, and (ii) she should not return E2MANY

- return ARGS_MAX + 1.  Then it makes it dangerous for the user, as
  she has to iterate update `min (ARGS_MAX, argsize)`.

Returning 0 is definitely simpler and safer for the user, as it tells
her "this is not an error, just generate your message without a list
of expecting tokens".  So let's still return 0, but set arg[0] to the
empty token when the list is really empty.

* data/skeletons/glr.c, data/skeletons/lalr1.cc, data/skeletons/lalr1.java
* data/skeletons/yacc.c (yyexpected_tokens): Put the empty symbol
first if there are no possible tokens at all.
* examples/c/bistromathic/parse.y: Demonstrate how to use that.
2020-05-06 08:11:52 +02:00
Akim Demaille cb9f4cb543 examples: fix handling of syntax errors
The shell grammar does not allow empty statements in then/else part of
an if, but examples/test failed to catch the syntax errors from the
script it ran.  So exited with success anyway.

You would expect 'set -e' to suffice, but with bash 3.2 actually it
does not.  As a matter of fact, I could find a way to have this behave
properly:

    $ cat test.sh
    set -e
    cleanup ()
    {
      status=$?
      echo "cleanup: $status"
      exit $status
    }
    trap cleanup 0 1 2 13 15
    . $1
    s=$?
    echo "test.sh: $s"
    exit $s

    $ cat bistro.test
    if true; then
    fi

    $ /bin/sh ./test.sh ./bistro.test
    ./bistro.test: line 2: syntax error near unexpected token `fi'
    cleanup: 0
    $ echo $?
    0

Remove the set -e (or the trap), and tada, it works...  So we have to
deal with the error by hand.

* examples/test ($exit): Replace with...
($status): this.
Preserve the exit status of the test case.
* examples/c/bistromathic/bistromathic.test: Fix syntax error.
2020-05-05 08:21:12 +02:00
Akim Demaille b86dcaf40b doc: beware of timestamp issues on Haiku
On Haiku, help2man is fired on a freshly extracted tarball.
Reported by Bruno Haible.
https://lists.gnu.org/r/bug-bison/2020-05/msg00055.html

* doc/local.mk (bison.1): Be robust to a missing help2man.
2020-05-04 19:06:59 +02:00
Akim Demaille 0fafbbdefb tests: beware of wchar_t portability issues on AIX
https://lists.gnu.org/r/bug-bison/2020-05/msg00050.html
Reported by Bruno Haible.

* tests/diagnostics.at: here.
2020-05-04 08:09:22 +02:00
Akim Demaille 4b85b969d0 glr.c: beware of portability issues with PTRDIFF_MAX
For instance test 386, "glr.cc api.value.type={double}":

    types.at:366: $CXX $CXXFLAGS $CPPFLAGS  $LDFLAGS -o test test.cc $LIBS
    stderr:
    test.cc: In function 'ptrdiff_t yysplitStack(yyGLRStack*, ptrdiff_t)':
    test.cc:490:4: error: 'PTRDIFF_MAX' was not declared in this scope
       (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : YY_CAST (ptrdiff_t, SIZE_MAX))
        ^
    test.cc:1805:37: note: in expansion of macro 'YYSIZEMAX'
           ptrdiff_t half_max_capacity = YYSIZEMAX / 2 / state_size;
                                         ^~~~~~~~~
    test.cc:490:4: note: suggested alternative: '__PTRDIFF_MAX__'
       (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : YY_CAST (ptrdiff_t, SIZE_MAX))
        ^
    test.cc:1805:37: note: in expansion of macro 'YYSIZEMAX'
           ptrdiff_t half_max_capacity = YYSIZEMAX / 2 / state_size;
                                         ^~~~~~~~~

The failing tests are using glr.cc only, which I don't understand, the
problem is rather in glr.c, so I would expect glr.c tests to also fail.

Reported by Bruno Haible.
https://lists.gnu.org/archive/html/bug-bison/2020-05/msg00053.html

* data/skeletons/yacc.c: Move the block that defines
YYPTRDIFF_T/YYPTRDIFF_MAXIMUM, YYSIZE_T/YYSIZE_MAXIMUM, and
YYSIZEOF to...
* data/skeletons/c.m4 (b4_sizes_types_define): Here.
(b4_c99_int_type): Also take care of the #undefinition of short.
* data/skeletons/yacc.c, data/skeletons/glr.c: Use
b4_sizes_types_define.
* data/skeletons/glr.c: Adjust to use YYPTRDIFF_T/YYPTRDIFF_MAXIMUM,
YYSIZE_T/YYSIZE_MAXIMUM.
2020-05-04 07:44:42 +02:00
Akim Demaille 7727693711 todo: update 2020-05-04 07:37:40 +02:00
Akim Demaille ce27796b74 examples: beware of strnlen portability issues
One function missing on Solaris 10 Sparc:

     CCLD     examples/c/bistromathic/bistromathic
    Undefined                       first referenced
    symbol                             in file
    strnlen                             examples/c/bistromathic/bistromathic-parse.o
    ld: fatal: symbol referencing errors. No output written to examples/c/bistromathic/bistromathic

Reported by Dagobert Michelsen.
https://lists.gnu.org/r/bug-bison/2020-05/msg00048.html

* examples/c/bistromathic/parse.y (xstrndup): Don't use strnlen.
xstrndup is assembled from gnulib's xstrndup, strndup and strnlen...
2020-05-04 06:48:00 +02:00
Akim Demaille 6135fdc152 examples: beware of portability issues with sh's trap
On AIX 7.2, when invoking "exit 77", we actually exit with 127.  The
"cleanup" function, called via trap, received an incorrect exit
status, something described in Autoconf's doc.
Reported by Bruno Haible.
https://lists.gnu.org/archive/html/bug-bison/2020-05/msg00029.html
https://lists.gnu.org/archive/html/bug-bison/2020-05/msg00047.html

* examples/test (skip): New.
* examples/c/bistromathic/bistromathic.test,
* examples/c/reccalc/reccalc.test: Use it, to ensure $? is set to 77
when the trap is called.
2020-05-04 06:48:00 +02:00
Akim Demaille f1497356e8 tests: beware of portability issues with diff -u
AIX 7.1 supports diff -u, but its output does not match the expected
one.
Reported by Bruno Haible.
https://lists.gnu.org/r/bug-bison/2020-05/msg00049.html

* tests/atlocal.in (DIFF_U_WORKS): New.
* tests/local.at (AT_DIFF_U_CHECK): New.
* tests/existing.at (_AT_TEST_EXISTING_GRAMMAR): Use AT_DIFF_U_CHECK.
2020-05-04 06:48:00 +02:00
Akim Demaille 1429569362 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2020-05-03 19:52:38 +02:00
20 changed files with 368 additions and 242 deletions
+1 -1
View File
@@ -1 +1 @@
3.5.92 3.5.94
+13 -34
View File
@@ -1,39 +1,6 @@
GNU Bison NEWS GNU Bison NEWS
* Noteworthy changes in release 3.5.93 (2020-05-03) [beta] * Noteworthy changes in release 3.6 (2020-05-08) [stable]
Portability issues.
* Noteworthy changes in release 3.5.92 (2020-05-03) [beta]
Portability issues.
More documentation.
Backward compatibility issues with C++.
* 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 ** Backward incompatible changes
@@ -138,6 +105,18 @@ GNU Bison NEWS
It makes little sense to use this feature without enabling LAC (lookahead It makes little sense to use this feature without enabling LAC (lookahead
correction). correction).
*** 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.
*** Deep overhaul of the symbol and token kinds *** Deep overhaul of the symbol and token kinds
To avoid the confusion with types in programming languages, we now refer To avoid the confusion with types in programming languages, we now refer
+7 -4
View File
@@ -1,4 +1,7 @@
* Bison 3.6 * Bison 3.6
** Doc
*** api.header.include
** Questions ** Questions
*** Java *** Java
- Should i18n be part of the Lexer? Currently it's a static method of - Should i18n be part of the Lexer? Currently it's a static method of
@@ -192,10 +195,10 @@ define it to the same type as the C ptrdiff_t type.
* Completion * Completion
Several features are not available in all the backends. Several features are not available in all the backends.
- push parsers: glr.c, glr.cc, lalr1.cc - lac: D, Java (easy)
- lac: D, Java - push parsers: glr.c, glr.cc, lalr1.cc (not very difficult)
- glr: D, Java - token constructors: Java, C, D (a bit difficult)
- token constructors: Java, C, D - glr: D, Java (super difficult)
* Bugs * Bugs
** Autotest has quotation issues ** Autotest has quotation issues
+49 -1
View File
@@ -205,7 +205,11 @@ m4_define([b4_c99_int_type],
# Define private types suitable for holding small integers in C99 or later. # Define private types suitable for holding small integers in C99 or later.
m4_define([b4_c99_int_type_define], m4_define([b4_c99_int_type_define],
[m4_copy_force([b4_c99_int_type], [b4_int_type])dnl [m4_copy_force([b4_c99_int_type], [b4_int_type])dnl
[/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure [#ifdef short
# undef short
#endif
/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
<limits.h> and (if available) <stdint.h> are included <limits.h> and (if available) <stdint.h> are included
so that the code can choose integer types of a good width. */ so that the code can choose integer types of a good width. */
@@ -261,6 +265,50 @@ typedef int yytype_uint16;
#endif]]) #endif]])
# b4_sizes_types_define
# ---------------------
# Define YYPTRDIFF_T/YYPTRDIFF_MAXIMUM, YYSIZE_T/YYSIZE_MAXIMUM,
# and YYSIZEOF.
m4_define([b4_sizes_types_define],
[[#ifndef YYPTRDIFF_T
# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
# define YYPTRDIFF_T __PTRDIFF_TYPE__
# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
# elif defined PTRDIFF_MAX
# ifndef ptrdiff_t
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# endif
# define YYPTRDIFF_T ptrdiff_t
# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
# else
# define YYPTRDIFF_T long
# define YYPTRDIFF_MAXIMUM LONG_MAX
# endif
#endif
#ifndef YYSIZE_T
# ifdef __SIZE_TYPE__
# define YYSIZE_T __SIZE_TYPE__
# elif defined size_t
# define YYSIZE_T size_t
# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
# define YYSIZE_T unsigned
# endif
#endif
#define YYSIZE_MAXIMUM \
YY_CAST (YYPTRDIFF_T, \
(YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
? YYPTRDIFF_MAXIMUM \
: YY_CAST (YYSIZE_T, -1)))
#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
]])
# b4_int_type_for(NAME) # b4_int_type_for(NAME)
# --------------------- # ---------------------
# Return a narrow int type able to handle numbers ranging from # Return a narrow int type able to handle numbers ranging from
+52 -52
View File
@@ -249,6 +249,7 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
#include <string.h> #include <string.h>
]b4_c99_int_type_define[ ]b4_c99_int_type_define[
]b4_sizes_types_define[
#ifndef YY_ #ifndef YY_
# if defined YYENABLE_NLS && YYENABLE_NLS # if defined YYENABLE_NLS && YYENABLE_NLS
@@ -277,9 +278,6 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
# define YYREALLOC realloc # define YYREALLOC realloc
#endif #endif
#define YYSIZEMAX \
(PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : YY_CAST (ptrdiff_t, SIZE_MAX))
#ifdef __cplusplus #ifdef __cplusplus
typedef bool yybool; typedef bool yybool;
# define yytrue true # define yytrue true
@@ -507,7 +505,7 @@ struct yyGLRState {
/** Preceding state in this stack */ /** Preceding state in this stack */
yyGLRState* yypred; yyGLRState* yypred;
/** Source position of the last token produced by my symbol */ /** Source position of the last token produced by my symbol */
ptrdiff_t yyposn; YYPTRDIFF_T yyposn;
union { union {
/** First in a chain of alternative reductions producing the /** First in a chain of alternative reductions producing the
* nonterminal corresponding to this state, threaded through * nonterminal corresponding to this state, threaded through
@@ -527,8 +525,8 @@ struct yyGLRStateSet {
* operation, yylookaheadNeeds[0] is not maintained since it would merely * operation, yylookaheadNeeds[0] is not maintained since it would merely
* duplicate yychar != ]b4_symbol(-2, id)[. */ * duplicate yychar != ]b4_symbol(-2, id)[. */
yybool* yylookaheadNeeds; yybool* yylookaheadNeeds;
ptrdiff_t yysize; YYPTRDIFF_T yysize;
ptrdiff_t yycapacity; YYPTRDIFF_T yycapacity;
}; };
struct yySemanticOption { struct yySemanticOption {
@@ -568,7 +566,7 @@ struct yyGLRStack {
YYJMP_BUF yyexception_buffer; YYJMP_BUF yyexception_buffer;
yyGLRStackItem* yyitems; yyGLRStackItem* yyitems;
yyGLRStackItem* yynextFree; yyGLRStackItem* yynextFree;
ptrdiff_t yyspaceLeft; YYPTRDIFF_T yyspaceLeft;
yyGLRState* yysplitPoint; yyGLRState* yysplitPoint;
yyGLRState* yylastDeleted; yyGLRState* yylastDeleted;
yyGLRStateSet yytops; yyGLRStateSet yytops;
@@ -680,7 +678,7 @@ yysymbol_name (yysymbol_kind_t yysymbol)
multiple parsers can coexist. */ multiple parsers can coexist. */
int yydebug; int yydebug;
static void yypstack (yyGLRStack* yystackp, ptrdiff_t yyk) static void yypstack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
YY_ATTRIBUTE_UNUSED; YY_ATTRIBUTE_UNUSED;
static void yypdumpstack (yyGLRStack* yystackp) static void yypdumpstack (yyGLRStack* yystackp)
YY_ATTRIBUTE_UNUSED; YY_ATTRIBUTE_UNUSED;
@@ -696,7 +694,7 @@ static void yypdumpstack (yyGLRStack* yystackp)
[simple], [simple],
[[]], [[]],
[[#ifndef yystrlen [[#ifndef yystrlen
# define yystrlen(S) (YY_CAST (ptrdiff_t, strlen (S))) # define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))
#endif #endif
]b4_parse_error_bmatch( ]b4_parse_error_bmatch(
@@ -731,12 +729,12 @@ yystpcpy (char *yydest, const char *yysrc)
backslash-backslash). YYSTR is taken from yytname. If YYRES is backslash-backslash). YYSTR is taken from yytname. If YYRES is
null, do not copy; instead, return the length of what the result null, do not copy; instead, return the length of what the result
would have been. */ would have been. */
static ptrdiff_t static YYPTRDIFF_T
yytnamerr (char *yyres, const char *yystr) yytnamerr (char *yyres, const char *yystr)
{ {
if (*yystr == '"') if (*yystr == '"')
{ {
ptrdiff_t yyn = 0; YYPTRDIFF_T yyn = 0;
char const *yyp = yystr; char const *yyp = yystr;
for (;;) for (;;)
@@ -1104,7 +1102,7 @@ yynewGLRStackItem (yyGLRStack* yystackp, yybool yyisState)
* alternative actions for YYSTATE. Assumes that YYRHS comes from * alternative actions for YYSTATE. Assumes that YYRHS comes from
* stack #YYK of *YYSTACKP. */ * stack #YYK of *YYSTACKP. */
static void static void
yyaddDeferredAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyGLRState* yystate, yyaddDeferredAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyGLRState* yystate,
yyGLRState* yyrhs, yyRuleNum yyrule) yyGLRState* yyrhs, yyRuleNum yyrule)
{ {
yySemanticOption* yynewOption = yySemanticOption* yynewOption =
@@ -1136,14 +1134,14 @@ yyinitStateSet (yyGLRStateSet* yyset)
yyset->yycapacity = 16; yyset->yycapacity = 16;
yyset->yystates yyset->yystates
= YY_CAST (yyGLRState**, = YY_CAST (yyGLRState**,
YYMALLOC (YY_CAST (size_t, yyset->yycapacity) YYMALLOC (YY_CAST (YYSIZE_T, yyset->yycapacity)
* sizeof yyset->yystates[0])); * sizeof yyset->yystates[0]));
if (! yyset->yystates) if (! yyset->yystates)
return yyfalse; return yyfalse;
yyset->yystates[0] = YY_NULLPTR; yyset->yystates[0] = YY_NULLPTR;
yyset->yylookaheadNeeds yyset->yylookaheadNeeds
= YY_CAST (yybool*, = YY_CAST (yybool*,
YYMALLOC (YY_CAST (size_t, yyset->yycapacity) YYMALLOC (YY_CAST (YYSIZE_T, yyset->yycapacity)
* sizeof yyset->yylookaheadNeeds[0])); * sizeof yyset->yylookaheadNeeds[0]));
if (! yyset->yylookaheadNeeds) if (! yyset->yylookaheadNeeds)
{ {
@@ -1152,7 +1150,7 @@ yyinitStateSet (yyGLRStateSet* yyset)
} }
memset (yyset->yylookaheadNeeds, memset (yyset->yylookaheadNeeds,
0, 0,
YY_CAST (size_t, yyset->yycapacity) * sizeof yyset->yylookaheadNeeds[0]); YY_CAST (YYSIZE_T, yyset->yycapacity) * sizeof yyset->yylookaheadNeeds[0]);
return yytrue; return yytrue;
} }
@@ -1165,14 +1163,14 @@ static void yyfreeStateSet (yyGLRStateSet* yyset)
/** Initialize *YYSTACKP to a single empty stack, with total maximum /** Initialize *YYSTACKP to a single empty stack, with total maximum
* capacity for all stacks of YYSIZE. */ * capacity for all stacks of YYSIZE. */
static yybool static yybool
yyinitGLRStack (yyGLRStack* yystackp, ptrdiff_t yysize) yyinitGLRStack (yyGLRStack* yystackp, YYPTRDIFF_T yysize)
{ {
yystackp->yyerrState = 0; yystackp->yyerrState = 0;
yynerrs = 0; yynerrs = 0;
yystackp->yyspaceLeft = yysize; yystackp->yyspaceLeft = yysize;
yystackp->yyitems yystackp->yyitems
= YY_CAST (yyGLRStackItem*, = YY_CAST (yyGLRStackItem*,
YYMALLOC (YY_CAST (size_t, yysize) YYMALLOC (YY_CAST (YYSIZE_T, yysize)
* sizeof yystackp->yynextFree[0])); * sizeof yystackp->yynextFree[0]));
if (!yystackp->yyitems) if (!yystackp->yyitems)
return yyfalse; return yyfalse;
@@ -1198,9 +1196,9 @@ yyexpandGLRStack (yyGLRStack* yystackp)
{ {
yyGLRStackItem* yynewItems; yyGLRStackItem* yynewItems;
yyGLRStackItem* yyp0, *yyp1; yyGLRStackItem* yyp0, *yyp1;
ptrdiff_t yynewSize; YYPTRDIFF_T yynewSize;
ptrdiff_t yyn; YYPTRDIFF_T yyn;
ptrdiff_t yysize = yystackp->yynextFree - yystackp->yyitems; YYPTRDIFF_T yysize = yystackp->yynextFree - yystackp->yyitems;
if (YYMAXDEPTH - YYHEADROOM < yysize) if (YYMAXDEPTH - YYHEADROOM < yysize)
yyMemoryExhausted (yystackp); yyMemoryExhausted (yystackp);
yynewSize = 2*yysize; yynewSize = 2*yysize;
@@ -1208,7 +1206,7 @@ yyexpandGLRStack (yyGLRStack* yystackp)
yynewSize = YYMAXDEPTH; yynewSize = YYMAXDEPTH;
yynewItems yynewItems
= YY_CAST (yyGLRStackItem*, = YY_CAST (yyGLRStackItem*,
YYMALLOC (YY_CAST (size_t, yynewSize) YYMALLOC (YY_CAST (YYSIZE_T, yynewSize)
* sizeof yynewItems[0])); * sizeof yynewItems[0]));
if (! yynewItems) if (! yynewItems)
yyMemoryExhausted (yystackp); yyMemoryExhausted (yystackp);
@@ -1273,7 +1271,7 @@ yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
/** Invalidate stack #YYK in *YYSTACKP. */ /** Invalidate stack #YYK in *YYSTACKP. */
static inline void static inline void
yymarkStackDeleted (yyGLRStack* yystackp, ptrdiff_t yyk) yymarkStackDeleted (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
{ {
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR) if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
yystackp->yylastDeleted = yystackp->yytops.yystates[yyk]; yystackp->yylastDeleted = yystackp->yytops.yystates[yyk];
@@ -1297,7 +1295,7 @@ yyundeleteLastStack (yyGLRStack* yystackp)
static inline void static inline void
yyremoveDeletes (yyGLRStack* yystackp) yyremoveDeletes (yyGLRStack* yystackp)
{ {
ptrdiff_t yyi, yyj; YYPTRDIFF_T yyi, yyj;
yyi = yyj = 0; yyi = yyj = 0;
while (yyj < yystackp->yytops.yysize) while (yyj < yystackp->yytops.yysize)
{ {
@@ -1330,8 +1328,8 @@ yyremoveDeletes (yyGLRStack* yystackp)
* state YYLRSTATE, at input position YYPOSN, with (resolved) semantic * state YYLRSTATE, at input position YYPOSN, with (resolved) semantic
* value *YYVALP and source location *YYLOCP. */ * value *YYVALP and source location *YYLOCP. */
static inline void static inline void
yyglrShift (yyGLRStack* yystackp, ptrdiff_t yyk, yy_state_t yylrState, yyglrShift (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yy_state_t yylrState,
ptrdiff_t yyposn, YYPTRDIFF_T yyposn,
YYSTYPE* yyvalp]b4_locations_if([, YYLTYPE* yylocp])[) YYSTYPE* yyvalp]b4_locations_if([, YYLTYPE* yylocp])[)
{ {
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate; yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
@@ -1351,8 +1349,8 @@ yyglrShift (yyGLRStack* yystackp, ptrdiff_t yyk, yy_state_t yylrState,
* state YYLRSTATE, at input position YYPOSN, with the (unresolved) * state YYLRSTATE, at input position YYPOSN, with the (unresolved)
* semantic value of YYRHS under the action for YYRULE. */ * semantic value of YYRHS under the action for YYRULE. */
static inline void static inline void
yyglrShiftDefer (yyGLRStack* yystackp, ptrdiff_t yyk, yy_state_t yylrState, yyglrShiftDefer (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yy_state_t yylrState,
ptrdiff_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule) YYPTRDIFF_T yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
{ {
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate; yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
YY_ASSERT (yynewState->yyisState); YY_ASSERT (yynewState->yyisState);
@@ -1382,7 +1380,7 @@ yyglrShiftDefer (yyGLRStack* yystackp, ptrdiff_t yyk, yy_state_t yylrState,
`----------------------------------------------------------------------*/ `----------------------------------------------------------------------*/
static inline void static inline void
yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, ptrdiff_t yyk, yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, YYPTRDIFF_T yyk,
yyRuleNum yyrule]b4_user_formals[) yyRuleNum yyrule]b4_user_formals[)
{ {
int yynrhs = yyrhsLength (yyrule);]b4_locations_if([ int yynrhs = yyrhsLength (yyrule);]b4_locations_if([
@@ -1415,7 +1413,7 @@ yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, ptrdiff_t yyk,
* and *YYLOCP to the computed location (if any). Return value is as * and *YYLOCP to the computed location (if any). Return value is as
* for userAction. */ * for userAction. */
static inline YYRESULTTAG static inline YYRESULTTAG
yydoAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule, yydoAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
YYSTYPE* yyvalp]b4_locuser_formals[) YYSTYPE* yyvalp]b4_locuser_formals[)
{ {
int yynrhs = yyrhsLength (yyrule); int yynrhs = yyrhsLength (yyrule);
@@ -1467,10 +1465,10 @@ yydoAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
* added to the options for the existing state's semantic value. * added to the options for the existing state's semantic value.
*/ */
static inline YYRESULTTAG static inline YYRESULTTAG
yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule, yyglrReduce (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
yybool yyforceEval]b4_user_formals[) yybool yyforceEval]b4_user_formals[)
{ {
ptrdiff_t yyposn = yystackp->yytops.yystates[yyk]->yyposn; YYPTRDIFF_T yyposn = yystackp->yytops.yystates[yyk]->yyposn;
if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR) if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR)
{ {
@@ -1492,7 +1490,7 @@ yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
} }
else else
{ {
ptrdiff_t yyi; YYPTRDIFF_T yyi;
int yyn; int yyn;
yyGLRState* yys, *yys0 = yystackp->yytops.yystates[yyk]; yyGLRState* yys, *yys0 = yystackp->yytops.yystates[yyk];
yy_state_t yynewLRState; yy_state_t yynewLRState;
@@ -1534,8 +1532,8 @@ yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
return yyok; return yyok;
} }
static ptrdiff_t static YYPTRDIFF_T
yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk) yysplitStack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
{ {
if (yystackp->yysplitPoint == YY_NULLPTR) if (yystackp->yysplitPoint == YY_NULLPTR)
{ {
@@ -1544,8 +1542,8 @@ yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
} }
if (yystackp->yytops.yycapacity <= yystackp->yytops.yysize) if (yystackp->yytops.yycapacity <= yystackp->yytops.yysize)
{ {
ptrdiff_t state_size = sizeof yystackp->yytops.yystates[0]; YYPTRDIFF_T state_size = YYSIZEOF (yystackp->yytops.yystates[0]);
ptrdiff_t half_max_capacity = YYSIZEMAX / 2 / state_size; YYPTRDIFF_T half_max_capacity = YYSIZE_MAXIMUM / 2 / state_size;
if (half_max_capacity < yystackp->yytops.yycapacity) if (half_max_capacity < yystackp->yytops.yycapacity)
yyMemoryExhausted (yystackp); yyMemoryExhausted (yystackp);
yystackp->yytops.yycapacity *= 2; yystackp->yytops.yycapacity *= 2;
@@ -1554,7 +1552,7 @@ yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
yyGLRState** yynewStates yyGLRState** yynewStates
= YY_CAST (yyGLRState**, = YY_CAST (yyGLRState**,
YYREALLOC (yystackp->yytops.yystates, YYREALLOC (yystackp->yytops.yystates,
(YY_CAST (size_t, yystackp->yytops.yycapacity) (YY_CAST (YYSIZE_T, yystackp->yytops.yycapacity)
* sizeof yynewStates[0]))); * sizeof yynewStates[0])));
if (yynewStates == YY_NULLPTR) if (yynewStates == YY_NULLPTR)
yyMemoryExhausted (yystackp); yyMemoryExhausted (yystackp);
@@ -1565,7 +1563,7 @@ yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
yybool* yynewLookaheadNeeds yybool* yynewLookaheadNeeds
= YY_CAST (yybool*, = YY_CAST (yybool*,
YYREALLOC (yystackp->yytops.yylookaheadNeeds, YYREALLOC (yystackp->yytops.yylookaheadNeeds,
(YY_CAST (size_t, yystackp->yytops.yycapacity) (YY_CAST (YYSIZE_T, yystackp->yytops.yycapacity)
* sizeof yynewLookaheadNeeds[0]))); * sizeof yynewLookaheadNeeds[0])));
if (yynewLookaheadNeeds == YY_NULLPTR) if (yynewLookaheadNeeds == YY_NULLPTR)
yyMemoryExhausted (yystackp); yyMemoryExhausted (yystackp);
@@ -1996,8 +1994,8 @@ yycompressStack (yyGLRStack* yystackp)
} }
static YYRESULTTAG static YYRESULTTAG
yyprocessOneStack (yyGLRStack* yystackp, ptrdiff_t yyk, yyprocessOneStack (yyGLRStack* yystackp, YYPTRDIFF_T yyk,
ptrdiff_t yyposn]b4_pure_formals[) YYPTRDIFF_T yyposn]b4_pure_formals[)
{ {
while (yystackp->yytops.yystates[yyk] != YY_NULLPTR) while (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
{ {
@@ -2040,7 +2038,7 @@ yyprocessOneStack (yyGLRStack* yystackp, ptrdiff_t yyk,
for (/* nothing */; *yyconflicts; yyconflicts += 1) for (/* nothing */; *yyconflicts; yyconflicts += 1)
{ {
YYRESULTTAG yyflag; YYRESULTTAG yyflag;
ptrdiff_t yynewStack = yysplitStack (yystackp, yyk); YYPTRDIFF_T yynewStack = yysplitStack (yystackp, yyk);
YY_DPRINTF ((stderr, "Splitting off stack %ld from %ld.\n", YY_DPRINTF ((stderr, "Splitting off stack %ld from %ld.\n",
YY_CAST (long, yynewStack), YY_CAST (long, yyk))); YY_CAST (long, yynewStack), YY_CAST (long, yyk)));
yyflag = yyglrReduce (yystackp, yynewStack, yyflag = yyglrReduce (yystackp, yynewStack,
@@ -2121,6 +2119,8 @@ yypcontext_expected_tokens (const yyGLRStack* yystackp,
yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
} }
} }
if (yyarg && yycount == 0 && 0 < yyargn)
yyarg[0] = ]b4_symbol(-2, kind)[;
return yycount; return yycount;
}]])[ }]])[
@@ -2228,7 +2228,7 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
one per "expected"). */ one per "expected"). */
yysymbol_kind_t yyarg[YYARGS_MAX]; yysymbol_kind_t yyarg[YYARGS_MAX];
/* Cumulated lengths of YYARG. */ /* Cumulated lengths of YYARG. */
ptrdiff_t yysize = 0; YYPTRDIFF_T yysize = 0;
/* Actual size of YYARG. */ /* Actual size of YYARG. */
int yycount int yycount
@@ -2259,11 +2259,11 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
int yyi; int yyi;
for (yyi = 0; yyi < yycount; ++yyi) for (yyi = 0; yyi < yycount; ++yyi)
{ {
ptrdiff_t yysz YYPTRDIFF_T yysz
= ]b4_parse_error_case( = ]b4_parse_error_case(
[verbose], [[yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]])]], [verbose], [[yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]])]],
[[yystrlen (yysymbol_name (yyarg[yyi]))]]);[ [[yystrlen (yysymbol_name (yyarg[yyi]))]]);[
if (YYSIZEMAX - yysize < yysz) if (YYSIZE_MAXIMUM - yysize < yysz)
yysize_overflow = yytrue; yysize_overflow = yytrue;
else else
yysize += yysz; yysize += yysz;
@@ -2271,7 +2271,7 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
} }
if (!yysize_overflow) if (!yysize_overflow)
yymsg = YY_CAST (char *, YYMALLOC (YY_CAST (size_t, yysize))); yymsg = YY_CAST (char *, YYMALLOC (YY_CAST (YYSIZE_T, yysize)));
if (yymsg) if (yymsg)
{ {
@@ -2348,7 +2348,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
/* Reduce to one stack. */ /* Reduce to one stack. */
{ {
ptrdiff_t yyk; YYPTRDIFF_T yyk;
for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1) for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR) if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
break; break;
@@ -2423,7 +2423,7 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
int yyresult; int yyresult;
yyGLRStack yystack; yyGLRStack yystack;
yyGLRStack* const yystackp = &yystack; yyGLRStack* const yystackp = &yystack;
ptrdiff_t yyposn; YYPTRDIFF_T yyposn;
YY_DPRINTF ((stderr, "Starting parse\n")); YY_DPRINTF ((stderr, "Starting parse\n"));
@@ -2505,7 +2505,7 @@ b4_dollar_popdef])[]dnl
while (yytrue) while (yytrue)
{ {
yysymbol_kind_t yytoken_to_shift; yysymbol_kind_t yytoken_to_shift;
ptrdiff_t yys; YYPTRDIFF_T yys;
for (yys = 0; yys < yystack.yytops.yysize; yys += 1) for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
yystackp->yytops.yylookaheadNeeds[yys] = yychar != ]b4_symbol(-2, id)[; yystackp->yytops.yylookaheadNeeds[yys] = yychar != ]b4_symbol(-2, id)[;
@@ -2612,8 +2612,8 @@ b4_dollar_popdef])[]dnl
yyGLRState** yystates = yystack.yytops.yystates; yyGLRState** yystates = yystack.yytops.yystates;
if (yystates) if (yystates)
{ {
ptrdiff_t yysize = yystack.yytops.yysize; YYPTRDIFF_T yysize = yystack.yytops.yysize;
ptrdiff_t yyk; YYPTRDIFF_T yyk;
for (yyk = 0; yyk < yysize; yyk += 1) for (yyk = 0; yyk < yysize; yyk += 1)
if (yystates[yyk]) if (yystates[yyk])
{ {
@@ -2660,7 +2660,7 @@ yypstates (yyGLRState* yyst)
} }
static void static void
yypstack (yyGLRStack* yystackp, ptrdiff_t yyk) yypstack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
{ {
yypstates (yystackp->yytops.yystates[yyk]); yypstates (yystackp->yytops.yystates[yyk]);
} }
@@ -2705,7 +2705,7 @@ yypdumpstack (yyGLRStack* yystackp)
YY_FPRINTF ((stderr, "Tops:")); YY_FPRINTF ((stderr, "Tops:"));
{ {
ptrdiff_t yyi; YYPTRDIFF_T yyi;
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1) for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
YY_FPRINTF ((stderr, "%ld: %ld; ", YY_CAST (long, yyi), YY_FPRINTF ((stderr, "%ld: %ld; ", YY_CAST (long, yyi),
YYINDEX (yystackp->yytops.yystates[yyi]))); YYINDEX (yystackp->yytops.yystates[yyi])));
+2
View File
@@ -1326,6 +1326,8 @@ b4_dollar_popdef])[]dnl
} }
} }
]])[ ]])[
if (yyarg && yycount == 0 && 0 < yyargn)
yyarg[0] = symbol_kind::]b4_symbol(-2, kind)[;
return yycount; return yycount;
} }
+2
View File
@@ -944,6 +944,8 @@ b4_dollar_popdef[]dnl
yyarg[yycount++] = SymbolKind.get (yyx); yyarg[yycount++] = SymbolKind.get (yyx);
} }
} }
if (yyarg != null && yycount == yyoffset && yyoffset < yyargn)
yyarg[yycount] = null;
return yycount - yyoffset; return yycount - yyoffset;
} }
} }
+4 -42
View File
@@ -403,50 +403,10 @@ m4_if(b4_api_prefix, [yy], [],
]b4_declare_symbol_enum[ ]b4_declare_symbol_enum[
]b4_user_post_prologue[ ]b4_user_post_prologue[
]b4_percent_code_get[]dnl ]b4_percent_code_get[
[#ifdef short
# undef short
#endif
]b4_c99_int_type_define[ ]b4_c99_int_type_define[
#ifndef YYPTRDIFF_T ]b4_sizes_types_define[
# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
# define YYPTRDIFF_T __PTRDIFF_TYPE__
# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
# elif defined PTRDIFF_MAX
# ifndef ptrdiff_t
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# endif
# define YYPTRDIFF_T ptrdiff_t
# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
# else
# define YYPTRDIFF_T long
# define YYPTRDIFF_MAXIMUM LONG_MAX
# endif
#endif
#ifndef YYSIZE_T
# ifdef __SIZE_TYPE__
# define YYSIZE_T __SIZE_TYPE__
# elif defined size_t
# define YYSIZE_T size_t
# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
# define YYSIZE_T unsigned
# endif
#endif
#define YYSIZE_MAXIMUM \
YY_CAST (YYPTRDIFF_T, \
(YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
? YYPTRDIFF_MAXIMUM \
: YY_CAST (YYSIZE_T, -1)))
#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
/* Stored state numbers (used for stacks). */ /* Stored state numbers (used for stacks). */
typedef ]b4_int_type(0, m4_eval(b4_states_number - 1))[ yy_state_t; typedef ]b4_int_type(0, m4_eval(b4_states_number - 1))[ yy_state_t;
@@ -1198,6 +1158,8 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
} }
}]])[ }]])[
if (yyarg && yycount == 0 && 0 < yyargn)
yyarg[0] = ]b4_symbol(-2, kind)[;
return yycount; return yycount;
} }
+93 -62
View File
@@ -300,10 +300,7 @@ Bison Declarations
Parser C-Language Interface Parser C-Language Interface
* Parser Function:: How to call @code{yyparse} and what it returns. * Parser Function:: How to call @code{yyparse} and what it returns.
* Push Parser Function:: How to call @code{yypush_parse} and what it returns. * Push Parser Interface:: How to create, use, and destroy push parsers.
* Pull Parser Function:: How to call @code{yypull_parse} and what it returns.
* Parser Create Function:: How to call @code{yypstate_new} and what it returns.
* Parser Delete Function:: How to call @code{yypstate_delete} and what it returns.
* Lexical:: You must supply a function @code{yylex} * Lexical:: You must supply a function @code{yylex}
which reads tokens. which reads tokens.
* Error Reporting:: Passing error messages to the user. * Error Reporting:: Passing error messages to the user.
@@ -6927,10 +6924,7 @@ in the grammar file, you are likely to run into trouble.
@menu @menu
* Parser Function:: How to call @code{yyparse} and what it returns. * Parser Function:: How to call @code{yyparse} and what it returns.
* Push Parser Function:: How to call @code{yypush_parse} and what it returns. * Push Parser Interface:: How to create, use, and destroy push parsers.
* Pull Parser Function:: How to call @code{yypull_parse} and what it returns.
* Parser Create Function:: How to call @code{yypstate_new} and what it returns.
* Parser Delete Function:: How to call @code{yypstate_delete} and what it returns.
* Lexical:: You must supply a function @code{yylex} * Lexical:: You must supply a function @code{yylex}
which reads tokens. which reads tokens.
* Error Reporting:: Passing error messages to the user. * Error Reporting:: Passing error messages to the user.
@@ -7033,16 +7027,40 @@ void yyerror (YYLTYPE *llocp, int *randomness, const char *msg);
int yyparse (int *randomness); int yyparse (int *randomness);
@end example @end example
@node Push Parser Function @node Push Parser Interface
@section The Push Parser Function @code{yypush_parse} @section Push Parser Interface
@findex yypush_parse
You call the function @code{yypush_parse} to parse a single token. This @findex yypstate_new
You call the function @code{yypstate_new} to create a new parser instance.
This function is available if either the @samp{%define api.push-pull push}
or @samp{%define api.push-pull both} declaration is used. @xref{Push Decl}.
@deftypefun {yypstate*} yypstate_new (@code{void})
@anchor{yypstate_new}
Return a valid parser instance if there is memory available, 0 otherwise.
In impure mode, it will also return 0 if a parser instance is currently
allocated.
@end deftypefun
@findex yypstate_delete
You call the function @code{yypstate_delete} to delete a parser instance.
function is available if either the @samp{%define api.push-pull push} or function is available if either the @samp{%define api.push-pull push} or
@samp{%define api.push-pull both} declaration is used. @samp{%define api.push-pull both} declaration is used.
@xref{Push Decl}. @xref{Push Decl}.
@deftypefun void yypstate_delete (@code{yypstate *}@var{yyps})
@anchor{yypstate_delete}
Reclaim the memory associated with a parser instance. After this call, you
should no longer attempt to use the parser instance.
@end deftypefun
@findex yypush_parse
You call the function @code{yypush_parse} to parse a single token. This
function is available if either the @samp{%define api.push-pull push} or
@samp{%define api.push-pull both} declaration is used. @xref{Push Decl}.
@deftypefun int yypush_parse (@code{yypstate *}@var{yyps}) @deftypefun int yypush_parse (@code{yypstate *}@var{yyps})
@anchor{yypush_parse}
The value returned by @code{yypush_parse} is the same as for @code{yyparse} The value returned by @code{yypush_parse} is the same as for @code{yyparse}
with the following exception: it returns @code{YYPUSH_MORE} if more input is with the following exception: it returns @code{YYPUSH_MORE} if more input is
required to finish parsing the grammar. required to finish parsing the grammar.
@@ -7056,50 +7074,35 @@ reuse. For example, a calculator application which parses each input line
as an expression can just keep reusing the same @code{yyps} even if an input as an expression can just keep reusing the same @code{yyps} even if an input
was invalid. was invalid.
@node Pull Parser Function
@section The Pull Parser Function @code{yypull_parse}
@findex yypull_parse
You call the function @code{yypull_parse} to parse the rest of the input You call the function @code{yypull_parse} to parse the rest of the input
stream. This function is available if the @samp{%define api.push-pull both} stream. This function is available if the @samp{%define api.push-pull both}
declaration is used. declaration is used. @xref{Push Decl}.
@xref{Push Decl}.
@deftypefun int yypull_parse (@code{yypstate *}@var{yyps}) @deftypefun int yypull_parse (@code{yypstate *}@var{yyps})
@anchor{yypull_parse}
The value returned by @code{yypull_parse} is the same as for @code{yyparse}. The value returned by @code{yypull_parse} is the same as for @code{yyparse}.
The parser instance @code{yyps} may be reused for new parses. The parser instance @code{yyps} may be reused for new parses.
@end deftypefun @end deftypefun
@node Parser Create Function @deftypefun int yypstate_expected_tokens (@code{const yypstate *}yyps, @code{yysymbol_kind_t} @var{argv}@code{[]}, @code{int} @var{argc})
@section The Parser Create Function @code{yystate_new} Fill @var{argv} with the expected tokens, which never includes
@findex yypstate_new @code{YYSYMBOL_YYEMPTY}, @code{YYSYMBOL_YYerror}, or
@code{YYSYMBOL_YYUNDEF}.
You call the function @code{yypstate_new} to create a new parser instance. Never put more than @var{argc} elements into @var{argv}, and on success
This function is available if either the @samp{%define api.push-pull push} or return the number of tokens stored in @var{argv}. If there are more
@samp{%define api.push-pull both} declaration is used. expected tokens than @var{argc}, fill @var{argv} up to @var{argc} and return
@xref{Push Decl}. 0. If there are no expected tokens, also return 0, but set @code{argv[0]}
to @code{YYSYMBOL_YYEMPTY}.
@deftypefun {yypstate*} yypstate_new (@code{void}) When LAC is enabled, may return a negative number on errors,
The function will return a valid parser instance if there was memory available such as @code{YYENOMEM} on memory exhaustion.
or 0 if no memory was available.
In impure mode, it will also return 0 if a parser instance is currently If @var{argv} is null, return the size needed to store all the possible
allocated. values, which is always less than @code{YYNTOKENS}.
@end deftypefun @end deftypefun
@node Parser Delete Function
@section The Parser Delete Function @code{yystate_delete}
@findex yypstate_delete
You call the function @code{yypstate_delete} to delete a parser instance.
function is available if either the @samp{%define api.push-pull push} or
@samp{%define api.push-pull both} declaration is used.
@xref{Push Decl}.
@deftypefun void yypstate_delete (@code{yypstate *}@var{yyps})
This function will reclaim the memory associated with a parser instance.
After this call, you should no longer attempt to use the parser instance.
@end deftypefun
@node Lexical @node Lexical
@section The Lexical Analyzer Function @code{yylex} @section The Lexical Analyzer Function @code{yylex}
@@ -7551,9 +7554,12 @@ Fill @var{argv} with the expected tokens, which never includes
@code{YYSYMBOL_YYUNDEF}. @code{YYSYMBOL_YYUNDEF}.
Never put more than @var{argc} elements into @var{argv}, and on success Never put more than @var{argc} elements into @var{argv}, and on success
return the effective number of tokens stored in @var{argv}. Return 0 if return the number of tokens stored in @var{argv}. If there are more
there are more than @var{argc} expected tokens, yet fill @var{argv} up to expected tokens than @var{argc}, fill @var{argv} up to @var{argc} and return
@var{argc}. When LAC is enabled, may return a negative number on errors, 0. If there are no expected tokens, also return 0, but set @code{argv[0]}
to @code{YYSYMBOL_YYEMPTY}.
When LAC is enabled, may return a negative number on errors,
such as @code{YYENOMEM} on memory exhaustion. such as @code{YYENOMEM} on memory exhaustion.
If @var{argv} is null, return the size needed to store all the possible If @var{argv} is null, return the size needed to store all the possible
@@ -7660,11 +7666,11 @@ recovery.
In either case, the rest of the action is not executed. In either case, the rest of the action is not executed.
@end deffn @end deffn
@deffn {Macro} YYEMPTY @deffn {Value} YYEMPTY
Value stored in @code{yychar} when there is no lookahead token. Value stored in @code{yychar} when there is no lookahead token.
@end deffn @end deffn
@deffn {Macro} YYEOF @deffn {Value} YYEOF
Value stored in @code{yychar} when the lookahead is the end of the input Value stored in @code{yychar} when the lookahead is the end of the input
stream. stream.
@end deffn @end deffn
@@ -12137,9 +12143,10 @@ Fill @var{argv} with the expected tokens, which never includes
@code{symbol_kind::S_YYUNDEF}. @code{symbol_kind::S_YYUNDEF}.
Never put more than @var{argc} elements into @var{argv}, and on success Never put more than @var{argc} elements into @var{argv}, and on success
return the effective number of tokens stored in @var{argv}. Return 0 if return the number of tokens stored in @var{argv}. If there are more
there are more than @var{argc} expected tokens, yet fill @var{argv} up to expected tokens than @var{argc}, fill @var{argv} up to @var{argc} and return
@var{argc}. 0. If there are no expected tokens, also return 0, but set @code{argv[0]}
to @code{symbol_kind::S_YYEMPTY}.
If @var{argv} is null, return the size needed to store all the possible If @var{argv} is null, return the size needed to store all the possible
values, which is always less than @code{YYNTOKENS}. values, which is always less than @code{YYNTOKENS}.
@@ -13298,9 +13305,10 @@ Fill @var{argv} with the expected tokens, which never includes
@code{SymbolKind.S_YYERROR}, or @code{SymbolKind.S_YYUNDEF}. @code{SymbolKind.S_YYERROR}, or @code{SymbolKind.S_YYUNDEF}.
Never put more than @var{argc} elements into @var{argv}, and on success Never put more than @var{argc} elements into @var{argv}, and on success
return the effective number of tokens stored in @var{argv}. Return 0 if return the number of tokens stored in @var{argv}. If there are more
there are more than @var{argc} expected tokens, yet fill @var{argv} up to expected tokens than @var{argc}, fill @var{argv} up to @var{argc} and return
@var{argc}. 0. If there are no expected tokens, also return 0, but set @code{argv[0]}
to @code{null}.
If @var{argv} is null, return the size needed to store all the possible If @var{argv} is null, return the size needed to store all the possible
values, which is always less than @code{YYNTOKENS}. values, which is always less than @code{YYNTOKENS}.
@@ -14692,6 +14700,14 @@ is given a nonzero value, the parser will output information on input
symbols and parser action. @xref{Tracing}. symbols and parser action. @xref{Tracing}.
@end deffn @end deffn
@deffn {Value} YYEMPTY
The pseudo token kind when there is no lookahead token.
@end deffn
@deffn {Value} YYEOF
The token kind denoting is the end of the input stream.
@end deffn
@deffn {Macro} yyerrok @deffn {Macro} yyerrok
Macro to cause parser to recover immediately to its normal mode Macro to cause parser to recover immediately to its normal mode
after a syntax error. @xref{Error Recovery}. after a syntax error. @xref{Error Recovery}.
@@ -14781,24 +14797,26 @@ Deprecated, use @code{%printer} instead (@pxref{Printer Decl}).
@deffn {Function} yypstate_delete @deffn {Function} yypstate_delete
The function to delete a parser instance, produced by Bison in push mode; The function to delete a parser instance, produced by Bison in push mode;
call this function to delete the memory associated with a parser. call this function to delete the memory associated with a parser.
@xref{Parser Delete Function}. Does nothing when called with a null pointer. @xref{yypstate_delete,,@code{yypstate_delete}}. Does nothing when called
with a null pointer.
@end deffn @end deffn
@deffn {Function} yypstate_new @deffn {Function} yypstate_new
The function to create a parser instance, produced by Bison in push mode; The function to create a parser instance, produced by Bison in push mode;
call this function to create a new parser. call this function to create a new parser.
@xref{Parser Create Function}. @xref{yypstate_new,,@code{yypstate_new}}.
@end deffn @end deffn
@deffn {Function} yypull_parse @deffn {Function} yypull_parse
The parser function produced by Bison in push mode; call this function to The parser function produced by Bison in push mode; call this function to
parse the rest of the input stream. parse the rest of the input stream.
@xref{Pull Parser Function}. @xref{yypull_parse,,@code{yypull_parse}}.
@end deffn @end deffn
@deffn {Function} yypush_parse @deffn {Function} yypush_parse
The parser function produced by Bison in push mode; call this function to The parser function produced by Bison in push mode; call this function to
parse a single token. @xref{Push Parser Function}. parse a single token.
@xref{yypush_parse,,@code{yypush_parse}}.
@end deffn @end deffn
@deffn {Macro} YYRECOVERING @deffn {Macro} YYRECOVERING
@@ -14846,6 +14864,10 @@ should not be confused with the @emph{symbol kinds}, used internally by the
parser. parser.
@end deffn @end deffn
@deffn {Value} YYUNDEF
The token kind denoting an unknown token.
@end deffn
@node Glossary @node Glossary
@appendix Glossary @appendix Glossary
@@ -14932,12 +14954,21 @@ A continuous flow of data between devices or programs.
@item Kind @item Kind
``Token'' and ``symbol'' are each overloaded to mean either a grammar symbol ``Token'' and ``symbol'' are each overloaded to mean either a grammar symbol
(kind) or all parse info (kind, value, location) associated with occurrences (kind) or all parse info (kind, value, location) associated with occurrences
of that grammar symbol from the input. To disambiguate, we use ``token of that grammar symbol from the input. To disambiguate,
kind'' and ``symbol kind'' to mean both grammar symbols and the types that
represent them in a base programming language (C, C++, etc.). However, we @itemize
use ``token'' and ``symbol'' without the word ``kind'' to mean parsed @item
we use ``token kind'' and ``symbol kind'' to mean both grammar symbols and
the values that represent them in a base programming language (C, C++,
etc.). The names of the types of these values are typically
@code{token_kind_t}, or @code{token_kind_type}, or @code{TokenKind},
depending on the programming language.
@item
we use ``token'' and ``symbol'' without the word ``kind'' to mean parsed
occurrences, and we append the word ``type'' to refer to the types that occurrences, and we append the word ``type'' to refer to the types that
represent them in a base programming language. represent them in a base programming language.
@end itemize
In summary: When you see ``kind'', interpret ``symbol'' or ``token'' to mean In summary: When you see ``kind'', interpret ``symbol'' or ``token'' to mean
a @emph{grammar symbol}. When you don't see ``kind'' (including when you a @emph{grammar symbol}. When you don't see ``kind'' (including when you
+24 -10
View File
@@ -131,7 +131,7 @@ dist_man_MANS = $(top_srcdir)/%D%/bison.1
EXTRA_DIST += $(dist_man_MANS:.1=.x) EXTRA_DIST += $(dist_man_MANS:.1=.x)
MAINTAINERCLEANFILES += $(dist_man_MANS) MAINTAINERCLEANFILES += $(dist_man_MANS)
# Differences to ignore when comparing the man page (the date). # Differences to ignore when comparing man pages (the date).
remove_time_stamp = \ remove_time_stamp = \
sed 's/^\(\.TH[^"]*"[^"]*"[^"]*\)"[^"]*"/\1/' sed 's/^\(\.TH[^"]*"[^"]*"[^"]*\)"[^"]*"/\1/'
@@ -140,17 +140,31 @@ if ! CROSS_COMPILING
MAN_DEPS = %D%/bison.help %D%/bison.x $(top_srcdir)/configure MAN_DEPS = %D%/bison.help %D%/bison.x $(top_srcdir)/configure
endif endif
# If we don't have help2man, just touch the target. Maintainers must
# have the real thing, so if there's a .git directory, fail hard.
#
# We shouldn't need this, but on some OS the timestamps in the tarball
# leave us no choice. See
# https://lists.gnu.org/r/bug-bison/2020-05/msg00055.html.
$(top_srcdir)/%D%/bison.1: $(MAN_DEPS) $(top_srcdir)/%D%/bison.1: $(MAN_DEPS)
$(AM_V_GEN)$(HELP2MAN) \ $(AM_V_GEN)if $(HELP2MAN) --version >/dev/null 2>&1; then \
--include=$(top_srcdir)/%D%/bison.x \ $(HELP2MAN) \
--output=$@.tmp tests/bison --include=$(top_srcdir)/%D%/bison.x \
$(AM_V_at)if $(remove_time_stamp) $@ >$@a.tmp 2>/dev/null && \ --output=$@.tmp tests/bison && \
$(remove_time_stamp) $@.tmp | cmp $@a.tmp - >/dev/null 2>&1; then \ { $(remove_time_stamp) $@ >$@a.tmp || true; } && \
touch $@; \ $(remove_time_stamp) $@.tmp >$@b.tmp && \
else \ if diff $@a.tmp $@b.tmp >/dev/null 2>&1; then \
mv $@.tmp $@; \ touch $@; \
else \
mv $@.tmp $@; \
fi && \
rm -f $@*.tmp; \
elif test -d $(srcdir)/.git; then \
echo >&2 "ERROR: $@: help2man is needed"; \
exit 1; \
else \
touch $@; \
fi fi
$(AM_V_at)rm -f $@*.tmp
if ENABLE_YACC if ENABLE_YACC
nodist_man_MANS = %D%/yacc.1 nodist_man_MANS = %D%/yacc.1
+20 -11
View File
@@ -41,13 +41,14 @@ echo >perfect '> 0
echo >ok '0' echo >ok '0'
echo '0' | prog >effective echo '0' | prog >effective
if diff perfect effective >/dev/null 2>&1; then echo "checking for readline output"
if diff perfect effective; then
# Alles ist gut. # Alles ist gut.
elif diff ok effective >/dev/null 2>&1; then strip_prompt=false
elif diff ok effective; then
strip_prompt=true strip_prompt=true
else else
echo "SKIP: this is not the GNU Readline we expect" skip "this is not the GNU Readline we expect"
exit 77
fi fi
@@ -96,7 +97,7 @@ cat >input <<EOF
EOF EOF
run 0 '> * run 0 '> *
> '' > ''
err: 1.1: syntax error: expected end of file or - or ( or exit or number or function or variable before *' err: 1.1: syntax error: expected end of file or - or ( or exit or number or function etc., before *'
cat >input <<EOF cat >input <<EOF
1 + 2 * * 3 1 + 2 * * 3
@@ -257,14 +258,22 @@ err: Cleanup: popping nterm input (1.1-4: )' -p
# From now on, the differences between versions of GNU Readline are # From now on, the differences between versions of GNU Readline are
# too painful to try to cope with. # too painful to try to cope with.
if $strip_prompt; then if $strip_prompt; then
echo "SKIP: this is not the GNU Readline we expect" echo "SKIP: this is not the GNU Readline we expect"
if $exit; then exit $status
exit 0
else
exit 1
fi
fi fi
# On Windows10/MSYS2 the ^G coming from <tab> completion is not
# emitted the same way
# (https://lists.gnu.org/r/bug-bison/2020-05/msg00076.html).
echo "checking for kernel name"
case `uname -s` in
(MSYS*)
echo "SKIP: this is Windows/MSYS"
exit $status
;;
esac
# Check completion after an operator. # Check completion after an operator.
sed -e 's/\\t/ /g' >input <<EOF sed -e 's/\\t/ /g' >input <<EOF
(1+\t\t (1+\t\t
+9 -4
View File
@@ -333,7 +333,7 @@ error_format_string (int argc)
case 5: return _("%@: syntax error: expected %0e or %1e or %2e or %3e 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 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 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"); case 8: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e etc., before %u");
} }
} }
@@ -341,12 +341,15 @@ error_format_string (int argc)
int int
yyreport_syntax_error (const yypcontext_t *ctx) yyreport_syntax_error (const yypcontext_t *ctx)
{ {
enum { ARGS_MAX = 7 }; enum { ARGS_MAX = 6 };
yysymbol_kind_t arg[ARGS_MAX]; yysymbol_kind_t arg[ARGS_MAX];
int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX); int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
if (argsize < 0) if (argsize < 0)
return argsize; return argsize;
const char *format = error_format_string (1 + argsize); const int too_many_expected_tokens = argsize == 0 && arg[0] != YYSYMBOL_YYEMPTY;
if (too_many_expected_tokens)
argsize = ARGS_MAX;
const char *format = error_format_string (1 + argsize + too_many_expected_tokens);
while (*format) while (*format)
// %@: location. // %@: location.
@@ -400,7 +403,9 @@ void yyerror (YYLTYPE *loc, char const *format, ...)
static char * static char *
xstrndup (const char *string, size_t n) xstrndup (const char *string, size_t n)
{ {
size_t len = strnlen (string, n); // len = strnlen (string, n), portably.
const char *end = memchr (string, '\0', n);
size_t len = end ? (size_t) (end - string) : n;
char *new = malloc (len + 1); char *new = malloc (len + 1);
assert (new); assert (new);
new[len] = '\0'; new[len] = '\0';
+1 -1
View File
@@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
(seq 0) >/dev/null 2>&1 || exit 77 (seq 0) >/dev/null 2>&1 || skip "gimme one seq"
cat >input <<EOF cat >input <<EOF
1+2*3 1+2*3
+29 -8
View File
@@ -25,7 +25,7 @@ medir=$(dirname "$1" | sed -e 's,.*examples/,,')
number=1 number=1
# Exit status of this script. # Exit status of this script.
exit=true status=0
# top_builddir. # top_builddir.
cwd=$(pwd) cwd=$(pwd)
@@ -34,6 +34,13 @@ cwd=$(pwd)
# See bistromathic.test. # See bistromathic.test.
strip_prompt=false strip_prompt=false
# If diff supports --strip-trailing-cr, use it, to avoid EOL issues
# when testing Java programs on Windows.
echo "checking for diff --strip-trailing-cr"
if diff --strip-trailing-cr "$1" "$1"; then
diff_opts=--strip-trailing-cr
fi
# The exercised program. # The exercised program.
abs_medir=$cwd/examples/$medir abs_medir=$cwd/examples/$medir
if test -x "$abs_medir/$me"; then if test -x "$abs_medir/$me"; then
@@ -68,6 +75,20 @@ trap cleanup 0 1 2 13 15
mkdir $$.dir mkdir $$.dir
cd $$.dir cd $$.dir
# skip [MSG]
# ----------
# Skip this test.
skip ()
{
if test x"$1" != x; then
echo "SKIP: $1"
fi
# See Autoconf's doc on 'trap'.
(exit 77); exit 77
}
# run [-noerr, -n] 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. # -noerr: ignore stderr, otherwise merge it into effective output.
@@ -115,7 +136,7 @@ run ()
} >eff } >eff
if test $sta_eff -eq $sta_exp; then if test $sta_eff -eq $sta_exp; then
if diff eff exp >/dev/null 2>&1; then if diff $diff_opts eff exp >/dev/null 2>&1; then
echo "$me: PASS: $number" echo "$me: PASS: $number"
else else
echo "$me: FAIL: $number" echo "$me: FAIL: $number"
@@ -126,21 +147,21 @@ run ()
echo "$me: effective output:" echo "$me: effective output:"
sed -e 's/^/ /' eff sed -e 's/^/ /' eff
echo "$me: diff:" echo "$me: diff:"
diff -u exp eff | sed -e 's/^/ /' diff $diff_opts -u exp eff | sed -e 's/^/ /'
exit=false status=1
fi fi
else else
echo "$me: FAIL: $number (expected status: $sta_exp, effective: $sta_eff)" echo "$me: FAIL: $number (expected status: $sta_exp, effective: $sta_eff)"
cat err_eff cat err_eff
exit=false status=1
fi fi
number=$(expr $number + 1) number=$(expr $number + 1)
} }
# We have cd'd one level deeper. # We have cd'd one level deeper.
case $1 in case $1 in
/*) . "$1";; /*) . "$1" || status=2;;
*) . "../$1";; *) . "../$1" || status=2;;
esac esac
$exit exit $status
+5 -2
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.5.91. */ /* A Bison parser, made by GNU Bison 3.6. */
/* Bison implementation for Yacc-like parsers in C /* Bison implementation for Yacc-like parsers in C
@@ -49,7 +49,7 @@
#define YYBISON 1 #define YYBISON 1
/* Bison version. */ /* Bison version. */
#define YYBISON_VERSION "3.5.91" #define YYBISON_VERSION "3.6"
/* Skeleton name. */ /* Skeleton name. */
#define YYSKELETON_NAME "yacc.c" #define YYSKELETON_NAME "yacc.c"
@@ -408,6 +408,7 @@ typedef int yytype_uint16;
#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
/* Stored state numbers (used for stacks). */ /* Stored state numbers (used for stacks). */
typedef yytype_uint8 yy_state_t; typedef yytype_uint8 yy_state_t;
@@ -1631,6 +1632,8 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
yyarg[yycount++] = yysym; yyarg[yycount++] = yysym;
} }
} }
if (yyarg && yycount == 0 && 0 < yyargn)
yyarg[0] = YYSYMBOL_YYEMPTY;
return yycount; return yycount;
} }
+1 -1
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.5.91. */ /* A Bison parser, made by GNU Bison 3.6. */
/* Bison interface for Yacc-like parsers in C /* Bison interface for Yacc-like parsers in C
+41
View File
@@ -144,3 +144,44 @@ export LC_CTYPE
# Empty if no xsltproc was found # Empty if no xsltproc was found
: ${XSLTPROC='@XSLTPROC@'} : ${XSLTPROC='@XSLTPROC@'}
# Some tests expect a precise diff format. See AT_DIFF_U_CHECK.
# See https://lists.gnu.org/r/bug-bison/2020-05/msg00049.html.
cat >conftest.1 <<EOF
1
2
3
4
5
6
EOF
cat >conftest.2 <<EOF
1
22
3
4
55
6
EOF
cat >conftest.expected <<EOF
@@ -1,6 +1,6 @@
1
-2
+22
3
4
-5
+55
6
EOF
diff -u conftest.1 conftest.2 2>/dev/null | sed -n '/^@@/,$p' | sed 's/^ $//' >conftest.diff
if diff conftest.expected conftest.diff >/dev/null; then
DIFF_U_WORKS=true
else
DIFF_U_WORKS=false
fi
rm conftest.*
+3 -2
View File
@@ -265,7 +265,8 @@ input.y: <warning>warning:</warning> fix-its can be applied. Rerun with option
]]) ]])
# Likewise, but currently not portable to Cygwin. # Likewise, but currently not portable to AIX and Cygwin.
# https://lists.gnu.org/r/bug-bison/2020-05/msg00050.html
# https://lists.gnu.org/r/bug-bison/2020-05/msg00003.html. # https://lists.gnu.org/r/bug-bison/2020-05/msg00003.html.
AT_TEST([[Tabulations and multibyte characters]], AT_TEST([[Tabulations and multibyte characters]],
[[%% [[%%
@@ -277,7 +278,7 @@ e: {∇⃗×𝐸⃗ = -∂𝐵⃗/∂t}
| <warning>^~~~~~~~~~~~~~</warning> | <warning>^~~~~~~~~~~~~~</warning>
| <fixit-insert>%empty</fixit-insert> | <fixit-insert>%empty</fixit-insert>
input.y: <warning>warning:</warning> fix-its can be applied. Rerun with option '--update'. [<warning>-Wother</warning>] input.y: <warning>warning:</warning> fix-its can be applied. Rerun with option '--update'. [<warning>-Wother</warning>]
]], [], [uname -a | grep -i cygwin]) ]], [], [uname -a | $EGREP -i 'aix|cygwin'])
## --------------- ## ## --------------- ##
+2 -7
View File
@@ -35,14 +35,9 @@ dnl time comes, just use sed to drop the line numbers. For now, as LR(1)
dnl support is rapidly evolving, let's keep that information to be careful. dnl support is rapidly evolving, let's keep that information to be careful.
dnl However, we don't do diffs for canonical LR(1) because the diff is huge. dnl However, we don't do diffs for canonical LR(1) because the diff is huge.
m4_pushdef([AT_LALR1_DIFF_CHECK], m4_pushdef([AT_LALR1_DIFF_CHECK],
[dnl We need diff -u, which is not portable. [AT_CHECK([[sed 's/^%define lr.type .*$//' input.y > input-lalr.y]])
AT_CHECK([diff -u /dev/null /dev/null || exit 77], [0], [ignore])
AT_CHECK([[sed 's/^%define lr.type .*$//' input.y > input-lalr.y]])
AT_BISON_CHECK([[--report=all input-lalr.y]], [[0]], [ignore], [ignore]) AT_BISON_CHECK([[--report=all input-lalr.y]], [[0]], [ignore], [ignore])
AT_CHECK([[diff -u input-lalr.output input.output \ AT_DIFF_U_CHECK([[input-lalr.output input.output]], [$1])])
| sed -n '/^@@/,$p' | sed 's/^ $//']],
[[0]], [$1])])
AT_TEST_TABLES_AND_PARSE([$2[: LALR(1)]], [[LALR]], [[last-state]], AT_TEST_TABLES_AND_PARSE([$2[: LALR(1)]], [[LALR]], [[last-state]],
[[%define lr.type lalr [[%define lr.type lalr
+10
View File
@@ -83,6 +83,16 @@ set x `LC_ALL=C ls -l '$1'` &&
## ------------- ## ## ------------- ##
# AT_DIFF_U_CHECK(DIFF-ARGS, EXPECTED-DIFF)
# -----------------------------------------
# If diff -u works as we expect, use it, with headers stripped.
m4_define([AT_DIFF_U_CHECK],
[if $DIFF_U_WORKS; then
AT_CHECK([diff -u $1 | sed -n '/^@@/,$p' | sed 's/^ $//'], [0], [$2])
fi
])
# AT_PERL_CHECK(PERL-ARGS, ...) # AT_PERL_CHECK(PERL-ARGS, ...)
# ----------------------------- # -----------------------------
# If Perl is available, run this test. # If Perl is available, run this test.