diff options
author | Akim Demaille <akim.demaille@gmail.com> | 2021-01-01 18:19:12 +0100 |
---|---|---|
committer | Akim Demaille <akim.demaille@gmail.com> | 2021-01-02 07:36:35 +0100 |
commit | 5a4e6062751043e43e260961336d8dafb83ae63e (patch) | |
tree | a16bc180a75d7e9b48408f225a6e6618a640a803 /examples | |
parent | 83f2eb3737b8037c79796dcb1648818d50897fc8 (diff) | |
download | bison-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.yy | 4 | ||||
-rw-r--r-- | examples/c/glr/c++-types.test | 18 | ||||
-rw-r--r-- | examples/c/glr/c++-types.y | 133 |
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; +} |