diff --git include/llvm/MC/MCParser/MCAsmLexer.h include/llvm/MC/MCParser/MCAsmLexer.h
index b05891c..ced6fce 100644
--- include/llvm/MC/MCParser/MCAsmLexer.h
+++ include/llvm/MC/MCParser/MCAsmLexer.h
@@ -15,6 +15,7 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/SMLoc.h"
+#include <functional>
 
 namespace llvm {
 
@@ -117,6 +118,10 @@ public:
 /// Generic assembler lexer interface, for use by target specific assembly
 /// lexers.
 class MCAsmLexer {
+public:
+  typedef std::function<AsmToken(const char **, const char *)>
+    IdentifierLexerTy;
+private:
   /// The current token, stored in the base class for faster access.
   AsmToken CurTok;
 
@@ -130,6 +135,7 @@ protected: // Can only create subclasses.
   const char *TokStart;
   bool SkipSpace;
   bool AllowAtInIdentifier;
+  IdentifierLexerTy IdentifierLexer;
 
   MCAsmLexer();
 
@@ -188,6 +194,13 @@ public:
 
   bool getAllowAtInIdentifier() { return AllowAtInIdentifier; }
   void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; }
+  IdentifierLexerTy getIdentifierLex() const {
+    return IdentifierLexer;
+  }
+  void setIdentifierLex(IdentifierLexerTy IdentifierLexer) {
+    this->IdentifierLexer = IdentifierLexer;
+  }
+
 };
 
 } // End llvm namespace
diff --git lib/MC/MCParser/AsmLexer.cpp lib/MC/MCParser/AsmLexer.cpp
index 5c8ec66..e0ddd3c 100644
--- lib/MC/MCParser/AsmLexer.cpp
+++ lib/MC/MCParser/AsmLexer.cpp
@@ -21,10 +21,15 @@
 #include <cstdlib>
 using namespace llvm;
 
+static AsmToken LexIdentifierFun(const bool &AllowAt, const char **CurPtrPtr,
+    const char *TokStart);
+
 AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI)  {
   CurPtr = nullptr;
   isAtStartOfLine = true;
   AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@");
+  IdentifierLexer = std::bind(LexIdentifierFun, std::cref(AllowAtInIdentifier),
+      std::placeholders::_1, std::placeholders::_2);
 }
 
 AsmLexer::~AsmLexer() {
@@ -66,12 +71,9 @@ 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() {
+static AsmToken LexFloatLiteralFun(const char **CurPtrPtr,
+    const char *TokStart) {
+  const char *&CurPtr = *CurPtrPtr;
   // Skip the fractional digit sequence.
   while (isdigit(*CurPtr))
     ++CurPtr;
@@ -91,6 +93,15 @@ AsmToken AsmLexer::LexFloatLiteral() {
                   StringRef(TokStart, CurPtr - TokStart));
 }
 
+/// 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() {
+  return LexFloatLiteralFun(&CurPtr, TokStart);
+}
+
 /// LexHexFloatLiteral matches essentially (.[0-9a-fA-F]*)?[pP][+-]?[0-9a-fA-F]+
 /// while making sure there are enough actual digits around for the constant to
 /// be valid.
@@ -143,18 +154,26 @@ static bool IsIdentifierChar(char c, bool AllowAt) {
   return isalnum(c) || c == '_' || c == '$' || c == '.' ||
          (c == '@' && AllowAt) || c == '?';
 }
-AsmToken AsmLexer::LexIdentifier() {
+
+static AsmToken LexIdentifierFun(const bool &AllowAt, const char **CurPtrPtr,
+    const char *TokStart) {
+  const char *& CurPtr = *CurPtrPtr;
+  const char PrevChar = *(CurPtr-1);
+
+  if (!(isalpha(PrevChar) || PrevChar == '_' || PrevChar == '.'))
+    return AsmToken(AsmToken::Error, StringRef(TokStart, 0));
+
   // Check for floating point literals.
   if (CurPtr[-1] == '.' && isdigit(*CurPtr)) {
     // Disambiguate a .1243foo identifier from a floating literal.
     while (isdigit(*CurPtr))
       ++CurPtr;
     if (*CurPtr == 'e' || *CurPtr == 'E' ||
-        !IsIdentifierChar(*CurPtr, AllowAtInIdentifier))
-      return LexFloatLiteral();
+        !IsIdentifierChar(*CurPtr, AllowAt))
+      return LexFloatLiteralFun(CurPtrPtr, TokStart);
   }
 
-  while (IsIdentifierChar(*CurPtr, AllowAtInIdentifier))
+  while (IsIdentifierChar(*CurPtr, AllowAt))
     ++CurPtr;
 
   // Handle . as a special case.
@@ -164,6 +183,10 @@ AsmToken AsmLexer::LexIdentifier() {
   return AsmToken(AsmToken::Identifier, StringRef(TokStart, CurPtr - TokStart));
 }
 
+AsmToken AsmLexer::LexIdentifier() {
+  return IdentifierLexer(&CurPtr, TokStart);
+}
+
 /// LexSlash: Slash: /
 ///           C-Style Comment: /* ... */
 AsmToken AsmLexer::LexSlash() {
@@ -505,13 +528,14 @@ AsmToken AsmLexer::LexToken() {
 
   isAtStartOfLine = false;
   switch (CurChar) {
-  default:
-    // Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
-    if (isalpha(CurChar) || CurChar == '_' || CurChar == '.')
-      return LexIdentifier();
-
-    // Unknown character, emit an error.
-    return ReturnError(TokStart, "invalid character in input");
+  default: {
+    // Handle identifier
+    // Default: [a-zA-Z_.][a-zA-Z0-9_$.@]*
+    AsmToken IdTok = LexIdentifier();
+    if (IdTok.is(AsmToken::Error))
+      return ReturnError(IdTok.getLoc().getPointer(), "invalid character in input");
+    return IdTok;
+  }
   case EOF: return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
   case 0:
   case ' ':
