From 4d6bb842d07230e71487f0c9439db32887cb7b98 Mon Sep 17 00:00:00 2001 From: devkabiir Date: Thu, 18 Apr 2019 00:44:13 +0530 Subject: [PATCH 01/65] =?UTF-8?q?=F0=9F=9A=A7wip=20(repo)=20fix=20type=20c?= =?UTF-8?q?asting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + analysis_options.yaml | 4 +- example/simple_arith.dart | 26 +- lib/parsers.dart | 122 +++- pubspec.yaml | 6 +- test/parsers_test.dart | 1269 ++++++++++++++++++----------------- test/src/parsers_model.dart | 18 +- 7 files changed, 765 insertions(+), 681 deletions(-) diff --git a/.gitignore b/.gitignore index 155a051..eaa784c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ doc/gen doc/tutorial/bin/packages .idea/ .packages +.dart_tool diff --git a/analysis_options.yaml b/analysis_options.yaml index 518eb90..400546c 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,2 +1,4 @@ analyzer: - strong-mode: true \ No newline at end of file + strong-mode: + implicit-casts: false + implicit-dynamic: true diff --git a/example/simple_arith.dart b/example/simple_arith.dart index b3d400e..37b2902 100644 --- a/example/simple_arith.dart +++ b/example/simple_arith.dart @@ -8,12 +8,11 @@ library simple_arith; import 'package:parsers/parsers.dart'; class Arith { - // Some combinators: functions that take parsers and return a parser. lexeme(parser) => parser < spaces; - token(str) => lexeme(string(str)); - parens(parser) => token('(') + parser + token(')') ^ (a,b,c) => b; + token(str) => lexeme(string(str as String)); + parens(parser) => token('(') + parser + token(')') ^ (a, b, c) => b; // The axiom of the grammar is an expression followed by end of file. @@ -21,24 +20,23 @@ class Arith { // We define some lexemes. - get comma => token(','); - get times => token('*'); - get plus => token('+'); + get comma => token(','); + get times => token('*'); + get plus => token('+'); get number => (lexeme(digit.many1) ^ digits2int) % 'natural number'; // This is the gist of the grammar, the BNF-like rules. - expr() => rec(mult).sepBy1(plus) ^ sum; - mult() => rec(atom).sepBy1(times) ^ prod; - atom() => number - | parens(rec(expr)); + expr() => rec(mult as Parser Function()).sepBy1(plus as Parser) ^ sum; + mult() => rec(atom as Parser Function()).sepBy1(times as Parser) ^ prod; + atom() => number | parens(rec(expr as Parser Function())); // These are simple Dart functions used as "actions" above to transform the // results of intermediate parsing steps. - digits2int(digits) => int.parse(digits.join()); - prod(xs) => xs.fold(1, (a,b) => a * b); - sum(xs) => xs.fold(0, (a,b) => a + b); + digits2int(digits) => int.parse((digits as Iterable).join()); + prod(xs) => xs.fold(1, (a, b) => a * b); + sum(xs) => xs.fold(0, (a, b) => a + b); } main() { @@ -48,7 +46,7 @@ main() { final bad = "1 * x + 2"; try { new Arith().start.parse(bad); - } catch(e) { + } catch (e) { print('parsing of 1 * x + 2 failed as expected: "$e"'); } } diff --git a/lib/parsers.dart b/lib/parsers.dart index eb70f0d..659f46d 100644 --- a/lib/parsers.dart +++ b/lib/parsers.dart @@ -7,10 +7,56 @@ library parsers; -import 'package:persistent/persistent.dart'; - part 'src/accumulators.dart'; +class Option { + final T _value; + final bool isDefined; + + const Option._internal(this.isDefined, this._value); + + factory Option.none() => const Option._internal(false, null); + + factory Option.some(T value) => new Option._internal(true, value); + + factory Option.fromNullable(T nullableValue) => nullableValue == null + ? new Option.none() + : new Option.some(nullableValue); + + T get value { + if (isDefined) return _value; + throw new StateError('Option.none() has no value'); + } + + T get asNullable => isDefined ? _value : null; + + T orElse(T defaultValue) => isDefined ? _value : defaultValue; + + T orElseCompute(T defaultValue()) => isDefined ? _value : defaultValue(); + + /// [:forall U, Option map(U f(T value)):] + Option map(f(T value)) => isDefined ? new Option.some(f(_value)) : this; + + /// [:forall U, Option map(Option f(T value)):] + Option expand(Option f(T value)) => isDefined ? f(_value) : this; + + /// Precondition: [:this is Option