1 //===- llvm/MC/MCAsmLexer.h - Abstract Asm Lexer Interface ------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_MC_MCPARSER_MCASMLEXER_H 11 #define LLVM_MC_MCPARSER_MCASMLEXER_H 12 13 #include "llvm/ADT/ArrayRef.h" 14 #include "llvm/ADT/SmallVector.h" 15 #include "llvm/MC/MCAsmMacro.h" 16 #include <algorithm> 17 #include <cassert> 18 #include <cstddef> 19 #include <cstdint> 20 #include <string> 21 22 namespace llvm { 23 24 /// A callback class which is notified of each comment in an assembly file as 25 /// it is lexed. 26 class AsmCommentConsumer { 27 public: 28 virtual ~AsmCommentConsumer() = default; 29 30 /// Callback function for when a comment is lexed. Loc is the start of the 31 /// comment text (excluding the comment-start marker). CommentText is the text 32 /// of the comment, excluding the comment start and end markers, and the 33 /// newline for single-line comments. 34 virtual void HandleComment(SMLoc Loc, StringRef CommentText) = 0; 35 }; 36 37 38 /// Generic assembler lexer interface, for use by target specific assembly 39 /// lexers. 40 class MCAsmLexer { 41 /// The current token, stored in the base class for faster access. 42 SmallVector<AsmToken, 1> CurTok; 43 44 /// The location and description of the current error 45 SMLoc ErrLoc; 46 std::string Err; 47 48 protected: // Can only create subclasses. 49 const char *TokStart = nullptr; 50 bool SkipSpace = true; 51 bool AllowAtInIdentifier; 52 bool IsAtStartOfStatement = true; 53 AsmCommentConsumer *CommentConsumer = nullptr; 54 55 bool AltMacroMode; 56 MCAsmLexer(); 57 58 virtual AsmToken LexToken() = 0; 59 SetError(SMLoc errLoc,const std::string & err)60 void SetError(SMLoc errLoc, const std::string &err) { 61 ErrLoc = errLoc; 62 Err = err; 63 } 64 65 public: 66 MCAsmLexer(const MCAsmLexer &) = delete; 67 MCAsmLexer &operator=(const MCAsmLexer &) = delete; 68 virtual ~MCAsmLexer(); 69 IsaAltMacroMode()70 bool IsaAltMacroMode() { 71 return AltMacroMode; 72 } 73 SetAltMacroMode(bool AltMacroSet)74 void SetAltMacroMode(bool AltMacroSet) { 75 AltMacroMode = AltMacroSet; 76 } 77 78 /// Consume the next token from the input stream and return it. 79 /// 80 /// The lexer will continuosly return the end-of-file token once the end of 81 /// the main input file has been reached. Lex()82 const AsmToken &Lex() { 83 assert(!CurTok.empty()); 84 // Mark if we parsing out a EndOfStatement. 85 IsAtStartOfStatement = CurTok.front().getKind() == AsmToken::EndOfStatement; 86 CurTok.erase(CurTok.begin()); 87 // LexToken may generate multiple tokens via UnLex but will always return 88 // the first one. Place returned value at head of CurTok vector. 89 if (CurTok.empty()) { 90 AsmToken T = LexToken(); 91 CurTok.insert(CurTok.begin(), T); 92 } 93 return CurTok.front(); 94 } 95 UnLex(AsmToken const & Token)96 void UnLex(AsmToken const &Token) { 97 IsAtStartOfStatement = false; 98 CurTok.insert(CurTok.begin(), Token); 99 } 100 isAtStartOfStatement()101 bool isAtStartOfStatement() { return IsAtStartOfStatement; } 102 103 virtual StringRef LexUntilEndOfStatement() = 0; 104 105 /// Get the current source location. 106 SMLoc getLoc() const; 107 108 /// Get the current (last) lexed token. getTok()109 const AsmToken &getTok() const { 110 return CurTok[0]; 111 } 112 113 /// Look ahead at the next token to be lexed. 114 const AsmToken peekTok(bool ShouldSkipSpace = true) { 115 AsmToken Tok; 116 117 MutableArrayRef<AsmToken> Buf(Tok); 118 size_t ReadCount = peekTokens(Buf, ShouldSkipSpace); 119 120 assert(ReadCount == 1); 121 (void)ReadCount; 122 123 return Tok; 124 } 125 126 /// Look ahead an arbitrary number of tokens. 127 virtual size_t peekTokens(MutableArrayRef<AsmToken> Buf, 128 bool ShouldSkipSpace = true) = 0; 129 130 /// Get the current error location getErrLoc()131 SMLoc getErrLoc() { 132 return ErrLoc; 133 } 134 135 /// Get the current error string getErr()136 const std::string &getErr() { 137 return Err; 138 } 139 140 /// Get the kind of current token. getKind()141 AsmToken::TokenKind getKind() const { return getTok().getKind(); } 142 143 /// Check if the current token has kind \p K. is(AsmToken::TokenKind K)144 bool is(AsmToken::TokenKind K) const { return getTok().is(K); } 145 146 /// Check if the current token has kind \p K. isNot(AsmToken::TokenKind K)147 bool isNot(AsmToken::TokenKind K) const { return getTok().isNot(K); } 148 149 /// Set whether spaces should be ignored by the lexer setSkipSpace(bool val)150 void setSkipSpace(bool val) { SkipSpace = val; } 151 getAllowAtInIdentifier()152 bool getAllowAtInIdentifier() { return AllowAtInIdentifier; } setAllowAtInIdentifier(bool v)153 void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; } 154 setCommentConsumer(AsmCommentConsumer * CommentConsumer)155 void setCommentConsumer(AsmCommentConsumer *CommentConsumer) { 156 this->CommentConsumer = CommentConsumer; 157 } 158 }; 159 160 } // end namespace llvm 161 162 #endif // LLVM_MC_MCPARSER_MCASMLEXER_H 163