if (auto context = state->context()) {
std::cout << *context;
}
- state->GetAllSources().Identify(std::cout, state->GetProvenance(), "");
+ state->cooked().allSources().Identify(
+ std::cout, state->GetProvenance(), "");
std::cout << " parser debug: " << std::string{str_, length_} << '\n';
return {Success{}};
}
o << " " << message_ << '\n';
}
-void Messages::Emit(std::ostream &o, const AllSources &sources) const {
+void Messages::Emit(std::ostream &o) const {
for (const auto &msg : messages_) {
- msg.Emit(o, sources);
+ msg.Emit(o, allSources_);
}
}
} // namespace parser
using iterator = list_type::iterator;
using const_iterator = list_type::const_iterator;
- Messages() {}
+ explicit Messages(const AllSources &sources) : allSources_{sources} {}
Messages(Messages &&that)
- : messages_{std::move(that.messages_)}, last_{that.last_} {}
+ : allSources_{that.allSources_}, messages_{std::move(that.messages_)},
+ last_{that.last_} {}
Messages &operator=(Messages &&that) {
swap(that);
return *this;
const_iterator cbegin() const { return messages_.cbegin(); }
const_iterator cend() const { return messages_.cend(); }
+ const AllSources &allSources() const { return allSources_; }
+
void Put(Message &&m) {
+ CHECK(m.provenance() < allSources_.size());
if (messages_.empty()) {
messages_.emplace_front(std::move(m));
last_ = messages_.begin();
}
}
- void Emit(std::ostream &, const AllSources &) const;
+ void Emit(std::ostream &) const;
private:
+ const AllSources &allSources_;
list_type messages_;
iterator last_; // valid iff messages_ nonempty
};
class ParseState {
public:
ParseState(const CookedSource &cooked)
- : cooked_{cooked}, p_{&cooked[0]}, remaining_{cooked.size()} {}
+ : cooked_{cooked}, p_{&cooked[0]},
+ remaining_{cooked.size()}, messages_{*cooked.allSources()} {}
ParseState(const ParseState &that)
- : cooked_{that.cooked_}, p_{that.p_},
- remaining_{that.remaining_}, column_{that.column_},
+ : cooked_{that.cooked_}, p_{that.p_}, remaining_{that.remaining_},
+ column_{that.column_}, messages_{*that.cooked_.allSources()},
userState_{that.userState_}, inCharLiteral_{that.inCharLiteral_},
inFortran_{that.inFortran_}, inFixedForm_{that.inFixedForm_},
enableOldDebugLines_{that.enableOldDebugLines_}, columns_{that.columns_},
std::memcpy(&that, buffer, bytes);
}
+ const CookedSource &cooked() const { return cooked_; }
+ int column() const { return column_; }
+ Messages *messages() { return &messages_; }
+
bool anyErrorRecovery() const { return anyErrorRecovery_; }
void set_anyErrorRecovery() { anyErrorRecovery_ = true; }
UserState *userState() const { return userState_; }
void set_userState(UserState *u) { userState_ = u; }
- int column() const { return column_; }
- Messages *messages() { return &messages_; }
-
MessageContext context() const { return context_; }
MessageContext set_context(MessageContext c) {
MessageContext was{context_};
bool tabInCurrentLine() const { return tabInCurrentLine_; }
- const AllSources &GetAllSources() const { return cooked_.sources(); }
const char *GetLocation() const { return p_; }
Provenance GetProvenance(const char *at) const {
return cooked_.GetProvenance(at).start;
if (def.isPredefined()) {
std::string name{def.replacement()[0].ToString()};
if (name == "__FILE__") {
- result->Put("\""s + prescanner_.GetCurrentPath() + '"');
+ result->Put("\""s +
+ prescanner_.allSources().GetPath(
+ prescanner_.GetCurrentProvenance()) +
+ '"');
continue;
}
if (name == "__LINE__") {
std::stringstream ss;
- ss << prescanner_.GetCurrentLineNumber();
+ ss << prescanner_.allSources().GetLineNumber(
+ prescanner_.GetCurrentProvenance());
result->Put(ss.str());
continue;
}
namespace Fortran {
namespace parser {
-CookedSource Prescanner::Prescan() {
+CookedSource Prescanner::Prescan(AllSources *allSources) {
startProvenance_ = 0;
- start_ = &allSources_[0];
- limit_ = start_ + allSources_.size();
+ start_ = &(*allSources)[0];
+ limit_ = start_ + allSources->size();
lineStart_ = start_;
+ BeginSourceLine(start_);
TokenSequence tokens, preprocessed;
- CookedSource cooked{allSources_};
+ CookedSource cooked{allSources};
while (lineStart_ < limit_) {
if (CommentLinesAndPreprocessorDirectives() && lineStart_ >= limit_) {
break;
return {std::move(tokens)};
}
-std::string Prescanner::GetCurrentPath() const {
- return allSources_.GetPath(GetCurrentProvenance());
-}
-
-int Prescanner::GetCurrentLineNumber() const {
- return allSources_.GetLineNumber(GetCurrentProvenance());
-}
-
void Prescanner::NextLine() {
void *vstart{static_cast<void *>(const_cast<char *>(lineStart_))};
void *v{std::memchr(vstart, '\n', limit_ - lineStart_)};
class Prescanner {
public:
- Prescanner(Messages &messages, AllSources &allSources)
- : messages_{messages}, allSources_{allSources}, preprocessor_{*this} {}
+ explicit Prescanner(Messages &messages)
+ : messages_{messages}, preprocessor_{*this} {}
Messages &messages() const { return messages_; }
bool anyFatalErrors() const { return anyFatalErrors_; }
return *this;
}
- CookedSource Prescan();
+ const AllSources &allSources() const { return messages_.allSources(); }
+
+ CookedSource Prescan(AllSources *);
std::optional<TokenSequence> NextTokenizedLine();
Provenance GetCurrentProvenance() const { return GetProvenance(at_); }
std::string GetCurrentPath() const; // __FILE__
void PayNewlineDebt(CookedSource *);
Messages &messages_;
- AllSources &allSources_;
Provenance startProvenance_;
const char *start_{nullptr}; // beginning of sourceFile_ content
void CookedSource::Marshal() {
CHECK(provenanceMap_.size() == buffer_.size());
- provenanceMap_.Put(sources_.AddCompilerInsertion("EOF"));
+ provenanceMap_.Put(allSources_->AddCompilerInsertion("EOF"));
data_.resize(buffer_.size());
char *p{&data_[0]};
for (char ch : buffer_) {
class CookedSource {
public:
- explicit CookedSource(AllSources &sources) : sources_{sources} {}
+ explicit CookedSource(AllSources *sources) : allSources_{sources} {}
size_t size() const { return data_.size(); }
const char &operator[](size_t n) const { return data_[n]; }
const char &at(size_t n) const { return data_.at(n); }
- AllSources &sources() const { return sources_; }
+ AllSources *allSources() const { return allSources_; }
ProvenanceRange GetProvenance(const char *) const;
void Identify(std::ostream &, const char *) const;
void Marshal(); // marshalls all text into one contiguous block
private:
- AllSources &sources_;
+ AllSources *allSources_;
CharBuffer buffer_; // before Marshal()
std::vector<char> data_; // all of it, prescanned and preprocessed
OffsetToProvenanceMappings provenanceMap_;
}
Fortran::parser::AllSources allSources{sourceFile};
- Fortran::parser::Messages messages;
- Fortran::parser::Prescanner prescanner{messages, allSources};
+ Fortran::parser::Messages messages{allSources};
+ Fortran::parser::Prescanner prescanner{messages};
Fortran::parser::CookedSource cooked{
prescanner.set_fixedForm(fixedForm)
.set_enableBackslashEscapesInCharLiterals(backslashEscapes)
.set_fixedFormColumnLimit(columns)
.set_enableOldDebugLines(enableOldDebugLines)
- .Prescan()};
- messages.Emit(std::cerr, allSources);
+ .Prescan(&allSources)};
+ messages.Emit(std::cerr);
if (prescanner.anyFatalErrors()) {
return 1;
}
std::cerr << "final position: ";
allSources.Identify(std::cerr, state.GetProvenance(), " ");
}
- state.messages()->Emit(std::cerr, allSources);
+ state.messages()->Emit(std::cerr);
return EXIT_FAILURE;
}
}