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