コード例 #1
0
// FIXME: Fortran 2008 stuff.
/// ParseDerivedTypeDefinitionStmt - Parse a type or a class definition.
///
/// [R422]:
///   derived-type-def :=
///     derived-type-stmt
///     [ private-sequence-stmt ] ...
///     component-def-stmt
///     [ component-def-stmt ] ...
///     end-type-stmt
///
/// [R423]:
///   derived-type-stmt :=
///     TYPE [ [ , access-spec ] :: ] type-name
///
/// [R424]:
///   private-sequence-stmt :=
///     PRIVATE or SEQUENCE
///
/// [R425]:
///   component-def-stmt :=
///     type-spec [ [ component-attr-spec-list ] :: ] component-decl-list
///
/// [R426]:
///   component-attr-spec-list :=
///     POINTER or
///     DIMENSION( component-array-spec )
///
/// [R427]:
///   component-array-spec :=
///     explicit-shape-spec-list or
///     deffered-shape-spec-list
///
/// [R428]:
///   component-decl :=
///     component-name [ ( component-array-spec ) ]
///     [ * char-length ] [ component-initialization ]
///
/// [R429]:
///   component-initialization :=
///     = initialization-expr or
///     => NULL()
///
/// [R430]:
///   end-type-stmt :=
///     END TYPE [ type-name ]
bool Parser::ParseDerivedTypeDefinitionStmt() {
  bool IsClass = Tok.is(tok::kw_CLASS);
  auto Loc = ConsumeToken();

  if(ConsumeIfPresent(tok::comma)) {
    //FIXME: access-spec
  }
  ConsumeIfPresent(tok::coloncolon);

  auto ID = Tok.getIdentifierInfo();
  auto IDLoc = Tok.getLocation();
  if(!ExpectAndConsume(tok::identifier)) {
    SkipUntilNextStatement();
    return true;
  } else
    ExpectStatementEnd();

  Actions.ActOnDerivedTypeDecl(Context, Loc, IDLoc, ID);

  // FIXME: private
  if(Tok.is(tok::kw_SEQUENCE)) {
    Actions.ActOnDerivedTypeSequenceStmt(Context, ConsumeToken());
    ExpectStatementEnd();
  }

  bool Done = false;
  while(!Done) {
    switch(Tok.getKind()) {
    case tok::kw_TYPE:
    case tok::kw_CLASS:
    case tok::kw_INTEGER:
    case tok::kw_REAL:
    case tok::kw_COMPLEX:
    case tok::kw_CHARACTER:
    case tok::kw_BYTE:
    case tok::kw_LOGICAL:
    case tok::kw_DOUBLEPRECISION:
    case tok::kw_DOUBLECOMPLEX:
      if(ParseDerivedTypeComponentStmt())
        SkipUntilNextStatement();
      else ExpectStatementEnd();
      break;
    default:
      Done = true;
      break;
    }
  }

  ParseEndTypeStmt();

  Actions.ActOnEndDerivedTypeDecl(Context);
  return false;
error:
  return true;
}
コード例 #2
0
ファイル: ParseSpecStmt.cpp プロジェクト: carlobertolli/flang
/// ParseEQUIVALENCEStmt - Parse the EQUIVALENCE statement.
///
///   [R554]:
///     equivalence-stmt :=
///         EQUIVALENCE equivalence-set-list
Parser::StmtResult Parser::ParseEQUIVALENCEStmt() {
  // Check if this is an assignment.
  if (IsNextToken(tok::equal))
    return StmtResult();

  auto Loc = ConsumeToken();
  SmallVector<Stmt*, 8> StmtList;
  SmallVector<Expr*, 8> ObjectList;

  bool OuterError = false;
  while(true) {
    auto PartLoc = Tok.getLocation();
    if(!ExpectAndConsume(tok::l_paren)) {
      if(!SkipUntil(tok::l_paren)) {
        OuterError = true;
        break;
      }
    }

    ObjectList.clear();
    bool InnerError = false;
    do {
      auto E = ParseExpectedExpression();
      if(E.isInvalid()) {
        InnerError = true;
        break;
      } else if(E.isUsable())
        ObjectList.push_back(E.get());
    } while(ConsumeIfPresent(tok::comma));

    auto S = Actions.ActOnEQUIVALENCE(Context, Loc, PartLoc, ObjectList, nullptr);
    if(S.isUsable())
      StmtList.push_back(S.get());

    if(InnerError) {
      if(!SkipUntil(tok::r_paren, true, true)) {
        OuterError = true;
        break;
      }
    }
    if(!ExpectAndConsume(tok::r_paren)) {
      if(!SkipUntil(tok::r_paren)) {
        OuterError = true;
        break;
      }
    }

    if(ConsumeIfPresent(tok::comma)) continue;
    if(IsPresent(tok::l_paren)) {
      ExpectAndConsume(tok::comma);
      continue;
    }
    break;
  }

  if(OuterError) SkipUntilNextStatement();
  else ExpectStatementEnd();

  return Actions.ActOnCompoundStmt(Context, Loc, StmtList, StmtLabel);
}
コード例 #3
0
ファイル: ParseExec.cpp プロジェクト: carlobertolli/flang
Parser::StmtResult Parser::ParseAmbiguousAssignmentStmt() {
  ParseStatementLabel();
  auto S = ParseAssignmentStmt();
  if(S.isInvalid()) SkipUntilNextStatement();
  else ExpectStatementEnd();
  return S;
}
コード例 #4
0
ファイル: ParseSpecStmt.cpp プロジェクト: carlobertolli/flang
/// ParseCOMMONStmt - Parse the COMMON statement.
///
///   [5.5.2] R557:
///     common-stmt :=
///         COMMON #
///         # [ / [common-block-name] / ] common-block-object-list #
///         # [ [,] / [common-block-name / #
///         #   common-block-object-list ] ...
Parser::StmtResult Parser::ParseCOMMONStmt() {
  // Check if this is an assignment.
  if (IsNextToken(tok::equal))
    return StmtResult();

  auto Loc = ConsumeToken();
  SmallVector<Stmt*, 8> StmtList;
  SmallVector<Expr*, 8> ObjectList;

  SourceLocation BlockIDLoc;
  const IdentifierInfo *BlockID = nullptr;

  bool Error = false;
  do {
    if(ConsumeIfPresent(tok::slash)) {
      if(ConsumeIfPresent(tok::slash))
        BlockID = nullptr;
      else {
        BlockIDLoc = Tok.getLocation();
        BlockID = Tok.getIdentifierInfo();
        if(!ExpectAndConsume(tok::identifier)) {
          Error = true;
          break;
        }
        if(!ExpectAndConsume(tok::slash)) {
          Error = true;
          break;
        }
      }
    } else if(ConsumeIfPresent(tok::slashslash))
      BlockID = nullptr;

    auto IDLoc = Tok.getLocation();
    auto IDInfo = Tok.getIdentifierInfo();
    SmallVector<ArraySpec*, 8> Dimensions;

    if(!ExpectAndConsume(tok::identifier)) {
      Error = true;
      break;
    }
    if(IsPresent(tok::l_paren)) {
      if(ParseArraySpec(Dimensions)) {
        Error = true;
        break;
      }
    }

    Actions.ActOnCOMMON(Context, Loc, BlockIDLoc,
                        IDLoc, BlockID, IDInfo,
                        Dimensions);
  } while(ConsumeIfPresent(tok::comma));


  if(Error) SkipUntilNextStatement();
  else ExpectStatementEnd();

  return Actions.ActOnCompoundStmt(Context, Loc, StmtList, StmtLabel);
}
コード例 #5
0
void Parser::ParseEndTypeStmt() {
  if(Tok.isNot(tok::kw_ENDTYPE)) {
    Diag.Report(Tok.getLocation(), diag::err_expected_kw)
      << "end type";
    Diag.Report(cast<NamedDecl>(Actions.CurContext)->getLocation(), diag::note_matching)
      << "type";
    return;
  }

  auto Loc = ConsumeToken();
  if(IsPresent(tok::identifier)) {
    auto ID = Tok.getIdentifierInfo();
    Actions.ActOnENDTYPE(Context, Loc, ConsumeToken(), ID);
  } else
    Actions.ActOnENDTYPE(Context, Loc, Loc, nullptr);
  ExpectStatementEnd();
}
コード例 #6
0
ファイル: ParseSpecStmt.cpp プロジェクト: carlobertolli/flang
/// ParseSAVEStmt - Parse the SAVE statement.
///
///   [R543]:
///     save-stmt :=
///         SAVE [ [::] saved-entity-list ]
Parser::StmtResult Parser::ParseSAVEStmt() {
  // Check if this is an assignment.
  if (IsNextToken(tok::equal))
    return StmtResult();

  auto Loc = ConsumeToken();
  if(Tok.isAtStartOfStatement())
    return Actions.ActOnSAVE(Context, Loc, StmtLabel);

  bool IsSaveStmt = ConsumeIfPresent(tok::coloncolon);
  SmallVector<Stmt *,8> StmtList;
  bool ListParsedOk = true;

  auto IDLoc = Tok.getLocation();
  auto II = Tok.getIdentifierInfo();
  StmtResult Stmt;
  if(ConsumeIfPresent(tok::slash)) {
    IDLoc = Tok.getLocation();
    II = Tok.getIdentifierInfo();
    if(ExpectAndConsume(tok::identifier)) {
      if(!ExpectAndConsume(tok::slash))
        ListParsedOk = false;
      Stmt = Actions.ActOnSAVECommonBlock(Context, Loc, IDLoc, II);
    }
    else ListParsedOk = false;
  }
  else if(ExpectAndConsume(tok::identifier)) {
    if(!IsSaveStmt && Features.FixedForm && (IsPresent(tok::equal) || IsPresent(tok::l_paren)))
      return ReparseAmbiguousAssignmentStatement();
    Stmt = Actions.ActOnSAVE(Context, Loc, IDLoc, II, nullptr);
  } else ListParsedOk = false;

  if(Stmt.isUsable())
    StmtList.push_back(Stmt.get());
  if(ListParsedOk) {
    while(ConsumeIfPresent(tok::comma)) {
      IDLoc = Tok.getLocation();
      II = Tok.getIdentifierInfo();
      if(ConsumeIfPresent(tok::slash)) {
        IDLoc = Tok.getLocation();
        II = Tok.getIdentifierInfo();
        if(!ExpectAndConsume(tok::identifier)) {
          ListParsedOk = false;
          break;
        }
        if(!ExpectAndConsume(tok::slash)) {
          ListParsedOk = false;
          break;
        }
        Stmt = Actions.ActOnSAVECommonBlock(Context, Loc, IDLoc, II);
      }
      else if(ExpectAndConsume(tok::identifier))
        Stmt = Actions.ActOnSAVE(Context, Loc, IDLoc, II, nullptr);
      else {
        ListParsedOk = false;
        break;
      }

      if(Stmt.isUsable())
        StmtList.push_back(Stmt.get());
    }
  }

  if(ListParsedOk) ExpectStatementEnd();
  else SkipUntilNextStatement();

  return Actions.ActOnCompoundStmt(Context, Loc, StmtList, StmtLabel);
}
コード例 #7
0
ファイル: ParseSpecStmt.cpp プロジェクト: carlobertolli/flang
/// ParseIMPLICITStmt - Parse the IMPLICIT statement.
///
///   [R560]:
///     implicit-stmt :=
///         IMPLICIT implicit-spec-list
///      or IMPLICIT NONE
Parser::StmtResult Parser::ParseIMPLICITStmt() {
  // Check if this is an assignment.
  if (IsNextToken(tok::equal))
    return StmtResult();

  auto Loc = ConsumeToken();

  if (ConsumeIfPresent(tok::kw_NONE)) {
    auto Result = Actions.ActOnIMPLICIT(Context, Loc, StmtLabel);
    ExpectStatementEnd();
    return Result;
  }

  SmallVector<Stmt*, 8> StmtList;

  while(true) {
    // FIXME: improved error recovery
    DeclSpec DS;
    if (ParseDeclarationTypeSpec(DS, false))
      return StmtError();

    if(!ExpectAndConsume(tok::l_paren)) {
      if(!SkipUntil(tok::l_paren))
        break;
    }

    bool InnerError = false;
    while(true) {
      auto FirstLoc = Tok.getLocation();
      auto First = Tok.getIdentifierInfo();
      if(!ExpectAndConsume(tok::identifier, diag::err_expected_letter)) {
        if(!SkipUntil(tok::comma)) {
          InnerError = true;
          break;
        }
        continue;
      }
      if(First->getName().size() > 1) {
        Diag.Report(FirstLoc, diag::err_expected_letter);
      }

      const IdentifierInfo *Second = nullptr;
      if (ConsumeIfPresent(tok::minus)) {
        auto SecondLoc = Tok.getLocation();
        Second = Tok.getIdentifierInfo();
        if(!ExpectAndConsume(tok::identifier, diag::err_expected_letter)) {
          if(!SkipUntil(tok::comma)) {
            InnerError = true;
            break;
          }
          continue;
        }
        if(Second->getName().size() > 1) {
          Diag.Report(SecondLoc, diag::err_expected_letter);
        }
      }

      auto Stmt = Actions.ActOnIMPLICIT(Context, Loc, DS,
                                        std::make_pair(First, Second), nullptr);
      if(Stmt.isUsable())
        StmtList.push_back(Stmt.take());

      if(ConsumeIfPresent(tok::comma))
        continue;
      break;
    }

    if(InnerError && Tok.isAtStartOfStatement())
      break;
    if(!ExpectAndConsume(tok::r_paren)) {
      if(!SkipUntil(tok::r_paren))
        break;
    }

    if(Tok.isAtStartOfStatement()) break;
    if(!ExpectAndConsume(tok::comma)) {
      if(!SkipUntil(tok::comma))
        break;
    }
  }

  ExpectStatementEnd();
  return Actions.ActOnCompoundStmt(Context, Loc, StmtList, StmtLabel);
}