Parser tool is a real-time compiler and runtime engine for strongly typed PEG parsers

Overview

parser_tool

Version 0.1.1 (BETA)

Parser tool is a real-time compiler and runtime engine for strongly typed PEG parsers.

Parser tool contains libraries that allow you to create strongly typed PEG parsers. The tool contains a compiler that compiles a parser in real time and an engine to execute the compiled parsers.

Advantages

  • Strongly typed parsers
  • Sufficiently high performance
  • Allows you to debug the parser through tracing support with information about the parsing progress
  • Expression notations are available during debugging
  • Allows you to print out grammar

Disvantages

  • Not as fast parsers as compared to parsers that compile directly into source code
  • The debugging process is not so clear and convenient

Planned features

  • Adding a semantic predicate

Example

import 'package:parser_tool/grammar.dart';
import 'package:parser_tool/grammar_builder.dart';
import 'package:parser_tool/grammar_compiler.dart';
import 'package:parser_tool/grammar_heplers.dart';

import '_parse_number.dart';

export 'package:parser_tool/parse.dart';

void main() {
  final text = '''
{"rocket": "๐Ÿš€ flies to the stars"}
''';
  final state = ParseState(text);
  final result = parser.parse(state);
  if (result == null) {
    throw state.buildError();
  }

  print(result.value);
}

final grammar = buildGrammar();

final Parser parser = compileGrammar(grammar);

Grammar buildGrammar() {
  // Nonterminals
  final array = Nonterminal<List>('array');
  final json = Nonterminal('json');
  final member = Nonterminal<MapEntry<String, dynamic>>('member');
  final members = Nonterminal<List<MapEntry<String, dynamic>>>('members');
  final object = Nonterminal<Map<String, dynamic>>('object');
  final value = Nonterminal('value');
  final values = Nonterminal<List>('values');

  // Terminals
  final $comma = Terminal(',');
  final $eof = Terminal('end of file');
  final $false = Terminal<bool>('false');
  final $leadingSpaces = Terminal('leading spaces');
  final $lbrace = Terminal('{');
  final $lbracket = Terminal('[');
  final $number = Terminal<num>('number');
  final $null = Terminal('null');
  final $rbrace = Terminal('}');
  final $rbracket = Terminal(']');
  final $semicolon = Terminal(':');
  final $string = Terminal<String>('string');
  final $true = Terminal<bool>('true');

  // Subterminals
  final _char = Subterminal<int>('char');
  final _escaped = Subterminal<int>('escaped');
  final _hexdig = Subterminal<int>('hexdig');
  final _hexdig4 = Subterminal<int>('hexdig4');
  final _unescaped = Subterminal<int>('unescaped');
  final _ws = Subterminal('ws');

  // Nonterminals
  array << seqm([$lbracket], values.opt, [$rbracket]).map((r) => r ?? []);

  json << seqm([$leadingSpaces], value, [$eof]);

  member <<
      seqfl($string, [$semicolon], value).map((r) => MapEntry(r.$1, r.$2));

  members << repsep(member, $comma);

  object <<
      seqm([$lbrace], members.opt, [$rbrace])
          .map((r) => {}..addEntries(r ?? []));

  value << object;
  value << array;
  value << $string;
  value << $number;
  value << $true;
  value << $false;
  value << $null;

  values << repsep(value, $comma);

  // Terminals
  $comma << seq([literal(','), _ws]);

  $eof << not(any());

  $false << seqr([literal('false'), _ws], false);

  $lbrace << seq([literal('{'), _ws]);

  $leadingSpaces << _ws;

  $lbracket << seq([literal('['), _ws]);

  $null << seqr([literal('null'), _ws], null);

  final zero = '0'.r;
  final digit = '0-9'.r;
  final minus = '-'.r;
  final integer = alt<dynamic>([
    zero,
    seq(['1-9'.r, digit.star])
  ]);
  final frac = seq(['.'.r, digit.plus]);
  final exp = seq(['eE'.r, '+-'.r.opt, digit.plus]);

  $number <<
      seqf(cap(seq([minus.opt, integer, frac.opt, exp.opt])), [_ws])
          .map(parseNumber);

  $rbrace << seq([literal('}'), _ws]);

  $rbracket << seq([literal(']'), _ws]);

  $semicolon << seq([literal(':'), _ws]);

  $string <<
      seqm([literal('"')], _char.star, [literal('"'), _ws])
          .map((r) => String.fromCharCodes(r));

  $true << seqr([literal('true'), _ws], true);

  // Subterminals
  _char << _unescaped;
  _char << seql([r'\\'.r], _escaped);

  _escaped << r'\u22\u2f\u5c'.r;
  _escaped << seqr(['b'.r], 0x08);
  _escaped << seqr(['f'.r], 0x0c);
  _escaped << seqr(['n'.r], 0x0a);
  _escaped << seqr(['r'.r], 0x0d);
  _escaped << seqr(['t'.r], 0x09);
  _escaped << seqr(['v'.r], 0x0b);
  _escaped << seql(['u'.r], _hexdig4).map((r) => r);

  _hexdig << 'a-f'.r.map((c) => c - 97);
  _hexdig << 'A-F'.r.map((c) => c - 65);
  _hexdig << '0-9'.r.map((c) => c - 48);

  _hexdig4 <<
      seq4(_hexdig, _hexdig, _hexdig, _hexdig)
          .map((r) => r.$1 * 0xfff + r.$2 * 0xff + r.$3 * 0xf + r.$4);

  _unescaped << r'\u20-\u21\u23-\u5b\u5d-\u10ffff'.r;

  _ws << r' \n\r\t'.r.star;

  final builder = GrammarBuilder();
  return builder.build(json);
}

