summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarphaman <arphaman@gmail.com>2013-09-19 19:26:28 +0100
committerarphaman <arphaman@gmail.com>2013-09-19 19:26:28 +0100
commit3000ac6a9047461463cd159f263a3509411a9e47 (patch)
treefbf0964574504593fca443eedc4cda8a117995ab
parentf888e52a1467a0cc68e3b979fae99246d802a486 (diff)
downloadflang-3000ac6a9047461463cd159f263a3509411a9e47.tar.gz
improved fixed form lexing for defined operators
-rw-r--r--include/flang/Parse/Lexer.h4
-rw-r--r--lib/Parse/Lexer.cpp70
-rw-r--r--test/Lexer/fixedFormDefinedOperators.f8
3 files changed, 59 insertions, 23 deletions
diff --git a/include/flang/Parse/Lexer.h b/include/flang/Parse/Lexer.h
index f4a7ad647f..3b158a3d43 100644
--- a/include/flang/Parse/Lexer.h
+++ b/include/flang/Parse/Lexer.h
@@ -226,6 +226,10 @@ class Lexer {
void LexFixedFormIdentifier(const fixedForm::KeywordMatcher &Matcher,
Token &Tok);
+ /// LexPossibleDefinedOperator - Tries to lex a defined operator
+ /// that begins with '.', returns true if sucessfull.
+ bool LexPossibleDefinedOperator(Token &Result);
+
/// LexFORMATDescriptor - Lex a format desriptor.
void LexFORMATDescriptor(Token &Result);
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index c314ab9989..083b38cfa1 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -882,7 +882,7 @@ void Lexer::FormDefinedOperatorTokenWithChars(Token &Result) {
unsigned TokLen;
llvm::StringRef FullOp;
- if (!Text.IsInCurrentAtom(TokStart)) {
+ if (!Text.IsInCurrentAtom(TokStart) || Result.needsCleaning()) {
llvm::SmallVector<llvm::StringRef, 2> Spelling;
FormTokenWithChars(Result, tok::unknown);
getSpelling(Result, Spelling);
@@ -1004,6 +1004,50 @@ void Lexer::LexFixedFormIdentifier(const fixedForm::KeywordMatcher &Matcher,
Tok.setFlag(Token::NeedsCleaning);
}
+bool Lexer::LexPossibleDefinedOperator(Token &Result) {
+ auto Char = getNextChar();
+ if (Features.FixedForm) {
+ while(isHorizontalWhitespace(Char)) {
+ Result.setFlag(Token::NeedsCleaning);
+ Char = getNextChar();
+ }
+ }
+ if (!isLetter(Char))
+ return false;
+ // Match [A-Za-z]*, we have already matched '.'.
+ if(Features.FixedForm) {
+ for(;;) {
+ Char = getNextChar();
+ if(!isLetter(Char)) {
+ if(!isHorizontalWhitespace(Char))
+ break;
+ Result.setFlag(Token::NeedsCleaning);
+ }
+ }
+ } else {
+ while (isLetter(Char))
+ Char = getNextChar();
+ }
+
+ if (Char != '.') {
+ Diags.Report(SourceLocation::getFromPointer(TokStart), diag::err_defined_operator_missing_end);
+ FormTokenWithChars(Result, tok::unknown);
+ return true;
+ }
+
+ // FIXME: fixed-form
+ Char = getNextChar();
+ if (Char == '_') {
+ // Parse the kind.
+ do {
+ Char = getNextChar();
+ } while (isIdentifierBody(Char) || isDecimalNumberBody(Char));
+ }
+
+ FormDefinedOperatorTokenWithChars(Result);
+ return true;
+}
+
/// LexFormatDescriptor - Lex the remainder of a format descriptor.
void Lexer::LexFORMATDescriptor(Token &Result) {
// Match [_A-Za-z0-9]*, we have already matched [A-Za-z$]
@@ -1247,28 +1291,8 @@ void Lexer::LexTokenInternal(Token &Result, bool IsPeekAhead) {
return LexTokenInternal(Result, IsPeekAhead);
case '.':
- Char = getNextChar();
- if (isLetter(Char)) {
- // Match [A-Za-z]*, we have already matched '.'.
- while (isLetter(Char))
- Char = getNextChar();
-
- if (Char != '.') {
- Diags.Report(SourceLocation::getFromPointer(TokStart),diag::err_defined_operator_missing_end);
- FormTokenWithChars(Result, tok::unknown);
- return;
- }
-
- Char = getNextChar();
- if (Char == '_') {
- // Parse the kind.
- do {
- Char = getNextChar();
- } while (isIdentifierBody(Char) || isDecimalNumberBody(Char));
- }
-
- return FormDefinedOperatorTokenWithChars(Result);
- }
+ if(LexPossibleDefinedOperator(Result))
+ return;
// FALLTHROUGH
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
diff --git a/test/Lexer/fixedFormDefinedOperators.f b/test/Lexer/fixedFormDefinedOperators.f
new file mode 100644
index 0000000000..71b53735aa
--- /dev/null
+++ b/test/Lexer/fixedFormDefinedOperators.f
@@ -0,0 +1,8 @@
+ program hello
+C RUN: %flang -fsyntax-only %s
+ integer i
+ logical l
+ if(l . and. l) i = 2
+ if(l . a nd . i . e q. 0) then
+ end if
+ end