Skip to content

Commit bb77165

Browse files
remove regex from yaml parser
Signed-off-by: Krystian Chmielewski <[email protected]>
1 parent 4ea4520 commit bb77165

File tree

3 files changed

+51
-5
lines changed

3 files changed

+51
-5
lines changed

shared/source/device_binary_format/yaml/yaml_parser.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,43 @@ bool tokenizeEndLine(ConstStringRef text, LinesCache &outLines, TokensCache &out
108108
return true;
109109
}
110110

111+
bool isValidInlineCollectionFormat(const char *context, const char *contextEnd) {
112+
auto consumeAlphaNum = [](const char *&text) {
113+
while (isAlphaNumeric(*text)) {
114+
text++;
115+
}
116+
};
117+
118+
bool endNum = false;
119+
bool endCollection = false;
120+
context++; // skip '['
121+
while (context < contextEnd && *context != '\n') {
122+
if (isWhitespace(*context)) {
123+
context++;
124+
} else if (false == endNum) {
125+
if (isAlphaNumeric(*context)) {
126+
consumeAlphaNum(context);
127+
endNum = true;
128+
} else {
129+
return false;
130+
}
131+
} else if (false == endCollection) {
132+
if (*context == ',') {
133+
context++;
134+
endNum = false;
135+
} else if (*context == ']') {
136+
context++;
137+
endCollection = true;
138+
} else {
139+
return false;
140+
}
141+
} else {
142+
return false;
143+
}
144+
}
145+
return endCollection;
146+
}
147+
111148
bool tokenize(ConstStringRef text, LinesCache &outLines, TokensCache &outTokens, std::string &outErrReason, std::string &outWarning) {
112149
if (text.empty()) {
113150
outWarning.append("NEO::Yaml : input text is empty\n");
@@ -200,7 +237,7 @@ bool tokenize(ConstStringRef text, LinesCache &outLines, TokensCache &outTokens,
200237
break;
201238
}
202239
case '[':
203-
if (false == std::regex_search(context.pos, inlineCollectionRegex)) {
240+
if (false == isValidInlineCollectionFormat(context.pos, text.end())) {
204241
outErrReason = constructYamlError(outLines.size(), context.lineBeginPos, context.pos, inlineCollectionYamlErrorMsg.data());
205242
return false;
206243
}

shared/source/device_binary_format/yaml/yaml_parser.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include "shared/source/utilities/stackvec.h"
1313

1414
#include <iterator>
15-
#include <regex>
1615
#include <string>
1716

1817
namespace NEO {
@@ -256,7 +255,7 @@ using LinesCache = StackVec<Line, 512>;
256255

257256
std::string constructYamlError(size_t lineNumber, const char *lineBeg, const char *parsePos, const char *reason = nullptr);
258257

259-
static std::regex inlineCollectionRegex(R"regex(^\[(\s*(\d|\w)+,?)+\s*\]\s*\n)regex");
258+
bool isValidInlineCollectionFormat(const char *context, const char *contextEnd);
260259
constexpr ConstStringRef inlineCollectionYamlErrorMsg = "NEO::Yaml : Inline collection is not in valid regex format - ^\\[(\\s*(\\d|\\w)+,?)+\\s*\\]\\s*\\n";
261260

262261
bool tokenize(ConstStringRef text, LinesCache &outLines, TokensCache &outTokens, std::string &outErrReason, std::string &outWarning);

shared/test/unit_test/device_binary_format/yaml/yaml_parser_tests.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ TEST(YamlIsMatched, WhenTextIsTooShortThenReturnFalse) {
166166
EXPECT_FALSE(NEO::Yaml::isMatched(text, text.begin(), "bcd"));
167167
}
168168

169+
TEST(YamlIsValidInlineCollectionFormat, WhenEndIsReachedThenReturnFalse) {
170+
const char coll[8] = "[ 1, 2 ";
171+
EXPECT_FALSE(NEO::Yaml::isValidInlineCollectionFormat(coll, coll + 7));
172+
}
173+
169174
TEST(YamlConsumeNumberOrSign, GivenValidNumberOrSignThenReturnProperEndingPosition) {
170175
ConstStringRef plus5 = "a+5";
171176
ConstStringRef minus7 = "b -7 [";
@@ -479,7 +484,12 @@ TEST(YamlTokenize, GivenInvalidInlineCollectionThenEmitsError) {
479484
warnings.clear();
480485
errors.clear();
481486

482-
success = NEO::Yaml::tokenize("[[1,2,3,4]]\n", lines, tokens, errors, warnings);
487+
success = NEO::Yaml::tokenize("[[1,2,3,4]\n", lines, tokens, errors, warnings);
488+
EXPECT_FALSE(success);
489+
EXPECT_STREQ("NEO::Yaml : Could not parse line : [0] : [[] <-- parser position on error. Reason : NEO::Yaml : Inline collection is not in valid regex format - ^\\[(\\s*(\\d|\\w)+,?)+\\s*\\]\\s*\\n\n", errors.c_str());
490+
EXPECT_TRUE(warnings.empty()) << warnings;
491+
492+
success = NEO::Yaml::tokenize("[1 2 3 4]\n", lines, tokens, errors, warnings);
483493
EXPECT_FALSE(success);
484494
EXPECT_STREQ("NEO::Yaml : Could not parse line : [0] : [[] <-- parser position on error. Reason : NEO::Yaml : Inline collection is not in valid regex format - ^\\[(\\s*(\\d|\\w)+,?)+\\s*\\]\\s*\\n\n", errors.c_str());
485495
EXPECT_TRUE(warnings.empty()) << warnings;
@@ -1317,7 +1327,7 @@ TEST(YamlBuildTree, GivenInlineCollectionThenProperlyCreatesChildNodes) {
13171327
R"===(
13181328
banana : yellow
13191329
kiwi : green
1320-
apple : [red, green, blue]
1330+
apple : [ red, green, blue ]
13211331
pear : pearish
13221332
)===";
13231333

0 commit comments

Comments
 (0)