Skip to content

Commit 9c65b60

Browse files
committed
Refactor ISQL creating FrontendParser class.
1 parent 0e0386a commit 9c65b60

18 files changed

+2797
-1559
lines changed

builds/win32/msvc15/isql_static.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<ClCompile Include="..\..\..\gen\isql\extract.cpp" />
2525
<ClCompile Include="..\..\..\src\common\fb_exception.cpp" />
2626
<ClCompile Include="..\..\..\src\isql\FrontendLexer.cpp" />
27+
<ClCompile Include="..\..\..\src\isql\FrontendParser.cpp" />
2728
<ClCompile Include="..\..\..\src\isql\InputDevices.cpp" />
2829
<ClCompile Include="..\..\..\gen\isql\isql.cpp" />
2930
<ClCompile Include="..\..\..\src\isql\iutils.cpp" />
@@ -40,6 +41,7 @@
4041
<ClInclude Include="..\..\..\src\isql\Extender.h" />
4142
<ClInclude Include="..\..\..\src\isql\extra_proto.h" />
4243
<ClInclude Include="..\..\..\src\isql\FrontendLexer.h" />
44+
<ClInclude Include="..\..\..\src\isql\FrontendParser.h" />
4345
<ClInclude Include="..\..\..\src\isql\InputDevices.h" />
4446
<ClInclude Include="..\..\..\src\isql\isql.h" />
4547
<ClInclude Include="..\..\..\src\isql\isql_proto.h" />

builds/win32/msvc15/isql_static.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
<ClCompile Include="..\..\..\src\isql\FrontendLexer.cpp">
3131
<Filter>ISQL files</Filter>
3232
</ClCompile>
33+
<ClCompile Include="..\..\..\src\isql\FrontendParser.cpp">
34+
<Filter>ISQL files</Filter>
35+
</ClCompile>
3336
<ClCompile Include="..\..\..\src\isql\InputDevices.cpp">
3437
<Filter>ISQL files</Filter>
3538
</ClCompile>
@@ -73,6 +76,9 @@
7376
<ClInclude Include="..\..\..\src\isql\FrontendLexer.h">
7477
<Filter>Header files</Filter>
7578
</ClInclude>
79+
<ClInclude Include="..\..\..\src\isql\FrontendParser.h">
80+
<Filter>Header files</Filter>
81+
</ClInclude>
7682
<ClInclude Include="..\..\..\src\isql\InputDevices.h">
7783
<Filter>Header files</Filter>
7884
</ClInclude>

builds/win32/msvc15/isql_test.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@
177177
</ItemGroup>
178178
<ItemGroup>
179179
<ClCompile Include="..\..\..\src\isql\tests\FrontendLexerTest.cpp" />
180+
<ClCompile Include="..\..\..\src\isql\tests\FrontendParserTest.cpp" />
180181
<ClCompile Include="..\..\..\src\isql\tests\ISqlTest.cpp" />
181182
</ItemGroup>
182183
<ItemGroup>

builds/win32/msvc15/isql_test.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
<ClCompile Include="..\..\..\src\isql\tests\FrontendLexerTest.cpp">
1111
<Filter>source</Filter>
1212
</ClCompile>
13+
<ClCompile Include="..\..\..\src\isql\tests\FrontendParserTest.cpp">
14+
<Filter>source</Filter>
15+
</ClCompile>
1316
<ClCompile Include="..\..\..\src\isql\tests\ISqlTest.cpp">
1417
<Filter>source</Filter>
1518
</ClCompile>

src/common/StdHelper.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* The contents of this file are subject to the Initial
3+
* Developer's Public License Version 1.0 (the "License");
4+
* you may not use this file except in compliance with the
5+
* License. You may obtain a copy of the License at
6+
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
7+
*
8+
* Software distributed under the License is distributed AS IS,
9+
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing rights
11+
* and limitations under the License.
12+
*
13+
* The Original Code was created by Adriano dos Santos Fernandes
14+
* for the Firebird Open Source RDBMS project.
15+
*
16+
* Copyright (c) 2024 Adriano dos Santos Fernandes <adrianosf at gmail.com>
17+
* and all contributors signed below.
18+
*
19+
* All Rights Reserved.
20+
* Contributor(s): ______________________________________.
21+
*
22+
*/
23+
24+
#ifndef FB_COMMON_STD_HELPER_H
25+
#define FB_COMMON_STD_HELPER_H
26+
27+
namespace Firebird {
28+
29+
// To be used with std::visit
30+
31+
template <typename... Ts>
32+
struct StdVisitOverloads : Ts...
33+
{
34+
using Ts::operator()...;
35+
};
36+
37+
template <typename... Ts>
38+
StdVisitOverloads(Ts...) -> StdVisitOverloads<Ts...>;
39+
40+
} // namespace Firebird
41+
42+
#endif // FB_COMMON_STD_HELPER_H

