bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/6] glr.c: example: several improvements


From: Akim Demaille
Subject: [PATCH 1/6] glr.c: example: several improvements
Date: Sat, 2 Jan 2021 16:30:26 +0100

* 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.
---
 TODO                          |   4 +
 examples/c++/glr/c++-types.yy |   4 +-
 examples/c/glr/c++-types.test |  18 ++---
 examples/c/glr/c++-types.y    | 133 +++++++++++++++++++++-------------
 4 files changed, 98 insertions(+), 61 deletions(-)

diff --git a/TODO b/TODO
index 1b3e008f..33501acf 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,8 @@
 * Soon
+** YY_LOCATION_PRINT
+This is an internal detail.  But it's very handy, we should make it public.
+It already has leaked in the documentation by accident.
+
 ** glr
 There is no test with "Parse on stack %ld rejected by rule %d" in it.
 
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;
+}
-- 
2.29.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]