00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00022 #ifndef INTELIB_SLEXER_HPP_SENTRY
00023 #define INTELIB_SLEXER_HPP_SENTRY
00024
00025 #include "../sexpress/sexpress.hpp"
00026 #include "../sexpress/sstring.hpp"
00027
00028 extern SLabel LexemaEof;
00029
00030
00031 #if defined(EOF) && EOF != -1
00032 #error This version assumes EOF is -1 and that is not true for your situation
00033
00034
00035
00036 #endif
00037
00038
00040
00047 class IntelibSLexAnalyser {
00048
00049 struct SpecChar {
00050 char ch;
00051 enum {
00052 non_term, term, non_delim, read_rest, read_string, ignore_until
00053 } status : 8;
00054 SpecChar *sub;
00055 SpecChar *next;
00056 char closer[4];
00057
00058 SReference token;
00059 SReference (*makestring)(const char *str);
00062
00063 SpecChar() : ch(0), status(non_term), sub(0), next(0),
00064 token(), makestring(0)
00065 { closer[0] = 0; }
00066 } *specchars, **special_state;
00067
00068 SString delimiter_chars;
00069
00070 enum State {
00071 home,
00072 string,
00073 stringq,
00074 token,
00075 token_force,
00076 special,
00077 special2,
00078 special3,
00079
00080
00081 comment
00082 } state;
00083 const char *closer;
00084 SReference (*string_finalizer)(const char *);
00086 int comment_closer_index;
00087 int postponed_char;
00088 SString buf;
00089
00090 int line, lexline;
00091 SReference lex;
00092 const char *error_message;
00093 public:
00095 IntelibSLexAnalyser();
00097 ~IntelibSLexAnalyser();
00098
00100 bool AddDelimiter(const char *prefix, const SReference &token);
00102 bool AddNonDelimiter(const char *prefix, const SReference &token);
00104
00105 bool AddTokenStarter(const char *prefix,
00106 SReference (*fun)(const char *str) = 0);
00108 bool AddStringStarter(const char *prefix, int closer_char,
00109 SReference (*fun)(const char *str) = 0);
00111 bool AddCommentStarter(const char *prefix, const char *closer = "\n");
00112
00114 enum FeedResult {
00115 res_empty,
00116 res_ready,
00117 res_continue,
00118 res_eof,
00119 res_error
00120 };
00121
00123
00124 FeedResult FeedChar(int c);
00125
00127 SReference Get() const;
00128
00130 int GetLine() const { return line; }
00132 void SetLine(int l) { line = l; }
00134 const char *GetErrorMessage() const { return error_message; }
00135
00137 void Drop();
00138
00139 private:
00140 SpecChar *AddSpecial(const char *prefix, bool extendable);
00141 SpecChar *DoAddSpecial(SpecChar **p, const char *str, bool ex);
00142
00143 FeedResult Home(int c);
00144 FeedResult String(int c);
00145 FeedResult Stringq(int c);
00146 FeedResult Token(int c);
00147 FeedResult Special(int c);
00148 FeedResult Special3(int c);
00149 FeedResult Comment(int c);
00150
00151 SReference ProcessToken(const char *s);
00152
00153 bool IsDelimiterChar(int c);
00154 };
00155
00156 #endif