Zen
A cross-platform functional programming language
|
00001 00005 #pragma once 00006 #include "Token.hpp" 00007 00009 namespace zbl { 00012 class Scanner { 00013 private: 00017 inline int read() { 00018 //assert(_stream.pos() == _npos); // pos() is a *very* expensive operation in Qt (at least 100x). 00019 if(_stream.end()) { 00020 //assert(_ch > 0); 00021 _ch = 0; 00022 } else { 00023 _ch = _stream.getChar(); 00024 if( _ch == '\n') { 00025 ++_line; 00026 _col = 0; 00027 } 00028 ++_col; 00029 } 00030 return _ch; 00031 } 00032 00037 inline int get(const int& pos) { 00038 assert(pos == _npos); 00039 return _ch; 00040 } 00041 00045 inline bool next() { 00046 if(_ch == 0) { 00047 _ch = 1; 00048 return false; 00049 } 00050 if(_ch == 1) { 00051 return false; 00052 } 00053 _string += _ch; 00054 ++_npos; 00055 read(); 00056 return true; 00057 } 00058 00059 public: 00063 inline Scanner(z::stream& stream) 00064 : _stream(stream), _ch(0), _tokenPos(0), _npos(0), _line(1), _col(0), _ccol(1), _tcol(1), start(*this), marker(*this), end(*this) { 00065 read(); 00066 } 00067 public: 00070 class cursor { 00071 public: 00075 inline cursor(Scanner& scanner) : _scanner(scanner), _pos(0) {} 00076 00077 public: 00081 inline int operator*() { 00082 return _scanner.get(_pos); 00083 } 00084 00088 inline cursor& operator++() { 00089 if(_scanner.next()) 00090 ++_pos; 00091 return ref(this); 00092 } 00093 00098 inline cursor& operator=(const cursor& src) { 00099 _pos = src._pos; 00100 return ref(this); 00101 } 00102 00103 private: 00105 Scanner& _scanner; 00106 00108 int _pos; 00109 }; 00110 private: 00114 inline z::string resetToken() { 00115 _ccol = _tcol; 00116 z::string s = _string; 00117 _string = z::string(""); 00118 _tokenPos = _npos; 00119 _tcol = _col; 00120 return s; 00121 } 00122 public: 00126 inline const z::string& getString() const {return _string;} 00127 00131 inline const int& getLine() const {return _line;} 00132 00136 inline const int& getCol() const {return _col;} 00137 00138 public: 00142 inline z::string getToken() { 00143 return resetToken(); 00144 } 00145 00146 public: 00153 inline Token createToken(const int& id, const z::string& s, const bool& hidden) { 00154 return Token(id, s, hidden, _line, _ccol); 00155 } 00156 00162 inline Token createToken(const int& id, const bool& hidden) { 00163 z::string s = resetToken(); 00164 return Token(id, s, hidden, _line, _ccol); 00165 } 00166 00172 inline Token createQuotedToken(const int& id, const bool& hidden) { 00173 z::string s = resetToken(); 00174 assert(s.length() >= 2); 00175 s = s.mid(1, s.length() - 2); 00176 return Token(id, s, hidden, _line, _ccol); 00177 } 00178 00184 inline Token createTrimmedToken(const int& id, const bool& hidden) { 00185 z::string s = resetToken(); 00186 assert(s.length() >= 1); 00187 s = s.mid(1); 00188 return Token(id, s, hidden, _line, _ccol); 00189 } 00190 00191 private: 00193 z::stream& _stream; 00194 00196 z::queue<int> _queue; 00197 00199 z::string _string; 00200 00202 int _ch; 00203 00205 int _tokenPos; 00206 00208 int _npos; 00209 00210 private: 00212 int _line; 00213 00215 int _col; 00216 00218 int _ccol; 00219 00221 int _tcol; 00222 00223 public: 00225 cursor start; 00226 00228 cursor marker; 00229 00231 cursor end; 00232 }; 00233 };