Parser<E> compileGrammar<E>(Grammar<E> grammar,
    [GrammarCompilerOptions options = const GrammarCompilerOptions()]) {
  final compiler = GrammarCompiler<E>(options);
  return compiler.compile(grammar);
}

To be continued...

You might also like...

A high-performance, web standards-compliant rendering engine based on Flutter.

A high-performance, web standards-compliant rendering engine based on Flutter.

A high-performance, web standards-compliant rendering engine based on Flutter.

Dec 30, 2022

Collects screen sizes and pixel densities for real iPhones, iPads, Google phones, Samsung phones, and more.

Collects screen sizes and pixel densities for real iPhones, iPads, Google phones, Samsung phones, and more.

Device Sizes This package aggregates screen sizes and pixel densities for as many physical devices as possible. The purpose of this package is to help

Jan 8, 2023

Converts SVG icons to OTF font and generates Flutter-compatible class. Provides an API and a CLI tool.

Fontify The Fontify package provides an easy way to convert SVG icons to OpenType font and generate Flutter-compatible class that contains identifiers

Oct 28, 2022

A cli tool to run Flutter applications and auto hot reload it when files are changed

Dashmon A minimalistic CLI tool to run Flutter applications and auto hot reload it when files are changed. It will watch changes your application code

Oct 6, 2022

A tool to easily install the Android SDK command-line and platform tools.

gibadb A tool to easily install the Android SDK command-line and platform tools. For developers: This README describes the CLI tool that ships with th

Sep 22, 2022

A code generation tool based on Database. :construction: developing :construction:

A code generation tool based on Database. :construction:  developing :construction:

dbgen A code generation tool based on Database. Getting Started This project is a starting point for a Flutter application. A few resources to get you

Jun 8, 2022

A CLI tool to help generate dart classes from json returned from API

Json 2 Dart Command line utility Important note There is already a package called json2dart so this package will be called json2dartc ! This project w

Oct 5, 2022

Command-line tool to provide null-safety percentage info of a project. Track your migration progress on mixed-version programs that execute with unsound null safety.

null_safety_percentage Command-line tool to provide null-safety percentage info of a project. Track your migration progress on mixed-version programs

Mar 27, 2022

A CLI tool to help batch renaming files.

batch_rename A CLI tool to enable batch renaming of files. Installation Clone the repo and add bin/batch_rename.exe to PATH: gh repo clone POWRFULCOW8

Nov 3, 2021
Owner
null
A Dart build script that downloads the Protobuf compiler and Dart plugin to streamline .proto to .dart compilation.

A Dart build script that downloads the Protobuf compiler and Dart plugin to streamline .proto to .dart compilation.

Julien Scholz 10 Oct 26, 2022
A collection of flutter and dart libraries allowing you to consume complex external forms at runtime.

flutter_dynamic_forms A collection of flutter and dart libraries providing a solution for Server Driven UI in your Flutter application. Package Pub ex

Ondล™ej Kunc 193 Dec 20, 2022
Easily swap Flutter web renderers at runtime

renderer_switcher Swap Web Renderers in a Flutter Web app at runtime. Installation To use this plugin, add renderer_switcher as a dependency in your p

Wilson Wilson 12 Oct 21, 2022
Open source SDK to quickly integrate subscriptions, stop worring about code maintenance, and getting advanced real-time data

Open source SDK to quickly integrate subscriptions, stop worring about code maintenance, and getting advanced real-time data. Javascript / iOS glue framework

glassfy 8 Oct 31, 2022
Args simple - A simple argument parser and handler, integrated with JSON and dart

args_simple A simple argument parser and handler, integrated with JSON and dart:

Graciliano Monteiro Passos 1 Jan 22, 2022
Dart phone number parser, based on libphonenumber and PhoneNumberKit.

Dart library for parsing phone numbers. Inspired by Google's libphonenumber and PhoneNumberKit for ios.

cedvdb 39 Dec 31, 2022
Dart phone number parser, based on libphonenumber and PhoneNumberKit.

Phone Numbers Parser Dart library for parsing phone numbers. Inspired by Google's libphonenumber and PhoneNumberKit for ios. The advantage of this lib

cedvdb 39 Dec 31, 2022
The Dart Time Machine is a date and time library for Flutter, Web, and Server with support for timezones, calendars, cultures, formatting and parsing.

The Dart Time Machine is a date and time library for Flutter, Web, and Server with support for timezones, calendars, cultures, formatting and parsing.

null 2 Oct 8, 2021
A Gura parser implementation for Dart

Gura Dart parser This repository contains the implementation of a Gura configuration format parser for Dart, written in pure Dart. (Compliant with spe

Zack Campbell 4 Aug 2, 2021
JSON API parser for Flutter

Flutter Japx - JSON:API Decoder/Encoder Lightweight [JSON:API][1] parser that flattens complex [JSON:API][1] structure and turns it into simple JSON a

Infinum 23 Dec 20, 2022