diff options
author | arphaman <arphaman@gmail.com> | 2013-09-19 19:26:28 +0100 |
---|---|---|
committer | arphaman <arphaman@gmail.com> | 2013-09-19 19:26:28 +0100 |
commit | 3000ac6a9047461463cd159f263a3509411a9e47 (patch) | |
tree | fbf0964574504593fca443eedc4cda8a117995ab | |
parent | f888e52a1467a0cc68e3b979fae99246d802a486 (diff) | |
download | flang-3000ac6a9047461463cd159f263a3509411a9e47.tar.gz |
improved fixed form lexing for defined operators
-rw-r--r-- | include/flang/Parse/Lexer.h | 4 | ||||
-rw-r--r-- | lib/Parse/Lexer.cpp | 70 | ||||
-rw-r--r-- | test/Lexer/fixedFormDefinedOperators.f | 8 |
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 |