diff options
author | Akim Demaille <akim.demaille@gmail.com> | 2021-09-07 08:21:40 +0200 |
---|---|---|
committer | Akim Demaille <akim.demaille@gmail.com> | 2021-09-12 12:03:58 +0200 |
commit | 2142e5915576b124d76e3acecd34e4bbf538d2fe (patch) | |
tree | e586523725fd02a55c9df66fc49502450875133f /examples | |
parent | a75072476e251db338f392bef4200d3a2fe2c17a (diff) | |
download | bison-2142e5915576b124d76e3acecd34e4bbf538d2fe.tar.gz |
c++: demonstrate custom error messages in the examples
Let's use c++/glr to demonstrate custom error messages in C++ (not
just in glr2.cc).
* examples/c++/glr/c++-types.yy (report_syntax_error): New.
* examples/c++/glr/c++-types.test: Adjust.
* examples/c/bistromathic/parse.y: Comment changes.
* tests/local.at (AT_YYERROR_DEFINE(c++)): Use a nicer way to print
the lookakead's name.
Diffstat (limited to 'examples')
-rw-r--r-- | examples/c++/README.md | 9 | ||||
-rw-r--r-- | examples/c++/glr/README.md | 3 | ||||
-rw-r--r-- | examples/c++/glr/c++-types.test | 2 | ||||
-rw-r--r-- | examples/c++/glr/c++-types.yy | 43 | ||||
-rw-r--r-- | examples/c/bistromathic/parse.y | 5 |
5 files changed, 56 insertions, 6 deletions
diff --git a/examples/c++/README.md b/examples/c++/README.md index 93cd09d5..dff3783e 100644 --- a/examples/c++/README.md +++ b/examples/c++/README.md @@ -39,6 +39,15 @@ examples. Extracted from the documentation: [A Complete C++ Example](https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html). +## glr + +This example demonstrates the use of GLR parsers to handle (local) +ambiguities in the C++ language. See the node "Merging GLR Parses" in +Bison's documentation. + +It uses (Bison) variants to store objects as semantic values. It also +demonstrates custom error messages in C++. + <!--- Local Variables: diff --git a/examples/c++/glr/README.md b/examples/c++/glr/README.md index 26067c27..ed06a0c6 100644 --- a/examples/c++/glr/README.md +++ b/examples/c++/glr/README.md @@ -4,6 +4,9 @@ This example demonstrates the use of GLR parsers to handle (local) ambiguities in the C++ language. See the node "Merging GLR Parses" in Bison's documentation. +It uses (Bison) variants to store objects as semantic values. It also +demonstrates custom error messages in C++. + <!--- Local Variables: fill-column: 76 diff --git a/examples/c++/glr/c++-types.test b/examples/c++/glr/c++-types.test index 7440ea24..db5be8d7 100644 --- a/examples/c++/glr/c++-types.test +++ b/examples/c++/glr/c++-types.test @@ -47,4 +47,4 @@ run 0 "\ 5.0-13: <OR>(<init-declare>(T, y, +(z, q)), =(<cast>(y, T), +(z, q))) 7.0-15: <error> 9.0-5: +(z, q) -err: 7.5: syntax error, unexpected identifier, expecting = or + or )" +err: 7.5: syntax error on token identifier (expected = or + or ))" diff --git a/examples/c++/glr/c++-types.yy b/examples/c++/glr/c++-types.yy index fa8889de..a3131b05 100644 --- a/examples/c++/glr/c++-types.yy +++ b/examples/c++/glr/c++-types.yy @@ -27,8 +27,8 @@ %locations %debug -// Nice error messages with details. -%define parse.error detailed +// Custom error messages. +%define parse.error custom %code requires { @@ -44,9 +44,11 @@ #include <fstream> #include <cstring> + // Merge two semantic values. static Node stmt_merge (const Node& x0, const Node& x1); + // Fetch a token. static yy::parser::symbol_type yylex (); } @@ -100,13 +102,41 @@ declarator std::istream* input = nullptr; yy::parser::location_type loc; -// An error reporting function. + +/*---------. +| Parser. | +`---------*/ + +// Generate a custom error message. +void +yy::parser::report_syntax_error (const context& ctx) const +{ + std::cerr << ctx.location () << ": syntax error"; + if (!ctx.lookahead ().empty ()) + std::cerr << " on token " << ctx.lookahead ().name (); + { + enum { TOKENMAX = 10 }; + symbol_kind_type expected[TOKENMAX]; + int n = ctx.expected_tokens (expected, TOKENMAX); + if (0 < n) + { + for (int i = 0; i < n; ++i) + std::cerr << (i == 0 ? " (expected " : " or ") + << symbol_name (expected[i]); + std::cerr << ')'; + } + } + std::cerr << '\n'; +} + +// Report the error to the user. void yy::parser::error (const location_type& l, const std::string& m) { std::cerr << l << ": " << m << '\n'; } +// Fetch the next token. static yy::parser::symbol_type yylex () { @@ -168,12 +198,19 @@ yylex () } } +// Merge two semantic values as an AST including both alternatives. static Node stmt_merge (const Node& x0, const Node& x1) { return Nterm ("<OR>", x0, x1); } + +/*-------. +| Main. | +`-------*/ + +// Parse `file` using parser `parse`. int process (yy::parser& parse, const std::string& file) { diff --git a/examples/c/bistromathic/parse.y b/examples/c/bistromathic/parse.y index e06db523..8b1591e6 100644 --- a/examples/c/bistromathic/parse.y +++ b/examples/c/bistromathic/parse.y @@ -465,8 +465,9 @@ yyreport_syntax_error (const yypcontext_t *ctx, const user_context *uctx) } -// Called by yyparse on error. -void yyerror (const YYLTYPE *loc, const user_context *uctx, char const *format, ...) +// Called by yyparse on errors to report the error to the user. +void +yyerror (const YYLTYPE *loc, const user_context *uctx, char const *format, ...) { if (uctx->silent) return; |