Skip to content

Commit 464656f

Browse files
committed
fixing syntax parser tests
1 parent 00237bf commit 464656f

File tree

3 files changed

+42
-44
lines changed

3 files changed

+42
-44
lines changed

.github/workflows/build.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141

4242
- name: Configure CMake
4343
run: >
44-
cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=${{ matrix.release }} -DENABLE_TESTING=ON
44+
cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=${{ matrix.release }} -DENABLE_TESTING=ON -DENABLE_EXAMPLES=ON
4545
4646
- name: Build
4747
run: cmake --build build --config ${{ matrix.release }}
@@ -56,3 +56,6 @@ jobs:
5656

5757
- name: Test
5858
run: ctest --test-dir build --output-on-failure
59+
60+
- name: Examples
61+
run: ./build/libtokamap/examples/simple_mapper/simple_mapper

libtokamap/src/utils/syntax_parser.cpp

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "syntax_parser.hpp"
22

3+
#include <format>
4+
#include <iostream>
35
#include <ctre/ctre.hpp>
46
#include <nlohmann/json.hpp>
57
#include <stack>
@@ -11,53 +13,39 @@ using namespace std::string_literals;
1113
namespace
1214
{
1315

14-
constexpr auto indices_re = ctll::fixed_string{R"(\{\{\s*(#\d+|.*\[#\d+\](\.\S+)?)\s*\}\})"};
15-
constexpr auto simple_index_re = ctll::fixed_string{R"(#(\d+))"};
16-
constexpr auto array_index_re = ctll::fixed_string{R"((.*)\[#(\d+)\](\.\S+)?)"};
17-
constexpr auto subindices_re = ctll::fixed_string{R"(\((.*\[#(\d+)\](\.\S+))\))"};
18-
19-
std::string expand_indices(const std::string& input)
20-
{
21-
// Handle simple index directly
22-
if (auto match = ctre::match<simple_index_re>(input)) {
23-
return "indices." + match.get<1>().to_string();
24-
}
25-
26-
// Handle array index with possible nesting
27-
if (auto match = ctre::match<array_index_re>(input)) {
28-
std::string array = match.get<1>().to_string();
29-
const std::string_view index = match.get<2>();
30-
const std::string_view field = match.get<3>();
31-
32-
// Iteratively unwrap nested array indices
33-
while (true) {
34-
if (auto submatch = ctre::match<subindices_re>(array)) {
35-
array = submatch.get<1>().to_string();
36-
} else if (auto nested_array = ctre::match<array_index_re>(array)) {
37-
const std::string_view subarray = nested_array.get<1>();
38-
const std::string_view subindex = nested_array.get<2>();
39-
const std::string subfield = nested_array.get<3>().to_string();
40-
41-
array = "at("s.append(subarray).append(", indices.").append(subindex).append(")");
42-
if (!subfield.empty()) {
43-
array += subfield;
44-
}
45-
} else {
46-
break;
47-
}
16+
constexpr auto indices_re = ctll::fixed_string{R"(\{\{(.*?)\}\})"};
17+
constexpr auto simple_index_re = ctll::fixed_string{R"((.*)#(\d+)(.*))"};
18+
constexpr auto array_index_re = ctll::fixed_string{R"(([^\[\]]*?)\[([^\[\]]*?)\](\.[^\[\]]*)?)"};
19+
20+
std::string expand_array(std::string input) {
21+
while (const auto& match = ctre::search<array_index_re>(input)) {
22+
std::string_view name = match.get<1>();
23+
std::string_view index = match.get<2>();
24+
std::string_view post = match.get<3>();
25+
if (name.starts_with('(')) {
26+
name = name.substr(1, name.size() - 1);
4827
}
49-
50-
std::string result = "at("s.append(array).append(", indices.").append(index).append(")");
51-
if (!field.empty()) {
52-
result += field;
28+
if (post.ends_with(')')) {
29+
post = post.substr(0, post.size() - 1);
5330
}
54-
return result;
31+
std::string result = std::format("at({}, {}){}", name, index, post);
32+
input = input.replace(match.begin() - input.begin(), match.size(), result);
5533
}
56-
57-
// Fallback if no match
5834
return input;
5935
}
6036

37+
std::string expand_indices(std::string input)
38+
{
39+
while (const auto& match = ctre::search<simple_index_re>(input)) {
40+
std::string_view pre = match.get<1>();
41+
std::string_view index = match.get<2>();
42+
std::string_view post = match.get<3>();
43+
input = std::format("{}indices.{}{}", pre, index, post);
44+
}
45+
46+
return expand_array(input);
47+
}
48+
6149
void walk_json(nlohmann::json& root)
6250
{
6351
std::stack<nlohmann::json*> stack;
@@ -82,6 +70,14 @@ void walk_json(nlohmann::json& root)
8270
}
8371
}
8472

73+
std::string trim(const std::string& line)
74+
{
75+
constexpr const char* white_space = " \t\v\r\n";
76+
std::size_t start = line.find_first_not_of(white_space);
77+
std::size_t end = line.find_last_not_of(white_space);
78+
return start == end ? std::string() : line.substr(start, end - start + 1);
79+
}
80+
8581
} // namespace
8682

8783
std::string libtokamap::process_string_node(std::string value) {
@@ -91,6 +87,7 @@ std::string libtokamap::process_string_node(std::string value) {
9187
for (const auto& match : ctre::search_all<indices_re>(value)) {
9288
std::string prefix{iter, match.begin()};
9389
auto expression = match.get<1>().to_string();
90+
expression = trim(expression);
9491
result.append(prefix).append("{{ ").append(expand_indices(expression)).append(" }}");
9592
iter = match.end();
9693
}

libtokamap/test/src/syntax_parser_test.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,12 @@ TEST_CASE("indices expansion and bracket matching", "[process_string_node]") {
163163
REQUIRE(result == expected);
164164
}
165165
SECTION("indices replace for arithmetic templating") {
166-
SKIP("FIXME");
167166
nlohmann::json input = "{{ #0 + 1 }}";
168167
nlohmann::json result = libtokamap::process_string_node(input);
169168
nlohmann::json expected = "{{ indices.0 + 1 }}";
170169
REQUIRE(result == expected);
171170
}
172171
SECTION("nested bracket replace (bracket matching)") {
173-
SKIP("FIXME");
174172
nlohmann::json input = "{{ foo[bar[#0].TYPE] }}";
175173
nlohmann::json result = libtokamap::process_string_node(input);
176174
nlohmann::json expected = "{{ at(foo, at(bar, indices.0).TYPE) }}";

0 commit comments

Comments
 (0)