/* Generated by re2c 0.13.5 on Wed Jun 25 12:01:36 2008 */ #line 1 "lexer.re" #include #include "lexer.hpp" #include "token.hpp" namespace SpasmImpl { namespace ASM { //! Namespace for all lexical analisys classes namespace Lexer { Lexer::Lexer(std::istream& _file, size_t _buffer_size) : file(&_file), buffer_size(_buffer_size), state(unsigned(-1)), lineno(0) { buffer = new char[buffer_size]; cursor = limit = marker = token_start = NULL; } Lexer::~Lexer() { delete[] buffer; } bool Lexer::tokenize(TokenStream& ts) { #line 43 "lexer.re" switch (state) { default: goto yy0; case 0: goto yyFillLabel0; case 1: goto yyFillLabel1; case 2: goto yyFillLabel2; case 3: goto yyFillLabel3; case 4: goto yyFillLabel4; } while (1) { #line 48 "lexer.cpp" yy0: state = (0); if ((limit - cursor) < 8) return true; yyFillLabel0: yych = *cursor; if (yych <= '<') { if (yych <= ')') { if (yych <= '\n') { if (yych <= 0x00) goto yy30; if (yych <= 0x08) goto yy32; if (yych <= '\t') goto yy26; goto yy28; } else { if (yych <= ' ') { if (yych <= 0x1F) goto yy32; goto yy26; } else { if (yych == '%') goto yy17; goto yy32; } } } else { if (yych <= '.') { if (yych <= '+') { if (yych <= '*') goto yy13; goto yy11; } else { if (yych != '-') goto yy32; } } else { if (yych <= '0') { if (yych <= '/') goto yy15; goto yy4; } else { if (yych <= '9') goto yy6; if (yych <= ';') goto yy32; goto yy23; } } } } else { if (yych <= 'f') { if (yych <= '_') { if (yych <= '@') goto yy32; if (yych <= 'Z') goto yy25; if (yych <= '^') goto yy32; goto yy25; } else { if (yych <= 'b') { if (yych <= '`') goto yy32; goto yy25; } else { if (yych <= 'c') goto yy20; if (yych <= 'd') goto yy9; goto yy25; } } } else { if (yych <= 'p') { if (yych <= 'k') { if (yych <= 'g') goto yy19; goto yy25; } else { if (yych <= 'l') goto yy21; if (yych <= 'o') goto yy25; goto yy7; } } else { if (yych <= 'r') { if (yych <= 'q') goto yy25; goto yy10; } else { if (yych <= 's') goto yy22; if (yych <= 'z') goto yy25; goto yy32; } } } } ++cursor; if ((yych = *cursor) == '0') goto yy99; #line 116 "lexer.re" { ts.push_token(Token(Token::minus, lineno)); token_start = cursor; continue; } #line 138 "lexer.cpp" yy4: yych = *(marker = ++cursor); if (yych == 'X') goto yy94; if (yych == 'x') goto yy94; yy5: #line 58 "lexer.re" { ts.push_token(Token(Token::integer, lineno, token_start, cursor)); token_start = cursor; continue; } #line 152 "lexer.cpp" yy6: yych = *++cursor; goto yy93; yy7: ++cursor; if ((yych = *cursor) <= 'q') { if (yych == 'o') goto yy80; goto yy37; } else { if (yych <= 'r') goto yy81; if (yych == 'u') goto yy82; goto yy37; } yy8: #line 212 "lexer.re" { ts.push_token(Token(Token::ident, lineno, token_start, cursor)); token_start = cursor; continue; } #line 175 "lexer.cpp" yy9: yych = *++cursor; if (yych == 'u') goto yy77; goto yy37; yy10: yych = *++cursor; if (yych == 'e') goto yy71; goto yy37; yy11: ++cursor; #line 109 "lexer.re" { ts.push_token(Token(Token::plus, lineno)); token_start = cursor; continue; } #line 193 "lexer.cpp" yy13: ++cursor; #line 123 "lexer.re" { ts.push_token(Token(Token::multiply, lineno)); token_start = cursor; continue; } #line 203 "lexer.cpp" yy15: ++cursor; #line 130 "lexer.re" { ts.push_token(Token(Token::divide, lineno)); token_start = cursor; continue; } #line 213 "lexer.cpp" yy17: ++cursor; #line 137 "lexer.re" { ts.push_token(Token(Token::modulus, lineno)); token_start = cursor; continue; } #line 223 "lexer.cpp" yy19: yych = *++cursor; if (yych == 'o') goto yy58; goto yy37; yy20: yych = *++cursor; if (yych == 'a') goto yy54; goto yy37; yy21: yych = *++cursor; if (yych == 'a') goto yy45; if (yych == 'o') goto yy46; goto yy37; yy22: yych = *++cursor; if (yych == 't') goto yy40; goto yy37; yy23: ++cursor; if ((yych = *cursor) == '=') goto yy38; #line 198 "lexer.re" { ts.push_token(Token(Token::less, lineno)); token_start = cursor; continue; } #line 251 "lexer.cpp" yy25: yych = *++cursor; goto yy37; yy26: ++cursor; yych = *cursor; goto yy35; yy27: #line 220 "lexer.re" { token_start = cursor; continue; } #line 266 "lexer.cpp" yy28: ++cursor; #line 226 "lexer.re" { ++lineno; token_start = cursor; continue; } #line 276 "lexer.cpp" yy30: ++cursor; #line 233 "lexer.re" { ts.push_token(Token(Token::endinput, lineno)); break; } #line 285 "lexer.cpp" yy32: ++cursor; #line 239 "lexer.re" { return false; } #line 292 "lexer.cpp" yy34: ++cursor; state = (1); if (limit <= cursor) return true; yyFillLabel1: yych = *cursor; yy35: if (yych == '\t') goto yy34; if (yych == ' ') goto yy34; goto yy27; yy36: ++cursor; state = (2); if (limit <= cursor) return true; yyFillLabel2: yych = *cursor; yy37: if (yych <= 'Z') { if (yych <= '/') goto yy8; if (yych <= '9') goto yy36; if (yych <= '@') goto yy8; goto yy36; } else { if (yych <= '_') { if (yych <= '^') goto yy8; goto yy36; } else { if (yych <= '`') goto yy8; if (yych <= 'z') goto yy36; goto yy8; } } yy38: ++cursor; #line 192 "lexer.re" { ts.push_token(Token(Token::lesseq, lineno)); token_start = cursor; continue; } #line 334 "lexer.cpp" yy40: yych = *++cursor; if (yych != 'o') goto yy37; yych = *++cursor; if (yych != 'r') goto yy37; yych = *++cursor; if (yych != 'e') goto yy37; ++cursor; if ((yych = *cursor) <= 'Z') { if (yych <= '/') goto yy44; if (yych <= '9') goto yy36; if (yych >= 'A') goto yy36; } else { if (yych <= '_') { if (yych >= '_') goto yy36; } else { if (yych <= '`') goto yy44; if (yych <= 'z') goto yy36; } } yy44: #line 186 "lexer.re" { ts.push_token(Token(Token::store, lineno)); token_start = cursor; continue; } #line 363 "lexer.cpp" yy45: yych = *++cursor; if (yych == 'b') goto yy50; goto yy37; yy46: yych = *++cursor; if (yych != 'a') goto yy37; yych = *++cursor; if (yych != 'd') goto yy37; ++cursor; if ((yych = *cursor) <= 'Z') { if (yych <= '/') goto yy49; if (yych <= '9') goto yy36; if (yych >= 'A') goto yy36; } else { if (yych <= '_') { if (yych >= '_') goto yy36; } else { if (yych <= '`') goto yy49; if (yych <= 'z') goto yy36; } } yy49: #line 179 "lexer.re" { ts.push_token(Token(Token::load, lineno)); token_start = cursor; continue; } #line 394 "lexer.cpp" yy50: yych = *++cursor; if (yych != 'e') goto yy37; yych = *++cursor; if (yych != 'l') goto yy37; ++cursor; if ((yych = *cursor) <= 'Z') { if (yych <= '/') goto yy53; if (yych <= '9') goto yy36; if (yych >= 'A') goto yy36; } else { if (yych <= '_') { if (yych >= '_') goto yy36; } else { if (yych <= '`') goto yy53; if (yych <= 'z') goto yy36; } } yy53: #line 205 "lexer.re" { ts.push_token(Token(Token::label, lineno)); token_start = cursor; continue; } #line 421 "lexer.cpp" yy54: yych = *++cursor; if (yych != 'l') goto yy37; yych = *++cursor; if (yych != 'l') goto yy37; ++cursor; if ((yych = *cursor) <= 'Z') { if (yych <= '/') goto yy57; if (yych <= '9') goto yy36; if (yych >= 'A') goto yy36; } else { if (yych <= '_') { if (yych >= '_') goto yy36; } else { if (yych <= '`') goto yy57; if (yych <= 'z') goto yy36; } } yy57: #line 165 "lexer.re" { ts.push_token(Token(Token::call, lineno)); token_start = cursor; continue; } #line 448 "lexer.cpp" yy58: ++cursor; if ((yych = *cursor) <= '_') { if (yych <= '@') { if (yych <= '/') goto yy59; if (yych <= '9') goto yy36; } else { if (yych <= 'Z') goto yy36; if (yych >= '_') goto yy36; } } else { if (yych <= 'f') { if (yych <= '`') goto yy59; if (yych <= 'e') goto yy36; goto yy61; } else { if (yych == 't') goto yy60; if (yych <= 'z') goto yy36; } } yy59: #line 158 "lexer.re" { ts.push_token(Token(Token::go, lineno)); token_start = cursor; continue; } #line 477 "lexer.cpp" yy60: yych = *++cursor; if (yych == 'r') goto yy67; goto yy37; yy61: yych = *++cursor; if (yych != 'a') goto yy37; yych = *++cursor; if (yych != 'l') goto yy37; yych = *++cursor; if (yych != 's') goto yy37; yych = *++cursor; if (yych != 'e') goto yy37; ++cursor; if ((yych = *cursor) <= 'Z') { if (yych <= '/') goto yy66; if (yych <= '9') goto yy36; if (yych >= 'A') goto yy36; } else { if (yych <= '_') { if (yych >= '_') goto yy36; } else { if (yych <= '`') goto yy66; if (yych <= 'z') goto yy36; } } yy66: #line 151 "lexer.re" { ts.push_token(Token(Token::gofalse, lineno)); token_start = cursor; continue; } #line 512 "lexer.cpp" yy67: yych = *++cursor; if (yych != 'u') goto yy37; yych = *++cursor; if (yych != 'e') goto yy37; ++cursor; if ((yych = *cursor) <= 'Z') { if (yych <= '/') goto yy70; if (yych <= '9') goto yy36; if (yych >= 'A') goto yy36; } else { if (yych <= '_') { if (yych >= '_') goto yy36; } else { if (yych <= '`') goto yy70; if (yych <= 'z') goto yy36; } } yy70: #line 144 "lexer.re" { ts.push_token(Token(Token::gotrue, lineno)); token_start = cursor; continue; } #line 539 "lexer.cpp" yy71: yych = *++cursor; if (yych == 'a') goto yy72; if (yych == 't') goto yy73; goto yy37; yy72: yych = *++cursor; if (yych == 'd') goto yy75; goto yy37; yy73: ++cursor; if ((yych = *cursor) <= 'Z') { if (yych <= '/') goto yy74; if (yych <= '9') goto yy36; if (yych >= 'A') goto yy36; } else { if (yych <= '_') { if (yych >= '_') goto yy36; } else { if (yych <= '`') goto yy74; if (yych <= 'z') goto yy36; } } yy74: #line 172 "lexer.re" { ts.push_token(Token(Token::ret, lineno)); token_start = cursor; continue; } #line 571 "lexer.cpp" yy75: ++cursor; if ((yych = *cursor) <= 'Z') { if (yych <= '/') goto yy76; if (yych <= '9') goto yy36; if (yych >= 'A') goto yy36; } else { if (yych <= '_') { if (yych >= '_') goto yy36; } else { if (yych <= '`') goto yy76; if (yych <= 'z') goto yy36; } } yy76: #line 95 "lexer.re" { ts.push_token(Token(Token::read, lineno)); token_start = cursor; continue; } #line 594 "lexer.cpp" yy77: yych = *++cursor; if (yych != 'p') goto yy37; ++cursor; if ((yych = *cursor) <= 'Z') { if (yych <= '/') goto yy79; if (yych <= '9') goto yy36; if (yych >= 'A') goto yy36; } else { if (yych <= '_') { if (yych >= '_') goto yy36; } else { if (yych <= '`') goto yy79; if (yych <= 'z') goto yy36; } } yy79: #line 88 "lexer.re" { ts.push_token(Token(Token::dup, lineno)); token_start = cursor; continue; } #line 619 "lexer.cpp" yy80: yych = *++cursor; if (yych == 'p') goto yy90; goto yy37; yy81: yych = *++cursor; if (yych == 'i') goto yy86; goto yy37; yy82: yych = *++cursor; if (yych != 's') goto yy37; yych = *++cursor; if (yych != 'h') goto yy37; ++cursor; if ((yych = *cursor) <= 'Z') { if (yych <= '/') goto yy85; if (yych <= '9') goto yy36; if (yych >= 'A') goto yy36; } else { if (yych <= '_') { if (yych >= '_') goto yy36; } else { if (yych <= '`') goto yy85; if (yych <= 'z') goto yy36; } } yy85: #line 74 "lexer.re" { ts.push_token(Token(Token::push, lineno)); token_start = cursor; continue; } #line 654 "lexer.cpp" yy86: yych = *++cursor; if (yych != 'n') goto yy37; yych = *++cursor; if (yych != 't') goto yy37; ++cursor; if ((yych = *cursor) <= 'Z') { if (yych <= '/') goto yy89; if (yych <= '9') goto yy36; if (yych >= 'A') goto yy36; } else { if (yych <= '_') { if (yych >= '_') goto yy36; } else { if (yych <= '`') goto yy89; if (yych <= 'z') goto yy36; } } yy89: #line 102 "lexer.re" { ts.push_token(Token(Token::print, lineno)); token_start = cursor; continue; } #line 681 "lexer.cpp" yy90: ++cursor; if ((yych = *cursor) <= 'Z') { if (yych <= '/') goto yy91; if (yych <= '9') goto yy36; if (yych >= 'A') goto yy36; } else { if (yych <= '_') { if (yych >= '_') goto yy36; } else { if (yych <= '`') goto yy91; if (yych <= 'z') goto yy36; } } yy91: #line 81 "lexer.re" { ts.push_token(Token(Token::pop, lineno)); token_start = cursor; continue; } #line 704 "lexer.cpp" yy92: ++cursor; state = (3); if (limit <= cursor) return true; yyFillLabel3: yych = *cursor; yy93: if (yych <= '/') goto yy5; if (yych <= '9') goto yy92; goto yy5; yy94: yych = *++cursor; if (yych <= '@') { if (yych <= '/') goto yy95; if (yych <= '9') goto yy96; } else { if (yych <= 'F') goto yy96; if (yych <= '`') goto yy95; if (yych <= 'f') goto yy96; } yy95: cursor = marker; goto yy5; yy96: ++cursor; state = (4); if (limit <= cursor) return true; yyFillLabel4: yych = *cursor; if (yych <= '@') { if (yych <= '/') goto yy98; if (yych <= '9') goto yy96; } else { if (yych <= 'F') goto yy96; if (yych <= '`') goto yy98; if (yych <= 'f') goto yy96; } yy98: #line 66 "lexer.re" { ts.push_token(Token(Token::xinteger, lineno, token_start, cursor)); token_start = cursor; continue; } #line 751 "lexer.cpp" yy99: ++cursor; yych = *cursor; goto yy5; #line 243 "lexer.re" } return true; } /*! ** Fills up the buffer when neccessary. ** Note the buffer is always filled to the maximum, not just the ** number of bytes neccessary for the lexer to continue. ** ** \param nbytes - the number of bytes */ void Lexer::buffer_grow(size_t new_size) { char* new_buffer = new char[new_size]; std::copy(buffer, limit, new_buffer); token_start = new_buffer + (token_start - buffer); cursor = new_buffer + (cursor - buffer); limit = new_buffer + new_size; buffer_size = new_size; delete[] buffer; buffer = new_buffer; } void Lexer::read(size_t nbytes) { if (token_start + nbytes > limit) { // we need larger buffer buffer_grow(token_start - buffer + nbytes); } std::copy(token_start, limit, buffer); cursor -= token_start - buffer; char* old_limit = limit - (token_start - buffer); token_start = buffer; file->read(old_limit, limit - old_limit); if (file->eof()) { size_t bytes = file->gcount(); std::fill(old_limit + bytes, limit, '\0'); } } void Lexer::buffer_init() { file->read(buffer, buffer_size); if (file->eof()) { size_t bytes = file->gcount(); std::fill(buffer + bytes, buffer + buffer_size, '\0'); } cursor = marker = token_start = buffer; limit = buffer + buffer_size; } } // namespace Lexer } // namespace ASM } // namespace SpasmImpl