mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
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.
This commit is contained in:
@@ -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 '('"
|
||||
|
||||
@@ -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,34 +51,12 @@ 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)
|
||||
{
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user