From 4f2afe3d399eb9485dc605f3cc3a6382dcae757a Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 27 Sep 2010 20:12:52 +0000 Subject: [PATCH] MC/AsmParser: Handle exponents in floating point literals. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114861 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCParser/AsmLexer.h | 1 + lib/MC/MCParser/AsmLexer.cpp | 39 ++++++++++++++++++++------- test/MC/AsmParser/floating-literals.s | 17 ++++++++++++ 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index 21878899cac..439ecb91e5a 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -61,6 +61,7 @@ private: AsmToken LexLineComment(); AsmToken LexDigit(); AsmToken LexQuote(); + AsmToken LexFloatLiteral(); }; } // end namespace llvm diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp index 1a71d2437df..7ca1cccc98c 100644 --- a/lib/MC/MCParser/AsmLexer.cpp +++ b/lib/MC/MCParser/AsmLexer.cpp @@ -64,6 +64,31 @@ int AsmLexer::getNextChar() { } } +/// LexFloatLiteral: [0-9]*[.][0-9]*([eE][+-]?[0-9]*)? +/// +/// The leading integral digit sequence and dot should have already been +/// consumed, some or all of the fractional digit sequence *can* have been +/// consumed. +AsmToken AsmLexer::LexFloatLiteral() { + // Skip the fractional digit sequence. + while (isdigit(*CurPtr)) + ++CurPtr; + + // Check for exponent; we intentionally accept a slighlty wider set of + // literals here and rely on the upstream client to reject invalid ones (e.g., + // "1e+"). + if (*CurPtr == 'e' || *CurPtr == 'E') { + ++CurPtr; + if (*CurPtr == '-' || *CurPtr == '+') + ++CurPtr; + while (isdigit(*CurPtr)) + ++CurPtr; + } + + return AsmToken(AsmToken::Real, + StringRef(TokStart, CurPtr - TokStart)); +} + /// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@]* static bool IsIdentifierChar(char c) { return isalnum(c) || c == '_' || c == '$' || c == '.' || c == '@'; @@ -71,12 +96,11 @@ static bool IsIdentifierChar(char c) { AsmToken AsmLexer::LexIdentifier() { // Check for floating point literals. if (CurPtr[-1] == '.' && isdigit(*CurPtr)) { + // Disambiguate a .1243foo identifier from a floating literal. while (isdigit(*CurPtr)) ++CurPtr; - if (!IsIdentifierChar(*CurPtr)) { - return AsmToken(AsmToken::Real, - StringRef(TokStart, CurPtr - TokStart)); - } + if (*CurPtr == 'e' || *CurPtr == 'E' || !IsIdentifierChar(*CurPtr)) + return LexFloatLiteral(); } while (IsIdentifierChar(*CurPtr)) @@ -150,12 +174,9 @@ AsmToken AsmLexer::LexDigit() { ++CurPtr; // Check for floating point literals. - if (*CurPtr == '.') { + if (*CurPtr == '.' || *CurPtr == 'e') { ++CurPtr; - while (isdigit(*CurPtr)) - ++CurPtr; - - return AsmToken(AsmToken::Real, StringRef(TokStart, CurPtr - TokStart)); + return LexFloatLiteral(); } StringRef Result(TokStart, CurPtr - TokStart); diff --git a/test/MC/AsmParser/floating-literals.s b/test/MC/AsmParser/floating-literals.s index dbeb81fb9ee..b8e6e3cc800 100644 --- a/test/MC/AsmParser/floating-literals.s +++ b/test/MC/AsmParser/floating-literals.s @@ -13,3 +13,20 @@ # CHECK: .quad 0 .double 0.0 + +# CHECK: .quad -4570379565595099136 +.double -1.2e3 +# CHECK: .quad -4690170861623122860 +.double -1.2e-5 +# CHECK: .quad -4465782973978902528 +.double -1.2e+10 +# CHECK: .quad 4681608360884174848 +.double 1e5 +# CHECK: .quad 4681608360884174848 +.double 1.e5 +# CHECK: .quad 4611686018427387904 +.double 2. + +// APFloat should reject these with an error, not crash: +//.double -1.2e+ +//.double -1.2e