-
Notifications
You must be signed in to change notification settings - Fork 1
/
CQEnum_InputSrc.hpp
197 lines (159 loc) · 5.49 KB
/
CQEnum_InputSrc.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#pragma once
//
// This file defines the input source we use for parsing the .cqenum
// file. It's the usual thing, in that it wraps an input stream,
// tracks current location (for error output), and provides lexical
// type parsing to break out tokens based on the known separator
// characters and such.
//
// On top of that we provide helpers to extract particular token types
// or check that the next token meets some criteria.
//
namespace CQSL { namespace CQEnum {
// The categories of tokens we understand
enum class ETokens
{
End
, Colon
, Comma
, Equals
, Identifier
, Number
, String
};
class InputSrc
{
public :
InputSrc() = default;
~InputSrc() = default;
// Unimplemented
InputSrc(const InputSrc&) = delete;
InputSrc(InputSrc&&) = delete;
InputSrc& operator=(const InputSrc&) = delete;
InputSrc& operator=(InputSrc&&) = delete;
//
// Check if the next token is an id type with the indicated name,
// optionally checking if it is followed by an equals sign. This
// saves a lot of busy work.
//
bool bCheckNextId
(
const std::string_view& svCheck
, const char* const pszFailMsg
, const bool bWithEquals
, const bool bThrowIfNot
);
//
// Used within blocks to look for the next child or the end of block,
// which is done in many of the parse's loops.
//
bool bNextChildOrEnd
(
const char* const pszBlock
, const char* const pszEndBlock
);
// The next input must be the end of the block of the given name
void CheckBlockEnd
(
const char* const pszCheck
);
void CheckColon();
void CheckComma();
void CheckEqualSign();
//
// The next input must be a key=value line where the value has
// the indicated name and the value is a signed number.
//
int32_t iCheckSignedValue
(
const char* const pszCheck
, const char* const pszFailMsg
);
// The next input must be a signed number
int32_t iGetSignedToken
(
const char* const pszFailMsg
);
// Get the next lexical token from the input stream
ETokens eGetNextToken(std::string& strText);
// Return the remainder of the current line
void GetLineRemainder
(
std::string& strToFill
);
// The next input must be an id token, returns the id text
void GetIdToken
(
const char* const pszFailMsg
, std::string& strToFill
);
//
// The next input must be a list of comma separated values
// which are returned as separated values.
//
void GetCommaSepValues
(
std::vector<std::string>& vToFill
);
//
// The next input must be a list of space separated values
// which are returned as separated values.
//
void GetSpacedValues
(
std::vector<std::string>& vToFill
);
// The next input must be a quoted string, returns the text
std::string strGetToken
(
const char* const pszFailMsg
);
void Open(const std::string& strSrcFile);
//
// The throw needs to be visible to the code analyzer, so we do it
// this way.
//
void ThrowParseErr(const std::string_view& svMsg)
{
throw std::runtime_error(BuildErrMsg(svMsg));
}
private :
// Is the char either a hex or decimal digit
bool bIsDigit(const char chTest, const bool bHex) const noexcept;
//
// Is the character valid for an identifier. First char is more restricted
// that subsequent ones.
//
bool bIsIdChar(const char chTest, const bool bFirst) const noexcept;
//
// Is the character a valid end of token separator, either white space or
// special characters that always separate tokens (if not currently within
// a quoted value.)
//
bool bIsEndSep(const char chTest) const noexcept;
bool bIsSpace(const char chTest) const noexcept;
std::string BuildErrMsg(const std::string_view& svMsg) const;
// Return the next character, optionally ignoring white space
char chGetNext(const bool ignoreWS);
void PushBack(const char chToPush);
void PushBack(const std::string& strToPush);
bool m_bFirstLineChar = true;
// The current line and column
uint32_t m_uColNum = 0;
uint32_t m_uLineNum = 0;
//
// The line/col of the start of the last parsed token, or the
// one currently being parsed. This is what we use for error
// messages.
//
uint32_t m_uLastTokenCol = 0;
uint32_t m_uLastTokenLine = 0;
std::ifstream m_strmSrc;
//
// Some temp strings for internal use. Don't assume they are unaffected
// across any call to any other method here.
//
std::string m_strTmpToken;
std::string m_strTmpTest;
};
}};