json: use new GBNF repetitions{m,n} syntax
This commit is contained in:
parent
15585e0f20
commit
93b754ec5c
7 changed files with 3557 additions and 3768 deletions
|
@ -16,58 +16,27 @@ static std::string join(Iterator begin, Iterator end, const std::string & separa
|
||||||
|
|
||||||
static std::string repeat(const std::string & str, size_t n);
|
static std::string repeat(const std::string & str, size_t n);
|
||||||
|
|
||||||
static std::string build_repetition(const std::string & item_rule, int min_items, int max_items, const std::string & separator_rule = "", bool item_rule_is_literal = false) {
|
static std::string build_repetition(const std::string & item_rule, int min_items, int max_items, const std::string & separator_rule = "") {
|
||||||
|
auto has_max = max_items != std::numeric_limits<int>::max();
|
||||||
|
|
||||||
|
if (min_items == 0 && max_items == 1) {
|
||||||
|
return item_rule + "?";
|
||||||
|
}
|
||||||
|
|
||||||
if (separator_rule.empty()) {
|
if (separator_rule.empty()) {
|
||||||
if (min_items == 0 && max_items == 1) {
|
if (min_items == 1 && !has_max) {
|
||||||
return item_rule + "?";
|
|
||||||
} else if (min_items == 1 && max_items == std::numeric_limits<int>::max()) {
|
|
||||||
return item_rule + "+";
|
return item_rule + "+";
|
||||||
}
|
} else if (min_items == 0 && !has_max) {
|
||||||
}
|
return item_rule + "*";
|
||||||
|
|
||||||
std::string result;
|
|
||||||
if (min_items > 0) {
|
|
||||||
if (item_rule_is_literal && separator_rule.empty()) {
|
|
||||||
result = "\"" + repeat(std::string(item_rule.begin() + 1, item_rule.end() - 1), min_items) + "\"";
|
|
||||||
} else {
|
} else {
|
||||||
std::vector<std::string> items(min_items, item_rule);
|
return item_rule + "{" + std::to_string(min_items) + "," + (has_max ? std::to_string(max_items) : "") + "}";
|
||||||
result = join(items.begin(), items.end(), separator_rule.empty() ? " " : " " + separator_rule + " ");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<std::string(int, bool)> opt_repetitions = [&](int up_to_n, bool prefix_with_sep) -> std::string {
|
auto result = item_rule + " " + build_repetition("(" + separator_rule + " " + item_rule + ")", min_items == 0 ? 0 : min_items - 1, has_max ? max_items - 1 : max_items);
|
||||||
auto content = prefix_with_sep && !separator_rule.empty() ? separator_rule + " " + item_rule : item_rule;
|
if (min_items == 0) {
|
||||||
|
result = "(" + result + ")?";
|
||||||
if (up_to_n == 0) {
|
|
||||||
return "";
|
|
||||||
} else if (up_to_n == 1) {
|
|
||||||
return "(" + content + ")?";
|
|
||||||
} else if (!separator_rule.empty() && !prefix_with_sep) {
|
|
||||||
return "(" + content + " " + opt_repetitions(up_to_n - 1, true) + ")?";
|
|
||||||
} else {
|
|
||||||
std::string res = repeat("(" + content + " ", up_to_n);
|
|
||||||
// strip trailing space
|
|
||||||
res = res.substr(0, res.length() - 1);
|
|
||||||
res += repeat(")?", up_to_n);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (min_items > 0 && max_items != min_items) {
|
|
||||||
result += " ";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_items != std::numeric_limits<int>::max()) {
|
|
||||||
result += opt_repetitions(max_items - min_items, min_items > 0);
|
|
||||||
} else {
|
|
||||||
std::string item_operator = "(" + (separator_rule.empty() ? "" : separator_rule + " ") + item_rule + ")";
|
|
||||||
if (min_items == 0 && !separator_rule.empty()) {
|
|
||||||
result = "(" + item_rule + " " + item_operator + "*)?";
|
|
||||||
} else {
|
|
||||||
result += item_operator + "*";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,30 +47,24 @@ struct BuiltinRule {
|
||||||
std::vector<std::string> deps;
|
std::vector<std::string> deps;
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string _up_to_15_digits = build_repetition("[0-9]", 0, 15);
|
|
||||||
|
|
||||||
std::unordered_map<std::string, BuiltinRule> PRIMITIVE_RULES = {
|
std::unordered_map<std::string, BuiltinRule> PRIMITIVE_RULES = {
|
||||||
{"boolean", {"(\"true\" | \"false\") space", {}}},
|
{"boolean", {"(\"true\" | \"false\") space", {}}},
|
||||||
{"decimal-part", {"[0-9] " + _up_to_15_digits, {}}},
|
{"decimal-part", {"[0-9]{1,16}", {}}},
|
||||||
{"integral-part", {"[0-9] | [1-9] " + _up_to_15_digits, {}}},
|
{"integral-part", {"[0-9] | [1-9] [0-9]{0,15}", {}}},
|
||||||
{"number", {"(\"-\"? integral-part) (\".\" decimal-part)? ([eE] [-+]? integral-part)? space", {"integral-part", "decimal-part"}}},
|
{"number", {"(\"-\"? integral-part) (\".\" decimal-part)? ([eE] [-+]? integral-part)? space", {"integral-part", "decimal-part"}}},
|
||||||
{"integer", {"(\"-\"? integral-part) space", {"integral-part"}}},
|
{"integer", {"(\"-\"? integral-part) space", {"integral-part"}}},
|
||||||
{"value", {"object | array | string | number | boolean | null", {"object", "array", "string", "number", "boolean", "null"}}},
|
{"value", {"object | array | string | number | boolean | null", {"object", "array", "string", "number", "boolean", "null"}}},
|
||||||
{"object", {"\"{\" space ( string \":\" space value (\",\" space string \":\" space value)* )? \"}\" space", {"string", "value"}}},
|
{"object", {"\"{\" space ( string \":\" space value (\",\" space string \":\" space value)* )? \"}\" space", {"string", "value"}}},
|
||||||
{"array", {"\"[\" space ( value (\",\" space value)* )? \"]\" space", {"value"}}},
|
{"array", {"\"[\" space ( value (\",\" space value)* )? \"]\" space", {"value"}}},
|
||||||
{"uuid", {"\"\\\"\" [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] "
|
{"uuid", {"\"\\\"\" [0-9a-fA-F]{8} \"-\" [0-9a-fA-F]{4} \"-\" [0-9a-fA-F]{4} \"-\" [0-9a-fA-F]{4} \"-\" [0-9a-fA-F]{12} \"\\\"\" space", {}}},
|
||||||
"\"-\" [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] "
|
{"char", {"[^\"\\\\] | \"\\\\\" ([\"\\\\/bfnrt] | \"u\" [0-9a-fA-F]{4})", {}}},
|
||||||
"\"-\" [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] "
|
|
||||||
"\"-\" [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] "
|
|
||||||
"\"-\" [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] \"\\\"\" space", {}}},
|
|
||||||
{"char", {"[^\"\\\\] | \"\\\\\" ([\"\\\\/bfnrt] | \"u\" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])", {}}},
|
|
||||||
{"string", {"\"\\\"\" char* \"\\\"\" space", {"char"}}},
|
{"string", {"\"\\\"\" char* \"\\\"\" space", {"char"}}},
|
||||||
{"null", {"\"null\" space", {}}},
|
{"null", {"\"null\" space", {}}},
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<std::string, BuiltinRule> STRING_FORMAT_RULES = {
|
std::unordered_map<std::string, BuiltinRule> STRING_FORMAT_RULES = {
|
||||||
{"date", {"[0-9] [0-9] [0-9] [0-9] \"-\" ( \"0\" [1-9] | \"1\" [0-2] ) \"-\" ( \"0\" [1-9] | [1-2] [0-9] | \"3\" [0-1] )", {}}},
|
{"date", {"[0-9]{4} \"-\" ( \"0\" [1-9] | \"1\" [0-2] ) \"-\" ( \"0\" [1-9] | [1-2] [0-9] | \"3\" [0-1] )", {}}},
|
||||||
{"time", {"([01] [0-9] | \"2\" [0-3]) \":\" [0-5] [0-9] \":\" [0-5] [0-9] ( \".\" [0-9] [0-9] [0-9] )? ( \"Z\" | ( \"+\" | \"-\" ) ( [01] [0-9] | \"2\" [0-3] ) \":\" [0-5] [0-9] )", {}}},
|
{"time", {"([01] [0-9] | \"2\" [0-3]) \":\" [0-5] [0-9] \":\" [0-5] [0-9] ( \".\" [0-9]{3} )? ( \"Z\" | ( \"+\" | \"-\" ) ( [01] [0-9] | \"2\" [0-3] ) \":\" [0-5] [0-9] )", {}}},
|
||||||
{"date-time", {"date \"T\" time", {"date", "time"}}},
|
{"date-time", {"date \"T\" time", {"date", "time"}}},
|
||||||
{"date-string", {"\"\\\"\" date \"\\\"\" space", {"date"}}},
|
{"date-string", {"\"\\\"\" date \"\\\"\" space", {"date"}}},
|
||||||
{"time-string", {"\"\\\"\" time \"\\\"\" space", {"time"}}},
|
{"time-string", {"\"\\\"\" time \"\\\"\" space", {"time"}}},
|
||||||
|
@ -385,8 +348,7 @@ private:
|
||||||
sub_is_literal ? "\"" + sub + "\"" : sub,
|
sub_is_literal ? "\"" + sub + "\"" : sub,
|
||||||
min_times,
|
min_times,
|
||||||
max_times,
|
max_times,
|
||||||
"",
|
""
|
||||||
sub_is_literal
|
|
||||||
);
|
);
|
||||||
seq.back().second = false;
|
seq.back().second = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -6,52 +6,22 @@ import re
|
||||||
import sys
|
import sys
|
||||||
from typing import Any, Dict, List, Set, Tuple, Union
|
from typing import Any, Dict, List, Set, Tuple, Union
|
||||||
|
|
||||||
def _build_repetition(item_rule, min_items, max_items, separator_rule=None, item_rule_is_literal=False):
|
|
||||||
|
def _build_repetition(item_rule, min_items, max_items, separator_rule=None):
|
||||||
|
|
||||||
|
if min_items == 0 and max_items == 1:
|
||||||
|
return f'{item_rule}?'
|
||||||
|
|
||||||
if not separator_rule:
|
if not separator_rule:
|
||||||
if min_items == 0 and max_items == 1:
|
if min_items == 1 and max_items is None:
|
||||||
return f'{item_rule}?'
|
|
||||||
elif min_items == 1 and max_items is None:
|
|
||||||
return f'{item_rule}+'
|
return f'{item_rule}+'
|
||||||
|
elif min_items == 0 and max_items is None:
|
||||||
result = ''
|
return f'{item_rule}*'
|
||||||
|
|
||||||
if min_items > 0:
|
|
||||||
if item_rule_is_literal and separator_rule is None:
|
|
||||||
result = '"' + (item_rule[1:-1] * min_items) + '"'
|
|
||||||
else:
|
else:
|
||||||
result = (f' {separator_rule} ' if separator_rule else ' ').join([item_rule] * min_items)
|
return f'{item_rule}{{{min_items},{max_items if max_items is not None else ""}}}'
|
||||||
|
|
||||||
def opt_repetitions(up_to_n, prefix_with_sep=False):
|
result = item_rule + ' ' + _build_repetition(f'({separator_rule} {item_rule})', min_items - 1 if min_items > 0 else 0, max_items - 1 if max_items is not None else None)
|
||||||
'''
|
return f'({result})?' if min_items == 0 else result
|
||||||
- n=4, no sep: '(a (a (a (a)?)?)?)?'
|
|
||||||
- n=4, sep=',', prefix: '("," a ("," a ("," a ("," a)?)?)?)?'
|
|
||||||
- n=4, sep=',', no prefix: '(a ("," a ("," a ("," a)?)?)?)?'
|
|
||||||
'''
|
|
||||||
|
|
||||||
content = f'{separator_rule} {item_rule}' if prefix_with_sep and separator_rule else item_rule
|
|
||||||
if up_to_n == 0:
|
|
||||||
return ''
|
|
||||||
elif up_to_n == 1:
|
|
||||||
return f'({content})?'
|
|
||||||
elif separator_rule and not prefix_with_sep:
|
|
||||||
return f'({content} {opt_repetitions(up_to_n - 1, prefix_with_sep=True)})?'
|
|
||||||
else:
|
|
||||||
return (f'({content} ' * up_to_n).rstrip() + (')?' * up_to_n)
|
|
||||||
|
|
||||||
if min_items > 0 and max_items != min_items:
|
|
||||||
result += ' '
|
|
||||||
|
|
||||||
if max_items is not None:
|
|
||||||
result += opt_repetitions(max_items - min_items, prefix_with_sep=min_items > 0)
|
|
||||||
else:
|
|
||||||
item_operator = f'({separator_rule + " " if separator_rule else ""}{item_rule})'
|
|
||||||
|
|
||||||
if min_items == 0 and separator_rule:
|
|
||||||
result = f'({item_rule} {item_operator}*)?'
|
|
||||||
else:
|
|
||||||
result += f'{item_operator}*'
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class BuiltinRule:
|
class BuiltinRule:
|
||||||
|
@ -59,31 +29,29 @@ class BuiltinRule:
|
||||||
self.content = content
|
self.content = content
|
||||||
self.deps = deps or []
|
self.deps = deps or []
|
||||||
|
|
||||||
_up_to_15_digits = _build_repetition('[0-9]', 0, 15)
|
|
||||||
|
|
||||||
# whitespace is constrained to a single space char to prevent model "running away" in
|
# whitespace is constrained to a single space char to prevent model "running away" in
|
||||||
# whitespace. Also maybe improves generation quality?
|
# whitespace. Also maybe improves generation quality?
|
||||||
SPACE_RULE = '" "?'
|
SPACE_RULE = '" "?'
|
||||||
|
|
||||||
PRIMITIVE_RULES = {
|
PRIMITIVE_RULES = {
|
||||||
'boolean' : BuiltinRule('("true" | "false") space', []),
|
'boolean' : BuiltinRule('("true" | "false") space', []),
|
||||||
'decimal-part' : BuiltinRule('[0-9] ' + _up_to_15_digits, []),
|
'decimal-part' : BuiltinRule('[0-9]{1,16}', []),
|
||||||
'integral-part': BuiltinRule('[0-9] | [1-9] ' + _up_to_15_digits, []),
|
'integral-part': BuiltinRule('[0-9] | [1-9] [0-9]{0,15}', []),
|
||||||
'number' : BuiltinRule('("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space', ['integral-part', 'decimal-part']),
|
'number' : BuiltinRule('("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space', ['integral-part', 'decimal-part']),
|
||||||
'integer' : BuiltinRule('("-"? integral-part) space', ['integral-part']),
|
'integer' : BuiltinRule('("-"? integral-part) space', ['integral-part']),
|
||||||
'value' : BuiltinRule('object | array | string | number | boolean | null', ['object', 'array', 'string', 'number', 'boolean', 'null']),
|
'value' : BuiltinRule('object | array | string | number | boolean | null', ['object', 'array', 'string', 'number', 'boolean', 'null']),
|
||||||
'object' : BuiltinRule('"{" space ( string ":" space value ("," space string ":" space value)* )? "}" space', ['string', 'value']),
|
'object' : BuiltinRule('"{" space ( string ":" space value ("," space string ":" space value)* )? "}" space', ['string', 'value']),
|
||||||
'array' : BuiltinRule('"[" space ( value ("," space value)* )? "]" space', ['value']),
|
'array' : BuiltinRule('"[" space ( value ("," space value)* )? "]" space', ['value']),
|
||||||
'uuid' : BuiltinRule(r'"\"" ' + ' "-" '.join('[0-9a-fA-F]' * n for n in [8, 4, 4, 4, 12]) + r' "\"" space', []),
|
'uuid' : BuiltinRule(r'"\"" [0-9a-fA-F]{8} "-" [0-9a-fA-F]{4} "-" [0-9a-fA-F]{4} "-" [0-9a-fA-F]{4} "-" [0-9a-fA-F]{12} "\"" space', []),
|
||||||
'char' : BuiltinRule(r'[^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])', []),
|
'char' : BuiltinRule(r'[^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})', []),
|
||||||
'string' : BuiltinRule(r'"\"" char* "\"" space', ['char']),
|
'string' : BuiltinRule(r'"\"" char* "\"" space', ['char']),
|
||||||
'null' : BuiltinRule('"null" space', []),
|
'null' : BuiltinRule('"null" space', []),
|
||||||
}
|
}
|
||||||
|
|
||||||
# TODO: support "uri", "email" string formats
|
# TODO: support "uri", "email" string formats
|
||||||
STRING_FORMAT_RULES = {
|
STRING_FORMAT_RULES = {
|
||||||
'date' : BuiltinRule('[0-9] [0-9] [0-9] [0-9] "-" ( "0" [1-9] | "1" [0-2] ) "-" ( \"0\" [1-9] | [1-2] [0-9] | "3" [0-1] )', []),
|
'date' : BuiltinRule('[0-9]{4} "-" ( "0" [1-9] | "1" [0-2] ) "-" ( \"0\" [1-9] | [1-2] [0-9] | "3" [0-1] )', []),
|
||||||
'time' : BuiltinRule('([01] [0-9] | "2" [0-3]) ":" [0-5] [0-9] ":" [0-5] [0-9] ( "." [0-9] [0-9] [0-9] )? ( "Z" | ( "+" | "-" ) ( [01] [0-9] | "2" [0-3] ) ":" [0-5] [0-9] )', []),
|
'time' : BuiltinRule('([01] [0-9] | "2" [0-3]) ":" [0-5] [0-9] ":" [0-5] [0-9] ( "." [0-9]{3} )? ( "Z" | ( "+" | "-" ) ( [01] [0-9] | "2" [0-3] ) ":" [0-5] [0-9] )', []),
|
||||||
'date-time' : BuiltinRule('date "T" time', ['date', 'time']),
|
'date-time' : BuiltinRule('date "T" time', ['date', 'time']),
|
||||||
'date-string' : BuiltinRule('"\\"" date "\\"" space', ['date']),
|
'date-string' : BuiltinRule('"\\"" date "\\"" space', ['date']),
|
||||||
'time-string' : BuiltinRule('"\\"" time "\\"" space', ['time']),
|
'time-string' : BuiltinRule('"\\"" time "\\"" space', ['time']),
|
||||||
|
@ -333,7 +301,7 @@ class SchemaConverter:
|
||||||
sub_rule_ids[sub] = id
|
sub_rule_ids[sub] = id
|
||||||
sub = id
|
sub = id
|
||||||
|
|
||||||
seq[-1] = (_build_repetition(f'"{sub}"' if sub_is_literal else sub, min_times, max_times, item_rule_is_literal=sub_is_literal), False)
|
seq[-1] = (_build_repetition(f'"{sub}"' if sub_is_literal else sub, min_times, max_times), False)
|
||||||
else:
|
else:
|
||||||
literal = ''
|
literal = ''
|
||||||
while i < length:
|
while i < length:
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
@ -2,57 +2,26 @@
|
||||||
const SPACE_RULE = '" "?';
|
const SPACE_RULE = '" "?';
|
||||||
|
|
||||||
function _buildRepetition(itemRule, minItems, maxItems, opts={}) {
|
function _buildRepetition(itemRule, minItems, maxItems, opts={}) {
|
||||||
|
if (minItems === 0 && maxItems === 1) {
|
||||||
|
return `${itemRule}?`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const separatorRule = opts.separatorRule ?? '';
|
const separatorRule = opts.separatorRule ?? '';
|
||||||
const itemRuleIsLiteral = opts.itemRuleIsLiteral ?? false
|
const itemRuleIsLiteral = opts.itemRuleIsLiteral ?? false
|
||||||
|
|
||||||
if (separatorRule === '') {
|
if (separatorRule === '') {
|
||||||
if (minItems === 0 && maxItems === 1) {
|
if (minItems === 1 && maxItems === undefined) {
|
||||||
return `${itemRule}?`;
|
|
||||||
} else if (minItems === 1 && maxItems === undefined) {
|
|
||||||
return `${itemRule}+`;
|
return `${itemRule}+`;
|
||||||
}
|
} else if (minItems === 0 && maxItems === undefined) {
|
||||||
}
|
return `${itemRule}*`;
|
||||||
|
|
||||||
let result = '';
|
|
||||||
if (minItems > 0) {
|
|
||||||
if (itemRuleIsLiteral && separatorRule === '') {
|
|
||||||
result = `"${itemRule.slice(1, -1).repeat(minItems)}"`;
|
|
||||||
} else {
|
} else {
|
||||||
result = Array.from({ length: minItems }, () => itemRule)
|
return `${itemRule}{${minItems},${maxItems !== undefined ? maxItems : ''}}`;
|
||||||
.join(separatorRule !== '' ? ` ${separatorRule} ` : ' ');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const optRepetitions = (upToN, prefixWithSep=false) => {
|
const result = itemRule + ' ' + _buildRepetition(`(${separatorRule} ${itemRule})`, minItems > 0 ? minItems - 1 : 0, maxItems !== undefined ? maxItems - 1 : undefined);
|
||||||
const content = separatorRule !== '' && prefixWithSep ? `${separatorRule} ${itemRule}` : itemRule;
|
return minItems === 0 ? `(${result})?` : result;
|
||||||
if (upToN === 0) {
|
|
||||||
return '';
|
|
||||||
} else if (upToN === 1) {
|
|
||||||
return `(${content})?`;
|
|
||||||
} else if (separatorRule !== '' && !prefixWithSep) {
|
|
||||||
return `(${content} ${optRepetitions(upToN - 1, true)})?`;
|
|
||||||
} else {
|
|
||||||
return Array.from({ length: upToN }, () => `(${content}`).join(' ').trim() + Array.from({ length: upToN }, () => ')?').join('');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (minItems > 0 && maxItems !== minItems) {
|
|
||||||
result += ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxItems !== undefined) {
|
|
||||||
result += optRepetitions(maxItems - minItems, minItems > 0);
|
|
||||||
} else {
|
|
||||||
const itemOperator = `(${separatorRule !== '' ? separatorRule + ' ' : ''}${itemRule})`;
|
|
||||||
|
|
||||||
if (minItems === 0 && separatorRule !== '') {
|
|
||||||
result = `(${itemRule} ${itemOperator}*)?`;
|
|
||||||
} else {
|
|
||||||
result += `${itemOperator}*`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class BuiltinRule {
|
class BuiltinRule {
|
||||||
|
@ -62,27 +31,25 @@ class BuiltinRule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const UP_TO_15_DIGITS = _buildRepetition('[0-9]', 0, 15);
|
|
||||||
|
|
||||||
const PRIMITIVE_RULES = {
|
const PRIMITIVE_RULES = {
|
||||||
boolean : new BuiltinRule('("true" | "false") space', []),
|
boolean : new BuiltinRule('("true" | "false") space', []),
|
||||||
'decimal-part' : new BuiltinRule('[0-9] ' + UP_TO_15_DIGITS, []),
|
'decimal-part' : new BuiltinRule('[0-9]{1,16}', []),
|
||||||
'integral-part': new BuiltinRule('[0-9] | [1-9] ' + UP_TO_15_DIGITS, []),
|
'integral-part': new BuiltinRule('[0-9] | [1-9] [0-9]{0,15}', []),
|
||||||
number : new BuiltinRule('("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space', ['integral-part', 'decimal-part']),
|
number : new BuiltinRule('("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space', ['integral-part', 'decimal-part']),
|
||||||
integer : new BuiltinRule('("-"? integral-part) space', ['integral-part']),
|
integer : new BuiltinRule('("-"? integral-part) space', ['integral-part']),
|
||||||
value : new BuiltinRule('object | array | string | number | boolean | null', ['object', 'array', 'string', 'number', 'boolean', 'null']),
|
value : new BuiltinRule('object | array | string | number | boolean | null', ['object', 'array', 'string', 'number', 'boolean', 'null']),
|
||||||
object : new BuiltinRule('"{" space ( string ":" space value ("," space string ":" space value)* )? "}" space', ['string', 'value']),
|
object : new BuiltinRule('"{" space ( string ":" space value ("," space string ":" space value)* )? "}" space', ['string', 'value']),
|
||||||
array : new BuiltinRule('"[" space ( value ("," space value)* )? "]" space', ['value']),
|
array : new BuiltinRule('"[" space ( value ("," space value)* )? "]" space', ['value']),
|
||||||
uuid : new BuiltinRule('"\\"" ' + [8, 4, 4, 4, 12].map(n => [...new Array(n)].map(_ => '[0-9a-fA-F]').join('')).join(' "-" ') + ' "\\"" space', []),
|
uuid : new BuiltinRule('"\\"" [0-9a-fA-F]{8} "-" [0-9a-fA-F]{4} "-" [0-9a-fA-F]{4} "-" [0-9a-fA-F]{4} "-" [0-9a-fA-F]{12} "\\"" space', []),
|
||||||
char : new BuiltinRule(`[^"\\\\] | "\\\\" (["\\\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])`, []),
|
char : new BuiltinRule(`[^"\\\\] | "\\\\" (["\\\\/bfnrt] | "u" [0-9a-fA-F]{4})`, []),
|
||||||
string : new BuiltinRule(`"\\"" char* "\\"" space`, ['char']),
|
string : new BuiltinRule(`"\\"" char* "\\"" space`, ['char']),
|
||||||
null : new BuiltinRule('"null" space', []),
|
null : new BuiltinRule('"null" space', []),
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: support "uri", "email" string formats
|
// TODO: support "uri", "email" string formats
|
||||||
const STRING_FORMAT_RULES = {
|
const STRING_FORMAT_RULES = {
|
||||||
'date' : new BuiltinRule('[0-9] [0-9] [0-9] [0-9] "-" ( "0" [1-9] | "1" [0-2] ) "-" ( \"0\" [1-9] | [1-2] [0-9] | "3" [0-1] )', []),
|
'date' : new BuiltinRule('[0-9]{4} "-" ( "0" [1-9] | "1" [0-2] ) "-" ( \"0\" [1-9] | [1-2] [0-9] | "3" [0-1] )', []),
|
||||||
'time' : new BuiltinRule('([01] [0-9] | "2" [0-3]) ":" [0-5] [0-9] ":" [0-5] [0-9] ( "." [0-9] [0-9] [0-9] )? ( "Z" | ( "+" | "-" ) ( [01] [0-9] | "2" [0-3] ) ":" [0-5] [0-9] )', []),
|
'time' : new BuiltinRule('([01] [0-9] | "2" [0-3]) ":" [0-5] [0-9] ":" [0-5] [0-9] ( "." [0-9]{3} )? ( "Z" | ( "+" | "-" ) ( [01] [0-9] | "2" [0-3] ) ":" [0-5] [0-9] )', []),
|
||||||
'date-time' : new BuiltinRule('date "T" time', ['date', 'time']),
|
'date-time' : new BuiltinRule('date "T" time', ['date', 'time']),
|
||||||
'date-string' : new BuiltinRule('"\\"" date "\\"" space', ['date']),
|
'date-string' : new BuiltinRule('"\\"" date "\\"" space', ['date']),
|
||||||
'time-string' : new BuiltinRule('"\\"" time "\\"" space', ['time']),
|
'time-string' : new BuiltinRule('"\\"" time "\\"" space', ['time']),
|
||||||
|
|
|
@ -104,9 +104,9 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
R"""(
|
R"""(
|
||||||
array ::= "[" space ( value ("," space value)* )? "]" space
|
array ::= "[" space ( value ("," space value)* )? "]" space
|
||||||
boolean ::= ("true" | "false") space
|
boolean ::= ("true" | "false") space
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
null ::= "null" space
|
null ::= "null" space
|
||||||
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
object ::= "{" space ( string ":" space value ("," space string ":" space value)* )? "}" space
|
object ::= "{" space ( string ":" space value ("," space string ":" space value)* )? "}" space
|
||||||
|
@ -129,18 +129,18 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
]
|
]
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
date ::= [0-9] [0-9] [0-9] [0-9] "-" ( "0" [1-9] | "1" [0-2] ) "-" ( "0" [1-9] | [1-2] [0-9] | "3" [0-1] )
|
date ::= [0-9]{4} "-" ( "0" [1-9] | "1" [0-2] ) "-" ( "0" [1-9] | [1-2] [0-9] | "3" [0-1] )
|
||||||
date-string ::= "\"" date "\"" space
|
date-string ::= "\"" date "\"" space
|
||||||
date-time ::= date "T" time
|
date-time ::= date "T" time
|
||||||
date-time-string ::= "\"" date-time "\"" space
|
date-time-string ::= "\"" date-time "\"" space
|
||||||
root ::= "[" space tuple-0 "," space uuid "," space tuple-2 "," space tuple-3 "]" space
|
root ::= "[" space tuple-0 "," space uuid "," space tuple-2 "," space tuple-3 "]" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
time ::= ([01] [0-9] | "2" [0-3]) ":" [0-5] [0-9] ":" [0-5] [0-9] ( "." [0-9] [0-9] [0-9] )? ( "Z" | ( "+" | "-" ) ( [01] [0-9] | "2" [0-3] ) ":" [0-5] [0-9] )
|
time ::= ([01] [0-9] | "2" [0-3]) ":" [0-5] [0-9] ":" [0-5] [0-9] ( "." [0-9]{3} )? ( "Z" | ( "+" | "-" ) ( [01] [0-9] | "2" [0-3] ) ":" [0-5] [0-9] )
|
||||||
time-string ::= "\"" time "\"" space
|
time-string ::= "\"" time "\"" space
|
||||||
tuple-0 ::= date-string
|
tuple-0 ::= date-string
|
||||||
tuple-2 ::= time-string
|
tuple-2 ::= time-string
|
||||||
tuple-3 ::= date-time-string
|
tuple-3 ::= date-time-string
|
||||||
uuid ::= "\"" [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] "-" [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] "-" [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] "-" [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] "-" [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] "\"" space
|
uuid ::= "\"" [0-9a-fA-F]{8} "-" [0-9a-fA-F]{4} "-" [0-9a-fA-F]{4} "-" [0-9a-fA-F]{4} "-" [0-9a-fA-F]{12} "\"" space
|
||||||
)"""
|
)"""
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
"type": "string"
|
"type": "string"
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
root ::= "\"" char* "\"" space
|
root ::= "\"" char* "\"" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
)"""
|
)"""
|
||||||
|
@ -165,7 +165,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
"minLength": 1
|
"minLength": 1
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
root ::= "\"" char+ "\"" space
|
root ::= "\"" char+ "\"" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
)"""
|
)"""
|
||||||
|
@ -179,8 +179,8 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
"minLength": 3
|
"minLength": 3
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
root ::= "\"" char char char (char)* "\"" space
|
root ::= "\"" char{3,} "\"" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
)"""
|
)"""
|
||||||
});
|
});
|
||||||
|
@ -193,8 +193,8 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
"maxLength": 3
|
"maxLength": 3
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
root ::= "\"" (char (char (char)?)?)? "\"" space
|
root ::= "\"" char{0,3} "\"" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
)"""
|
)"""
|
||||||
});
|
});
|
||||||
|
@ -208,8 +208,8 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
"maxLength": 4
|
"maxLength": 4
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
root ::= "\"" char (char (char (char)?)?)? "\"" space
|
root ::= "\"" char{1,4} "\"" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
)"""
|
)"""
|
||||||
});
|
});
|
||||||
|
@ -233,7 +233,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
root ::= ("-"? integral-part) space
|
root ::= ("-"? integral-part) space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
)"""
|
)"""
|
||||||
|
@ -282,7 +282,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
"prefixItems": [{ "type": "string" }]
|
"prefixItems": [{ "type": "string" }]
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
root ::= "[" space string "]" space
|
root ::= "[" space string "]" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
string ::= "\"" char* "\"" space
|
string ::= "\"" char* "\"" space
|
||||||
|
@ -296,9 +296,9 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
"prefixItems": [{ "type": "string" }, { "type": "number" }]
|
"prefixItems": [{ "type": "string" }, { "type": "number" }]
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
root ::= "[" space string "," space number "]" space
|
root ::= "[" space string "," space number "]" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
|
@ -313,8 +313,8 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
"type": "number"
|
"type": "number"
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
root ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
root ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
)"""
|
)"""
|
||||||
|
@ -331,7 +331,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
boolean ::= ("true" | "false") space
|
boolean ::= ("true" | "false") space
|
||||||
root ::= "[" space boolean "," space boolean ("," space boolean)* "]" space
|
root ::= "[" space boolean ("," space boolean)+ "]" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
)"""
|
)"""
|
||||||
});
|
});
|
||||||
|
@ -347,7 +347,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
boolean ::= ("true" | "false") space
|
boolean ::= ("true" | "false") space
|
||||||
root ::= "[" space (boolean)? "]" space
|
root ::= "[" space boolean? "]" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
)"""
|
)"""
|
||||||
});
|
});
|
||||||
|
@ -379,12 +379,12 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
"maxItems": 5
|
"maxItems": 5
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
integer ::= ("-"? integral-part) space
|
integer ::= ("-"? integral-part) space
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
item ::= number | integer
|
item ::= number | integer
|
||||||
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
root ::= "[" space item "," space item "," space item ("," space item ("," space item)?)? "]" space
|
root ::= "[" space item ("," space item){2,4} "]" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
)"""
|
)"""
|
||||||
});
|
});
|
||||||
|
@ -437,7 +437,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
dot ::= [^\x0A\x0D]
|
dot ::= [^\x0A\x0D]
|
||||||
root ::= "\"" ("(" root-1 (root-1 (root-1)?)? ")")? root-1 root-1 root-1 "-" root-1 root-1 root-1 root-1 " " "aaa" ("a" ("a")?)? "nd" dot dot dot "\"" space
|
root ::= "\"" ("(" root-1{1,3} ")")? root-1{3,3} "-" root-1{4,4} " " "a"{3,5} "nd" dot dot dot "\"" space
|
||||||
root-1 ::= [0-9]
|
root-1 ::= [0-9]
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
)"""
|
)"""
|
||||||
|
@ -465,7 +465,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
a-kv ::= "\"a\"" space ":" space string
|
a-kv ::= "\"a\"" space ":" space string
|
||||||
b-kv ::= "\"b\"" space ":" space string
|
b-kv ::= "\"b\"" space ":" space string
|
||||||
c-kv ::= "\"c\"" space ":" space string
|
c-kv ::= "\"c\"" space ":" space string
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
root ::= "{" space b-kv "," space c-kv "," space a-kv "}" space
|
root ::= "{" space b-kv "," space c-kv "," space a-kv "}" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
string ::= "\"" char* "\"" space
|
string ::= "\"" char* "\"" space
|
||||||
|
@ -485,7 +485,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
a-kv ::= "\"a\"" space ":" space string
|
a-kv ::= "\"a\"" space ":" space string
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
root ::= "{" space (a-kv )? "}" space
|
root ::= "{" space (a-kv )? "}" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
string ::= "\"" char* "\"" space
|
string ::= "\"" char* "\"" space
|
||||||
|
@ -509,7 +509,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
b-kv ::= "\"b\"" space ":" space string
|
b-kv ::= "\"b\"" space ":" space string
|
||||||
b-rest ::= ( "," space c-kv )?
|
b-rest ::= ( "," space c-kv )?
|
||||||
c-kv ::= "\"c\"" space ":" space string
|
c-kv ::= "\"c\"" space ":" space string
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
root ::= "{" space (a-kv a-rest | b-kv b-rest | c-kv )? "}" space
|
root ::= "{" space (a-kv a-rest | b-kv b-rest | c-kv )? "}" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
string ::= "\"" char* "\"" space
|
string ::= "\"" char* "\"" space
|
||||||
|
@ -533,7 +533,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
a-kv ::= "\"a\"" space ":" space string
|
a-kv ::= "\"a\"" space ":" space string
|
||||||
b-kv ::= "\"b\"" space ":" space string
|
b-kv ::= "\"b\"" space ":" space string
|
||||||
c-kv ::= "\"c\"" space ":" space string
|
c-kv ::= "\"c\"" space ":" space string
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
d-kv ::= "\"d\"" space ":" space string
|
d-kv ::= "\"d\"" space ":" space string
|
||||||
d-rest ::= ( "," space c-kv )?
|
d-rest ::= ( "," space c-kv )?
|
||||||
root ::= "{" space b-kv "," space a-kv ( "," space ( d-kv d-rest | c-kv ) )? "}" space
|
root ::= "{" space b-kv "," space a-kv ( "," space ( d-kv d-rest | c-kv ) )? "}" space
|
||||||
|
@ -553,9 +553,9 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
additional-kv ::= string ":" space additional-value
|
additional-kv ::= string ":" space additional-value
|
||||||
additional-kvs ::= additional-kv ( "," space additional-kv )*
|
additional-kvs ::= additional-kv ( "," space additional-kv )*
|
||||||
additional-value ::= "[" space (number ("," space number)*)? "]" space
|
additional-value ::= "[" space (number ("," space number)*)? "]" space
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
root ::= "{" space (additional-kvs )? "}" space
|
root ::= "{" space (additional-kvs )? "}" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
|
@ -573,9 +573,9 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
R"""(
|
R"""(
|
||||||
array ::= "[" space ( value ("," space value)* )? "]" space
|
array ::= "[" space ( value ("," space value)* )? "]" space
|
||||||
boolean ::= ("true" | "false") space
|
boolean ::= ("true" | "false") space
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
null ::= "null" space
|
null ::= "null" space
|
||||||
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
object ::= "{" space ( string ":" space value ("," space string ":" space value)* )? "}" space
|
object ::= "{" space ( string ":" space value ("," space string ":" space value)* )? "}" space
|
||||||
|
@ -595,9 +595,9 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
R"""(
|
R"""(
|
||||||
array ::= "[" space ( value ("," space value)* )? "]" space
|
array ::= "[" space ( value ("," space value)* )? "]" space
|
||||||
boolean ::= ("true" | "false") space
|
boolean ::= ("true" | "false") space
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
null ::= "null" space
|
null ::= "null" space
|
||||||
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
object ::= "{" space ( string ":" space value ("," space string ":" space value)* )? "}" space
|
object ::= "{" space ( string ":" space value ("," space string ":" space value)* )? "}" space
|
||||||
|
@ -636,9 +636,9 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
a-kv ::= "\"a\"" space ":" space number
|
a-kv ::= "\"a\"" space ":" space number
|
||||||
additional-kv ::= string ":" space string
|
additional-kv ::= string ":" space string
|
||||||
additional-kvs ::= additional-kv ( "," space additional-kv )*
|
additional-kvs ::= additional-kv ( "," space additional-kv )*
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
root ::= "{" space a-kv ( "," space ( additional-kvs ) )? "}" space
|
root ::= "{" space a-kv ( "," space ( additional-kvs ) )? "}" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
|
@ -661,9 +661,9 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
a-rest ::= additional-kvs
|
a-rest ::= additional-kvs
|
||||||
additional-kv ::= string ":" space number
|
additional-kv ::= string ":" space number
|
||||||
additional-kvs ::= additional-kv ( "," space additional-kv )*
|
additional-kvs ::= additional-kv ( "," space additional-kv )*
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
root ::= "{" space (a-kv a-rest | additional-kvs )? "}" space
|
root ::= "{" space (a-kv a-rest | additional-kvs )? "}" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
|
@ -689,9 +689,9 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
additional-kvs ::= additional-kv ( "," space additional-kv )*
|
additional-kvs ::= additional-kv ( "," space additional-kv )*
|
||||||
b-kv ::= "\"b\"" space ":" space number
|
b-kv ::= "\"b\"" space ":" space number
|
||||||
b-rest ::= additional-kvs
|
b-rest ::= additional-kvs
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
root ::= "{" space a-kv ( "," space ( b-kv b-rest | additional-kvs ) )? "}" space
|
root ::= "{" space a-kv ( "," space ( b-kv b-rest | additional-kvs ) )? "}" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
|
@ -720,7 +720,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
}
|
}
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
|
char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4})
|
||||||
foo ::= "{" space foo-a-kv "}" space
|
foo ::= "{" space foo-a-kv "}" space
|
||||||
foo-a-kv ::= "\"a\"" space ":" space string
|
foo-a-kv ::= "\"a\"" space ":" space string
|
||||||
root ::= foo
|
root ::= foo
|
||||||
|
@ -752,10 +752,10 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
alternative-1 ::= bar
|
alternative-1 ::= bar
|
||||||
bar ::= "{" space (bar-b-kv )? "}" space
|
bar ::= "{" space (bar-b-kv )? "}" space
|
||||||
bar-b-kv ::= "\"b\"" space ":" space number
|
bar-b-kv ::= "\"b\"" space ":" space number
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
foo ::= "{" space (foo-a-kv )? "}" space
|
foo ::= "{" space (foo-a-kv )? "}" space
|
||||||
foo-a-kv ::= "\"a\"" space ":" space number
|
foo-a-kv ::= "\"a\"" space ":" space number
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
root ::= alternative-0 | alternative-1
|
root ::= alternative-0 | alternative-1
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
|
@ -798,8 +798,8 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
c-kv ::= "\"c\"" space ":" space number
|
c-kv ::= "\"c\"" space ":" space number
|
||||||
d-kv ::= "\"d\"" space ":" space number
|
d-kv ::= "\"d\"" space ":" space number
|
||||||
d-rest ::= ( "," space c-kv )?
|
d-rest ::= ( "," space c-kv )?
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
root ::= "{" space a-kv "," space b-kv ( "," space ( d-kv d-rest | c-kv ) )? "}" space
|
root ::= "{" space a-kv "," space b-kv ( "," space ( d-kv d-rest | c-kv ) )? "}" space
|
||||||
space ::= " "?
|
space ::= " "?
|
||||||
|
@ -841,8 +841,8 @@ static void test_all(const std::string & lang, std::function<void(const TestCase
|
||||||
"definitions": {}
|
"definitions": {}
|
||||||
})""",
|
})""",
|
||||||
R"""(
|
R"""(
|
||||||
decimal-part ::= [0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
decimal-part ::= [0-9]{1,16}
|
||||||
integral-part ::= [0-9] | [1-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9] ([0-9])?)?)?)?)?)?)?)?)?)?)?)?)?)?)?
|
integral-part ::= [0-9] | [1-9] [0-9]{0,15}
|
||||||
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
|
||||||
number- ::= "{" space number-number-kv "}" space
|
number- ::= "{" space number-number-kv "}" space
|
||||||
number-kv ::= "\"number\"" space ":" space number-
|
number-kv ::= "\"number\"" space ":" space number-
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue