Skip to content

Commit c1f156a

Browse files
[Fix] Fix JsonSchemaConverter for numbers "-0. ..." (#462)
This PR fixes the bug in the number format of the JsonSchemaConverter. Currently, the corresponding rule is: ``` "(\"0\" | \"-\"? [1-9] [0-9]*) (\".\" [0-9]+)? ([eE] [+-]? [0-9]+)?" ``` and it cannot accept numbers like `-0.123`. This PR fixes it by replacing it with: ``` "\"-\"? (\"0\" | [1-9] [0-9]*) (\".\" [0-9]+)? ([eE] [+-]? [0-9]+)?" ``` --------- Signed-off-by: Yuchuan <[email protected]>
1 parent a32ac89 commit c1f156a

File tree

6 files changed

+44
-30
lines changed

6 files changed

+44
-30
lines changed

cpp/json_schema_converter.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1963,7 +1963,7 @@ std::string JSONSchemaConverter::VisitNumber(
19631963
return converted_regex;
19641964
}
19651965

1966-
return "(\"0\" | \"-\"? [1-9] [0-9]*) (\".\" [0-9]+)? ([eE] [+-]? [0-9]+)?";
1966+
return "\"-\"? (\"0\" | [1-9] [0-9]*) (\".\" [0-9]+)? ([eE] [+-]? [0-9]+)?";
19671967
}
19681968

