|
27 | 27 | %locations
|
28 | 28 | %debug
|
29 | 29 |
|
30 |
| -// Nice error messages with details. |
31 |
| -%define parse.error detailed |
| 30 | +// Custom error messages. |
| 31 | +%define parse.error custom |
32 | 32 |
|
33 | 33 | %code requires
|
34 | 34 | {
|
|
44 | 44 | #include <fstream>
|
45 | 45 | #include <cstring>
|
46 | 46 |
|
| 47 | + // Merge two semantic values. |
47 | 48 | static Node
|
48 | 49 | stmt_merge (const Node& x0, const Node& x1);
|
49 | 50 |
|
| 51 | + // Fetch a token. |
50 | 52 | static yy::parser::symbol_type
|
51 | 53 | yylex ();
|
52 | 54 | }
|
@@ -100,13 +102,41 @@ declarator
|
100 | 102 | std::istream* input = nullptr;
|
101 | 103 | yy::parser::location_type loc;
|
102 | 104 |
|
103 |
| -// An error reporting function. |
| 105 | + |
| 106 | +/*---------. |
| 107 | +| Parser. | |
| 108 | +`---------*/ |
| 109 | + |
| 110 | +// Generate a custom error message. |
| 111 | +void |
| 112 | +yy::parser::report_syntax_error (const context& ctx) const |
| 113 | +{ |
| 114 | + std::cerr << ctx.location () << ": syntax error"; |
| 115 | + if (!ctx.lookahead ().empty ()) |
| 116 | + std::cerr << " on token " << ctx.lookahead ().name (); |
| 117 | + { |
| 118 | + enum { TOKENMAX = 10 }; |
| 119 | + symbol_kind_type expected[TOKENMAX]; |
| 120 | + int n = ctx.expected_tokens (expected, TOKENMAX); |
| 121 | + if (0 < n) |
| 122 | + { |
| 123 | + for (int i = 0; i < n; ++i) |
| 124 | + std::cerr << (i == 0 ? " (expected " : " or ") |
| 125 | + << symbol_name (expected[i]); |
| 126 | + std::cerr << ')'; |
| 127 | + } |
| 128 | + } |
| 129 | + std::cerr << '\n'; |
| 130 | +} |
| 131 | + |
| 132 | +// Report the error to the user. |
104 | 133 | void
|
105 | 134 | yy::parser::error (const location_type& l, const std::string& m)
|
106 | 135 | {
|
107 | 136 | std::cerr << l << ": " << m << '\n';
|
108 | 137 | }
|
109 | 138 |
|
| 139 | +// Fetch the next token. |
110 | 140 | static yy::parser::symbol_type
|
111 | 141 | yylex ()
|
112 | 142 | {
|
@@ -168,12 +198,19 @@ yylex ()
|
168 | 198 | }
|
169 | 199 | }
|
170 | 200 |
|
| 201 | +// Merge two semantic values as an AST including both alternatives. |
171 | 202 | static Node
|
172 | 203 | stmt_merge (const Node& x0, const Node& x1)
|
173 | 204 | {
|
174 | 205 | return Nterm ("<OR>", x0, x1);
|
175 | 206 | }
|
176 | 207 |
|
| 208 | + |
| 209 | +/*-------. |
| 210 | +| Main. | |
| 211 | +`-------*/ |
| 212 | + |
| 213 | +// Parse `file` using parser `parse`. |
177 | 214 | int
|
178 | 215 | process (yy::parser& parse, const std::string& file)
|
179 | 216 | {
|
|
0 commit comments