mirror of
				https://github.com/ggml-org/llama.cpp.git
				synced 2025-10-31 08:51:55 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into bins
This commit is contained in:
		| @@ -402,12 +402,26 @@ if (LLAMA_CUBLAS) | |||||||
| endif() | endif() | ||||||
|  |  | ||||||
| if (LLAMA_CUDA) | if (LLAMA_CUDA) | ||||||
|     cmake_minimum_required(VERSION 3.17) |     cmake_minimum_required(VERSION 3.18)  # for CMAKE_CUDA_ARCHITECTURES | ||||||
|  |  | ||||||
|     find_package(CUDAToolkit) |     find_package(CUDAToolkit) | ||||||
|     if (CUDAToolkit_FOUND) |     if (CUDAToolkit_FOUND) | ||||||
|         message(STATUS "CUDA found") |         message(STATUS "CUDA found") | ||||||
|  |  | ||||||
|  |         if (NOT DEFINED CMAKE_CUDA_ARCHITECTURES) | ||||||
|  |             # 52 == lowest CUDA 12 standard | ||||||
|  |             # 60 == f16 CUDA intrinsics | ||||||
|  |             # 61 == integer CUDA intrinsics | ||||||
|  |             # 70 == compute capability at which unrolling a loop in mul_mat_q kernels is faster | ||||||
|  |             if (LLAMA_CUDA_F16 OR LLAMA_CUDA_DMMV_F16) | ||||||
|  |                 set(CMAKE_CUDA_ARCHITECTURES "60;61;70") # needed for f16 CUDA intrinsics | ||||||
|  |             else() | ||||||
|  |                 set(CMAKE_CUDA_ARCHITECTURES "52;61;70") # lowest CUDA 12 standard + lowest for integer intrinsics | ||||||
|  |                 #set(CMAKE_CUDA_ARCHITECTURES "OFF") # use this to compile much faster, but only F16 models work | ||||||
|  |             endif() | ||||||
|  |         endif() | ||||||
|  |         message(STATUS "Using CUDA architectures: ${CMAKE_CUDA_ARCHITECTURES}") | ||||||
|  |  | ||||||
|         enable_language(CUDA) |         enable_language(CUDA) | ||||||
|  |  | ||||||
|         set(GGML_HEADERS_CUDA ggml-cuda.h) |         set(GGML_HEADERS_CUDA ggml-cuda.h) | ||||||
| @@ -472,21 +486,6 @@ if (LLAMA_CUDA) | |||||||
|         else() |         else() | ||||||
|             set(LLAMA_EXTRA_LIBS ${LLAMA_EXTRA_LIBS} CUDA::cuda_driver) # required by cuDeviceGetAttribute(), cuMemGetAllocationGranularity(...), ... |             set(LLAMA_EXTRA_LIBS ${LLAMA_EXTRA_LIBS} CUDA::cuda_driver) # required by cuDeviceGetAttribute(), cuMemGetAllocationGranularity(...), ... | ||||||
|         endif() |         endif() | ||||||
|  |  | ||||||
|     if (NOT DEFINED CMAKE_CUDA_ARCHITECTURES) |  | ||||||
|         # 52 == lowest CUDA 12 standard |  | ||||||
|         # 60 == f16 CUDA intrinsics |  | ||||||
|         # 61 == integer CUDA intrinsics |  | ||||||
|         # 70 == compute capability at which unrolling a loop in mul_mat_q kernels is faster |  | ||||||
|         if (LLAMA_CUDA_F16 OR LLAMA_CUDA_DMMV_F16) |  | ||||||
|             set(CMAKE_CUDA_ARCHITECTURES "60;61;70") # needed for f16 CUDA intrinsics |  | ||||||
|         else() |  | ||||||
|             set(CMAKE_CUDA_ARCHITECTURES "52;61;70") # lowest CUDA 12 standard + lowest for integer intrinsics |  | ||||||
|             #set(CMAKE_CUDA_ARCHITECTURES "") # use this to compile much faster, but only F16 models work |  | ||||||
|         endif() |  | ||||||
|     endif() |  | ||||||
|     message(STATUS "Using CUDA architectures: ${CMAKE_CUDA_ARCHITECTURES}") |  | ||||||
|  |  | ||||||
|     else() |     else() | ||||||
|         message(WARNING "CUDA not found") |         message(WARNING "CUDA not found") | ||||||
|     endif() |     endif() | ||||||
|   | |||||||
| @@ -40,7 +40,7 @@ static std::string build_repetition(const std::string & item_rule, int min_items | |||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| const std::string SPACE_RULE = "\" \"?"; | const std::string SPACE_RULE = "| \" \" | \"\\n\" [ \\t]{0,20}"; | ||||||
|  |  | ||||||
| struct BuiltinRule { | struct BuiltinRule { | ||||||
|     std::string content; |     std::string content; | ||||||
| @@ -57,7 +57,7 @@ std::unordered_map<std::string, BuiltinRule> PRIMITIVE_RULES = { | |||||||
|     {"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]{8} \"-\" [0-9a-fA-F]{4} \"-\" [0-9a-fA-F]{4} \"-\" [0-9a-fA-F]{4} \"-\" [0-9a-fA-F]{12} \"\\\"\" 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", {}}}, | ||||||
|     {"char",   {"[^\"\\\\] | \"\\\\\" ([\"\\\\/bfnrt] | \"u\" [0-9a-fA-F]{4})", {}}}, |     {"char",   {"[^\"\\\\\\x7F\\x00-\\x1F] | [\\\\] ([\"\\\\bfnrt] | \"u\" [0-9a-fA-F]{4})", {}}}, | ||||||
|     {"string", {"\"\\\"\" char* \"\\\"\" space", {"char"}}}, |     {"string", {"\"\\\"\" char* \"\\\"\" space", {"char"}}}, | ||||||
|     {"null", {"\"null\" space", {}}}, |     {"null", {"\"null\" space", {}}}, | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -29,9 +29,8 @@ class BuiltinRule: | |||||||
|         self.content = content |         self.content = content | ||||||
|         self.deps = deps or [] |         self.deps = deps or [] | ||||||
|  |  | ||||||
| # whitespace is constrained to a single space char to prevent model "running away" in | # Constraining spaces to prevent model "running away". | ||||||
| # whitespace. Also maybe improves generation quality? | SPACE_RULE = '| " " | "\\n" [ \\t]{0,20}' | ||||||
| SPACE_RULE = '" "?' |  | ||||||
|  |  | ||||||
| PRIMITIVE_RULES = { | PRIMITIVE_RULES = { | ||||||
|     'boolean'      : BuiltinRule('("true" | "false") space', []), |     'boolean'      : BuiltinRule('("true" | "false") space', []), | ||||||
| @@ -43,7 +42,7 @@ PRIMITIVE_RULES = { | |||||||
|     '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'"\"" [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', []), |     '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]{4})', []), |     'char'         : BuiltinRule(r'[^"\\\x7F\x00-\x1F] | [\\] (["\\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', []), | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| // WARNING: This file was ported from json_schema_to_grammar.py, please fix bugs / add features there first. | // WARNING: This file was ported from json_schema_to_grammar.py, please fix bugs / add features there first. | ||||||
| const SPACE_RULE = '" "?'; | const SPACE_RULE = '| " " | "\\n" [ \\t]{0,20}'; | ||||||
|  |  | ||||||
| function _buildRepetition(itemRule, minItems, maxItems, opts={}) { | function _buildRepetition(itemRule, minItems, maxItems, opts={}) { | ||||||
|   if (minItems === 0 && maxItems === 1) { |   if (minItems === 0 && maxItems === 1) { | ||||||
| @@ -41,7 +41,7 @@ const PRIMITIVE_RULES = { | |||||||
|   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('"\\"" [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', []), |   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]{4})`, []), |   char           : new BuiltinRule(`[^"\\\\\\x7F\\x00-\\x1F] | [\\\\] (["\\\\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', []), | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -94,6 +94,8 @@ This guide provides a brief overview. Check out the GBNF files in this directory | |||||||
| ./llama-cli -m <model> --grammar-file grammars/some-grammar.gbnf -p 'Some prompt' | ./llama-cli -m <model> --grammar-file grammars/some-grammar.gbnf -p 'Some prompt' | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | `llama.cpp` can also convert JSON schemas to grammars either ahead of time or at each request, see below. | ||||||
|  |  | ||||||
| ## Troubleshooting | ## Troubleshooting | ||||||
|  |  | ||||||
| Grammars currently have performance gotchas (see https://github.com/ggerganov/llama.cpp/issues/4218). | Grammars currently have performance gotchas (see https://github.com/ggerganov/llama.cpp/issues/4218). | ||||||
| @@ -103,3 +105,40 @@ Grammars currently have performance gotchas (see https://github.com/ggerganov/ll | |||||||
| A common pattern is to allow repetitions of a pattern `x` up to N times. | A common pattern is to allow repetitions of a pattern `x` up to N times. | ||||||
|  |  | ||||||
| While semantically correct, the syntax `x? x? x?.... x?` (with N repetitions) may result in extremely slow sampling. Instead, you can write `x{0,N}` (or `(x (x (x ... (x)?...)?)?)?` w/ N-deep nesting in earlier llama.cpp versions). | While semantically correct, the syntax `x? x? x?.... x?` (with N repetitions) may result in extremely slow sampling. Instead, you can write `x{0,N}` (or `(x (x (x ... (x)?...)?)?)?` w/ N-deep nesting in earlier llama.cpp versions). | ||||||
|  |  | ||||||
|  | ## Using GBNF grammars | ||||||
|  |  | ||||||
|  | You can use GBNF grammars: | ||||||
|  |  | ||||||
|  | - In the [server](../examples/server)'s completion endpoints, passed as the `grammar` body field | ||||||
|  | - In the [main](../examples/main) CLI, passed as the `--grammar` & `--grammar-file` flags | ||||||
|  | - With the [gbnf-validator](../examples/gbnf-validator) tool, to test them against strings. | ||||||
|  |  | ||||||
|  | ## JSON Schemas → GBNF | ||||||
|  |  | ||||||
|  | `llama.cpp` supports converting a subset of https://json-schema.org/ to GBNF grammars: | ||||||
|  |  | ||||||
|  | - In the [server](../examples/server): | ||||||
|  |     - For any completion endpoints, passed as the `json_schema` body field | ||||||
|  |     - For the `/chat/completions` endpoint, passed inside the `result_format` body field (e.g. `{"type", "json_object", "schema": {"items": {}}}`) | ||||||
|  | - In the [main](../examples/main) CLI, passed as the `--json` / `-j` flag | ||||||
|  | - To convert to a grammar ahead of time: | ||||||
|  |     - in CLI, with [json_schema_to_grammar.py](../examples/json_schema_to_grammar.py) | ||||||
|  |     - in JavaScript with [json-schema-to-grammar.mjs](../examples/server/public/json-schema-to-grammar.mjs) (this is used by the [server](../examples/server)'s Web UI) | ||||||
|  |  | ||||||
|  | Take a look at [tests](../../tests/test-json-schema-to-grammar.cpp) to see which features are likely supported (you'll also find usage examples in https://github.com/ggerganov/llama.cpp/pull/5978, https://github.com/ggerganov/llama.cpp/pull/6659 & https://github.com/ggerganov/llama.cpp/pull/6555). | ||||||
|  |  | ||||||
|  | Here is also a non-exhaustive list of **unsupported** features: | ||||||
|  |  | ||||||
|  | - `additionalProperties`: to be fixed in https://github.com/ggerganov/llama.cpp/pull/7840 | ||||||
|  | - `minimum`, `exclusiveMinimum`, `maximum`, `exclusiveMaximum` | ||||||
|  |     - `integer` constraints to be implemented in https://github.com/ggerganov/llama.cpp/pull/7797 | ||||||
|  | - Remote `$ref`s in the C++ version (Python & JavaScript versions fetch https refs) | ||||||
|  | - Mixing `properties` w/ `anyOf` / `oneOf` in the same type (https://github.com/ggerganov/llama.cpp/issues/7703) | ||||||
|  | - `string` formats `uri`, `email` | ||||||
|  | - [`contains`](https://json-schema.org/draft/2020-12/json-schema-core#name-contains) / `minContains` | ||||||
|  | - `uniqueItems` | ||||||
|  | - `$anchor` (cf. [dereferencing](https://json-schema.org/draft/2020-12/json-schema-core#name-dereferencing)) | ||||||
|  | - [`not`](https://json-schema.org/draft/2020-12/json-schema-core#name-not) | ||||||
|  | - [Conditionals](https://json-schema.org/draft/2020-12/json-schema-core#name-keywords-for-applying-subsche) `if` / `then` / `else` / `dependentSchemas` | ||||||
|  | - [`patternProperties`](https://json-schema.org/draft/2020-12/json-schema-core#name-patternproperties) | ||||||
|   | |||||||
| @@ -16,10 +16,10 @@ array  ::= | |||||||
| string ::= | string ::= | ||||||
|   "\"" ( |   "\"" ( | ||||||
|     [^"\\\x7F\x00-\x1F] | |     [^"\\\x7F\x00-\x1F] | | ||||||
|     "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F]) # escapes |     "\\" (["\\bfnrt] | "u" [0-9a-fA-F]{4}) # escapes | ||||||
|   )* "\"" ws |   )* "\"" ws | ||||||
|  |  | ||||||
| number ::= ("-"? ([0-9] | [1-9] [0-9]*)) ("." [0-9]+)? ([eE] [-+]? [0-9]+)? ws | number ::= ("-"? ([0-9] | [1-9] [0-9]{0,15})) ("." [0-9]+)? ([eE] [-+]? [0-9] [1-9]{0,15})? ws | ||||||
|  |  | ||||||
| # Optional space: by convention, applied in this grammar after literal chars when allowed | # Optional space: by convention, applied in this grammar after literal chars when allowed | ||||||
| ws ::= ([ \t\n] ws)? | ws ::= | " " | "\n" [ \t]{0,20} | ||||||
|   | |||||||
| @@ -25,10 +25,10 @@ array  ::= | |||||||
| string ::= | string ::= | ||||||
|   "\"" ( |   "\"" ( | ||||||
|     [^"\\\x7F\x00-\x1F] | |     [^"\\\x7F\x00-\x1F] | | ||||||
|     "\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F]) # escapes |     "\\" (["\\bfnrt] | "u" [0-9a-fA-F]{4}) # escapes | ||||||
|   )* "\"" ws |   )* "\"" ws | ||||||
|  |  | ||||||
| number ::= ("-"? ([0-9] | [1-9] [0-9]*)) ("." [0-9]+)? ([eE] [-+]? [0-9]+)? ws | number ::= ("-"? ([0-9] | [1-9] [0-9]{0,15})) ("." [0-9]+)? ([eE] [-+]? [1-9] [0-9]{0,15})? ws | ||||||
|  |  | ||||||
| # Optional space: by convention, applied in this grammar after literal chars when allowed | # Optional space: by convention, applied in this grammar after literal chars when allowed | ||||||
| ws ::= ([ \t\n] ws)? | ws ::= | " " | "\n" [ \t]{0,20} | ||||||
|   | |||||||
| @@ -105,14 +105,14 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             decimal-part ::= [0-9]{1,16} |             decimal-part ::= [0-9]{1,16} | ||||||
|             integral-part ::= [0] | [1-9] [0-9]{0,15} |             integral-part ::= [0] | [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 | ||||||
|             root ::= object |             root ::= object | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|             value ::= object | array | string | number | boolean | null |             value ::= object | array | string | number | boolean | null | ||||||
|         )""" |         )""" | ||||||
| @@ -135,7 +135,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|             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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|             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 ::= ([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 | ||||||
| @@ -152,9 +152,9 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             root ::= "\"" char* "\"" space |             root ::= "\"" char* "\"" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -166,9 +166,9 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             root ::= "\"" char+ "\"" space |             root ::= "\"" char+ "\"" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -180,9 +180,9 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             root ::= "\"" char{3,} "\"" space |             root ::= "\"" char{3,} "\"" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -194,9 +194,9 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             root ::= "\"" char{0,3} "\"" space |             root ::= "\"" char{0,3} "\"" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -209,9 +209,9 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             root ::= "\"" char{1,4} "\"" space |             root ::= "\"" char{1,4} "\"" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -223,7 +223,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|         })""", |         })""", | ||||||
|         R"""( |         R"""( | ||||||
|             root ::= ("true" | "false") space |             root ::= ("true" | "false") space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -236,7 +236,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|         R"""( |         R"""( | ||||||
|             integral-part ::= [0] | [1-9] [0-9]{0,15} |             integral-part ::= [0] | [1-9] [0-9]{0,15} | ||||||
|             root ::= ("-"? integral-part) space |             root ::= ("-"? integral-part) space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -248,7 +248,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|         })""", |         })""", | ||||||
|         R"""( |         R"""( | ||||||
|             root ::= "\"foo\"" |             root ::= "\"foo\"" | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -260,7 +260,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|         })""", |         })""", | ||||||
|         R"""( |         R"""( | ||||||
|             root ::= "123" |             root ::= "123" | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -272,7 +272,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|         })""", |         })""", | ||||||
|         R"""( |         R"""( | ||||||
|             root ::= "\"red\"" | "\"amber\"" | "\"green\"" | "null" | "42" | "[\"foo\"]" |             root ::= "\"red\"" | "\"amber\"" | "\"green\"" | "null" | "42" | "[\"foo\"]" | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -283,9 +283,9 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             root ::= "[" space string "]" space |             root ::= "[" space string "]" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
| @@ -297,12 +297,12 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             decimal-part ::= [0-9]{1,16} |             decimal-part ::= [0-9]{1,16} | ||||||
|             integral-part ::= [0] | [1-9] [0-9]{0,15} |             integral-part ::= [0] | [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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
| @@ -317,7 +317,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|             decimal-part ::= [0-9]{1,16} |             decimal-part ::= [0-9]{1,16} | ||||||
|             integral-part ::= [0] | [1-9] [0-9]{0,15} |             integral-part ::= [0] | [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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -333,7 +333,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 |             root ::= "[" space boolean ("," space boolean)+ "]" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -349,7 +349,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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -365,7 +365,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 |             root ::= "[" space (boolean ("," space boolean)?)? "]" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -386,7 +386,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|             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){2,4} "]" space |             root ::= "[" space item ("," space item){2,4} "]" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -399,7 +399,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|         })""", |         })""", | ||||||
|         R"""( |         R"""( | ||||||
|             root ::= "\"" "ab" "c"? "d"* "ef" "g"+ ("hij")? "kl" "\"" space |             root ::= "\"" "ab" "c"? "d"* "ef" "g"+ ("hij")? "kl" "\"" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -412,7 +412,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|         })""", |         })""", | ||||||
|         R"""( |         R"""( | ||||||
|             root ::= "\"" "[]{}()|+*?" "\"" space |             root ::= "\"" "[]{}()|+*?" "\"" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -425,7 +425,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|         })""", |         })""", | ||||||
|         R"""( |         R"""( | ||||||
|             root ::= "\"" "\"" "\"" space |             root ::= "\"" "\"" "\"" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -440,7 +440,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|             dot ::= [^\x0A\x0D] |             dot ::= [^\x0A\x0D] | ||||||
|             root ::= "\"" ("(" root-1{1,3} ")")? root-1{3,3} "-" root-1{4,4} " " "a"{3,5} "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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -466,9 +466,9 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
| @@ -486,9 +486,9 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             root ::= "{" space  (a-kv )? "}" space |             root ::= "{" space  (a-kv )? "}" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
| @@ -510,9 +510,9 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
| @@ -534,11 +534,11 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\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 | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
| @@ -554,12 +554,12 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             decimal-part ::= [0-9]{1,16} |             decimal-part ::= [0-9]{1,16} | ||||||
|             integral-part ::= [0] | [1-9] [0-9]{0,15} |             integral-part ::= [0] | [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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
| @@ -574,14 +574,14 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             decimal-part ::= [0-9]{1,16} |             decimal-part ::= [0-9]{1,16} | ||||||
|             integral-part ::= [0] | [1-9] [0-9]{0,15} |             integral-part ::= [0] | [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 | ||||||
|             root ::= object |             root ::= object | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|             value ::= object | array | string | number | boolean | null |             value ::= object | array | string | number | boolean | null | ||||||
|         )""" |         )""" | ||||||
| @@ -596,14 +596,14 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             decimal-part ::= [0-9]{1,16} |             decimal-part ::= [0-9]{1,16} | ||||||
|             integral-part ::= [0] | [1-9] [0-9]{0,15} |             integral-part ::= [0] | [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 | ||||||
|             root ::= object |             root ::= object | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|             value ::= object | array | string | number | boolean | null |             value ::= object | array | string | number | boolean | null | ||||||
|         )""" |         )""" | ||||||
| @@ -618,7 +618,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|         })""", |         })""", | ||||||
|         R"""( |         R"""( | ||||||
|             root ::= "{" space  "}" space |             root ::= "{" space  "}" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -637,12 +637,12 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             decimal-part ::= [0-9]{1,16} |             decimal-part ::= [0-9]{1,16} | ||||||
|             integral-part ::= [0] | [1-9] [0-9]{0,15} |             integral-part ::= [0] | [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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
| @@ -662,12 +662,12 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             decimal-part ::= [0-9]{1,16} |             decimal-part ::= [0-9]{1,16} | ||||||
|             integral-part ::= [0] | [1-9] [0-9]{0,15} |             integral-part ::= [0] | [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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
| @@ -690,12 +690,12 @@ 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]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4}) | ||||||
|             decimal-part ::= [0-9]{1,16} |             decimal-part ::= [0-9]{1,16} | ||||||
|             integral-part ::= [0] | [1-9] [0-9]{0,15} |             integral-part ::= [0] | [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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
| @@ -721,11 +721,11 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|             } |             } | ||||||
|         })""", |         })""", | ||||||
|         R"""( |         R"""( | ||||||
|             char ::= [^"\\] | "\\" (["\\/bfnrt] | "u" [0-9a-fA-F]{4}) |             char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\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 | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|             string ::= "\"" char* "\"" space |             string ::= "\"" char* "\"" space | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
| @@ -759,7 +759,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|             integral-part ::= [0] | [1-9] [0-9]{0,15} |             integral-part ::= [0] | [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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -803,7 +803,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|             integral-part ::= [0] | [1-9] [0-9]{0,15} |             integral-part ::= [0] | [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 ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
| @@ -851,7 +851,7 @@ static void test_all(const std::string & lang, std::function<void(const TestCase | |||||||
|             number-number-kv ::= "\"number\"" space ":" space number-number |             number-number-kv ::= "\"number\"" space ":" space number-number | ||||||
|             number-number-root-kv ::= "\"root\"" space ":" space number |             number-number-root-kv ::= "\"root\"" space ":" space number | ||||||
|             root ::= "{" space number-kv "}" space |             root ::= "{" space number-kv "}" space | ||||||
|             space ::= " "? |             space ::= | " " | "\n" [ \t]{0,20} | ||||||
|         )""" |         )""" | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 ochafik
					ochafik