2018-05-01 21:50:34 +02:00
|
|
|
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2018-02-16 20:42:17 +01:00
|
|
|
#ifndef FORTRAN_PARSER_USER_STATE_H_
|
|
|
|
#define FORTRAN_PARSER_USER_STATE_H_
|
2018-01-30 20:52:12 +01:00
|
|
|
|
|
|
|
// Instances of ParseState (parse-state.h) incorporate instances of this
|
|
|
|
// UserState class, which encapsulates any semantic information necessary for
|
|
|
|
// parse tree construction so as to avoid any need for representing
|
|
|
|
// state in static data.
|
|
|
|
|
2018-03-20 18:59:07 +01:00
|
|
|
#include "char-block.h"
|
2018-07-18 01:58:21 +02:00
|
|
|
#include "features.h"
|
2018-04-21 00:19:20 +02:00
|
|
|
#include "parse-tree.h"
|
2018-07-18 01:58:21 +02:00
|
|
|
#include "../common/idioms.h"
|
2018-01-30 20:52:12 +01:00
|
|
|
#include <cinttypes>
|
2018-04-20 23:27:49 +02:00
|
|
|
#include <optional>
|
2018-04-21 01:14:57 +02:00
|
|
|
#include <ostream>
|
2018-03-17 00:13:49 +01:00
|
|
|
#include <set>
|
2018-10-03 01:42:15 +02:00
|
|
|
#include <unordered_map>
|
2018-01-30 20:52:12 +01:00
|
|
|
|
2018-05-02 22:48:12 +02:00
|
|
|
namespace Fortran::parser {
|
2018-03-17 00:13:49 +01:00
|
|
|
|
2018-04-20 20:23:51 +02:00
|
|
|
class CookedSource;
|
2018-04-19 22:03:23 +02:00
|
|
|
class ParsingLog;
|
2018-04-20 23:27:49 +02:00
|
|
|
class ParseState;
|
2018-04-19 22:03:23 +02:00
|
|
|
|
2018-07-18 01:58:21 +02:00
|
|
|
class Success {}; // for when one must return something that's present
|
|
|
|
|
2018-01-30 20:52:12 +01:00
|
|
|
class UserState {
|
2018-02-05 21:54:36 +01:00
|
|
|
public:
|
2018-07-18 20:19:21 +02:00
|
|
|
UserState(const CookedSource &cooked, LanguageFeatureControl features)
|
|
|
|
: cooked_{cooked}, features_{features} {}
|
2018-04-20 20:23:51 +02:00
|
|
|
|
|
|
|
const CookedSource &cooked() const { return cooked_; }
|
2018-07-18 20:19:21 +02:00
|
|
|
const LanguageFeatureControl &features() const { return features_; }
|
2018-04-20 20:23:51 +02:00
|
|
|
|
2018-04-21 01:14:57 +02:00
|
|
|
std::ostream *debugOutput() const { return debugOutput_; }
|
|
|
|
UserState &set_debugOutput(std::ostream *out) {
|
|
|
|
debugOutput_ = out;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2018-04-19 22:03:23 +02:00
|
|
|
ParsingLog *log() const { return log_; }
|
2018-04-20 02:02:12 +02:00
|
|
|
UserState &set_log(ParsingLog *log) {
|
|
|
|
log_ = log;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool instrumentedParse() const { return instrumentedParse_; }
|
|
|
|
UserState &set_instrumentedParse(bool yes) {
|
|
|
|
instrumentedParse_ = yes;
|
|
|
|
return *this;
|
|
|
|
}
|
2018-04-19 22:03:23 +02:00
|
|
|
|
2018-03-31 00:23:37 +02:00
|
|
|
void NewSubprogram() {
|
|
|
|
doLabels_.clear();
|
|
|
|
nonlabelDoConstructNestingDepth_ = 0;
|
2018-03-31 01:21:12 +02:00
|
|
|
oldStructureComponents_.clear();
|
2018-03-31 00:23:37 +02:00
|
|
|
}
|
|
|
|
|
2018-01-30 20:52:12 +01:00
|
|
|
using Label = std::uint64_t;
|
|
|
|
bool IsDoLabel(Label label) const {
|
2018-10-03 01:42:15 +02:00
|
|
|
auto iter{doLabels_.find(label)};
|
|
|
|
return iter != doLabels_.end() &&
|
|
|
|
iter->second >= nonlabelDoConstructNestingDepth_;
|
2018-01-30 20:52:12 +01:00
|
|
|
}
|
2018-10-03 01:42:15 +02:00
|
|
|
void NewDoLabel(Label label) {
|
|
|
|
doLabels_[label] = nonlabelDoConstructNestingDepth_;
|
2018-01-30 20:52:12 +01:00
|
|
|
}
|
2018-04-20 02:02:12 +02:00
|
|
|
|
2018-01-30 20:52:12 +01:00
|
|
|
void EnterNonlabelDoConstruct() { ++nonlabelDoConstructNestingDepth_; }
|
|
|
|
void LeaveDoConstruct() {
|
|
|
|
if (nonlabelDoConstructNestingDepth_ > 0) {
|
|
|
|
--nonlabelDoConstructNestingDepth_;
|
|
|
|
}
|
|
|
|
}
|
2018-02-05 23:29:26 +01:00
|
|
|
|
2018-03-31 01:21:12 +02:00
|
|
|
void NoteOldStructureComponent(const CharBlock &name) {
|
|
|
|
oldStructureComponents_.insert(name);
|
2018-03-17 00:13:49 +01:00
|
|
|
}
|
2018-03-31 01:21:12 +02:00
|
|
|
bool IsOldStructureComponent(const CharBlock &name) const {
|
|
|
|
return oldStructureComponents_.find(name) != oldStructureComponents_.end();
|
2018-03-17 00:13:49 +01:00
|
|
|
}
|
|
|
|
|
2018-02-05 21:54:36 +01:00
|
|
|
private:
|
2018-04-20 20:23:51 +02:00
|
|
|
const CookedSource &cooked_;
|
|
|
|
|
2018-04-21 01:14:57 +02:00
|
|
|
std::ostream *debugOutput_{nullptr};
|
|
|
|
|
2018-04-20 02:02:12 +02:00
|
|
|
ParsingLog *log_{nullptr};
|
|
|
|
bool instrumentedParse_{false};
|
|
|
|
|
2018-10-03 01:42:15 +02:00
|
|
|
std::unordered_map<Label, int> doLabels_;
|
2018-01-30 20:52:12 +01:00
|
|
|
int nonlabelDoConstructNestingDepth_{0};
|
2018-04-20 02:02:12 +02:00
|
|
|
|
2018-03-31 01:21:12 +02:00
|
|
|
std::set<CharBlock> oldStructureComponents_;
|
2018-07-18 01:58:21 +02:00
|
|
|
|
2018-07-18 20:19:21 +02:00
|
|
|
LanguageFeatureControl features_;
|
2018-01-30 20:52:12 +01:00
|
|
|
};
|
2018-04-20 23:27:49 +02:00
|
|
|
|
2018-04-21 00:19:20 +02:00
|
|
|
// Definitions of parser classes that manipulate the UserState.
|
2018-04-20 23:27:49 +02:00
|
|
|
struct StartNewSubprogram {
|
|
|
|
using resultType = Success;
|
|
|
|
static std::optional<Success> Parse(ParseState &);
|
|
|
|
};
|
2018-04-21 00:19:20 +02:00
|
|
|
|
|
|
|
struct CapturedLabelDoStmt {
|
2018-06-18 20:03:43 +02:00
|
|
|
using resultType = Statement<common::Indirection<LabelDoStmt>>;
|
2018-04-21 00:19:20 +02:00
|
|
|
static std::optional<resultType> Parse(ParseState &);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct EndDoStmtForCapturedLabelDoStmt {
|
2018-06-18 20:03:43 +02:00
|
|
|
using resultType = Statement<common::Indirection<EndDoStmt>>;
|
2018-04-21 00:19:20 +02:00
|
|
|
static std::optional<resultType> Parse(ParseState &);
|
|
|
|
};
|
|
|
|
|
2018-04-21 00:47:40 +02:00
|
|
|
struct EnterNonlabelDoConstruct {
|
|
|
|
using resultType = Success;
|
|
|
|
static std::optional<Success> Parse(ParseState &);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct LeaveDoConstruct {
|
|
|
|
using resultType = Success;
|
|
|
|
static std::optional<Success> Parse(ParseState &);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct OldStructureComponentName {
|
|
|
|
using resultType = Name;
|
|
|
|
static std::optional<Name> Parse(ParseState &);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct StructureComponents {
|
|
|
|
using resultType = DataComponentDefStmt;
|
|
|
|
static std::optional<DataComponentDefStmt> Parse(ParseState &);
|
|
|
|
};
|
2018-10-25 14:55:23 +02:00
|
|
|
}
|
2018-02-16 20:42:17 +01:00
|
|
|
#endif // FORTRAN_PARSER_USER_STATE_H_
|