[flang] Fix parsing bug on DATA statement
authorTim Keith <tkeith@nvidia.com>
Fri, 21 Feb 2020 23:31:12 +0000 (15:31 -0800)
committerTim Keith <tkeith@nvidia.com>
Fri, 21 Feb 2020 23:31:12 +0000 (15:31 -0800)
This DATA statement was getting a parsing error:
`data x /a(i)%b/`

The parser was expecting the ending '/' where the '%' was. The problem
was parsing `a(i)` as a structure constructor. Instead, move the
constant subobject case before structure constructor, but match it only
if not followed by '('. That is because in `data x /a(1)(2)/`, `a(1)` is
a valid structure constructor.

Also, remove the NamedConstant alternative from DataStmtRepeat. A named
constant is always parsed as a ConstantSubobject so it can never occur.

Original-commit: flang-compiler/f18@04a76b272675d47ec7752420b15976c69a907dab
Reviewed-on: https://github.com/flang-compiler/f18/pull/1012

flang/include/flang/parser/parse-tree.h
flang/lib/parser/Fortran-parsers.cpp

index 57093e3..f1e02e0 100644 (file)
@@ -1412,9 +1412,7 @@ struct DataStmtConstant {
 // (only literal-constant -> int-literal-constant applies)
 struct DataStmtRepeat {
   UNION_CLASS_BOILERPLATE(DataStmtRepeat);
-  std::variant<IntLiteralConstant, Scalar<Integer<NamedConstant>>,
-      Scalar<Integer<ConstantSubobject>>>
-      u;
+  std::variant<IntLiteralConstant, Scalar<Integer<ConstantSubobject>>> u;
 };
 
 // R843 data-stmt-value -> [data-stmt-repeat *] data-stmt-constant
index f895189..d15901a 100644 (file)
@@ -818,12 +818,10 @@ constexpr auto constantSubobject{constant(indirect(designator))};
 
 // R844 data-stmt-repeat -> scalar-int-constant | scalar-int-constant-subobject
 // R607 int-constant -> constant
-// Factored into:
-//   constant -> literal-constant -> int-literal-constant   and
-//   constant -> named-constant
+// Factored into: constant -> literal-constant -> int-literal-constant
+// The named-constant alternative of constant is subsumed by constant-subobject
 TYPE_PARSER(construct<DataStmtRepeat>(intLiteralConstant) ||
-    construct<DataStmtRepeat>(scalar(integer(constantSubobject))) ||
-    construct<DataStmtRepeat>(scalar(integer(namedConstant))))
+    construct<DataStmtRepeat>(scalar(integer(constantSubobject))))
 
 // R845 data-stmt-constant ->
 //        scalar-constant | scalar-constant-subobject |
@@ -833,8 +831,8 @@ TYPE_PARSER(construct<DataStmtRepeat>(intLiteralConstant) ||
 // references into constant subobjects.
 TYPE_PARSER(first(construct<DataStmtConstant>(scalar(Parser<ConstantValue>{})),
     construct<DataStmtConstant>(nullInit),
+    construct<DataStmtConstant>(scalar(constantSubobject)) / !"("_tok,
     construct<DataStmtConstant>(Parser<StructureConstructor>{}),
-    construct<DataStmtConstant>(scalar(constantSubobject)),
     construct<DataStmtConstant>(signedRealLiteralConstant),
     construct<DataStmtConstant>(signedIntLiteralConstant),
     extension<LanguageFeature::SignedComplexLiteral>(