|
9 | 9 | // Per-type parsers for executable statements
|
10 | 10 |
|
11 | 11 | #include "basic-parsers.h"
|
12 |
| -#include "debug-parser.h" |
13 | 12 | #include "expr-parsers.h"
|
14 | 13 | #include "misc-parsers.h"
|
15 | 14 | #include "stmt-parser.h"
|
@@ -282,18 +281,26 @@ TYPE_CONTEXT_PARSER("loop control"_en_US,
|
282 | 281 | "CONCURRENT" >> concurrentHeader,
|
283 | 282 | many(Parser<LocalitySpec>{})))))
|
284 | 283 |
|
| 284 | +// "DO" is a valid statement, so the loop control is optional; but for |
| 285 | +// better recovery from errors in the loop control, don't parse a |
| 286 | +// DO statement with a bad loop control as a DO statement that has |
| 287 | +// no loop control and is followed by garbage. |
| 288 | +static constexpr auto loopControlOrEndOfStmt{ |
| 289 | + construct<std::optional<LoopControl>>(Parser<LoopControl>{}) || |
| 290 | + lookAhead(":\n"_ch) >> construct<std::optional<LoopControl>>()}; |
| 291 | + |
285 | 292 | // R1121 label-do-stmt -> [do-construct-name :] DO label [loop-control]
|
286 | 293 | // A label-do-stmt with a do-construct-name is parsed as a nonlabel-do-stmt
|
287 | 294 | // with an optional label.
|
288 | 295 | TYPE_CONTEXT_PARSER("label DO statement"_en_US,
|
289 |
| - construct<LabelDoStmt>("DO" >> label, maybe(loopControl))) |
| 296 | + construct<LabelDoStmt>("DO" >> label, loopControlOrEndOfStmt)) |
290 | 297 |
|
291 | 298 | // R1122 nonlabel-do-stmt -> [do-construct-name :] DO [loop-control]
|
292 | 299 | TYPE_CONTEXT_PARSER("nonlabel DO statement"_en_US,
|
293 | 300 | construct<NonLabelDoStmt>(
|
294 |
| - name / ":", "DO" >> maybe(label), maybe(loopControl)) || |
| 301 | + name / ":", "DO" >> maybe(label), loopControlOrEndOfStmt) || |
295 | 302 | construct<NonLabelDoStmt>(construct<std::optional<Name>>(),
|
296 |
| - construct<std::optional<Label>>(), "DO" >> maybe(loopControl))) |
| 303 | + construct<std::optional<Label>>(), "DO" >> loopControlOrEndOfStmt)) |
297 | 304 |
|
298 | 305 | // R1132 end-do-stmt -> END DO [do-construct-name]
|
299 | 306 | TYPE_CONTEXT_PARSER("END DO statement"_en_US,
|
|
0 commit comments