Skip to content

Commit d522cd4

Browse files
committed
Centralize the parsing logic for #identifiers and make it more similar to
the identifier parsing logic.
1 parent 319e2a7 commit d522cd4

File tree

4 files changed

+64
-65
lines changed

4 files changed

+64
-65
lines changed

include/swift/Parse/Lexer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ class Lexer {
423423
void skipHashbang();
424424

425425
void skipSlashStarComment();
426+
void lexHash();
426427
void lexIdentifier();
427428
void lexDollarIdent();
428429
void lexOperatorIdentifier();

include/swift/Parse/Token.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,11 @@ enum class tok {
3838
floating_literal,
3939
string_literal,
4040
sil_local_name, // %42 in SIL mode.
41-
pound_if,
42-
pound_else,
43-
pound_elseif,
44-
pound_endif,
45-
pound_line,
46-
pound_available,
47-
pound_selector,
4841
comment,
4942

5043
#define KEYWORD(X) kw_ ## X,
5144
#define PUNCTUATOR(X, Y) X,
45+
#define POUND_KEYWORD(X) pound_ ## X,
5246
#include "swift/Parse/Tokens.def"
5347

5448
NUM_TOKENS

include/swift/Parse/Tokens.def

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
#define STMT_KEYWORD(kw) KEYWORD(kw)
3333
#endif
3434

35+
/// POUND_KEYWORD(kw)
36+
/// Every keyword in the #foo namespace.
37+
#ifndef POUND_KEYWORD
38+
#define POUND_KEYWORD(kw)
39+
#endif
40+
41+
3542
/// SIL_KEYWORD(kw)
3643
/// Expands for every SIL keyword. These are only keywords when parsing SIL.
3744
#ifndef SIL_KEYWORD
@@ -155,9 +162,19 @@ PUNCTUATOR(question_infix,"?") // if not left-bound
155162
PUNCTUATOR(sil_dollar, "$") // Only in SIL mode.
156163
PUNCTUATOR(sil_exclamation, "!") // Only in SIL mode.
157164

165+
// Keywords in the # namespace. "if" becomes "tok::pound_if".
166+
POUND_KEYWORD(if)
167+
POUND_KEYWORD(else)
168+
POUND_KEYWORD(elseif)
169+
POUND_KEYWORD(endif)
170+
POUND_KEYWORD(line)
171+
POUND_KEYWORD(available)
172+
POUND_KEYWORD(selector)
173+
158174

159175
#undef KEYWORD
160176
#undef DECL_KEYWORD
161177
#undef STMT_KEYWORD
162178
#undef SIL_KEYWORD
163179
#undef PUNCTUATOR
180+
#undef POUND_KEYWORD

lib/Parse/Lexer.cpp

Lines changed: 45 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,48 @@ void Lexer::lexIdentifier() {
575575
return formToken(Kind, TokStart);
576576
}
577577

578+
/// lexHash - Handle #], #! for shebangs, and the family of #identifiers.
579+
void Lexer::lexHash() {
580+
const char *TokStart = CurPtr-1;
581+
if (*CurPtr == ']') { // #]
582+
CurPtr++;
583+
return formToken(tok::r_square_lit, TokStart);
584+
}
585+
586+
// Allow a hashbang #! line at the beginning of the file.
587+
if (CurPtr - 1 == BufferStart && *CurPtr == '!') {
588+
CurPtr--;
589+
if (BufferID != SourceMgr.getHashbangBufferID())
590+
diagnose(CurPtr, diag::lex_hashbang_not_allowed);
591+
skipHashbang();
592+
return lexImpl();
593+
}
594+
595+
// Scan for [a-z]+ to see what we match.
596+
const char *tmpPtr = CurPtr;
597+
while (clang::isLowercase(*tmpPtr))
598+
++tmpPtr;
599+
600+
// Map the character sequence onto
601+
tok Kind = llvm::StringSwitch<tok>(StringRef(CurPtr, tmpPtr-CurPtr))
602+
#define KEYWORD(kw)
603+
#define POUND_KEYWORD(id) \
604+
.Case(#id, tok::pound_##id)
605+
#include "swift/Parse/Tokens.def"
606+
.Default(tok::pound);
607+
608+
// If we didn't find a match, then just return tok::pound. This is highly
609+
// dubious in terms of error recovery, but is useful for code completion and
610+
// SIL parsing.
611+
if (Kind == tok::pound)
612+
return formToken(tok::pound, TokStart);
613+
614+
// If we found something specific, return it.
615+
CurPtr = tmpPtr;
616+
return formToken(Kind, TokStart);
617+
}
618+
619+
578620
/// Is the operator beginning at the given character "left-bound"?
579621
static bool isLeftBound(const char *tokBegin, const char *bufferBegin) {
580622
// The first character in the file is not left-bound.
@@ -1584,65 +1626,10 @@ void Lexer::lexImpl() {
15841626
case ';': return formToken(tok::semi, TokStart);
15851627
case ':': return formToken(tok::colon, TokStart);
15861628

1587-
case '#': {
1588-
if (*CurPtr == ']') { // #]
1589-
CurPtr++;
1590-
return formToken(tok::r_square_lit, TokStart);
1591-
}
1592-
1593-
if (getSubstring(TokStart + 1, 2).equals("if") &&
1594-
isWhitespace(CurPtr[2])) {
1595-
CurPtr += 2;
1596-
return formToken(tok::pound_if, TokStart);
1597-
}
1598-
1599-
if (getSubstring(TokStart + 1, 4).equals("else") &&
1600-
isWhitespace(CurPtr[4])) {
1601-
CurPtr += 4;
1602-
return formToken(tok::pound_else, TokStart);
1603-
}
1604-
1605-
if (getSubstring(TokStart + 1, 6).equals("elseif") &&
1606-
isWhitespace(CurPtr[6])) {
1607-
CurPtr += 6;
1608-
return formToken(tok::pound_elseif, TokStart);
1609-
}
1610-
1611-
if (getSubstring(TokStart + 1, 5).equals("endif") &&
1612-
(isWhitespace(CurPtr[5]) || CurPtr[5] == '\0')) {
1613-
CurPtr += 5;
1614-
return formToken(tok::pound_endif, TokStart);
1615-
}
1616-
1617-
if (getSubstring(TokStart + 1, 4).equals("line") &&
1618-
isWhitespace(CurPtr[4])) {
1619-
CurPtr += 4;
1620-
return formToken(tok::pound_line, TokStart);
1621-
}
1622-
1623-
if (getSubstring(TokStart + 1, 9).equals("available")) {
1624-
CurPtr += 9;
1625-
return formToken(tok::pound_available, TokStart);
1626-
}
1627-
1628-
if (getSubstring(TokStart + 1, 8).equals("selector")) {
1629-
CurPtr += 8;
1630-
return formToken(tok::pound_selector, TokStart);
1631-
}
1632-
1633-
// Allow a hashbang #! line at the beginning of the file.
1634-
if (CurPtr - 1 == BufferStart && *CurPtr == '!') {
1635-
CurPtr--;
1636-
if (BufferID != SourceMgr.getHashbangBufferID())
1637-
diagnose(CurPtr, diag::lex_hashbang_not_allowed);
1638-
skipHashbang();
1639-
goto Restart;
1640-
}
1641-
1642-
return formToken(tok::pound, TokStart);
1643-
}
1629+
case '#':
1630+
return lexHash();
16441631

1645-
// Operator characters.
1632+
// Operator characters.
16461633
case '/':
16471634
if (CurPtr[0] == '/') { // "//"
16481635
skipSlashSlashComment();

0 commit comments

Comments
 (0)