llvm/flang/lib/parser/prescan.h
peter klausler 79d044e9b5 [flang] Take flang-compiler/f18#2 on unparsing, now using the new parse tree walker.
Clean out old data structure formatter.

Create stand-alone Parsing class to compose parts of the parser together.

Hello, world!

Better error recovery on command line errors.

Fix bugs from initial run at f77_correct.

Allow parentheses on PROGRAM statement.

Fix Hollerith scanning.

Remove REDIMENSION with good error recovery.

Fix new "spaces" parser, clean up calls to it.

Fix bugs exposed by in38.f90.

Escaped \a is not special to pgf90; get slashes around STRUCTURE name right.

Better multi-byte source encoding support in Hollerith.

Reformat C++.

More work on multi-byte source encoding.

Pass 219 tests in f77_correct, with good excuses for the rest.

Original-commit: flang-compiler/f18@8a1a0aa2dc
Reviewed-on: https://github.com/flang-compiler/f18/pull/25
Tree-same-pre-rewrite: false
2018-03-13 16:32:09 -07:00

146 lines
4.4 KiB
C++

#ifndef FORTRAN_PARSER_PRESCAN_H_
#define FORTRAN_PARSER_PRESCAN_H_
// Defines a fast Fortran source prescanning phase that implements some
// character-level features of the language that can be inefficient to
// support directly in a backtracking parser. This phase handles Fortran
// line continuation, comment removal, card image margins, padding out
// fixed form character literals on truncated card images, file
// inclusion, and driving the Fortran source preprocessor.
#include "characters.h"
#include "message.h"
#include "provenance.h"
#include "token-sequence.h"
#include <optional>
#include <string>
namespace Fortran {
namespace parser {
class Messages;
class Preprocessor;
class Prescanner {
public:
Prescanner(Messages *, CookedSource *, Preprocessor *);
Prescanner(const Prescanner &);
Messages *messages() const { return messages_; }
Prescanner &set_fixedForm(bool yes) {
inFixedForm_ = yes;
return *this;
}
Prescanner &set_encoding(Encoding code) {
encoding_ = code;
return *this;
}
Prescanner &set_enableOldDebugLines(bool yes) {
enableOldDebugLines_ = yes;
return *this;
}
Prescanner &set_enableBackslashEscapesInCharLiterals(bool yes) {
enableBackslashEscapesInCharLiterals_ = yes;
return *this;
}
Prescanner &set_fixedFormColumnLimit(int limit) {
fixedFormColumnLimit_ = limit;
return *this;
}
bool Prescan(ProvenanceRange);
// Callbacks for use by Preprocessor.
std::optional<TokenSequence> NextTokenizedLine();
Provenance GetCurrentProvenance() const { return GetProvenance(at_); }
Message &Complain(MessageFixedText);
Message &Complain(MessageFormattedText &&);
private:
void BeginSourceLine(const char *at) {
at_ = at;
column_ = 1;
tabInCurrentLine_ = false;
preventHollerith_ = false;
delimiterNesting_ = 0;
}
void BeginSourceLineAndAdvance() {
BeginSourceLine(lineStart_);
NextLine();
}
Provenance GetProvenance(const char *sourceChar) const {
return startProvenance_ + (sourceChar - start_);
}
void EmitChar(TokenSequence *tokens, char ch) {
tokens->PutNextTokenChar(ch, GetCurrentProvenance());
}
void EmitInsertedChar(TokenSequence *tokens, char ch) {
Provenance provenance{
cooked_->allSources()->CompilerInsertionProvenance(ch)};
tokens->PutNextTokenChar(ch, provenance);
}
char EmitCharAndAdvance(TokenSequence *tokens, char ch) {
EmitChar(tokens, ch);
NextChar();
return *at_;
}
void NextLine();
void LabelField(TokenSequence *);
void NextChar();
void SkipSpaces();
bool NextToken(TokenSequence *);
bool ExponentAndKind(TokenSequence *);
void QuotedCharacterLiteral(TokenSequence *);
void Hollerith(TokenSequence *, int);
bool PadOutCharacterLiteral(TokenSequence *);
bool CommentLines();
bool CommentLinesAndPreprocessorDirectives();
bool IsFixedFormCommentLine(const char *);
bool IsFreeFormComment(const char *);
bool IncludeLine(const char *);
bool IsPreprocessorDirectiveLine(const char *);
const char *FixedFormContinuationLine();
bool FixedFormContinuation();
bool FreeFormContinuation();
void PayNewlineDebt(Provenance);
Messages *messages_;
CookedSource *cooked_;
Preprocessor *preprocessor_;
Provenance startProvenance_;
const char *start_{nullptr}; // beginning of current source file content
const char *limit_{nullptr}; // first address after end of current source
const char *at_{nullptr}; // next character to process; < lineStart_
int column_{1}; // card image column position of next character
const char *lineStart_{nullptr}; // next line to process; <= limit_
bool tabInCurrentLine_{false};
bool preventHollerith_{false};
bool anyFatalErrors_{false};
int newlineDebt_{0}; // newline characters consumed but not yet emitted
bool inCharLiteral_{false};
bool inPreprocessorDirective_{false};
bool inFixedForm_{false};
int fixedFormColumnLimit_{72};
Encoding encoding_{Encoding::UTF8};
bool enableOldDebugLines_{false};
bool enableBackslashEscapesInCharLiterals_{true};
int delimiterNesting_{0};
Provenance spaceProvenance_{
cooked_->allSources()->CompilerInsertionProvenance(' ')};
Provenance backslashProvenance_{
cooked_->allSources()->CompilerInsertionProvenance('\\')};
ProvenanceRange sixSpaceProvenance_{
cooked_->allSources()->AddCompilerInsertion(" "s)};
};
} // namespace parser
} // namespace Fortran
#endif // FORTRAN_PARSER_PRESCAN_H_