[flang] Fix parse of .TRUE._8
authorpeter klausler <pklausler@nvidia.com>
Sat, 16 Mar 2019 17:04:18 +0000 (10:04 -0700)
committerpeter klausler <pklausler@nvidia.com>
Sun, 17 Mar 2019 22:51:02 +0000 (15:51 -0700)
Original-commit: flang-compiler/f18@b03e7a691d21f84b53a04ed71327720f5500c924
Reviewed-on: https://github.com/flang-compiler/f18/pull/336

flang/lib/parser/grammar.h
flang/lib/parser/token-parsers.h
flang/lib/semantics/expression.cc

index 7df25e7..8c1a7ea 100644 (file)
@@ -688,17 +688,10 @@ TYPE_CONTEXT_PARSER(
 // R725 logical-literal-constant ->
 //        .TRUE. [_ kind-param] | .FALSE. [_ kind-param]
 // Also accept .T. and .F. as extensions.
-TYPE_PARSER(
-    construct<LogicalLiteralConstant>(
-        (".TRUE."_tok ||
-            extension<LanguageFeature::LogicalAbbreviations>(".T."_tok)) >>
-            pure(true),
-        maybe(underscore >> kindParam)) ||
+TYPE_PARSER(construct<LogicalLiteralConstant>(
+                logicalTRUE, maybe(underscore >> kindParam)) ||
     construct<LogicalLiteralConstant>(
-        (".FALSE."_tok ||
-            extension<LanguageFeature::LogicalAbbreviations>(".F."_tok)) >>
-            pure(false),
-        maybe(underscore >> kindParam)))
+        logicalFALSE, maybe(underscore >> kindParam)))
 
 // R726 derived-type-def ->
 //        derived-type-stmt [type-param-def-stmt]...
@@ -1625,13 +1618,13 @@ constexpr auto primary{instrumented("primary"_en_US,
 
 // R1002 level-1-expr -> [defined-unary-op] primary
 // TODO: Reasonable extension: permit multiple defined-unary-ops
-constexpr auto level1Expr{sourced(first(
-    construct<Expr>(construct<Expr::DefinedUnary>(definedOpName, primary)),
-    primary,
-    extension<LanguageFeature::SignedPrimary>(
-        construct<Expr>(construct<Expr::UnaryPlus>("+" >> primary))),
-    extension<LanguageFeature::SignedPrimary>(
-        construct<Expr>(construct<Expr::Negate>("-" >> primary)))))};
+constexpr auto level1Expr{sourced(
+    first(primary,  // must come before define op to resolve .TRUE._8 ambiguity
+        construct<Expr>(construct<Expr::DefinedUnary>(definedOpName, primary)),
+        extension<LanguageFeature::SignedPrimary>(
+            construct<Expr>(construct<Expr::UnaryPlus>("+" >> primary))),
+        extension<LanguageFeature::SignedPrimary>(
+            construct<Expr>(construct<Expr::Negate>("-" >> primary)))))};
 
 // R1004 mult-operand -> level-1-expr [power-op mult-operand]
 // R1007 power-op -> **
index c51287a..bd92159 100644 (file)
@@ -704,10 +704,22 @@ constexpr auto rawName{nonDigitIdChar >> many(nonDigitIdChar || digit)};
 TYPE_PARSER(space >> sourced(rawName >> construct<Name>()))
 constexpr auto keyword{construct<Keyword>(name)};
 
+constexpr auto logicalTRUE{
+    (".TRUE."_tok ||
+        extension<LanguageFeature::LogicalAbbreviations>(".T."_tok)) >>
+    pure(true)};
+constexpr auto logicalFALSE{
+    (".FALSE."_tok ||
+        extension<LanguageFeature::LogicalAbbreviations>(".F."_tok)) >>
+    pure(false)};
+
 // R1003 defined-unary-op -> . letter [letter]... .
 // R1023 defined-binary-op -> . letter [letter]... .
 // R1414 local-defined-operator -> defined-unary-op | defined-binary-op
 // R1415 use-defined-operator -> defined-unary-op | defined-binary-op
+// C1003 A defined operator must be distinct from logical literal constants
+// and intrinsic operator names; this is handled by attempting their parses
+// first, and by name resolution on their definitions, for best errors.
 // N.B. The name of the operator is captured without the periods around it.
 constexpr auto definedOpNameChar{
     letter || extension<LanguageFeature::PunctuationInNames>("$@"_ch)};
index 83c2161..98c207f 100644 (file)
@@ -279,7 +279,7 @@ MaybeExpr ExpressionAnalyzer::TopLevelChecks(DataRef &&dataRef) {
     if (componentRank > 0) {
       int baseRank{component->base().Rank()};
       if (baseRank > 0) {
-        Say("reference to whole rank-%d component '%%%s' of "
+        Say("Reference to whole rank-%d component '%%%s' of "
             "rank-%d array of derived type is not allowed"_err_en_US,
             componentRank, symbol.name().ToString().data(), baseRank);
       } else {