00001 #ifndef _Lexer_h_
00002 #define _Lexer_h_
00003 #include <ctype.h>
00004 #include <stdio.h>
00005
00006 #include <iostream>
00007 #include <fstream>
00008
00009 #include "Error.h"
00010 #include "readline.h"
00011
00018 class Lexer {
00019 friend class SyntaxError;
00020 private:
00021 const char *_fn;
00022 std::ifstream _is;
00023
00024 string _tok;
00025
00026 string _buf;
00027 int _line;
00028 const char *_cbuf;
00029 const char *_cbufp;
00030 public:
00031 Lexer(const char *fn = NULL) {
00032 _fn = NULL;
00033 if (fn)
00034 open(fn);
00035 } void close() {
00036 if (!_fn)
00037 return;
00038 _fn = NULL;
00039 _is.close();
00040 }
00041
00042 void open(const char *fn) {
00043 _is.open(fn);
00044 if (!_is.good())
00045 throw IOError("Stream bad", -1, ERROR_LOCATION);
00046 _fn = fn;
00047 _line = 0;
00048 _buf = "";
00049 _cbufp = _cbuf = _buf.c_str();
00050 }
00051
00052 int eof() {
00053 return _is.eof();
00054 }
00055
00056 string curToken() {
00057 return _tok;
00058 }
00059
00060 string getToken() {
00061 const char *q;
00062 while (!(*_cbufp)) {
00063 if (!_is.good())
00064 throw IOError("Stream bad", -1,
00065 ERROR_LOCATION);
00066 _line++;
00067 nlreadline(_is, _buf, 0);
00068 if (_is.eof())
00069 return "";
00070 if (!_is.good())
00071 throw IOError("Stream bad", -1,
00072 ERROR_LOCATION);
00073 _cbufp = _cbuf = _buf.c_str();
00074 while (isspace(*_cbufp))
00075 _cbufp++;
00076 if (*_cbufp == '#')
00077 _cbufp = _cbuf + _buf.length();
00078 }
00079 q = _cbufp;
00080 while (*q && !isspace(*q))
00081 q++;
00082 _tok.assign(_cbufp, q - _cbufp);
00083 _cbufp = q;
00084 while (isspace(*_cbufp))
00085 _cbufp++;
00086 return _tok;
00087 }
00088
00089 void putbackToken(string token) {
00090 _buf.replace(0, _cbufp - _cbuf, token + ' ');
00091 _cbufp = _cbuf = _buf.c_str();
00092 }
00093
00094 int isFlag(const string & token, const char *strg, int *flag) {
00095 const char *ctok = token.c_str();
00096 if (strcmp(ctok, strg) == 0) {
00097 *flag = 1;
00098 return 1;
00099 }
00100 if (strncmp(ctok, "not-", 4) == 0
00101 && strcmp(ctok + 4, strg) == 0) {
00102 *flag = 0;
00103 return 1;
00104 }
00105 return 0;
00106 }
00107 };
00108
00115 class SyntaxError:public Error {
00116 public:
00117 SyntaxError(const Lexer & lex, const char *txt, const char *file,
00118 const char *function, int line)
00119 :Error(txt, file, function, line) {
00120 char buf[256];
00121 sprintf(buf, ":%d: ", lex._line);
00122
00123 _errtext = lex._fn;
00124 _errtext += buf;
00125 _errtext += txt;
00126 VERB(slog.p(Logger::Error);
00127 SyntaxError::print());
00128 } virtual void print() {
00129 slog << "Exception!\n"
00130 << " Type: Syntax\n"
00131 << " Desc: " << _errtext << "\n";
00132 }
00133 };
00134
00135 #endif