12 #include "llvm/ADT/StringExtras.h"
13 #include "llvm/ADT/StringSwitch.h"
14 #include "llvm/Support/SourceMgr.h"
30 bytes = bytes.drop_front().drop_back();
32 bytes = bytes.drop_front(2).drop_back(2);
35 result.reserve(bytes.size());
36 for (
unsigned i = 0, e = bytes.size(); i != e;) {
43 assert(i + 1 <= e &&
"invalid string should be caught by lexer");
51 result.push_back(
'\n');
54 result.push_back(
'\t');
60 assert(i + 1 <= e &&
"invalid string should be caught by lexer");
63 assert(llvm::isHexDigit(c1) && llvm::isHexDigit(c2) &&
"invalid escape");
64 result.push_back((llvm::hexDigitValue(c1) << 4) | llvm::hexDigitValue(c2));
76 : srcMgr(mgr), diagEngine(diagEngine), addedHandlerToDiagEngine(false),
77 codeCompletionLocation(nullptr) {
78 curBufferID = mgr.getMainFileID();
79 curBuffer = srcMgr.getMemoryBuffer(curBufferID)->getBuffer();
80 curPtr = curBuffer.begin();
83 if (codeCompleteContext) {
84 codeCompletionLocation =
92 srcMgr.PrintMessage(
diag.getLocation().Start,
diag.getSeverity(),
95 srcMgr.PrintMessage(note.getLocation().Start, note.getSeverity(),
98 addedHandlerToDiagEngine =
true;
103 if (addedHandlerToDiagEngine)
108 std::string includedFile;
110 srcMgr.AddIncludeFile(filename.str(), includeLoc.End, includedFile);
114 curBufferID = bufferID;
115 curBuffer = srcMgr.getMemoryBuffer(curBufferID)->getBuffer();
116 curPtr = curBuffer.begin();
131 SMRange(SMLoc::getFromPointer(loc), SMLoc::getFromPointer(loc + 1)), msg);
134 int Lexer::getNextChar() {
135 char curChar = *curPtr++;
138 return static_cast<unsigned char>(curChar);
142 if (curPtr - 1 != curBuffer.end())
154 if ((*curPtr ==
'\n' || (*curPtr ==
'\r')) && *curPtr != curChar)
162 const char *tokStart = curPtr;
165 if (tokStart == codeCompletionLocation)
169 int curChar = getNextChar();
173 if (isalpha(curChar) || curChar ==
'_')
174 return lexIdentifier(tokStart);
177 return emitError(tokStart,
"unexpected character");
183 SMLoc parentIncludeLoc = srcMgr.getParentIncludeLoc(curBufferID);
184 if (parentIncludeLoc.isValid()) {
185 curBufferID = srcMgr.FindBufferContainingLoc(parentIncludeLoc);
186 curBuffer = srcMgr.getMemoryBuffer(curBufferID)->getBuffer();
187 curPtr = parentIncludeLoc.getPointer();
195 if (*curPtr ==
'>') {
199 return emitError(tokStart,
"unexpected character");
207 if (*curPtr ==
'>') {
215 if (*curPtr ==
'{') {
217 return lexString(tokStart,
true);
236 if (*curPtr ==
'/') {
240 return emitError(tokStart,
"unexpected character");
250 return lexDirective(tokStart);
252 return lexString(tokStart,
false);
264 return lexNumber(tokStart);
270 void Lexer::lexComment() {
272 assert(*curPtr ==
'/');
283 if (curPtr - 1 == curBuffer.end()) {
295 Token Lexer::lexDirective(
const char *tokStart) {
297 while (isalnum(*curPtr) || *curPtr ==
'_')
300 StringRef str(tokStart, curPtr - tokStart);
304 Token Lexer::lexIdentifier(
const char *tokStart) {
306 while (isalnum(*curPtr) || *curPtr ==
'_')
310 StringRef str(tokStart, curPtr - tokStart);
334 return Token(kind, str);
337 Token Lexer::lexNumber(
const char *tokStart) {
338 assert(isdigit(curPtr[-1]));
341 while (isdigit(*curPtr))
347 Token Lexer::lexString(
const char *tokStart,
bool isStringBlock) {
354 if (curPtr == codeCompletionLocation) {
356 tokStart + (isStringBlock ? 2 : 1));
369 if (!isStringBlock || *curPtr !=
']')
376 if (curPtr - 1 != curBuffer.end())
380 StringRef expectedEndStr = isStringBlock ?
"}]" :
"\"";
382 "expected '" + expectedEndStr +
"' in string literal");
390 return emitError(curPtr - 1,
"expected '\"' in string literal");
395 if (*curPtr ==
'"' || *curPtr ==
'\\' || *curPtr ==
'n' ||
398 }
else if (llvm::isHexDigit(*curPtr) && llvm::isHexDigit(curPtr[1])) {
402 return emitError(curPtr - 1,
"unknown escape in string literal");
static std::string diag(const llvm::Value &value)
This represents a token in the MLIR syntax.
This class provides an abstract interface into the parser for hooking in code completion events.
SMLoc getCodeCompleteLoc() const
Return the location used to provide code completion.
Token emitError(SMRange loc, const Twine &msg)
Emit an error to the lexer with the given location and message.
Token emitErrorAndNote(SMRange loc, const Twine &msg, SMRange noteLoc, const Twine ¬e)
Token lexToken()
Lex the next token and return it.
LogicalResult pushInclude(StringRef filename, SMRange includeLoc)
Push an include of the given file.
Lexer(llvm::SourceMgr &mgr, ast::DiagnosticEngine &diagEngine, CodeCompleteContext *codeCompleteContext)
bool is(Kind k) const
Return if the token has the given kind.
StringRef getSpelling() const
Return the bytes that make up this token.
@ code_complete_string
Token signifying a code completion location within a string.
@ code_complete
Token signifying a code completion location.
@ less
Paired punctuation.
@ kw_Attr
General keywords.
Kind getKind() const
Return the kind of this token.
std::string getStringValue() const
Given a token containing a string literal, return its value, including removing the quote characters ...
This class manages the construction and emission of PDLL diagnostics.
void setHandlerFn(HandlerFn &&newHandler)
Set the handler function for this diagnostic engine.
InFlightDiagnostic emitError(SMRange loc, const Twine &msg)
Emit an error to the diagnostic engine.
const HandlerFn & getHandlerFn() const
Get the current handler function of this diagnostic engine.
This class provides a simple implementation of a PDLL diagnostic.
Diagnostic & attachNote(const Twine &msg, std::optional< SMRange > noteLoc=std::nullopt)
Attach a note to this diagnostic.
Include the generated interface declarations.