diff options
author | Akim Demaille <akim.demaille@gmail.com> | 2020-01-25 07:59:26 +0100 |
---|---|---|
committer | Akim Demaille <akim.demaille@gmail.com> | 2020-01-26 14:02:08 +0100 |
commit | c592202345f7dfcb1d4c5ba5eb0199f44e8d9c45 (patch) | |
tree | 6b08b08df15de94881be18105da837b191d07838 /examples | |
parent | 0917f4dc7603d9f41e362c9b0bac806b5b5e8b0d (diff) | |
download | bison-c592202345f7dfcb1d4c5ba5eb0199f44e8d9c45.tar.gz |
examples: clean up
* examples/c/calc/calc.y: Restore to its original state, with
parse.error=detailed instead of parse.error=custom (this example
should be simple).
* examples/c/calc/calc.test: Check syntax errors.
* examples/c/lexcalc/parse.y: Add comments.
Diffstat (limited to 'examples')
-rw-r--r-- | examples/c/calc/calc.test | 6 | ||||
-rw-r--r-- | examples/c/calc/calc.y | 67 | ||||
-rw-r--r-- | examples/c/lexcalc/parse.y | 17 | ||||
-rw-r--r-- | examples/c/lexcalc/scan.l | 2 | ||||
-rw-r--r-- | examples/c/reccalc/scan.l | 8 |
5 files changed, 42 insertions, 58 deletions
diff --git a/examples/c/calc/calc.test b/examples/c/calc/calc.test index 9f3c9e2f..d778cf75 100644 --- a/examples/c/calc/calc.test +++ b/examples/c/calc/calc.test @@ -34,4 +34,10 @@ cat >input <<EOF (1+2) * 3 EOF run 0 9 +# Check the traces. run -noerr 0 9 -p + +cat >input <<EOF +1++2 +EOF +run 0 "err: syntax error, unexpected '+', expecting number or '('" diff --git a/examples/c/calc/calc.y b/examples/c/calc/calc.y index 20f000a2..7757648d 100644 --- a/examples/c/calc/calc.y +++ b/examples/c/calc/calc.y @@ -1,50 +1,35 @@ %code top { #include <ctype.h> /* isdigit. */ - #include <stdbool.h> #include <stdio.h> /* For printf, etc. */ #include <string.h> /* strcmp. */ int yylex (void); void yyerror (char const *); - - bool show_expected = false; - -#define PRINT_EXPECTED_TOKENS() \ - do { \ - if (show_expected) \ - { \ - yyparse_context_t ctx \ - = {yyssp, yytoken, yyesa, &yyes, &yyes_capacity}; \ - int tokens[YYNTOKENS]; \ - int cnt = yyexpected_tokens (&ctx, tokens, YYNTOKENS); \ - fprintf (stderr, "expected tokens in state %d rule %d (%d):", \ - *yyssp, yyn - 1, cnt); \ - for (int i = 0; i < cnt; ++i) \ - fprintf (stderr, " %s", yysymbol_name(tokens[i])); \ - fprintf (stderr, "\n"); \ - } \ - } while (0) } %define api.header.include {"calc.h"} -%define api.value.type union /* Generate YYSTYPE from these types: */ -%define parse.error custom -%define parse.lac full + +/* Generate YYSTYPE from the types used in %token and %type. */ +%define api.value.type union %token <double> NUM "number" %type <double> expr term fact -/* Generate the parser description file. */ +/* Generate the parser description file (calc.output). */ %verbose + +/* Nice error messages with details. */ +%define parse.error detailed + /* Enable run-time traces (yydebug). */ %define parse.trace -/* Formatting semantic values. */ +/* Formatting semantic values in debug traces. */ %printer { fprintf (yyo, "%g", $$); } <double>; %% /* The grammar follows. */ input: - %empty { PRINT_EXPECTED_TOKENS (); } -| input line { PRINT_EXPECTED_TOKENS (); } + %empty +| input line ; line: @@ -66,35 +51,13 @@ term: ; fact: - "number" { PRINT_EXPECTED_TOKENS (); } -| '(' expr { PRINT_EXPECTED_TOKENS (); } ')' { $$ = $expr; } + "number" +| '(' expr ')' { $$ = $2; } ; %% int -yyreport_syntax_error (const yyparse_context_t *ctx) -{ - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 10 }; - /* Arguments of yyformat: reported tokens (one for the "unexpected", - one per "expected"). */ - int arg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int n = yysyntax_error_arguments (ctx, arg, sizeof arg / sizeof *arg); - if (n == -2) - return 2; - fprintf (stderr, "SYNTAX ERROR on token [%s]", yysymbol_name (arg[0])); - if (1 < n) - { - fprintf (stderr, " (expected:"); - for (int i = 1; i < n; ++i) - fprintf (stderr, " [%s]", yysymbol_name (arg[i])); - fprintf (stderr, ")"); - } - fprintf (stderr, "\n"); - return 0; -} - -int yylex (void) { int c; @@ -130,9 +93,7 @@ main (int argc, char const* argv[]) { /* Enable parse traces on option -p. */ for (int i = 1; i < argc; ++i) - if (!strcmp (argv[i], "-e")) - show_expected = 1; - else if (!strcmp (argv[i], "-p")) + if (!strcmp (argv[i], "-p")) yydebug = 1; return yyparse (); } diff --git a/examples/c/lexcalc/parse.y b/examples/c/lexcalc/parse.y index 68b1b175..060af4ab 100644 --- a/examples/c/lexcalc/parse.y +++ b/examples/c/lexcalc/parse.y @@ -19,12 +19,24 @@ #include <stdlib.h> // getenv. } +// Don't share global variables between the scanner and the parser. %define api.pure full + +// To avoid name clashes (e.g., with C's EOF) prefix token definitions +// with TOK_ (e.g., TOK_EOF). %define api.token.prefix {TOK_} + +// %token and %type use genuine types (e.g., "%token <int>"). Let +// %bison define YYSTYPE as a union of all these types. %define api.value.type union -%define parse.error verbose + +// Generate detailed error messages. +%define parse.error detailed + +// Enable debug traces (see yydebug in main). %define parse.trace - // Error count, exchanged between main, yyparse and yylex. + +// Error count, exchanged between main, yyparse and yylex. %param {int *nerrs} %token @@ -77,6 +89,7 @@ exp: ; %% // Epilogue (C code). + void yyerror (int *nerrs, const char *msg) { fprintf (stderr, "%s\n", msg); diff --git a/examples/c/lexcalc/scan.l b/examples/c/lexcalc/scan.l index 815f7782..e0b68504 100644 --- a/examples/c/lexcalc/scan.l +++ b/examples/c/lexcalc/scan.l @@ -1,4 +1,4 @@ -/* Prologue (directives). -*- C++ -*- */ +/* Prologue (directives). -*- C -*- */ /* Disable Flex features we don't need, to avoid warnings. */ %option nodefault noinput nounput noyywrap diff --git a/examples/c/reccalc/scan.l b/examples/c/reccalc/scan.l index fbb781aa..0bf5210c 100644 --- a/examples/c/reccalc/scan.l +++ b/examples/c/reccalc/scan.l @@ -1,4 +1,4 @@ -/* Prologue (directives). -*- C++ -*- */ +/* Prologue (directives). -*- C -*- */ /* Disable Flex features we don't need, to avoid warnings. */ %option nodefault noinput nounput noyywrap @@ -17,10 +17,14 @@ %% %{ + // Number of opened parentheses. int nesting = 0; + // A buffer storing the text inside the outer parentheses. char *str = NULL; - int size = 0; + // Its allocated size. int capacity = 0; + // Its used size. + int size = 0; #define STR_APPEND() \ do { \ if (capacity < size + yyleng + 1) \ |