1 //===-- lib/Parser/expr-parsers.h -------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef FORTRAN_PARSER_EXPR_PARSERS_H_
10 #define FORTRAN_PARSER_EXPR_PARSERS_H_
12 #include "basic-parsers.h"
13 #include "token-parsers.h"
14 #include "type-parsers.h"
15 #include "flang/Parser/parse-tree.h"
17 namespace Fortran::parser
{
19 // R403 scalar-xyz -> xyz
20 // Also define constant-xyz, int-xyz, default-char-xyz.
21 template <typename PA
> inline constexpr auto scalar(const PA
&p
) {
22 return construct
<Scalar
<typename
PA::resultType
>>(p
); // scalar-p
25 template <typename PA
> inline constexpr auto constant(const PA
&p
) {
26 return construct
<Constant
<typename
PA::resultType
>>(p
); // constant-p
29 template <typename PA
> inline constexpr auto integer(const PA
&p
) {
30 return construct
<Integer
<typename
PA::resultType
>>(p
); // int-p
33 template <typename PA
> inline constexpr auto logical(const PA
&p
) {
34 return construct
<Logical
<typename
PA::resultType
>>(p
); // logical-p
37 template <typename PA
> inline constexpr auto defaultChar(const PA
&p
) {
38 return construct
<DefaultChar
<typename
PA::resultType
>>(p
); // default-char-p
41 // N.B. charLiteralConstantWithoutKind does not skip preceding space.
42 constexpr auto charLiteralConstantWithoutKind
{
43 "'"_ch
>> CharLiteral
<'\''>{} || "\""_ch
>> CharLiteral
<'"'>{}};
45 // R904 logical-variable -> variable
46 // Appears only as part of scalar-logical-variable.
47 constexpr auto scalarLogicalVariable
{scalar(logical(variable
))};
49 // R906 default-char-variable -> variable
50 // Appears only as part of scalar-default-char-variable.
51 constexpr auto scalarDefaultCharVariable
{scalar(defaultChar(variable
))};
53 // R907 int-variable -> variable
54 // Appears only as part of scalar-int-variable.
55 constexpr auto scalarIntVariable
{scalar(integer(variable
))};
57 // R930 errmsg-variable -> scalar-default-char-variable
58 // R1207 iomsg-variable -> scalar-default-char-variable
59 constexpr auto msgVariable
{construct
<MsgVariable
>(scalarDefaultCharVariable
)};
61 // R1024 logical-expr -> expr
62 constexpr auto logicalExpr
{logical(indirect(expr
))};
63 constexpr auto scalarLogicalExpr
{scalar(logicalExpr
)};
65 // R1025 default-char-expr -> expr
66 constexpr auto defaultCharExpr
{defaultChar(indirect(expr
))};
67 constexpr auto scalarDefaultCharExpr
{scalar(defaultCharExpr
)};
69 // R1026 int-expr -> expr
70 constexpr auto intExpr
{integer(indirect(expr
))};
71 constexpr auto scalarIntExpr
{scalar(intExpr
)};
73 // R1029 constant-expr -> expr
74 constexpr auto constantExpr
{constant(indirect(expr
))};
75 constexpr auto scalarExpr
{scalar(indirect(expr
))};
77 // R1030 default-char-constant-expr -> default-char-expr
78 constexpr auto scalarDefaultCharConstantExpr
{scalar(defaultChar(constantExpr
))};
80 // R1031 int-constant-expr -> int-expr
81 constexpr auto intConstantExpr
{integer(constantExpr
)};
82 constexpr auto scalarIntConstantExpr
{scalar(intConstantExpr
)};
84 // R935 lower-bound-expr -> scalar-int-expr
85 // R936 upper-bound-expr -> scalar-int-expr
86 constexpr auto boundExpr
{scalarIntExpr
};
88 // R1115 team-value -> scalar-expr
89 constexpr auto teamValue
{scalar(indirect(expr
))};
91 // R1124 do-variable -> scalar-int-variable-name
92 constexpr auto doVariable
{scalar(integer(name
))};
94 // NOTE: In loop-control we allow REAL name and bounds too.
95 // This means parse them without the integer constraint and check later.
96 inline constexpr auto loopBounds(decltype(scalarExpr
) &p
) {
97 return construct
<LoopBounds
<ScalarName
, ScalarExpr
>>(
98 scalar(name
) / "=", p
/ ",", p
, maybe("," >> p
));
100 template <typename PA
> inline constexpr auto loopBounds(const PA
&p
) {
101 return construct
<LoopBounds
<DoVariable
, typename
PA::resultType
>>(
102 doVariable
/ "=", p
/ ",", p
, maybe("," >> p
));
104 } // namespace Fortran::parser