diff --git a/common/json-schema-to-grammar.cpp b/common/json-schema-to-grammar.cpp index ebcd46c16..275bdb97c 100644 --- a/common/json-schema-to-grammar.cpp +++ b/common/json-schema-to-grammar.cpp @@ -429,12 +429,12 @@ private: out << " | "; } out << "[" << kv.first << "]"; - if (kv.second.is_end_of_string) { - out << " " << char_rule << "+"; - } else { + if (!kv.second.children.empty()) { out << " ("; visit(kv.second); out << ")"; + } else if (kv.second.is_end_of_string) { + out << " " << char_rule << "+"; } } if (!node.children.empty()) { @@ -446,7 +446,11 @@ private: }; visit(trie); - out << " )? [\"] space"; + out << " )"; + if (!trie.is_end_of_string) { + out << "?"; + } + out << " [\"] space"; return out.str(); } diff --git a/examples/json_schema_to_grammar.py b/examples/json_schema_to_grammar.py index cb255a6d0..6c2e0992a 100755 --- a/examples/json_schema_to_grammar.py +++ b/examples/json_schema_to_grammar.py @@ -142,12 +142,12 @@ class SchemaConverter: else: out.append(' | ') out.append(f'[{c}]') - if (child.is_end_of_string): - out.append(f' {char_rule}+') - else: + if child.children: out.append(f' (') visit(child) out.append(')') + elif child.is_end_of_string: + out.append(f' {char_rule}+') if node.children: if not first: out.append(' | ') diff --git a/examples/server/public/json-schema-to-grammar.mjs b/examples/server/public/json-schema-to-grammar.mjs index 96e4daae2..3a7b6c86a 100644 --- a/examples/server/public/json-schema-to-grammar.mjs +++ b/examples/server/public/json-schema-to-grammar.mjs @@ -367,18 +367,19 @@ export class SchemaConverter { for (const c of Object.keys(node.children).sort()) { const child = node.children[c]; rejects.push(c); - if (!first) { + if (first) { + first = false; + } else { out.push(' | '); } out.push(`[${c}]`); - if (child.isEndOfString) { - out.push(` ${charRuleName}+`); - } else { + if (Object.keys(child.children).length > 0) { out.push(' ('); visit(child); out.push(')'); + } else if (child.isEndOfString) { + out.push(` ${charRuleName}+`); } - first = false; } if (Object.keys(node.children).length > 0) { if (!first) { diff --git a/tests/test-json-schema-to-grammar.cpp b/tests/test-json-schema-to-grammar.cpp index 20a722768..a33237205 100755 --- a/tests/test-json-schema-to-grammar.cpp +++ b/tests/test-json-schema-to-grammar.cpp @@ -697,6 +697,82 @@ static void test_all(const std::string & lang, std::function