19691969
std::string JSONSchemaConverter::VisitString(

tests/python/test_function_calling_converter.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def test_string_schema(input_str: str, accepted: bool):
2727
xml_any ::= basic_number | xml_string | basic_boolean | basic_null | basic_array | basic_object
2828
basic_any ::= basic_number | basic_string | basic_boolean | basic_null | basic_array | basic_object
2929
basic_integer ::= ("0" | "-"? [1-9] [0-9]*)
30-
basic_number ::= ("0" | "-"? [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
30+
basic_number ::= "-"? ("0" | [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
3131
basic_string ::= ["] basic_string_sub
3232
basic_boolean ::= "true" | "false"
3333
basic_null ::= "null"
@@ -72,7 +72,7 @@ def test_additional_properties_schema(input_str: str, accepted: bool):
7272
xml_any ::= basic_number | xml_string | basic_boolean | basic_null | basic_array | basic_object
7373
basic_any ::= basic_number | basic_string | basic_boolean | basic_null | basic_array | basic_object
7474
basic_integer ::= ("0" | "-"? [1-9] [0-9]*)
75-
basic_number ::= ("0" | "-"? [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
75+
basic_number ::= "-"? ("0" | [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
7676
basic_string ::= ["] basic_string_sub
7777
basic_boolean ::= "true" | "false"
7878
basic_null ::= "null"
@@ -116,7 +116,7 @@ def test_not_required_properties_schema(input_str: str, accepted: bool):
116116
xml_any ::= basic_number | xml_string | basic_boolean | basic_null | basic_array | basic_object
117117
basic_any ::= basic_number | basic_string | basic_boolean | basic_null | basic_array | basic_object
118118
basic_integer ::= ("0" | "-"? [1-9] [0-9]*)
119-
basic_number ::= ("0" | "-"? [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
119+
basic_number ::= "-"? ("0" | [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
120120
basic_string ::= ["] basic_string_sub
121121
basic_boolean ::= "true" | "false"
122122
basic_null ::= "null"
@@ -201,7 +201,7 @@ def test_inner_object_schema(input_str: str, accepted: bool):
201201
xml_any ::= basic_number | xml_string | basic_boolean | basic_null | basic_array | basic_object
202202
basic_any ::= basic_number | basic_string | basic_boolean | basic_null | basic_array | basic_object
203203
basic_integer ::= ("0" | "-"? [1-9] [0-9]*)
204-
basic_number ::= ("0" | "-"? [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
204+
basic_number ::= "-"? ("0" | [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
205205
basic_string ::= ["] basic_string_sub
206206
basic_boolean ::= "true" | "false"
207207
basic_null ::= "null"
@@ -253,7 +253,7 @@ def test_numbers_schema(input_str: str, accepted: bool):
253253
xml_any ::= basic_number | xml_string | basic_boolean | basic_null | basic_array | basic_object
254254
basic_any ::= basic_number | basic_string | basic_boolean | basic_null | basic_array | basic_object
255255
basic_integer ::= ("0" | "-"? [1-9] [0-9]*)
256-
basic_number ::= ("0" | "-"? [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
256+
basic_number ::= "-"? ("0" | [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
257257
basic_string ::= ["] basic_string_sub
258258
basic_boolean ::= "true" | "false"
259259
basic_null ::= "null"
@@ -332,7 +332,7 @@ def test_string_format_length_schema(input_str: str, accepted: bool):
332332
xml_any ::= basic_number | xml_string | basic_boolean | basic_null | basic_array | basic_object
333333
basic_any ::= basic_number | basic_string | basic_boolean | basic_null | basic_array | basic_object
334334
basic_integer ::= ("0" | "-"? [1-9] [0-9]*)
335-
basic_number ::= ("0" | "-"? [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
335+
basic_number ::= "-"? ("0" | [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
336336
basic_string ::= ["] basic_string_sub
337337
basic_boolean ::= "true" | "false"
338338
basic_null ::= "null"

tests/python/test_grammar_matcher_json_schema.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from xgrammar.testing import (
1212
_get_masked_tokens_from_bitmask,
1313
_get_matcher_from_grammar_and_tokenizer_info,
14+
_is_grammar_accept_string,
1415
)
1516

1617

@@ -554,5 +555,20 @@ def test_regression_empty_property_key_regex():
554555
assert _ is not None
555556

556557

558+
def test_json_schema_number_without_constraint():
559+
schema = {"type": "object", "properties": {"value": {"type": "number"}}, "required": ["value"]}
560+
grammar = xgr.Grammar.from_json_schema(schema)
561+
assert _is_grammar_accept_string(grammar, '{"value": -0.5}')
562+
assert _is_grammar_accept_string(grammar, '{"value": -1.5}')
563+
assert _is_grammar_accept_string(grammar, '{"value": 0}')
564+
assert _is_grammar_accept_string(grammar, '{"value": 1234567890}')
565+
assert _is_grammar_accept_string(grammar, '{"value": 3.14159}')
566+
assert _is_grammar_accept_string(grammar, '{"value": 1e10}')
567+
assert _is_grammar_accept_string(grammar, '{"value": -2.5E-3}')
568+
assert _is_grammar_accept_string(grammar, '{"value": 0.0}')
569+
assert _is_grammar_accept_string(grammar, '{"value": -0.0}')
570+
assert not _is_grammar_accept_string(grammar, '{"value": "abc"}')
571+
572+
557573
if __name__ == "__main__":
558574
pytest.main(sys.argv)

tests/python/test_grammar_matcher_structural_tag.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,19 @@ class Schema(BaseModel):
5353
basic_integer_1_1 ::= ("" | ("-")) (=([1-9] [0-9]*))
5454
basic_escape_2 ::= (([\"\\/bfnrt]) | ("u" [A-Fa-f0-9] [A-Fa-f0-9] [A-Fa-f0-9] [A-Fa-f0-9])) (=(basic_string_sub_2))
5555
basic_string_sub_2 ::= (("\"") | ([^\0-\x1f\"\\\r\n] basic_string_sub_2) | ("\\" basic_escape_2 basic_string_sub_2)) (=([ \n\t]* [,}\]:]))
56-
basic_number_9 ::= ((basic_number_7_2 basic_number_3_2 basic_number_6_2)) (=(root_part_0_2 [ \n\t]* "}"))
56+
basic_number_9 ::= ((basic_number_1_2 basic_number_7_2 basic_number_3_2 basic_number_6_2)) (=(root_part_0_2 [ \n\t]* "}"))
5757
basic_string_2 ::= (("\"" basic_string_sub_2))
5858
root_prop_1 ::= (("[" [ \n\t]* basic_string_2 root_prop_1_1 [ \n\t]* "]") | ("[" [ \n\t]* "]"))
5959
root_part_0_2 ::= (([ \n\t]* "," [ \n\t]* "\"arg4\"" [ \n\t]* ":" [ \n\t]* root_prop_1)) (=([ \n\t]* "}"))
6060
root_2 ::= (("{" [ \n\t]* "\"arg3\"" [ \n\t]* ":" [ \n\t]* basic_number_9 root_part_0_2 [ \n\t]* "}")) (=("</function>"))
61-
basic_number_1_2 ::= ("" | ("-")) (=([1-9] [0-9]*))
61+
basic_number_1_2 ::= ("" | ("-")) (=(basic_number_7_2 basic_number_3_2 basic_number_6_2))
6262
basic_number_2_2 ::= (([0-9] basic_number_2_2) | ([0-9]))
6363
basic_number_3_2 ::= ("" | ("." basic_number_2_2)) (=(basic_number_6_2))
6464
basic_number_4_2 ::= ("" | ([+\-])) (=(basic_number_5_2))
6565
basic_number_5_2 ::= (([0-9] basic_number_5_2) | ([0-9]))
6666
basic_number_6_2 ::= ("" | ([eE] basic_number_4_2 basic_number_5_2))
6767
root_prop_1_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_string_2 root_prop_1_1)) (=([ \n\t]* "]"))
68-
basic_number_7_2 ::= (("0") | (basic_number_1_2 [1-9] [0-9]*)) (=(basic_number_3_2 basic_number_6_2))
68+
basic_number_7_2 ::= (("0") | ([1-9] [0-9]*)) (=(basic_number_3_2 basic_number_6_2))
6969
triggered_tags_group ::= (("1>" root "</function>") | ("2>" root_1 "</function>"))
7070
triggered_tags_group_1 ::= ((">" root_2 "</function>"))
7171
triggered_tags ::= TagDispatch(
@@ -82,7 +82,7 @@ class Schema(BaseModel):
8282
basic_string_sub ::= (("\"") | ([^\0-\x1f\"\\\r\n] basic_string_sub) | ("\\" basic_escape basic_string_sub)) (=([ \n\t]* [,}\]:]))
8383
basic_any ::= ((basic_number) | (basic_string) | (basic_boolean) | (basic_null) | (basic_array) | (basic_object))
8484
basic_integer ::= (("0") | (basic_integer_1 [1-9] [0-9]*))
85-
basic_number ::= ((basic_number_7 basic_number_3 basic_number_6))
85+
basic_number ::= ((basic_number_1 basic_number_7 basic_number_3 basic_number_6))
8686
basic_string ::= (("\"" basic_string_sub))
8787
basic_boolean ::= (("true") | ("false"))
8888
basic_null ::= (("null"))
@@ -99,12 +99,12 @@ class Schema(BaseModel):
9999
basic_number_6 ::= ("" | ([eE] basic_number_4 basic_number_5))
100100
basic_array_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_any basic_array_1))
101101
basic_object_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_string [ \n\t]* ":" [ \n\t]* basic_any basic_object_1))
102-
basic_number_7 ::= (("0") | (basic_number_1 [1-9] [0-9]*))
102+
basic_number_7 ::= (("0") | ([1-9] [0-9]*))
103103
basic_escape_1 ::= (([\"\\/bfnrt]) | ("u" [A-Fa-f0-9] [A-Fa-f0-9] [A-Fa-f0-9] [A-Fa-f0-9]))
104104
basic_string_sub_1 ::= (("\"") | ([^\0-\x1f\"\\\r\n] basic_string_sub_1) | ("\\" basic_escape_1 basic_string_sub_1)) (=([ \n\t]* [,}\]:]))
105105
basic_any_1 ::= ((basic_number_8) | (basic_string_1) | (basic_boolean_1) | (basic_null_1) | (basic_array_2) | (basic_object_2))
106106
basic_integer_2 ::= (("0") | (basic_integer_1_1 [1-9] [0-9]*))
107-
basic_number_8 ::= ((basic_number_7_1 basic_number_3_1 basic_number_6_1))
107+
basic_number_8 ::= ((basic_number_1_1 basic_number_7_1 basic_number_3_1 basic_number_6_1))
108108
basic_string_1 ::= (("\"" basic_string_sub_1))
109109
basic_boolean_1 ::= (("true") | ("false"))
110110
basic_null_1 ::= (("null"))
@@ -121,12 +121,12 @@ class Schema(BaseModel):
121121
basic_number_6_1 ::= ("" | ([eE] basic_number_4_1 basic_number_5_1))
122122
basic_array_1_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_any_1 basic_array_1_1))
123123
basic_object_1_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_string_1 [ \n\t]* ":" [ \n\t]* basic_any_1 basic_object_1_1))
124-
basic_number_7_1 ::= (("0") | (basic_number_1_1 [1-9] [0-9]*))
124+
basic_number_7_1 ::= (("0") | ([1-9] [0-9]*))
125125
basic_escape_2 ::= (([\"\\/bfnrt]) | ("u" [A-Fa-f0-9] [A-Fa-f0-9] [A-Fa-f0-9] [A-Fa-f0-9]))
126126
basic_string_sub_2 ::= (("\"") | ([^\0-\x1f\"\\\r\n] basic_string_sub_2) | ("\\" basic_escape_2 basic_string_sub_2)) (=([ \n\t]* [,}\]:]))
127127
basic_any_2 ::= ((basic_number_9) | (basic_string_2) | (basic_boolean_2) | (basic_null_2) | (basic_array_3) | (basic_object_3))
128128
basic_integer_3 ::= (("0") | (basic_integer_1_2 [1-9] [0-9]*))
129-
basic_number_9 ::= ((basic_number_7_2 basic_number_3_2 basic_number_6_2))
129+
basic_number_9 ::= ((basic_number_1_2 basic_number_7_2 basic_number_3_2 basic_number_6_2))
130130
basic_string_2 ::= (("\"" basic_string_sub_2))
131131
basic_boolean_2 ::= (("true") | ("false"))
132132
basic_null_2 ::= (("null"))
@@ -145,7 +145,7 @@ class Schema(BaseModel):
145145
basic_array_1_2 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_any_2 basic_array_1_2))
146146
basic_object_1_2 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_string_2 [ \n\t]* ":" [ \n\t]* basic_any_2 basic_object_1_2))
147147
root_prop_1_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_string_2 root_prop_1_1))
148-
basic_number_7_2 ::= (("0") | (basic_number_1_2 [1-9] [0-9]*))
148+
basic_number_7_2 ::= (("0") | ([1-9] [0-9]*))
149149
triggered_tags_group ::= (("1>" root "</function>") | ("2>" root_1 "</function>"))
150150
triggered_tags_group_1 ::= ((">" root_2 "</function>"))
151151
triggered_tags ::= TagDispatch(
@@ -178,7 +178,6 @@ class Schema2(BaseModel):
178178
triggers = ["<function=f", "<function=g"]
179179

180180
grammar = xgr.Grammar.from_structural_tag(tags, triggers)
181-
182181
assert str(grammar) == expected_grammar_test_structural_tag_before_optimization
183182

184183
accepted_inputs = [
@@ -212,7 +211,6 @@ class Schema2(BaseModel):
212211

213212
compiler = xgr.GrammarCompiler(xgr.TokenizerInfo([]))
214213
compiled_grammar = compiler.compile_structural_tag(tags, triggers)
215-
216214
assert str(compiled_grammar.grammar) == expected_grammar_test_structural_tag_after_optimization
217215

218216

tests/python/test_json_schema_converter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
basic_string_sub ::= ("\"" | [^\0-\x1f\"\\\r\n] basic_string_sub | "\\" basic_escape basic_string_sub) (= [ \n\t]* [,}\]:])
2020
basic_any ::= basic_number | basic_string | basic_boolean | basic_null | basic_array | basic_object
2121
basic_integer ::= ("0" | "-"? [1-9] [0-9]*)
22-
basic_number ::= ("0" | "-"? [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
22+
basic_number ::= "-"? ("0" | [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
2323
basic_string ::= ["] basic_string_sub
2424
basic_boolean ::= "true" | "false"
2525
basic_null ::= "null"
@@ -31,7 +31,7 @@
3131
basic_string_sub ::= ("\"" | [^\0-\x1f\"\\\r\n] basic_string_sub | "\\" basic_escape basic_string_sub) (= [ \n\t]* [,}\]:])
3232
basic_any ::= basic_number | basic_string | basic_boolean | basic_null | basic_array | basic_object
3333
basic_integer ::= ("0" | "-"? [1-9] [0-9]*)
34-
basic_number ::= ("0" | "-"? [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
34+
basic_number ::= "-"? ("0" | [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
3535
basic_string ::= ["] basic_string_sub
3636
basic_boolean ::= "true" | "false"
3737
basic_null ::= "null"

tests/python/test_structural_tag_converter.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def test_const_string_format(
126126
basic_string_sub ::= (("\"") | ([^\0-\x1f\"\\\r\n] basic_string_sub) | ("\\" basic_escape basic_string_sub)) (=([ \n\t]* [,}\]:]))
127127
basic_any ::= ((basic_number) | (basic_string) | (basic_boolean) | (basic_null) | (basic_array) | (basic_object))
128128
basic_integer ::= (("0") | (basic_integer_1 [1-9] [0-9]*))
129-
basic_number ::= ((basic_number_7 basic_number_3 basic_number_6))
129+
basic_number ::= ((basic_number_1 basic_number_7 basic_number_3 basic_number_6))
130130
basic_string ::= (("\"" basic_string_sub))
131131
basic_boolean ::= (("true") | ("false"))
132132
basic_null ::= (("null"))
@@ -142,7 +142,7 @@ def test_const_string_format(
142142
basic_number_6 ::= ("" | ([eE] basic_number_4 basic_number_5))
143143
basic_array_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_any basic_array_1))
144144
basic_object_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_string [ \n\t]* ":" [ \n\t]* basic_any basic_object_1))
145-
basic_number_7 ::= (("0") | (basic_number_1 [1-9] [0-9]*))
145+
basic_number_7 ::= (("0") | ([1-9] [0-9]*))
146146
root_1 ::= ((root))
147147
""",
148148
)
@@ -186,7 +186,7 @@ def test_json_schema_format(
186186
xml_any ::= ((basic_number) | (xml_string) | (basic_boolean) | (basic_null) | (basic_array) | (basic_object))
187187
basic_any ::= ((basic_number) | (basic_string) | (basic_boolean) | (basic_null) | (basic_array) | (basic_object))
188188
basic_integer ::= (("0") | (basic_integer_1 [1-9] [0-9]*))
189-
basic_number ::= ((basic_number_7 basic_number_3 basic_number_6))
189+
basic_number ::= ((basic_number_1 basic_number_7 basic_number_3 basic_number_6))
190190
basic_string ::= (("\"" basic_string_sub))
191191
basic_boolean ::= (("true") | ("false"))
192192
basic_null ::= (("null"))
@@ -205,7 +205,7 @@ def test_json_schema_format(
205205
basic_array_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_any basic_array_1))
206206
basic_object_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_string [ \n\t]* ":" [ \n\t]* basic_any basic_object_1))
207207
root_prop_1_1 ::= ("" | ("-"))
208-
basic_number_7 ::= (("0") | (basic_number_1 [1-9] [0-9]*))
208+
basic_number_7 ::= (("0") | ([1-9] [0-9]*))
209209
root_1 ::= ((root))
210210
""",
211211
)
@@ -304,7 +304,7 @@ def test_regex_format(
304304
basic_string_sub ::= (("\"") | ([^\0-\x1f\"\\\r\n] basic_string_sub) | ("\\" basic_escape basic_string_sub)) (=([ \n\t]* [,}\]:]))
305305
basic_any ::= ((basic_number) | (basic_string) | (basic_boolean) | (basic_null) | (basic_array) | (basic_object))
306306
basic_integer ::= (("0") | (basic_integer_1 [1-9] [0-9]*))
307-
basic_number ::= ((basic_number_7 basic_number_3 basic_number_6))
307+
basic_number ::= ((basic_number_1 basic_number_7 basic_number_3 basic_number_6))
308308
basic_string ::= (("\"" basic_string_sub))
309309
basic_boolean ::= (("true") | ("false"))
310310
basic_null ::= (("null"))
@@ -320,7 +320,7 @@ def test_regex_format(
320320
basic_number_6 ::= ("" | ([eE] basic_number_4 basic_number_5))
321321
basic_array_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_any basic_array_1))
322322
basic_object_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_string [ \n\t]* ":" [ \n\t]* basic_any basic_object_1))
323-
basic_number_7 ::= (("0") | (basic_number_1 [1-9] [0-9]*))
323+
basic_number_7 ::= (("0") | ([1-9] [0-9]*))
324324
root_1 ::= ("" | ([\-+*/]))
325325
root_2 ::= ((root_1_1))
326326
root_1_1 ::= ("" | ([simple]))
@@ -369,7 +369,7 @@ def test_sequence_format(
369369
basic_string_sub ::= (("\"") | ([^\0-\x1f\"\\\r\n] basic_string_sub) | ("\\" basic_escape basic_string_sub)) (=([ \n\t]* [,}\]:]))
370370
basic_any ::= ((basic_number) | (basic_string) | (basic_boolean) | (basic_null) | (basic_array) | (basic_object))
371371
basic_integer ::= (("0") | (basic_integer_1 [1-9] [0-9]*))
372-
basic_number ::= ((basic_number_7 basic_number_3 basic_number_6))
372+
basic_number ::= ((basic_number_1 basic_number_7 basic_number_3 basic_number_6))
373373
basic_string ::= (("\"" basic_string_sub))
374374
basic_boolean ::= (("true") | ("false"))
375375
basic_null ::= (("null"))
@@ -385,7 +385,7 @@ def test_sequence_format(
385385
basic_number_6 ::= ("" | ([eE] basic_number_4 basic_number_5))
386386
basic_array_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_any basic_array_1))
387387
basic_object_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_string [ \n\t]* ":" [ \n\t]* basic_any basic_object_1))
388-
basic_number_7 ::= (("0") | (basic_number_1 [1-9] [0-9]*))
388+
basic_number_7 ::= (("0") | ([1-9] [0-9]*))
389389
or ::= ((const_string) | (root))
390390
root_1 ::= ((or))
391391
""",
@@ -423,7 +423,7 @@ def test_or_format(
423423
basic_string_sub ::= (("\"") | ([^\0-\x1f\"\\\r\n] basic_string_sub) | ("\\" basic_escape basic_string_sub)) (=([ \n\t]* [,}\]:]))
424424
basic_any ::= ((basic_number) | (basic_string) | (basic_boolean) | (basic_null) | (basic_array) | (basic_object))
425425
basic_integer ::= (("0") | (basic_integer_1 [1-9] [0-9]*))
426-
basic_number ::= ((basic_number_7 basic_number_3 basic_number_6))
426+
basic_number ::= ((basic_number_1 basic_number_7 basic_number_3 basic_number_6))
427427
basic_string ::= (("\"" basic_string_sub))
428428
basic_boolean ::= (("true") | ("false"))
429429
basic_null ::= (("null"))
@@ -439,7 +439,7 @@ def test_or_format(
439439
basic_number_6 ::= ("" | ([eE] basic_number_4 basic_number_5))
440440
basic_array_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_any basic_array_1))
441441
basic_object_1 ::= ("" | ([ \n\t]* "," [ \n\t]* basic_string [ \n\t]* ":" [ \n\t]* basic_any basic_object_1))
442-
basic_number_7 ::= (("0") | (basic_number_1 [1-9] [0-9]*))
442+
basic_number_7 ::= (("0") | ([1-9] [0-9]*))
443443
tag ::= (("BEG" root "END"))
444444
root_1 ::= ((tag))
445445
""",

0 commit comments

Comments
 (0)