-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlex.cpp
More file actions
77 lines (74 loc) · 2.02 KB
/
lex.cpp
File metadata and controls
77 lines (74 loc) · 2.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#line 256 "1_fn-gen.md"
#include "lex.h"
#include "err.h"
#include <cstring>
#include <iostream>
#include <limits>
#include <map>
const Token &Lexer::advance() {
auto ch = std::cin.get();
while (ch != EOF && ch <= ' ') { ch = std::cin.get(); }
if (ch == EOF) { tok_ = Token { Token::Kind::end_of_input, "" }; }
else if (std::isalpha(ch)) { tok_ = read_identifier_or_keyword(ch); }
else if (std::isdigit(ch)) { tok_ = read_number(ch); }
else switch (ch) {
case '(':
tok_ = Token { Token::Kind::left_parenthesis, "(" };
break;
case ')':
tok_ = Token { Token::Kind::right_parenthesis, ")" };
break;
case '*':
tok_ = Token { Token::Kind::asterisk, "*" };
break;
case '.':
tok_ = Token { Token::Kind::period, "." };
break;
case ':':
tok_ = Token { Token::Kind::colon, ":" };
break;
case ';':
tok_ = Token { Token::Kind::semicolon, ";" };
break;
default:
err("unknown char '", static_cast<char>(ch), "'");
}
return tok_;
}
#line 302
const Token &Lexer::read_number(int ch) {
std::string rep { }; int value { 0 };
for (; ch != EOF && std::isdigit(ch); ch = std::cin.get()) {
rep += static_cast<char>(ch);
int digit { ch - '0' };
if (value > (std::numeric_limits<int>::max() - digit) / 10) {
err("INTEGER too big: ", quote(rep));
}
value = value * 10 + digit;
}
if (ch != EOF) { std::cin.putback(ch); }
tok_ = Token { Token::Kind::integer_number, rep, value };
return tok_;
}
#line 325
static std::map<std::string, Token::Kind> keywords {
{ "BEGIN", Token::Kind::BEGIN },
{ "END", Token::Kind::END },
{ "MODULE", Token::Kind::MODULE },
{ "PROCEDURE", Token::Kind::PROCEDURE },
{ "RETURN", Token::Kind::RETURN }
};
#line 339
const Token &Lexer::read_identifier_or_keyword(int ch) {
std::string rep { };
for (; ch != EOF && std::isalnum(ch); ch = std::cin.get()) {
rep += static_cast<char>(ch);
}
if (ch != EOF) { std::cin.putback(ch); }
auto got { keywords.find(rep) };
tok_ = Token {
got != keywords.end() ? got->second : Token::Kind::identifier,
rep
};
return tok_;
}