23 #include <unordered_map>
37 #define TC_FORALL_TOKEN_KINDS(_) \
38 _(TK_EOF, "eof", "") \
39 _(TK_NUMBER, "number", "") \
40 _(TK_BOOL_VALUE, "bool_value", "") \
41 _(TK_MIN, "min", "min") \
42 _(TK_MAX, "max", "max") \
43 _(TK_WHERE, "where", "where") \
44 _(TK_FLOAT, "float", "float") \
45 _(TK_DOUBLE, "double", "double") \
46 _(TK_DEF, "def", "def") \
47 _(TK_ARROW, "arrow", "->") \
48 _(TK_EQUIVALENT, "equivalent", "<=>") \
49 _(TK_IDENT, "ident", "") \
50 _(TK_STRING, "string", "") \
51 _(TK_CONST, "const", "") \
52 _(TK_LIST, "list", "") \
53 _(TK_OPTION, "option", "") \
54 _(TK_APPLY, "apply", "") \
55 _(TK_COMPREHENSION, "comprehension", "") \
56 _(TK_TENSOR_TYPE, "tensor_type", "") \
57 _(TK_RANGE_CONSTRAINT, "range_constraint", "") \
58 _(TK_PARAM, "param", "") \
59 _(TK_INFERRED, "inferred", "") \
60 _(TK_ACCESS, "access", "") \
61 _(TK_BUILT_IN, "built-in", "") \
62 _(TK_PLUS_EQ, "plus_eq", "+=") \
63 _(TK_TIMES_EQ, "times_eq", "*=") \
64 _(TK_MIN_EQ, "min_eq", "min=") \
65 _(TK_MAX_EQ, "max_eq", "max=") \
66 _(TK_PLUS_EQ_B, "plus_eq_b", "+=!") \
67 _(TK_TIMES_EQ_B, "times_eq_b", "*=!") \
68 _(TK_MIN_EQ_B, "min_eq_b", "min=!") \
69 _(TK_MAX_EQ_B, "max_eq_b", "max=!") \
70 _(TK_INT8, "int8", "int8") \
71 _(TK_INT16, "int16", "int16") \
72 _(TK_INT32, "int32", "int32") \
73 _(TK_INT64, "int64", "int64") \
74 _(TK_UINT8, "uint8", "uint8") \
75 _(TK_UINT16, "uint16", "uint16") \
76 _(TK_UINT32, "uint32", "uint32") \
77 _(TK_UINT64, "uint64", "uint64") \
78 _(TK_BOOL, "bool", "bool") \
79 _(TK_CAST, "cast", "") \
80 _(TK_IN, "in", "in") \
81 _(TK_GE, "ge", ">=") \
82 _(TK_LE, "le", "<=") \
83 _(TK_EQ, "eq", "==") \
84 _(TK_NE, "neq", "!=") \
85 _(TK_AND, "and", "&&") \
86 _(TK_OR, "or", "||") \
87 _(TK_LET, "let", "") \
88 _(TK_EXISTS, "exists", "exists")
90 static const char* valid_single_char_tokens =
"+-*/()[]?:,={}><!";
97 #define DEFINE_TOKEN(tok, _, _2) tok,
116 if (entry ==
nullptr) {
119 entry->insert(str + 1, tok);
130 std::vector<std::vector<int>> binary_ops = {
134 {
'>',
'<', TK_LE, TK_GE, TK_EQ, TK_NE},
138 std::vector<std::vector<int>> unary_ops = {
142 std::stringstream ss;
143 for (
const char* c = valid_single_char_tokens; *c; c++) {
144 const char str[] = {*c,
'\0'};
145 head->insert(str, *c);
148 #define ADD_CASE(tok, _, tokstring) \
149 if (*tokstring != '\0') { \
150 head->insert(tokstring, tok); \
158 for (
auto& group : binary_ops) {
159 for (
auto& element : group) {
165 for (
auto& group : unary_ops) {
166 for (
auto& element : group) {
172 bool isNumber(
const std::string& str,
size_t start,
size_t* len) {
173 char first = str[start];
178 if (first ==
'-' || first ==
'+')
180 const char* startptr = str.c_str() + start;
182 std::strtod(startptr, &endptr);
183 *len = endptr - startptr;
190 const std::string& str,
196 while (pos < str.size() && isspace(str[pos]))
199 if (pos < str.size() && str[pos] ==
'#') {
200 while (pos < str.size() && str[pos] !=
'\n')
203 return match(str, pos, kind, start, len);
206 if (pos == str.size()) {
219 bool matched =
false;
222 for (
size_t i = 0; pos + i < str.size() && (ident || cur !=
nullptr); i++) {
233 auto it = cur->
children.find(str[pos + i]);
234 cur = (it == cur->
children.end()) ?
nullptr : it->second.get();
235 if (cur && cur->
kind != 0) {
289 return isalpha(n) || n ==
'_' || (i > 0 && isdigit(n));
292 std::unordered_map<int, int>
294 std::unordered_map<int, int>
305 const std::shared_ptr<std::string>&
file_,
308 : file_(file_), start_(start_), end_(end_) {}
309 const std::string
text()
const {
316 const std::string& str =
file();
317 size_t begin =
start();
319 while (begin > 0 && str[begin - 1] !=
'\n')
321 while (end < str.size() && str[
end] !=
'\n')
323 out << str.substr(0, end) <<
"\n";
324 out << std::string(
start() - begin,
' ');
325 size_t len = std::min(
size(), end -
start());
326 out << std::string(len,
'~')
327 << (len <
size() ?
"... <--- HERE" :
" <--- HERE");
328 out << str.substr(end);
329 if (str.size() > 0 && str.back() !=
'\n')
332 const std::string&
file()
const {
335 const std::shared_ptr<std::string>&
file_ptr()
const {
356 assert(TK_NUMBER ==
kind);
358 double r = std::stod(
text(), &idx);
371 std::shared_ptr<std::string>
file;
373 :
file(std::make_shared<std::string>(str)),
427 pos = start + length;
std::unordered_map< char, TokenTrieRef > children
Definition: lexer.h:122
bool isUnary(int kind, int *prec)
Definition: lexer.h:244
Token lex()
Definition: lexer.h:416
void highlight(std::ostream &out) const
Definition: lexer.h:315
size_t size() const
Definition: lexer.h:312
bool isBinary(int kind, int *prec)
Definition: lexer.h:252
Token lookahead()
Definition: lexer.h:385
std::unique_ptr< Token > lookahead_
Definition: lexer.h:432
size_t end_
Definition: lexer.h:348
std::shared_ptr< std::string > file_
Definition: lexer.h:346
size_t start() const
Definition: lexer.h:338
bool validIdent(size_t i, char n)
Definition: lexer.h:288
int kind
Definition: lexer.h:121
SourceRange(const std::shared_ptr< std::string > &file_, size_t start_, size_t end_)
Definition: lexer.h:304
TokenTrieRef head
Definition: lexer.h:291
#define TC_FORALL_TOKEN_KINDS(_)
Definition: lexer.h:37
Token expect(int kind)
Definition: lexer.h:405
Token cur_
Definition: lexer.h:431
bool match(const std::string &str, size_t pos, int *kind, size_t *start, size_t *len)
Definition: lexer.h:189
Token & cur()
Definition: lexer.h:411
SharedParserData()
Definition: lexer.h:128
bool isScalarType(int kind)
Definition: lexer.h:268
Token next()
Definition: lexer.h:391
Lexer(const std::string &str)
Definition: lexer.h:372
#define ADD_CASE(tok, _, tokstring)
std::string text()
Definition: lexer.h:362
bool isNumber(const std::string &str, size_t start, size_t *len)
Definition: lexer.h:172
std::unordered_map< int, int > binary_prec
Definition: lexer.h:295
TokenTrie()
Definition: lexer.h:108
int kind
Definition: lexer.h:352
std::shared_ptr< std::string > file
Definition: lexer.h:371
size_t pos
Definition: lexer.h:430
void reportError(const std::string &what, const Token &t)
size_t start_
Definition: lexer.h:347
void reportError(const std::string &what)
Definition: lexer.h:402
TokenKind
Definition: lexer.h:92
std::string kindString() const
Definition: lexer.h:365
const std::string text() const
Definition: lexer.h:309
std::string kindToString(int kind)
bool nextIf(int kind)
Definition: lexer.h:379
bool isRightAssociative(int kind)
Definition: lexer.h:260
SourceRange range
Definition: lexer.h:353
double doubleValue()
Definition: lexer.h:355
SharedParserData & sharedParserData()
const std::string & file() const
Definition: lexer.h:332
Token(int kind, const SourceRange &range)
Definition: lexer.h:354
void insert(const char *str, int tok)
Definition: lexer.h:109
size_t end() const
Definition: lexer.h:341
const std::shared_ptr< std::string > & file_ptr() const
Definition: lexer.h:335
std::unique_ptr< TokenTrie > TokenTrieRef
Definition: lexer.h:106
std::unordered_map< int, int > unary_prec
Definition: lexer.h:293
SharedParserData & shared
Definition: lexer.h:433
#define DEFINE_TOKEN(tok, _, _2)
Definition: lexer.h:97