[TargetVersion] Only enable on RISC-V and AArch64 (#115991)
[llvm-project.git] / flang / lib / Parser / stmt-parser.h
blobee45c6fd5d38c13d2ce4128bb6f86a0b83c5163e
1 //===-- lib/Parser/stmt-parser.h --------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef FORTRAN_PARSER_STMT_PARSER_H_
10 #define FORTRAN_PARSER_STMT_PARSER_H_
12 // Basic parsing of statements.
14 #include "basic-parsers.h"
15 #include "token-parsers.h"
17 namespace Fortran::parser {
19 // statement(p) parses Statement<P> for some statement type P that is the
20 // result type of the argument parser p, while also handling labels and
21 // end-of-statement markers.
23 // R611 label -> digit [digit]...
24 constexpr auto label{space >> digitString64 / spaceCheck};
26 template <typename PA>
27 inline constexpr auto unterminatedStatement(const PA &p) {
28 return skipStuffBeforeStatement >>
29 sourced(construct<Statement<typename PA::resultType>>(
30 maybe(label), space >> p));
33 constexpr auto atEndOfStmt{space >>
34 withMessage("expected end of statement"_err_en_US, lookAhead(";\n"_ch))};
35 constexpr auto checkEndOfKnownStmt{recovery(atEndOfStmt, SkipTo<'\n'>{})};
37 constexpr auto endOfLine{
38 "\n"_ch >> ok || fail("expected end of line"_err_en_US)};
40 constexpr auto semicolons{";"_ch >> skipMany(";"_tok) / space / maybe("\n"_ch)};
41 constexpr auto endOfStmt{
42 space >> withMessage("expected end of statement"_err_en_US,
43 semicolons || endOfLine)};
44 constexpr auto forceEndOfStmt{recovery(endOfStmt, SkipPast<'\n'>{})};
46 template <typename PA> inline constexpr auto statement(const PA &p) {
47 return unterminatedStatement(p) / endOfStmt;
50 // unlabeledStatement() is basically statement() for those few situations
51 // in Fortran where a statement cannot have a label.
52 template <typename PA> inline constexpr auto unlabeledStatement(const PA &p) {
53 return space >>
54 sourced(construct<UnlabeledStatement<typename PA::resultType>>(p));
57 // This unambiguousStatement() variant of statement() provides better error
58 // recovery for contexts containing statements that might have trailing
59 // garbage, but it must be used only when no instance of the statement in
60 // question could also be a legal prefix of some other statement that might
61 // be valid at that point. It only makes sense to use this within "some()"
62 // or "many()" so as to not end the list of statements.
63 template <typename PA> inline constexpr auto unambiguousStatement(const PA &p) {
64 return unterminatedStatement(p) / forceEndOfStmt;
67 constexpr auto ignoredStatementPrefix{
68 skipStuffBeforeStatement >> maybe(label) >> maybe(name / ":") >> space};
70 // Error recovery within a statement() call: skip *to* the end of the line,
71 // unless at an END or CONTAINS statement.
72 constexpr auto inStmtErrorRecovery{!"END"_tok >> !"CONTAINS"_tok >>
73 SkipTo<'\n'>{} >> construct<ErrorRecovery>()};
75 // Error recovery within statement sequences: skip *past* the end of the line,
76 // but not over an END or CONTAINS statement.
77 constexpr auto skipStmtErrorRecovery{!"END"_tok >> !"CONTAINS"_tok >>
78 SkipPast<'\n'>{} >> construct<ErrorRecovery>()};
80 // Error recovery across statements: skip the line, unless it looks
81 // like it might end the containing construct.
82 constexpr auto stmtErrorRecoveryStart{ignoredStatementPrefix};
83 constexpr auto skipBadLine{SkipPast<'\n'>{} >> construct<ErrorRecovery>()};
84 constexpr auto executionPartErrorRecovery{stmtErrorRecoveryStart >>
85 !"END"_tok >> !"CONTAINS"_tok >> !"ELSE"_tok >> !"CASE"_tok >>
86 !"TYPE IS"_tok >> !"CLASS"_tok >> !"RANK"_tok >>
87 !("!$ACC "_sptok >> "END"_tok) >>
88 !("!$OMP "_sptok >> ("END"_tok || "SECTION"_id)) >> skipBadLine};
90 // END statement error recovery
91 constexpr auto missingOptionalName{pure<std::optional<Name>>()};
92 constexpr auto noNameEnd{"END" >> missingOptionalName};
94 // For unrecognizable construct END statements. Be sure to not consume
95 // a program unit's END statement.
96 constexpr auto progUnitEndStmt{
97 "END" >> (lookAhead("\n"_ch) || "SUBROUTINE"_tok || "FUNCTION"_tok ||
98 "PROCEDURE"_tok || "MODULE"_tok || "SUBMODULE"_tok ||
99 "PROGRAM"_tok || "BLOCK DATA"_tok)};
100 constexpr auto constructEndStmtErrorRecovery{
101 !progUnitEndStmt >> ("END"_tok >> SkipTo<'\n'>{} || ok)};
102 constexpr auto namedConstructEndStmtErrorRecovery{
103 constructEndStmtErrorRecovery >> missingOptionalName};
105 constexpr auto progUnitEndStmtErrorRecovery{
106 (many(!"END"_tok >> SkipPast<'\n'>{}) >>
107 ("END"_tok >> SkipTo<'\n'>{} || consumedAllInput)) >>
108 missingOptionalName};
110 constexpr auto beginDirective{skipStuffBeforeStatement >> "!"_ch};
111 constexpr auto endDirective{space >> endOfLine};
113 } // namespace Fortran::parser
114 #endif // FORTRAN_PARSER_STMT_PARSER_H_