1
|
inline bool iscib(int c) {
|
2
|
return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_' || c == '$';
|
3
|
}
|
4
|
|
5
|
inline bool iscid(int c) {
|
6
|
return iscib(c) || c >= '0' && c <= '9';
|
7
|
}
|
8
|
|
9
|
class CParser {
|
10
|
protected:
|
11
|
const char *term;
|
12
|
const char *wspc;
|
13
|
const char *lineptr;
|
14
|
int line;
|
15
|
String fn;
|
16
|
bool skipspaces;
|
17
|
bool skipcomments;
|
18
|
bool nestcomments;
|
19
|
bool uescape;
|
20
|
|
21
|
bool Spaces0();
|
22
|
const char *IsId0(const char *s) const;
|
23
|
bool Id0(const char *id);
|
24
|
void DoSpaces() { if(skipspaces) Spaces(); }
|
25
|
|
26
|
public:
|
27
|
struct Error : public Exc { Error(const char *s) : Exc(s) {} };
|
28
|
|
29
|
void ThrowError(const char *s);
|
30
|
void ThrowError() { ThrowError(""); }
|
31
|
|
32
|
bool Spaces() { wspc = term; return ((byte)*term <= ' ' || *term == '/') && Spaces0(); }
|
33
|
char PeekChar() const { return *term; }
|
34
|
char GetChar();
|
35
|
|
36
|
bool IsChar(char c) const { return *term == c; }
|
37
|
bool IsChar2(char c1, char c2) const { return term[0] == c1 && term[1] == c2; }
|
38
|
bool IsChar3(char c1, char c2, char c3) const { return term[0] == c1 && term[1] == c2 && term[2] == c3; }
|
39
|
bool Char(char c);
|
40
|
bool Char2(char c1, char c2);
|
41
|
bool Char3(char c1, char c2, char c3);
|
42
|
void PassChar(char c) throw(Error);
|
43
|
void PassChar2(char c1, char c2) throw(Error);
|
44
|
void PassChar3(char c1, char c2, char c3) throw(Error);
|
45
|
bool Id(const char *s) { return term[0] == s[0] && (s[1] == 0 || term[1] == s[1]) && Id0(s); }
|
46
|
void PassId(const char *s) throw(Error);
|
47
|
bool IsId() const { return iscib(*term); }
|
48
|
bool IsId(const char *s) const { return term[0] == s[0] && (s[1] == 0 || term[1] == s[1]) && IsId0(s); }
|
49
|
String ReadId() throw(Error);
|
50
|
String ReadIdt() throw(Error);
|
51
|
bool IsInt() const;
|
52
|
int Sgn();
|
53
|
int ReadInt() throw(Error);
|
54
|
int ReadInt(int min, int max) throw(Error);
|
55
|
int64 ReadInt64() throw(Error);
|
56
|
int64 ReadInt64(int64 min, int64 max) throw(Error);
|
57
|
bool IsNumber() const { return IsDigit(*term); }
|
58
|
bool IsNumber(int base) const;
|
59
|
uint32 ReadNumber(int base = 10) throw(Error);
|
60
|
uint64 ReadNumber64(int base = 10) throw(Error);
|
61
|
bool IsDouble() const { return IsInt(); }
|
62
|
bool IsDouble2() const { return IsInt() || IsChar('.'); }
|
63
|
double ReadDouble() throw(Error);
|
64
|
bool IsString() const { return IsChar('\"'); };
|
65
|
String ReadOneString(bool chkend = true) throw(Error);
|
66
|
String ReadString(bool chkend = true) throw(Error);
|
67
|
String ReadOneString(int delim, bool chkend = true) throw(Error);
|
68
|
String ReadString(int delim, bool chkend = true) throw(Error);
|
69
|
|
70
|
void SkipTerm();
|
71
|
|
72
|
struct Pos {
|
73
|
const char *ptr;
|
74
|
const char *wspc;
|
75
|
const char *lineptr;
|
76
|
int line;
|
77
|
String fn;
|
78
|
|
79
|
int GetColumn(int tabsize = 4) const;
|
80
|
|
81
|
Pos(const char *ptr = NULL, int line = 1, String fn = Null) : ptr(ptr), line(line), fn(fn) {}
|
82
|
};
|
83
|
|
84
|
const char *GetPtr() const { return (const char *)term; }
|
85
|
const char *GetSpacePtr() const { return (const char *)wspc; }
|
86
|
|
87
|
Pos GetPos() const;
|
88
|
void SetPos(const Pos& pos);
|
89
|
|
90
|
bool IsEof() const { return *term == '\0'; }
|
91
|
operator bool() const { return *term; }
|
92
|
|
93
|
int GetLine() const { return line; }
|
94
|
int GetColumn(int tabsize) const;
|
95
|
String GetFileName() const { return fn; }
|
96
|
|
97
|
static String LineInfoComment(const String& filename, int line = 1, int column = 1);
|
98
|
String GetLineInfoComment(int tabsize = 4) const;
|
99
|
enum { LINEINFO_ESC = '\2' };
|
100
|
|
101
|
void Set(const char *ptr, const char *fn, int line = 1);
|
102
|
void Set(const char *ptr);
|
103
|
|
104
|
CParser& SkipSpaces(bool b = true) { skipspaces = b; return *this; }
|
105
|
CParser& NoSkipSpaces() { skipspaces = false; return *this; }
|
106
|
CParser& UnicodeEscape(bool b = true) { uescape = b; return *this; }
|
107
|
CParser& SkipComments(bool b = true);
|
108
|
CParser& NoSkipComments() { return SkipComments(false); }
|
109
|
CParser& NestComments(bool b = true);
|
110
|
CParser& NoNestComments() { return NestComments(false); }
|
111
|
|
112
|
CParser(const char *ptr);
|
113
|
CParser(const char *ptr, const char *fn, int line = 1);
|
114
|
CParser();
|
115
|
};
|
116
|
|
117
|
inline bool CParser::Char(char c)
|
118
|
{
|
119
|
if(IsChar(c)) {
|
120
|
term++;
|
121
|
DoSpaces();
|
122
|
return true;
|
123
|
}
|
124
|
return false;
|
125
|
}
|
126
|
|
127
|
inline bool CParser::Char2(char c1, char c2)
|
128
|
{
|
129
|
if(IsChar2(c1, c2)) {
|
130
|
term += 2;
|
131
|
DoSpaces();
|
132
|
return true;
|
133
|
}
|
134
|
return false;
|
135
|
}
|
136
|
|
137
|
inline bool CParser::Char3(char c1, char c2, char c3)
|
138
|
{
|
139
|
if(IsChar3(c1, c2, c3)) {
|
140
|
term += 3;
|
141
|
DoSpaces();
|
142
|
return true;
|
143
|
}
|
144
|
return false;
|
145
|
}
|
146
|
|
147
|
enum {
|
148
|
ASCSTRING_SMART = 0x01,
|
149
|
ASCSTRING_OCTALHI = 0x02,
|
150
|
ASCSTRING_JSON = 0x04,
|
151
|
};
|
152
|
|
153
|
String AsCString(const char *s, const char *end, int linemax = INT_MAX, const char *linepfx = NULL,
|
154
|
dword flags = 0);
|
155
|
String AsCString(const char *s, int linemax = INT_MAX, const char *linepfx = NULL,
|
156
|
dword flags = 0);
|
157
|
String AsCString(const String& s, int linemax = INT_MAX, const char *linepfx = NULL,
|
158
|
dword flags = 0);
|