{"id":13550759,"url":"https://github.com/mezoni/parser_builder","last_synced_at":"2025-05-06T11:31:33.466Z","repository":{"id":61975115,"uuid":"451143914","full_name":"mezoni/parser_builder","owner":"mezoni","description":"Lightweight template-based parser build system. Simple prototyping. Comfortable debugging. Effective developing.","archived":false,"fork":false,"pushed_at":"2022-06-08T15:11:06.000Z","size":1172,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-31T08:43:28.239Z","etag":null,"topics":["dart","parser","parser-combinator","parser-combinators","parser-framework"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mezoni.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-23T15:20:18.000Z","updated_at":"2024-05-10T03:39:26.000Z","dependencies_parsed_at":"2022-10-24T13:45:35.471Z","dependency_job_id":null,"html_url":"https://github.com/mezoni/parser_builder","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mezoni%2Fparser_builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mezoni%2Fparser_builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mezoni%2Fparser_builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mezoni%2Fparser_builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mezoni","download_url":"https://codeload.github.com/mezoni/parser_builder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224500029,"owners_count":17321622,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","parser","parser-combinator","parser-combinators","parser-framework"],"created_at":"2024-08-01T12:01:37.235Z","updated_at":"2024-11-13T18:18:20.444Z","avatar_url":"https://github.com/mezoni.png","language":"Dart","funding_links":[],"categories":["Dart"],"sub_categories":[],"readme":"# parser_builder\n\nLightweight template-based parser build system. Simple prototyping. Comfortable debugging. Effective developing.\n\nVersion: 2.0.34\n\nIt is under development (not all built-in common buildres are implemented but can be used without them), but you can already play around.  \n\nAt the moment, the implementation of useful built-in common parser builders is underway.\n\nThe build system is already implemented and ready to use and you can try it out in action. Rewrite your existing parser and feel the difference!  \nThe generated combinations of parsers are very small and very efficient.  \nAsk questions if something is not clear.  \n\n## Advantage\n\n- `Very simple and clear` build and code generation system\n- `Templates-based` (visually intuitive) definition of parser builders\n- Parser declaration based on `combinations of parsers`\n- Allows to build parsers to `parse any kind of data` (binary data, tokens, etc.)\n- Support for generating parsers `into functions or into statements` (inlined parser code)\n- The performance of the generated parsers is `quite high`\n- The generated parsers `does not wrap the values` of the parse results\n- The parser builder generates `fully strongly typed` parsers\n- Small size of the embedded `runtime code (about 6 Kb)` to support the work of the parser\n- The size of generated parser rules `starts from 350 bytes` (without runtime code)\n- The generated source code of the parsers is `human-friendly` as if you wrote it by hand\n- Very `handy debugging` and setting breakpoints to any place of parsing\n- An `elegant way to implement your own tracing` which can easily be turned off\n- Very `flexible error handling` system\n- Built-in `error preprocessing` procedures (grouping and flattening errors)\n- `Fully customizable` (according to your needs) error reporting procedures\n- Error messages `can be easily localized` (translated into another language) before being output\n- Includes high-performance, most common `built-in parser builders`\n- Includes built-in parser builders `to simplify parsing expressions`\n- Includes built-in parser builder `for lightweight (on demand) memoization`\n- Support for `32 bit Unicode characters` out of the box (no need to worry about that)\n- Included built-in simple script for `fast building of parsers`\n\n## Projects using parser builder\n\n- [fast_csv](https://pub.dev/packages/fast_csv)\n- [fast_json](https://pub.dev/packages/fast_json)\n\n## Included parser builders\n\nbuilt-in:\n- [`Named`](https://github.com/mezoni/parser_builder/blob/master/lib/src/parser_builder/named.dart)\n- [`Ref`](https://github.com/mezoni/parser_builder/blob/master/lib/src/parser_builder/ref.dart)\n\n[`branch`](https://github.com/mezoni/parser_builder/blob/master/lib/src/branch):\n- [`Alt`](https://github.com/mezoni/parser_builder/blob/master/lib/src/branch/alt.dart)\n- [`Alt2..Alt7`](https://github.com/mezoni/parser_builder/blob/master/lib/src/branch/alt.dart)\n\n[`bytes`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes):\n- [`NoneOfTags`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/none_of_tags.dart)\n- [`SkipWhile`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/skip_while.dart)\n- [`SkipWhile1`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/skip_while1.dart)\n- [`Tag`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/tag.dart)\n- [`TagNoCase`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/tag_no_case.dart)\n- [`TagOf`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/tag_of.dart)\n- [`Tags`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/tags.dart)\n- [`TagValues`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/tag_values.dart)\n- [`TakeUntil`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/take_until.dart)\n- [`TakeUntil1`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/take_until1.dart)\n- [`TakeWhile`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/take_while.dart)\n- [`TakeWhile1`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/take_while1.dart)\n- [`TakeWhileMN`](https://github.com/mezoni/parser_builder/blob/master/lib/src/bytes/take_while_m_n.dart)\n\n[`character`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character):\n- [`Alpha0`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/alpha0.dart)\n- [`Alpha1`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/alpha1.dart)\n- [`Alphanumeric0`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/alphanumeric0.dart)\n- [`Alphanumeric1`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/alphanumeric1.dart)\n- [`AnyChar`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/any_char.dart)\n- [`Char`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/char.dart)\n- [`Digit0`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/digit0.dart)\n- [`Digit1`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/digit1.dart)\n- [`HexDigit0`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/hex_digit0.dart)\n- [`HexDigit1`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/hex_digit1.dart)\n- [`NoneOf`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/none_of.dart)\n- [`NoneOfOf`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/none_of_of.dart)\n- [`OneOf`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/one_of.dart)\n- [`Satisfy`](https://github.com/mezoni/parser_builder/blob/master/lib/src/character/satisfy.dart)\n\n[`combinator`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator):\n- [`And`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator/and.dart) (not tested yet)\n- [`Calculate`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator/calculate.dart) (not tested yet)\n- [`Consumed`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator/consumed.dart)\n- [`Eof`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator/eof.dart)\n- [`Fast`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator/fast.dart)\n- [`Map1`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator/map1.dart)\n- [`Not`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator/not.dart)\n- [`Opt`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator/opt.dart)\n- [`Peek`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator/peek.dart)\n- [`Recognize`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator/recognize.dart)\n- [`Value`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator/value.dart)\n- [`Verify`](https://github.com/mezoni/parser_builder/blob/master/lib/src/combinator/verify.dart)\n\n[`error`](https://github.com/mezoni/parser_builder/blob/master/lib/src/error):\n- [`Expected`](https://github.com/mezoni/parser_builder/blob/master/lib/src/error/expected.dart)\n- [`Nested`](https://github.com/mezoni/parser_builder/blob/master/lib/src/error/nested.dart)\n\n[`expression`](https://github.com/mezoni/parser_builder/blob/master/lib/src/expression):\n- [`BinaryExpression`](https://github.com/mezoni/parser_builder/blob/master/lib/src/expression/binary_expression.dart)\n- [`IdentifierExpression`](https://github.com/mezoni/parser_builder/blob/master/lib/src/expression/identifier_expression.dart)\n- [`PostfixExpression`](https://github.com/mezoni/parser_builder/blob/master/lib/src/expression/postfix_expression.dart)\n- [`PrefixExpression`](https://github.com/mezoni/parser_builder/blob/master/lib/src/expression/prefix_expression.dart)\n\n[`memoization`](https://github.com/mezoni/parser_builder/blob/master/lib/src/memoization):\n- [`Memoize`](https://github.com/mezoni/parser_builder/blob/master/lib/src/memoization/memoize.dart)\n\n[`multi`](https://github.com/mezoni/parser_builder/blob/master/lib/src/multi):\n- [`FoldMany0`](https://github.com/mezoni/parser_builder/blob/master/lib/src/multi/fold_many0.dart)\n- `FoldMany1` (not implenented yet)\n- [`Many0`](https://github.com/mezoni/parser_builder/blob/master/lib/src/multi/many0.dart)\n- [`Many0Count`](https://github.com/mezoni/parser_builder/blob/master/lib/src/multi/many0_count.dart)\n- [`Many1`](https://github.com/mezoni/parser_builder/blob/master/lib/src/multi/many1.dart)\n- [`Many1Count`](https://github.com/mezoni/parser_builder/blob/master/lib/src/multi/many1_count.dart)\n- [`ManyMN`](https://github.com/mezoni/parser_builder/blob/master/lib/src/multi/many_m_n.dart)\n- [`ManyN`](https://github.com/mezoni/parser_builder/blob/master/lib/src/multi/many_n.dart)\n- [`ManyTill`](https://github.com/mezoni/parser_builder/blob/master/lib/src/multi/many_till.dart)\n- [`SeparatedList0`](https://github.com/mezoni/parser_builder/blob/master/lib/src/multi/separated_list0.dart)\n- [`SeparatedList1`](https://github.com/mezoni/parser_builder/blob/master/lib/src/multi/separated_list1.dart)\n- [`SeparatedListN`](https://github.com/mezoni/parser_builder/blob/master/lib/src/multi/separated_list_n.dart)\n\n[`sequence`](https://github.com/mezoni/parser_builder/blob/master/lib/src/sequence):\n- [`Delimited`](https://github.com/mezoni/parser_builder/blob/master/lib/src/sequence/delimited.dart)\n- [`Map2..Map7`](https://github.com/mezoni/parser_builder/blob/master/lib/src/sequence/map.dart)\n- [`Pair`](https://github.com/mezoni/parser_builder/blob/master/lib/src/sequence/pair.dart)\n- [`Preceded`](https://github.com/mezoni/parser_builder/blob/master/lib/src/sequence/preceded.dart)\n- [`SeparatedPair`](https://github.com/mezoni/parser_builder/blob/master/lib/src/sequence/separated_pair.dart)\n- [`SkipMany0`](https://github.com/mezoni/parser_builder/blob/master/lib/src/sequence/skip_many0.dart)\n- [`Terminated`](https://github.com/mezoni/parser_builder/blob/master/lib/src/sequence/terminated.dart)\n- [`Tuple1..Tuple7`](https://github.com/mezoni/parser_builder/blob/master/lib/src/sequence/tuple.dart)\n\n[`string`](https://github.com/mezoni/parser_builder/blob/master/lib/src/string):\n- [`EscapeSequence`](https://github.com/mezoni/parser_builder/blob/master/lib/src/string/escape_sequence.dart)\n- [`StringValue`](https://github.com/mezoni/parser_builder/blob/master/lib/src/string/string_value.dart)\n\n## Built-in semantic actions\n\n- [`ExpressionAction`](https://github.com/mezoni/parser_builder/blob/master/lib/src/parser_builder/semantic_action.dart)\n- [`FunctionAction`](https://github.com/mezoni/parser_builder/blob/master/lib/src/parser_builder/semantic_action.dart)\n- [`VariableAction`](https://github.com/mezoni/parser_builder/blob/master/lib/src/parser_builder/semantic_action.dart)\n\n## Character class (additional semantic actions for character ranges)\n\n- [`CharClass`](https://github.com/mezoni/parser_builder/blob/master/lib/src/transformers/char_class.dart)\n- [`CharClasses`](https://github.com/mezoni/parser_builder/blob/master/lib/src/transformers/char_classes.dart)\n- [`NotCharClass`](https://github.com/mezoni/parser_builder/blob/master/lib/src/transformers/not_char_class.dart)\n\n## How to start write your parser?\n\nTake look  at this very simple example of hex color parser builder:\n\n```dart\nimport 'package:parser_builder/bytes.dart';\nimport 'package:parser_builder/char_class.dart';\nimport 'package:parser_builder/combinator.dart';\nimport 'package:parser_builder/error.dart';\nimport 'package:parser_builder/fast_build.dart';\nimport 'package:parser_builder/parser_builder.dart';\nimport 'package:parser_builder/sequence.dart';\n\nimport 'hex_color_parser_helper.dart';\n\nFuture\u003cvoid\u003e main(List\u003cString\u003e args) async {\n  final context = Context();\n  final filename = 'example/hex_color_parser.g.dart';\n  await fastBuild(context, [_parse], filename,\n      partOf: 'hex_color_parser.dart', publish: {'parse': _parse});\n}\n\nconst _hexColor = Named(\n    '_hexColor',\n    Nested(\n        'hexadecimal color',\n        Preceded(\n            Tag('#'),\n            Indicate(\n                'A hexadecimal color starting with \"#\" must be followed by 6 hexadecimal digits',\n                Map3(\n                    _hexPrimary,\n                    _hexPrimary,\n                    _hexPrimary,\n                    ExpressionAction\u003cColor\u003e(\n                        ['r', 'g', 'b'], 'Color({{r}}, {{g}}, {{b}})'))))));\n\nconst _hexPrimary = Named(\n    '_hexPrimary',\n    Map1(TakeWhileMN(2, 2, CharClass('[0-9A-Fa-f]')),\n        ExpressionAction\u003cint\u003e(['x'], 'int.parse({{x}}, radix: 16)')));\n\nconst _parse = Named('_parse', _hexColor);\n\n```\n\nFunction `fastBuild` performs the following operations:  \n- Building specified parsers\n- Combining of the parser code from different parts (header + code + footer)\n- Write code to file\n- Code formatting\n\nThe rest of the code includes the following elements:  \n- Parser combintors declarations\n\nThe generated source code can be found here:  \nhttps://github.com/mezoni/parser_builder/blob/master/example/hex_color_parser.g.dart\n\nTo get started, you may to copy 3 files:  \nhttps://github.com/mezoni/parser_builder/blob/master/example/hex_color_parser_builder.dart  \nhttps://github.com/mezoni/parser_builder/blob/master/example/hex_color_parser_helper.dart  \nhttps://github.com/mezoni/parser_builder/blob/master/example/hex_color_parser.dart  \n\nRename them as you need.  \nThe file `hex_color_parser_builder.dart` is parser builder script. Place it in the \"tool\" directory.  \nThis is where you will declare and build your parser.\n\nThe file `hex_color_parser.dart` is parser script. This will be the public part of your parser.  \nYou can modify it as you wish.\n\nThe file `hex_color_parser_helper.dart` is parser dependency script (as an example).  \nThis file is not particularly required, but for convenience, you can place various functions and data structures in it, which can be referenced from the builder (the data that the parser needs). This data does not have to be in this file.\n\nThe file `hex_color_parser.g.dart` is generated by your parser builder.\n\nWhen static metaprogramming appears in Dart, then some of these operations will not have to be performed and parsers will be generated on the fly, through just one macro annotation.  \nWell, of course, you will have to write a small macro for building (with code like in the `main` function).\n\n## Example of parser declaration\n\n```dart\nconst _comma = Terminated(Tag(','), _ws);\n\nconst _eof = Eof\u003cString\u003e();\n\nconst _escaped = Named('_escaped', Alt2(_escapeSeq, _escapeHex));\n\nconst _escapeHex = Named\u003cString, int\u003e(\n    '_escapeHex',\n    Map3(\n        PosToVal('start'),\n        Fast(Satisfy(CharClass('[u]'))),\n        HandleLastErrorPos\u003cString, String\u003e(\n          Alt2(\n            TakeWhileMN(4, 4, CharClass('[0-9a-fA-F]')),\n            FailMessage(\n                StatePos.lastErrorPos,\n                \"An escape sequence starting with '\\\\u' must be followed by 4 hexadecimal digits\",\n                '{{start|value}}',\n                StatePos.lastErrorPos),\n          ),\n        ),\n        ExpressionAction\u003cint\u003e(['s'], '_toHexValue({{s}})')),\n    [_inline]);\n\nconst _escapeSeq = EscapeSequence({\n  0x22: 0x22,\n  0x2f: 0x2f,\n  0x5c: 0x5c,\n  0x62: 0x08,\n  0x66: 0x0c,\n  0x6e: 0x0a,\n  0x72: 0x0d,\n  0x74: 0x09\n});\n\nconst _false = Named('_false', Value(false, Tag('false')));\n\nconst _inline = '@pragma(\\'vm:prefer-inline\\')';\n\n```\n\n## Example of generated code\n\n```dart\nColor? _hexColor(State\u003cString\u003e state) {\n  Color? $0;\n  final source = state.source;\n  final $pos = state.minErrorPos;\n  state.minErrorPos = state.pos + 1;\n  final $pos1 = state.pos;\n  state.ok = state.pos \u003c source.length \u0026\u0026 source.codeUnitAt(state.pos) == 35;\n  if (state.ok) {\n    state.pos += 1;\n  } else {\n    state.fail(state.pos, ParseError.expected, '#');\n  }\n  if (state.ok) {\n    final $pos2 = state.start;\n    state.start = state.pos;\n    final $pos3 = state.setLastErrorPos(-1);\n    final $pos4 = state.pos;\n    int? $1;\n    $1 = _hexPrimary(state);\n    if (state.ok) {\n      int? $2;\n      $2 = _hexPrimary(state);\n      if (state.ok) {\n        int? $3;\n        $3 = _hexPrimary(state);\n        if (state.ok) {\n          final v1 = $1!;\n          final v2 = $2!;\n          final v3 = $3!;\n          $0 = Color(v1, v2, v3);\n        }\n      }\n    }\n    if (!state.ok) {\n      state.pos = $pos4;\n    }\n    if (!state.ok) {\n      state.ok = false;\n      state.fail(\n          state.lastErrorPos,\n          ParseError.message,\n          'A hexadecimal color starting with \"#\" must be followed by 6 hexadecimal digits',\n          state.start);\n    }\n    state.restoreLastErrorPos($pos3);\n    state.start = $pos2;\n    if (!state.ok) {\n      state.pos = $pos1;\n    }\n  }\n  state.minErrorPos = $pos;\n  if (!state.ok) {\n    state.ok = false;\n    state.fail(state.pos, ParseError.expected, 'hexadecimal color');\n  }\n  return $0;\n}\n\n```\n\nThis code was generated from this declaration:\n\n```dart\nconst _hexColor = Named(\n    '_hexColor',\n    Nested(\n        'hexadecimal color',\n        Preceded(\n            Tag('#'),\n            Indicate(\n                'A hexadecimal color starting with \"#\" must be followed by 6 hexadecimal digits',\n                Map3(\n                    _hexPrimary,\n                    _hexPrimary,\n                    _hexPrimary,\n                    ExpressionAction\u003cColor\u003e(\n                        ['r', 'g', 'b'], 'Color({{r}}, {{g}}, {{b}})'))))));\n\n```\n\n## Inlining code example\n\nDeclaration of `_json` parser.\n\n\n```dart\nconst _eof = Eof();\n\nconst _json = Named('_json', Delimited(_ws, _value, _eof));\n```\n\nThe `Eof` parser was inlined because it was not named.  \nInlined means that it was generated without a function declaration for it (only as statements).\n\n```dart\ndynamic _json(State\u003cString\u003e state) {\n  dynamic $0;\n  final source = state.source;\n  final $pos = state.pos;\n  _ws(state);\n  if (state.ok) {\n    $0 = _value(state);\n    if (state.ok) {\n      state.ok = state.pos \u003e= source.length;\n      if (!state.ok) {\n        state.fail(state.pos, ParseError.expected, 'EOF');\n      }\n    }\n    if (!state.ok) {\n      $0 = null;\n      state.pos = $pos;\n    }\n  }\n  return $0;\n}\n\n```\n\nThis code was generated from this declaration:\n\n```dart\nconst _json = Named\u003cString, dynamic\u003e('_json', Delimited(_ws, _value, _eof));\n```\n\n## How to declare a parser builder\n\nDeclaring your own parser builder (if required) is very simple. The process is very simple.  \nLet's take a look at an existing parser builder and assume it doesn't exist and you need to create one just like it.  \nThis is an implementation of the well-known parsing expression called `optional` (aka `?`).\n\n```dart\npart of '../../combinator.dart';\n\nclass Opt\u003cI, O\u003e extends ParserBuilder\u003cI, O?\u003e {\n  static const _template = '''\n{{p1}}\nif (!state.ok) {\n  state.ok = true;\n}''';\n\n  final ParserBuilder\u003cI, O\u003e parser;\n\n  const Opt(this.parser);\n\n  @override\n  String build(Context context, ParserResult? result) {\n    final values = {\n      'p1': parser.build(context, result),\n    };\n    return render(_template, values);\n  }\n}\n\n```\n\nAn updated version of this section will be added later...\n\n## Performance\n\nCurrent performance of the generated JSON parser.  \n\nThe performance is about 1.10-1.17 times lower than that of a hand-written high-quality specialized state machine based JSON parser from the Dart SDK.\n\nBetter results in many cases are obtained in AOT mode. If the Dart SDK compiler had made more efficient use placement of (short lifetime) local variables in registers, the results could have been slightly better. At the moment, the generated parser code is not optimized for using machine registers, because performance tests, unfortunately, do not show a gain from this kind of optimization.\n\nAOT mode:\n\n```\nParse 50 times: E:\\prj\\test_json\\bin\\data\\canada.json (2251.05 Kb)\nDart SDK JSON : k: 2.14, 41.12 MB/s, 2610.1430 ms (100.00%),\nSimple JSON NEW 1: k: 1.00, 87.92 MB/s, 1220.8190 ms (46.77%),\n\nParse 50 times: E:\\prj\\test_json\\bin\\data\\citm_catalog.json (1727.03 Kb)\nDart SDK JSON : k: 1.00, 88.31 MB/s, 932.4810 ms (85.68%),\nSimple JSON NEW 1: k: 1.17, 75.67 MB/s, 1088.3250 ms (100.00%),\n\nParse 50 times: E:\\prj\\test_json\\bin\\data\\twitter.json (567.93 Kb)\nDart SDK JSON : k: 1.00, 58.00 MB/s, 466.9370 ms (86.75%),\nSimple JSON NEW 1: k: 1.15, 50.31 MB/s, 538.2810 ms (100.00%),\n\nOS: Microsoft Windows 7 Ultimate 6.1.7601\nKernel: Windows_NT 6.1.7601\nProcessor (4 core) Intel(R) Core(TM) i5-3450 CPU @ 3.10GHz\n```\n\nJIT mode:\n\n```\nParse 50 times: E:\\prj\\test_json\\bin\\data\\canada.json (2251.05 Kb)\nDart SDK JSON : k: 3.23, 49.09 MB/s, 2186.4390 ms (100.00%),\nSimple JSON NEW 1: k: 1.00, 158.81 MB/s, 675.8890 ms (30.91%),\n\nParse 50 times: E:\\prj\\test_json\\bin\\data\\citm_catalog.json (1727.03 Kb)\nDart SDK JSON : k: 1.00, 107.11 MB/s, 768.8210 ms (86.74%),\nSimple JSON NEW 1: k: 1.15, 92.91 MB/s, 886.3120 ms (100.00%),\n\nParse 50 times: E:\\prj\\test_json\\bin\\data\\twitter.json (567.93 Kb)\nDart SDK JSON : k: 1.00, 65.10 MB/s, 416.0140 ms (91.71%),\nSimple JSON NEW 1: k: 1.09, 59.70 MB/s, 453.6420 ms (100.00%),\n\nOS: Microsoft Windows 7 Ultimate 6.1.7601\nKernel: Windows_NT 6.1.7601\nProcessor (4 core) Intel(R) Core(TM) i5-3450 CPU @ 3.10GHz\n```\n\nThe data for the test is taken from here:\nhttps://github.com/serde-rs/json-benchmark/tree/master/data\n\n\nThere is a reasonable explanation for this: this is a combinators of universal parsers. It will always be slower than a specialized parser written by hand.  \nBecause the redundancy that exists in parser combinators cannot be eliminated when generating code.  \nThe same redundancy allows you to use combinators to parse any type of data, not just text. For the same reason, they are slightly less efficient at parsing text.\n\nBut there are still advantages. This is a high development speed and quite informative error messages.\n\nThe advantages over parsers that are limited only by notation are obvious. You can implement everything that such parsers support, and everything else that you need can simply be added.  \nBut parsers using the notation can have the advantage that they can greatly optimize the generated code.  \n\nBut at the same time, nothing prevents the programmer from writing sub parsers manually for those parsing places where performance is very critical. And again, this has its share of advantages of combined parsers. Add a little bit of your own code and your parser is already much faster.  \nBasically, this concerns the parsing of complex structures with specific data formats (strings, numbers, and so on).  \nThe fastest parser for them is the state machine. It can and should be created manually and/or using third-party tools. And it will be only some part of the whole parser.  \n\nIf I had a lot of free time, then I could probably write a code-first generator of small state machines for quickly parsing data of various formats. For example, to write lexers or sub parsers.\n\n## More info...\n\nTo be continued...\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmezoni%2Fparser_builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmezoni%2Fparser_builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmezoni%2Fparser_builder/lists"}