src/common/classes/MetaString.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,30 @@ class MetaString
9393
int compare(const AbstractString& s) const { return compare(s.c_str(), s.length()); }
9494
int compare(const MetaString& m) const { return memcmp(data, m.data, MAX_SQL_IDENTIFIER_SIZE); }
9595

96+
string toQuotedString() const
97+
{
98+
string s;
99+
100+
if (hasData())
101+
{
102+
s.reserve(count + 2);
103+
104+
s.append("\"");
105+
106+
for (const auto c : *this)
107+
{
108+
if (c == '"')
109+
s.append("\"");
110+
111+
s.append(&c, 1);
112+
}
113+
114+
s.append("\"");
115+
}
116+
117+
return s;
118+
}
119+
96120
bool operator==(const char* s) const { return compare(s) == 0; }
97121
bool operator!=(const char* s) const { return compare(s) != 0; }
98122
bool operator==(const AbstractString& s) const { return compare(s) == 0; }

src/isql/FrontendLexer.cpp

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@
2828
#include <cctype>
2929

3030

31-
static std::string trim(std::string_view str);
32-
33-
static std::string trim(std::string_view str)
31+
std::string FrontendLexer::trim(std::string_view str)
3432
{
3533
auto finish = str.end();
3634
auto start = str.begin();
@@ -142,7 +140,7 @@ std::variant<FrontendLexer::SingleStatement, FrontendLexer::IncompleteTokenError
142140

143141
while (pos < end)
144142
{
145-
if (end - pos >= term.length() && std::equal(term.begin(), term.end(), pos))
143+
if (std::size_t(end - pos) >= term.length() && std::equal(term.begin(), term.end(), pos))
146144
{
147145
const auto initialStatement = std::string(buffer.cbegin(), pos);
148146
pos += term.length();
@@ -224,13 +222,58 @@ FrontendLexer::Token FrontendLexer::getToken()
224222
return token;
225223
}
226224

227-
std::optional<FrontendLexer::Token> FrontendLexer::getStringToken()
225+
FrontendLexer::Token FrontendLexer::getNameToken()
228226
{
227+
skipSpacesAndComments();
228+
229229
Token token;
230230

231+
if (pos >= end)
232+
{
233+
token.type = Token::TYPE_EOF;
234+
return token;
235+
}
236+
237+
if (const auto optStringToken = getStringToken(); optStringToken.has_value())
238+
return optStringToken.value();
239+
240+
const auto start = pos;
241+
bool first = true;
242+
243+
while (pos < end)
244+
{
245+
const auto c = *pos++;
246+
247+
if (!((c >= 'A' && c <= 'Z') ||
248+
(c >= 'a' && c <= 'z') ||
249+
c == '{' ||
250+
c == '}' ||
251+
(!first && c >= '0' && c <= '9') ||
252+
(!first && c == '$') ||
253+
(!first && c == '_')))
254+
{
255+
if (!first)
256+
--pos;
257+
258+
break;
259+
}
260+
261+
first = false;
262+
}
263+
264+
token.processedText = token.rawText = std::string(start, pos);
265+
std::transform(token.processedText.begin(), token.processedText.end(),
266+
token.processedText.begin(), toupper);
267+
268+
return token;
269+
}
270+
271+
std::optional<FrontendLexer::Token> FrontendLexer::getStringToken()
272+
{
231273
if (pos >= end)
232274
return std::nullopt;
233275

276+
Token token;
234277
const auto start = pos;
235278

236279
switch (toupper(*pos))

src/isql/FrontendLexer.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ class FrontendLexer
4848
Type type = TYPE_OTHER;
4949
std::string rawText;
5050
std::string processedText;
51+
52+
std::string getProcessedString() const
53+
{
54+
return type == FrontendLexer::Token::TYPE_STRING || type == FrontendLexer::Token::TYPE_META_STRING ?
55+
processedText : rawText;
56+
}
5157
};
5258

5359
struct SingleStatement
@@ -74,6 +80,7 @@ class FrontendLexer
7480
FrontendLexer& operator=(const FrontendLexer&) = delete;
7581

7682
public:
83+
static std::string trim(std::string_view str);
7784
static std::string stripComments(std::string_view statement);
7885

7986
public:
@@ -87,6 +94,11 @@ class FrontendLexer
8794
return pos;
8895
}
8996

97+
void setPos(std::string::const_iterator newPos)
98+
{
99+
pos = newPos;
100+
}
101+
90102
void rewind()
91103
{
92104
deletePos = buffer.begin();
@@ -97,7 +109,9 @@ class FrontendLexer
97109
void appendBuffer(std::string_view newBuffer);
98110
void reset();
99111
std::variant<SingleStatement, FrontendLexer::IncompleteTokenError> getSingleStatement(std::string_view term);
112+
100113
Token getToken();
114+
Token getNameToken();
101115

102116
private:
103117
std::optional<Token> getStringToken();

0 commit comments

Comments
 (0)