summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2021-01-01 18:19:12 +0100
committerAkim Demaille <akim.demaille@gmail.com>2021-01-02 07:36:35 +0100
commit5a4e6062751043e43e260961336d8dafb83ae63e (patch)
treea16bc180a75d7e9b48408f225a6e6618a640a803 /examples
parent83f2eb3737b8037c79796dcb1648818d50897fc8 (diff)
downloadbison-5a4e6062751043e43e260961336d8dafb83ae63e.tar.gz
glr.c: example: several improvements
* examples/c/glr/c++-types.y (node_print): New. Use YY_LOCATION_PRINT instead of duplicating it. And actually use it in the action instead of badly duplicating it. (main): Add proper option support. * examples/c/glr/c++-types.test: Adjust expectations on locations. * examples/c++/glr/c++-types.yy: Fix bad iteration.
Diffstat (limited to 'examples')
-rw-r--r--examples/c++/glr/c++-types.yy4
-rw-r--r--examples/c/glr/c++-types.test18
-rw-r--r--examples/c/glr/c++-types.y133
3 files changed, 94 insertions, 61 deletions
diff --git a/examples/c++/glr/c++-types.yy b/examples/c++/glr/c++-types.yy
index c5fcf620..266bd100 100644
--- a/examples/c++/glr/c++-types.yy
+++ b/examples/c++/glr/c++-types.yy
@@ -192,11 +192,11 @@ main (int argc, char **argv)
bool ran = false;
for (int i = 1; i < argc; ++i)
// Enable parse traces on option -p.
- if (strcmp (argv[1], "-p") == 0)
+ if (strcmp (argv[i], "-p") == 0)
parse.set_debug_level (1);
else
{
- int status = process (parse, argv[1]);
+ int status = process (parse, argv[i]);
ran = true;
if (!status)
return status;
diff --git a/examples/c/glr/c++-types.test b/examples/c/glr/c++-types.test
index 0a1cdb26..46e10483 100644
--- a/examples/c/glr/c++-types.test
+++ b/examples/c/glr/c++-types.test
@@ -35,13 +35,13 @@ T (y y) = z + q;
z + q;
EOF
run 0 "\
-1.0-1.5: +(z,q)
-3.0-3.3: <declare>(T,x)
-5.0-5.7: <init-declare>(T,x,y)
-7.0-7.5: =(x,y)
-9.0-9.9: +(<cast>(x,T),y)
-11.0-11.5: <OR>(<declare>(T,x),<cast>(x,T))
-13.0-13.13: <OR>(<init-declare>(T,y,+(z,q)),=(<cast>(y,T),+(z,q)))
-15.0-15.15: <error>
-17.0-17.5: +(z,q)
+1.0-4: +(z,q)
+3.0-2: <declare>(T,x)
+5.0-6: <init-declare>(T,x,y)
+7.0-4: =(x,y)
+9.0-8: +(<cast>(x,T),y)
+11.0-4: <OR>(<declare>(T,x),<cast>(x,T))
+13.0-12: <OR>(<init-declare>(T,y,+(z,q)),=(<cast>(y,T),+(z,q)))
+15.0-14: <error>
+17.0-4: +(z,q)
err: 15.5: syntax error, unexpected identifier, expecting '=' or '+' or ')'"
diff --git a/examples/c/glr/c++-types.y b/examples/c/glr/c++-types.y
index a760b600..b44bd6ad 100644
--- a/examples/c/glr/c++-types.y
+++ b/examples/c/glr/c++-types.y
@@ -1,4 +1,22 @@
-/* Simplified C++ Type and Expression Grammar. */
+/* -*- C -*-
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Simplified C++ Type and Expression Grammar.
+ Written by Paul Hilfinger for Bison's test suite. */
%define api.pure
%header
@@ -47,9 +65,9 @@
static Node *new_term (char *);
static void free_node (Node *);
static char *node_to_string (Node *);
+ static void node_print (FILE *, Node *);
static Node *stmtMerge (YYSTYPE x0, YYSTYPE x1);
- static int location_print (FILE *yyo, YYLTYPE const * const yylocp);
static void yyerror (YYLTYPE const * const llocp, const char *msg);
static yytoken_kind_t yylex (YYSTYPE *lvalp, YYLTYPE *llocp);
}
@@ -67,17 +85,16 @@
%type <Node*> stmt expr decl declarator TYPENAME ID
%destructor { free_node ($$); } <Node*>
+%printer { node_print (yyo, $$); } <Node*>
%%
prog : %empty
| prog stmt {
- char *output = node_to_string ($2);
- printf ("%d.%d-%d.%d: %s\n",
- @2.first_line, @2.first_column,
- @2.last_line, @2.last_column,
- output);
- free (output);
+ YY_LOCATION_PRINT (stdout, @2);
+ fputs (": ", stdout);
+ node_print (stdout, $2);
+ putc ('\n', stdout);
free_node ($2);
}
;
@@ -108,51 +125,17 @@ declarator
%%
-int
-main (int argc, char **argv)
-{
- // Enable parse traces on option -p.
- if (1 < argc && strcmp (argv[1], "-p") == 0)
- yydebug = 1;
- return yyparse ();
-}
-
-
-/* Print *YYLOCP on YYO. */
-
-static int
-location_print (FILE *yyo, YYLTYPE const * const yylocp)
-{
- int res = 0;
- int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
- if (0 <= yylocp->first_line)
- {
- res += fprintf (yyo, "%d", yylocp->first_line);
- if (0 <= yylocp->first_column)
- res += fprintf (yyo, ".%d", yylocp->first_column);
- }
- if (0 <= yylocp->last_line)
- {
- if (yylocp->first_line < yylocp->last_line)
- {
- res += fprintf (yyo, "-%d", yylocp->last_line);
- if (0 <= end_col)
- res += fprintf (yyo, ".%d", end_col);
- }
- else if (0 <= end_col && yylocp->first_column < end_col)
- res += fprintf (yyo, "-%d", end_col);
- }
- return res;
-}
-
/* A C error reporting function. */
static
void yyerror (YYLTYPE const * const llocp, const char *msg)
{
- location_print (stderr, llocp);
+ YY_LOCATION_PRINT (stderr, *llocp);
fprintf (stderr, ": %s\n", msg);
}
+/* The input file. */
+FILE * input = NULL;
+
yytoken_kind_t
yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
{
@@ -162,8 +145,8 @@ yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
while (1)
{
int c;
- assert (!feof (stdin));
- c = getchar ();
+ assert (!feof (input));
+ c = getc (input);
switch (c)
{
case EOF:
@@ -193,11 +176,11 @@ yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
buffer[i++] = (char) c;
colNum += 1;
assert (i != sizeof buffer - 1);
- c = getchar ();
+ c = getc (input);
}
while (isalnum (c) || c == '_');
- ungetc (c, stdin);
+ ungetc (c, input);
buffer[i++] = 0;
if (isupper ((unsigned char) buffer[0]))
{
@@ -297,9 +280,59 @@ node_to_string (Node *node)
return res;
}
+static void node_print (FILE *out, Node *n)
+{
+ char *str = node_to_string (n);
+ fputs (str, out);
+ free (str);
+}
+
static Node*
stmtMerge (YYSTYPE x0, YYSTYPE x1)
{
return new_nterm ("<OR>(%s,%s)", x0.stmt, x1.stmt, NULL);
}
+
+static int
+process (const char *file)
+{
+ int is_stdin = !file || strcmp (file, "-") == 0;
+ if (is_stdin)
+ input = stdin;
+ else
+ input = fopen (file, "r");
+ assert (input);
+ int status = yyparse ();
+ if (!is_stdin)
+ fclose (input);
+ return status;
+}
+
+int
+main (int argc, char **argv)
+{
+ if (getenv ("YYDEBUG"))
+ yydebug = 1;
+
+ int ran = 0;
+ for (int i = 1; i < argc; ++i)
+ // Enable parse traces on option -p.
+ if (strcmp (argv[i], "-p") == 0)
+ yydebug = 1;
+ else
+ {
+ int status = process (argv[i]);
+ ran = 1;
+ if (!status)
+ return status;
+ }
+
+ if (!ran)
+ {
+ int status = process (NULL);
+ if (!status)
+ return status;
+ }
+ return 0;
+}