49 Lexer(
const Lexer&) =
delete;
54 Lexer& operator=(
const Lexer&) =
delete;
62 Lexer(std::shared_ptr<std::istream> buffer,
const std::string& fname =
"")
63 : loc_(fname, 1, 1), buf_(buffer) {}
72 Token next_token() {
return lex(); }
76 std::shared_ptr<std::istream> buf_;
83 void skip_char(
int n = 1) {
85 loc_.advance_column(n);
93 bool skip_whitespace() {
96 while (buf_->peek() ==
' ' || buf_->peek() ==
'\t') {
101 loc_.advance_column(consumed);
111 void skip_line_comment() {
114 while (buf_->peek() != 0 && buf_->peek() !=
'\n' &&
115 buf_->peek() !=
'\r') {
120 loc_.advance_column(consumed);
131 Token lex_numeric_constant(Location tok_start) {
135 while (std::isdigit(buf_->peek())) {
136 str.push_back(buf_->peek());
140 if (buf_->peek() !=
'.') {
141 return Token(tok_start, Token::Kind::nninteger, str);
145 str.push_back(buf_->peek());
147 while (std::isdigit(buf_->peek())) {
148 str.push_back(buf_->peek());
152 return Token(tok_start, Token::Kind::real, str);
163 Token lex_identifier(Location tok_start) {
167 while (std::isalpha(buf_->peek()) || std::isdigit(buf_->peek()) ||
168 buf_->peek() ==
'_') {
169 str.push_back(buf_->peek());
174 auto keyword = keywords.find(str);
175 if (keyword != keywords.end()) {
176 return Token(tok_start, keyword->second, str);
179 return Token(tok_start, Token::Kind::identifier, str);
190 Token lex_string(Location tok_start) {
194 while (buf_->peek() !=
'"' && buf_->peek() !=
'\n' &&
195 buf_->peek() !=
'\r') {
196 str.push_back(buf_->peek());
200 if (buf_->peek() !=
'"') {
201 std::cerr <<
"Unmatched \", strings must on the same line\n";
202 return Token(tok_start, Token::Kind::unknown, str);
206 return Token(tok_start, Token::Kind::string, str);
217 Location tok_start = loc_;
220 switch (buf_->peek()) {
223 return Token(tok_start, Token::Kind::eof,
"");
227 if (buf_->peek() !=
'\n') {
240 if (buf_->peek() ==
'/') {
244 return Token(tok_start, Token::Kind::slash,
"/");
247 case '0':
case '1':
case '2':
case '3':
case '4':
248 case '5':
case '6':
case '7':
case '8':
case '9':
249 return lex_numeric_constant(tok_start);
254 if (buf_->peek() ==
'X') {
256 return Token(tok_start, Token::Kind::kw_cx,
"CX");
259 loc_.advance_column();
260 return Token(tok_start, Token::Kind::unknown,
261 std::string({
'C', (char) buf_->get()}));
265 return Token(tok_start, Token::Kind::kw_u,
"U");
269 case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
270 case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
271 case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
272 case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
273 return lex_identifier(tok_start);
278 return Token(tok_start, Token::Kind::l_square,
"[");
282 return Token(tok_start, Token::Kind::r_square,
"]");
286 return Token(tok_start, Token::Kind::l_paren,
"(");
290 return Token(tok_start, Token::Kind::r_paren,
")");
294 return Token(tok_start, Token::Kind::l_brace,
"{");
298 return Token(tok_start, Token::Kind::r_brace,
"}");
302 return Token(tok_start, Token::Kind::star,
"*");
306 return Token(tok_start, Token::Kind::plus,
"+");
311 if (buf_->peek() ==
'>') {
313 return Token(tok_start, Token::Kind::arrow,
"->");
316 return Token(tok_start, Token::Kind::minus,
"-");
320 return Token(tok_start, Token::Kind::caret,
"^");
324 return Token(tok_start, Token::Kind::semicolon,
";");
328 if (buf_->peek() ==
'=') {
330 return Token(tok_start, Token::Kind::equalequal,
"==");
333 loc_.advance_column();
334 return Token(tok_start, Token::Kind::unknown,
335 std::string({
'=', (char) buf_->get()}));
339 return Token(tok_start, Token::Kind::comma,
";");
343 return lex_string(tok_start);
346 loc_.advance_column();
347 return Token(tok_start, Token::Kind::unknown,
348 std::string({(char) buf_->get()}));
Quantum++ main namespace.
Definition: circuits.h:35