Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
057bbdc
json: support minimum for positive integer values
Apr 30, 2024
d69ccb0
json: fix min 0
Apr 30, 2024
c37c484
json: min + max integer constraints
May 1, 2024
af63f4f
json: handle negative min / max integer bounds
May 1, 2024
a381deb
json: fix missing paren min/max bug
May 1, 2024
f8db478
json: proper paren fix
May 1, 2024
5a86c6f
json: integration test for schemas
May 18, 2024
431edb8
json: fix bounds tests
May 18, 2024
b6b6a6c
Update json-schema-to-grammar.cpp
May 19, 2024
a786c03
Merge remote-tracking branch 'origin/master' into json-bounds2
Jun 8, 2024
931b543
json: fix negative max
Jun 8, 2024
4c1c293
json: fix negative min (w/ more than 1 digit)
Jun 8, 2024
ac2a8f8
Update test-grammar-integration.cpp
Jun 8, 2024
3549702
json: nit: move string rules together
Jun 8, 2024
e933680
json: port min/max integer support to Python & JS
Jun 8, 2024
a0f1904
nit: move + rename _build_min_max_int
Jun 8, 2024
dcc27d1
fix min in [1, 9]
Jun 9, 2024
d1f6791
Update test-grammar-integration.cpp
Jun 9, 2024
cad377d
add C++11-compatible replacement for std::string_view
Jun 9, 2024
d6483a9
add min/max constrained int field to pydantic json schema example
Jun 10, 2024
f03e9b9
Merge remote-tracking branch 'origin/master' into json-bounds2
Jun 12, 2024
6fa7364
Merge remote-tracking branch 'origin/master' into json-bounds2
Jun 22, 2024
948e55e
fix merge
Jun 22, 2024
670d5a6
json: add integration tests for min/max bounds
Jun 22, 2024
9fb8a75
Merge remote-tracking branch 'origin/master' into json-bounds2
Jun 23, 2024
d7d957d
Merge remote-tracking branch 'origin/master' into json-bounds2
Jun 24, 2024
3a80d1e
reshuffle/merge min/max integ test cases
Jun 24, 2024
09a9b75
nits / cleanups
Jun 24, 2024
48f417d
Merge remote-tracking branch 'origin/master' into json-bounds2
Jun 25, 2024
36bf003
defensive code against string out of bounds (apparently different beh…
Jun 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add C++11-compatible replacement for std::string_view
  • Loading branch information
ochafik committed Jun 9, 2024
commit cad377d3a1b3bfccfb1097fab738c1abf2aeb3e0
130 changes: 85 additions & 45 deletions common/json-schema-to-grammar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,45 @@ static std::string build_repetition(const std::string & item_rule, const int min
return result;
}

/* Minimalistic replacement for std::string_view, which is only available from C++17 onwards */
class string_view {
const std::string & _str;
const size_t _start;
const size_t _end;
public:
string_view(const std::string & str, size_t start = 0, size_t end = std::string::npos) : _str(str), _start(start), _end(end == std::string::npos ? str.length() : end) {}

size_t size() const {
return _end - _start;
}

size_t length() const {
return size();
}

operator std::string() const {
return str();
}

std::string str() const {
return _str.substr(_start, _end - _start);
}

string_view substr(size_t pos, size_t len = std::string::npos) const {
return string_view(_str, _start + pos, len == std::string::npos ? _end : _start + pos + len);
}

char operator[](size_t pos) const {
return _str[_start + pos];
}

bool operator==(const string_view & other) const {
std::string this_str = *this;
std::string other_str = other;
return this_str == other_str;
}
};

static void _build_min_max_int(int min_value, int max_value, std::stringstream & out, int decimals_left = 16, bool top_level = true) {
auto has_min = min_value != std::numeric_limits<int>::min();
auto has_max = max_value != std::numeric_limits<int>::max();
Expand Down Expand Up @@ -68,60 +107,61 @@ static void _build_min_max_int(int min_value, int max_value, std::stringstream &
}
out << "}";
};
std::function<void(const std::string_view &, const std::string_view &)> uniform_range = [&](const std::string_view & from, const std::string_view & to) {
size_t i = 0;
while (from[i] == to[i]) {
i++;
}
if (i > 0) {
out << "\"" << from.substr(0, i) << "\"";
}
if (i < from.length()) {
std::function<void(const string_view &, const string_view &)> uniform_range =
[&](const string_view & from, const string_view & to) {
size_t i = 0;
while (from[i] == to[i]) {
i++;
}
if (i > 0) {
out << " ";
out << "\"" << from.substr(0, i).str() << "\"";
}
auto sub_len = from.length() - i - 1;
if (sub_len > 0) {
auto from_sub = from.substr(i + 1);
auto to_sub = to.substr(i + 1);
auto sub_zeros = repeat("0", sub_len);
auto sub_nines = repeat("9", sub_len);

auto to_reached = false;
out << "(";
if (from_sub == sub_zeros) {
digit_range(from[i], to[i] - 1);
if (i < from.length()) {
if (i > 0) {
out << " ";
more_digits(sub_len, sub_len);
} else {
out << "[" << from[i] << "] ";
}
auto sub_len = from.length() - i - 1;
if (sub_len > 0) {
auto from_sub = from.substr(i + 1);
auto to_sub = to.substr(i + 1);
auto sub_zeros = repeat("0", sub_len);
auto sub_nines = repeat("9", sub_len);

auto to_reached = false;
out << "(";
uniform_range(from_sub, sub_nines);
out << ")";
if (from[i] < to[i] - 1) {
out << " | ";
if (to_sub == sub_nines) {
digit_range(from[i] + 1, to[i]);
to_reached = true;
} else {
digit_range(from[i] + 1, to[i] - 1);
}
if (from_sub == sub_zeros) {
digit_range(from[i], to[i] - 1);
out << " ";
more_digits(sub_len, sub_len);
} else {
out << "[" << from[i] << "] ";
out << "(";
uniform_range(from_sub, sub_nines);
out << ")";
if (from[i] < to[i] - 1) {
out << " | ";
if (to_sub == sub_nines) {
digit_range(from[i] + 1, to[i]);
to_reached = true;
} else {
digit_range(from[i] + 1, to[i] - 1);
}
out << " ";
more_digits(sub_len, sub_len);
}
}
if (!to_reached) {
out << " | ";
digit_range(to[i], to[i]);
out << " ";
uniform_range(sub_zeros, to_sub);
}
out << ")";
} else {
out << "[" << from[i] << "-" << to[i] << "]";
}
if (!to_reached) {
out << " | ";
digit_range(to[i], to[i]);
out << " ";
uniform_range(sub_zeros, to_sub);
}
out << ")";
} else {
out << "[" << from[i] << "-" << to[i] << "]";
}
}
};
};

if (has_min && has_max) {
if (min_value < 0 && max_value < 0) {
Expand Down