summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/flang/Parse/Lexer.h5
-rw-r--r--lib/Parse/Lexer.cpp20
-rw-r--r--test/Lexer/fixedFormString.f3
-rw-r--r--test/Lexer/torture.f954
4 files changed, 21 insertions, 11 deletions
diff --git a/include/flang/Parse/Lexer.h b/include/flang/Parse/Lexer.h
index 0732338071..51c6ce39e5 100644
--- a/include/flang/Parse/Lexer.h
+++ b/include/flang/Parse/Lexer.h
@@ -93,13 +93,14 @@ class Lexer {
/// SkipBlankLinesAndComments - Helper function that skips blank lines and
/// lines with only comments.
- bool SkipBlankLinesAndComments(unsigned &I, const char *&LineBegin);
+ bool SkipBlankLinesAndComments(unsigned &I, const char *&LineBegin,
+ bool IgnoreContinuationChar = false);
void SkipFixedFormBlankLinesAndComments(unsigned &I, const char *&LineBegin);
/// GetCharacterLiteral - A character literal has to be treated specially
/// because an ampersand may exist within it.
- void GetCharacterLiteral(unsigned &I, const char *&LineBegin);
+ void GetCharacterLiteral(unsigned &I, const char *&LineBegin, bool &PadAtoms);
/// Padding - This is an extra space that we insert between two
/// continuations which were merged. E.g.:
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index 5995e153a8..a4809b6b53 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -86,7 +86,7 @@ void Lexer::LineOfText::SetState(const State &S) {
/// SkipBlankLinesAndComments - Helper function that skips blank lines and lines
/// with only comments.
bool Lexer::LineOfText::
-SkipBlankLinesAndComments(unsigned &I, const char *&LineBegin) {
+SkipBlankLinesAndComments(unsigned &I, const char *&LineBegin, bool IgnoreContinuationChar) {
// Skip blank lines and lines with only comments.
while (isVerticalWhitespace(*BufPtr) && *BufPtr != '\0')
++BufPtr;
@@ -112,7 +112,7 @@ SkipBlankLinesAndComments(unsigned &I, const char *&LineBegin) {
// had a previous continuation character at the end of the line, then readjust
// the LineBegin.
if (I != 132 && *BufPtr == '&') {
- if (Atoms.empty()) // FIXME: This isn't sufficient.
+ if (Atoms.empty() && !IgnoreContinuationChar)
Diags.Report(SourceLocation::getFromPointer(BufPtr),
diag::err_continuation_out_of_context);
++I, ++BufPtr;
@@ -150,7 +150,7 @@ SkipFixedFormBlankLinesAndComments(unsigned &I, const char *&LineBegin) {
/// GetCharacterLiteral - A character literal has to be treated specially
/// because an ampersand may exist within it.
void Lexer::LineOfText::
-GetCharacterLiteral(unsigned &I, const char *&LineBegin) {
+GetCharacterLiteral(unsigned &I, const char *&LineBegin, bool &PadAtoms) {
// Skip blank lines and lines with only comments.
SkipBlankLinesAndComments(I, LineBegin);
@@ -195,7 +195,7 @@ GetCharacterLiteral(unsigned &I, const char *&LineBegin) {
I++, ++BufPtr;
LineBegin = BufPtr;
I = 0;
- SkipBlankLinesAndComments(I, LineBegin);
+ SkipBlankLinesAndComments(I, LineBegin, true);
char next = *BufPtr;
bool endQuote = true;
if(DoubleQuotes){
@@ -211,6 +211,7 @@ GetCharacterLiteral(unsigned &I, const char *&LineBegin) {
}
I = currentI;BufPtr = CurrentBufPtr; LineBegin = CurrentLineBegin;
if(!endQuote){
+ PadAtoms = false;
skipNextQuoteChar = true;
continue;
}
@@ -267,6 +268,7 @@ void Lexer::LineOfText::GetNextLine() {
unsigned I = 0;
bool BeginsWithAmp = true;
+ bool PadAtoms = true;
const char *AmpersandPos = 0;
if(LanguageOptions.FixedForm) {
@@ -276,8 +278,8 @@ void Lexer::LineOfText::GetNextLine() {
while (I != 72 && !isVerticalWhitespace(*BufPtr) && *BufPtr != '\0') {
++I, ++BufPtr;
}
- if(!Atoms.empty())
- Atoms.push_back(StringRef(Padding));
+ //if(!Atoms.empty())
+ // Atoms.push_back(StringRef(Padding));
Atoms.push_back(StringRef(LineBegin, BufPtr - LineBegin));
// Increment the buffer pointer to the start of the next line.
@@ -309,7 +311,7 @@ void Lexer::LineOfText::GetNextLine() {
while (I != 132 && !isVerticalWhitespace(*BufPtr) && *BufPtr != '\0') {
if (*BufPtr == '\'' || *BufPtr == '"') {
// TODO: A BOZ constant doesn't get parsed like a character literal.
- GetCharacterLiteral(I, LineBegin);
+ GetCharacterLiteral(I, LineBegin, PadAtoms);
if (I == 132 || isVerticalWhitespace(*BufPtr))
break;
} else if (*BufPtr == '&') {
@@ -350,7 +352,7 @@ void Lexer::LineOfText::GetNextLine() {
if (AmpersandPos) {
Atoms.push_back(StringRef(LineBegin, AmpersandPos - LineBegin));
} else {
- if (!BeginsWithAmp && !Atoms.empty())
+ if (!BeginsWithAmp && !Atoms.empty() && PadAtoms)
// This is a line that doesn't start with an '&'. The tokens are not
// contiguous. Insert a space to indicate this.
Atoms.push_back(StringRef(Padding));
@@ -1078,6 +1080,8 @@ void Lexer::LexCharacterLiteralConstant(Token &Result,
}
} else {
if (C == '\'') {
+ auto Next = peekNextChar();
+ llvm::outs() <<"Next:" << int(Next) << "," << Next<<"\n";
if (peekNextChar() != '\'') {
getNextChar();
break;
diff --git a/test/Lexer/fixedFormString.f b/test/Lexer/fixedFormString.f
index f5d2e2c5d7..22709f4c4a 100644
--- a/test/Lexer/fixedFormString.f
+++ b/test/Lexer/fixedFormString.f
@@ -14,4 +14,7 @@ C CHECK: ' He lloWo - rld'
.' Blah blah blah
.Blah blah blah
.Blah blah blah.'/
+ DATA MESS(08)/
+ .' ''UNKOWN'
+ .' STATUS.'/
END
diff --git a/test/Lexer/torture.f95 b/test/Lexer/torture.f95
index 1e8f01e65e..fd1228450d 100644
--- a/test/Lexer/torture.f95
+++ b/test/Lexer/torture.f95
@@ -8,7 +8,7 @@ P&
&M&
& TORTURE
! Torture the lexer and parser.
- CHARACTER (LEN=256) :: A, B, C, D, E, F
+ CHARACTER (LEN=256) :: A, B, C, D, E, F, G
A = '&
&'
@@ -25,4 +25,6 @@ P&
&"'
E = ''''
F = """"
+ G = ''&
+&''
END PROGRAM TORTURE