From c2c9e408360c234b9090df48d32b19d8bfe0970f Mon Sep 17 00:00:00 2001 From: "thomashii@dukefirehawk.com" Date: Fri, 7 May 2021 12:42:02 +0800 Subject: [PATCH] Updated combinator --- .../combinator/lib/src/combinator/cache.dart | 4 +-- .../combinator/lib/src/combinator/cast.dart | 4 +-- .../combinator/lib/src/combinator/chain.dart | 24 ++++++++------- .../combinator/lib/src/combinator/check.dart | 7 ++--- .../lib/src/combinator/combinator.dart | 6 ++-- .../lib/src/combinator/compare.dart | 4 +-- .../combinator/lib/src/combinator/index.dart | 2 +- .../lib/src/combinator/longest.dart | 13 ++++---- .../combinator/lib/src/combinator/match.dart | 8 ++--- .../lib/src/combinator/max_depth.dart | 2 +- .../combinator/lib/src/combinator/negate.dart | 4 +-- .../lib/src/combinator/recursion.dart | 6 ++-- .../combinator/lib/src/combinator/reduce.dart | 4 +-- .../lib/src/combinator/reference.dart | 9 +++--- .../combinator/lib/src/combinator/safe.dart | 5 ++-- .../lib/src/combinator/to_list.dart | 14 +++++---- .../combinator/lib/src/combinator/util.dart | 30 +++++++++---------- packages/combinator/test/common.dart | 2 +- packages/combinator/test/list_test.dart | 2 +- packages/combinator/test/misc_test.dart | 5 ++-- packages/combinator/test/recursion_test.dart | 6 ++-- 21 files changed, 82 insertions(+), 79 deletions(-) diff --git a/packages/combinator/lib/src/combinator/cache.dart b/packages/combinator/lib/src/combinator/cache.dart index f57569f0..b07b38e0 100644 --- a/packages/combinator/lib/src/combinator/cache.dart +++ b/packages/combinator/lib/src/combinator/cache.dart @@ -1,7 +1,7 @@ part of lex.src.combinator; class _Cache extends Parser { - final Map?> _cache = {}; + final Map> _cache = {}; final Parser parser; _Cache(this.parser); @@ -10,7 +10,7 @@ class _Cache extends Parser { ParseResult __parse(ParseArgs args) { return _cache.putIfAbsent(args.scanner.position, () { return parser._parse(args.increaseDepth()); - })!.change(parser: this); + }).change(parser: this); } @override diff --git a/packages/combinator/lib/src/combinator/cast.dart b/packages/combinator/lib/src/combinator/cast.dart index bc7280ad..9b531d43 100644 --- a/packages/combinator/lib/src/combinator/cast.dart +++ b/packages/combinator/lib/src/combinator/cast.dart @@ -8,7 +8,7 @@ class _Cast extends Parser { @override ParseResult __parse(ParseArgs args) { var result = parser._parse(args.increaseDepth()); - return new ParseResult( + return ParseResult( args.trampoline, args.scanner, this, @@ -39,7 +39,7 @@ class _CastDynamic extends Parser { @override ParseResult __parse(ParseArgs args) { var result = parser._parse(args.increaseDepth()); - return new ParseResult( + return ParseResult( args.trampoline, args.scanner, this, diff --git a/packages/combinator/lib/src/combinator/chain.dart b/packages/combinator/lib/src/combinator/chain.dart index 16af1658..c7d094aa 100644 --- a/packages/combinator/lib/src/combinator/chain.dart +++ b/packages/combinator/lib/src/combinator/chain.dart @@ -5,7 +5,7 @@ part of lex.src.combinator; /// If [failFast] is `true` (default), then the first failure to parse will abort the parse. ListParser chain(Iterable> parsers, {bool failFast: true, SyntaxErrorSeverity? severity}) { - return new _Chain( + return _Chain( parsers, failFast != false, severity ?? SyntaxErrorSeverity.error); } @@ -22,7 +22,7 @@ class _Alt extends Parser { return result.successful ? result : result.addErrors([ - new SyntaxError( + SyntaxError( severity, errorMessage, result.span ?? args.scanner.emptySpan), ]); } @@ -43,8 +43,8 @@ class _Chain extends ListParser { @override ParseResult> __parse(ParseArgs args) { var errors = []; - var results = []; - var spans = []; + var results = []; + var spans = []; bool successful = true; for (var parser in parsers) { @@ -54,32 +54,36 @@ class _Chain extends ListParser { if (parser is _Alt) errors.addAll(result.errors); if (failFast) { - return new ParseResult( + return ParseResult( args.trampoline, args.scanner, this, false, result.errors); } successful = false; } - results.add(result.value); + if (result.value != null) { + results.add(result.value!); + } - if (result.span != null) spans.add(result.span); + if (result.span != null) { + spans.add(result.span!); + } } FileSpan? span; if (spans.isNotEmpty) { - span = spans.reduce((a, b) => a!.expand(b!)); + span = spans.reduce((a, b) => a.expand(b)); } - return new ParseResult>( + return ParseResult>( args.trampoline, args.scanner, this, successful, errors, span: span, - value: new List.unmodifiable(results), + value: List.unmodifiable(results), ); } diff --git a/packages/combinator/lib/src/combinator/check.dart b/packages/combinator/lib/src/combinator/check.dart index a9bfcc63..c15d7051 100644 --- a/packages/combinator/lib/src/combinator/check.dart +++ b/packages/combinator/lib/src/combinator/check.dart @@ -16,11 +16,10 @@ class _Check extends Parser { return result; else if (!matcher.matches(result.value, matchState)) { return result.change(successful: false).addErrors([ - new SyntaxError( + SyntaxError( severity, errorMessage ?? - matcher.describe(new StringDescription('Expected ')).toString() + - '.', + matcher.describe(StringDescription('Expected ')).toString() + '.', result.span, ), ]); @@ -30,7 +29,7 @@ class _Check extends Parser { @override void stringify(CodeBuffer buffer) { - var d = matcher.describe(new StringDescription()); + var d = matcher.describe(StringDescription()); buffer ..writeln('check($d) (') ..indent(); diff --git a/packages/combinator/lib/src/combinator/combinator.dart b/packages/combinator/lib/src/combinator/combinator.dart index 08e1349e..280699a6 100644 --- a/packages/combinator/lib/src/combinator/combinator.dart +++ b/packages/combinator/lib/src/combinator/combinator.dart @@ -249,7 +249,7 @@ abstract class Parser { ListParser then(Parser other) => chain([this, other]); /// Casts this instance into a [ListParser]. - ListParser toList() => _ToList(this); + ListParser toList() => _ToList(this); /// Consumes and ignores any trailing occurrences of [pattern]. Parser trail(Pattern pattern) => @@ -371,7 +371,7 @@ class ParseResult { ParseResult change( {Parser? parser, bool? successful, - Iterable? errors, + Iterable errors = const [], FileSpan? span, T? value}) { return ParseResult( @@ -379,7 +379,7 @@ class ParseResult { scanner, parser ?? this.parser, successful ?? this.successful, - errors ?? this.errors, + errors, span: span ?? this.span, value: value ?? this.value, ); diff --git a/packages/combinator/lib/src/combinator/compare.dart b/packages/combinator/lib/src/combinator/compare.dart index 44a1ddd2..4ee0b813 100644 --- a/packages/combinator/lib/src/combinator/compare.dart +++ b/packages/combinator/lib/src/combinator/compare.dart @@ -13,8 +13,8 @@ class _Compare extends ListParser { result = result.change( value: result.value?.isNotEmpty == true ? result.value : []); - result = result.change(value: new List.from(result.value!)); - return new ParseResult>( + result = result.change(value: List.from(result.value!)); + return ParseResult>( args.trampoline, args.scanner, this, diff --git a/packages/combinator/lib/src/combinator/index.dart b/packages/combinator/lib/src/combinator/index.dart index 6eb9eaf8..89a6177c 100644 --- a/packages/combinator/lib/src/combinator/index.dart +++ b/packages/combinator/lib/src/combinator/index.dart @@ -14,7 +14,7 @@ class _Index extends Parser { if (result.successful) value = index == -1 ? result.value!.last : result.value!.elementAt(index); - return new ParseResult( + return ParseResult( args.trampoline, args.scanner, this, diff --git a/packages/combinator/lib/src/combinator/longest.dart b/packages/combinator/lib/src/combinator/longest.dart index 7028bd16..fa9124e7 100644 --- a/packages/combinator/lib/src/combinator/longest.dart +++ b/packages/combinator/lib/src/combinator/longest.dart @@ -5,8 +5,7 @@ part of lex.src.combinator; /// You can provide a custom [errorMessage]. Parser longest(Iterable> parsers, {Object? errorMessage, SyntaxErrorSeverity? severity}) { - return new _Longest( - parsers, errorMessage, severity ?? SyntaxErrorSeverity.error); + return _Longest(parsers, errorMessage, severity ?? SyntaxErrorSeverity.error); } class _Longest extends Parser { @@ -23,7 +22,7 @@ class _Longest extends Parser { .where((p) => !args.trampoline.isActive(p, args.scanner.position)); if (inactive.isEmpty) { - return new ParseResult(args.trampoline, args.scanner, this, false, []); + return ParseResult(args.trampoline, args.scanner, this, false, []); } int replay = args.scanner.position; @@ -48,7 +47,7 @@ class _Longest extends Parser { if (errorMessage != false) errors.add( - new SyntaxError( + SyntaxError( severity, errorMessage?.toString() ?? 'No match found for ${parsers.length} alternative(s)', @@ -56,7 +55,7 @@ class _Longest extends Parser { ), ); - return new ParseResult(args.trampoline, args.scanner, this, false, errors); + return ParseResult(args.trampoline, args.scanner, this, false, errors); } @override @@ -82,7 +81,7 @@ class _Longest extends Parser { } errors.add( - new SyntaxError( + SyntaxError( severity, errorMessage?.toString() ?? 'No match found for ${parsers.length} alternative(s)', @@ -90,7 +89,7 @@ class _Longest extends Parser { ), ); - return new ParseResult(args.trampoline, args.scanner, this, false, errors); + return ParseResult(args.trampoline, args.scanner, this, false, errors); } @override diff --git a/packages/combinator/lib/src/combinator/match.dart b/packages/combinator/lib/src/combinator/match.dart index e533a503..338faff6 100644 --- a/packages/combinator/lib/src/combinator/match.dart +++ b/packages/combinator/lib/src/combinator/match.dart @@ -3,7 +3,7 @@ part of lex.src.combinator; /// Expects to match a given [pattern]. If it is not matched, you can provide a custom [errorMessage]. Parser match(Pattern pattern, {String? errorMessage, SyntaxErrorSeverity? severity}) => - new _Match(pattern, errorMessage, severity ?? SyntaxErrorSeverity.error); + _Match(pattern, errorMessage, severity ?? SyntaxErrorSeverity.error); class _Match extends Parser { final Pattern pattern; @@ -16,14 +16,14 @@ class _Match extends Parser { ParseResult __parse(ParseArgs args) { var scanner = args.scanner; if (!scanner.scan(pattern)) - return new ParseResult(args.trampoline, scanner, this, false, [ - new SyntaxError( + return ParseResult(args.trampoline, scanner, this, false, [ + SyntaxError( severity, errorMessage ?? 'Expected "$pattern".', scanner.emptySpan, ), ]); - return new ParseResult( + return ParseResult( args.trampoline, scanner, this, diff --git a/packages/combinator/lib/src/combinator/max_depth.dart b/packages/combinator/lib/src/combinator/max_depth.dart index 1c28a9d2..42befcff 100644 --- a/packages/combinator/lib/src/combinator/max_depth.dart +++ b/packages/combinator/lib/src/combinator/max_depth.dart @@ -9,7 +9,7 @@ class _MaxDepth extends Parser { @override ParseResult __parse(ParseArgs args) { if (args.depth > cap) { - return new ParseResult(args.trampoline, args.scanner, this, false, []); + return ParseResult(args.trampoline, args.scanner, this, false, []); } return parser._parse(args.increaseDepth()); diff --git a/packages/combinator/lib/src/combinator/negate.dart b/packages/combinator/lib/src/combinator/negate.dart index d49582d8..b507bdcc 100644 --- a/packages/combinator/lib/src/combinator/negate.dart +++ b/packages/combinator/lib/src/combinator/negate.dart @@ -12,7 +12,7 @@ class _Negate extends Parser { var result = parser._parse(args.increaseDepth()).change(parser: this); if (!result.successful) { - return new ParseResult( + return ParseResult( args.trampoline, args.scanner, this, @@ -27,7 +27,7 @@ class _Negate extends Parser { if (errorMessage != null) { result = result.addErrors([ - new SyntaxError( + SyntaxError( severity, errorMessage, result.span, diff --git a/packages/combinator/lib/src/combinator/recursion.dart b/packages/combinator/lib/src/combinator/recursion.dart index faf7b5bf..76516943 100644 --- a/packages/combinator/lib/src/combinator/recursion.dart +++ b/packages/combinator/lib/src/combinator/recursion.dart @@ -13,7 +13,7 @@ class Recursion { postfix ??= {}; } - Parser precedence(int p) => new _Precedence(this, p); + Parser precedence(int p) => _Precedence(this, p); void stringify(CodeBuffer buffer) { buffer @@ -106,7 +106,7 @@ class _Precedence extends Parser { // If we're not done scanning, then we need some sort of guard to ensure the // that this exact parser does not run again in the exact position. } - return new ParseResult( + return ParseResult( args.trampoline, args.scanner, this, @@ -118,7 +118,7 @@ class _Precedence extends Parser { } } - return new ParseResult( + return ParseResult( args.trampoline, args.scanner, this, diff --git a/packages/combinator/lib/src/combinator/reduce.dart b/packages/combinator/lib/src/combinator/reduce.dart index 951da47b..29f1f1f3 100644 --- a/packages/combinator/lib/src/combinator/reduce.dart +++ b/packages/combinator/lib/src/combinator/reduce.dart @@ -11,7 +11,7 @@ class _Reduce extends Parser { ParseResult> result = parser._parse(args.increaseDepth()); if (!result.successful) - return new ParseResult( + return ParseResult( args.trampoline, args.scanner, this, @@ -21,7 +21,7 @@ class _Reduce extends Parser { result = result.change( value: result.value?.isNotEmpty == true ? result.value : []); - return new ParseResult( + return ParseResult( args.trampoline, args.scanner, this, diff --git a/packages/combinator/lib/src/combinator/reference.dart b/packages/combinator/lib/src/combinator/reference.dart index aefa32d3..737b94d4 100644 --- a/packages/combinator/lib/src/combinator/reference.dart +++ b/packages/combinator/lib/src/combinator/reference.dart @@ -1,6 +1,6 @@ part of lex.src.combinator; -Reference reference() => new Reference._(); +Reference reference() => Reference._(); class Reference extends Parser { Parser? _parser; @@ -10,22 +10,21 @@ class Reference extends Parser { void set parser(Parser value) { if (_parser != null) - throw new StateError( - 'There is already a parser assigned to this reference.'); + throw StateError('There is already a parser assigned to this reference.'); _parser = value; } @override ParseResult __parse(ParseArgs args) { if (_parser == null) - throw new StateError('There is no parser assigned to this reference.'); + throw StateError('There is no parser assigned to this reference.'); return _parser!._parse(args); } @override ParseResult _parse(ParseArgs args) { if (_parser == null) - throw new StateError('There is no parser assigned to this reference.'); + throw StateError('There is no parser assigned to this reference.'); return _parser!._parse(args); } diff --git a/packages/combinator/lib/src/combinator/safe.dart b/packages/combinator/lib/src/combinator/safe.dart index 6820d3ee..a2542295 100644 --- a/packages/combinator/lib/src/combinator/safe.dart +++ b/packages/combinator/lib/src/combinator/safe.dart @@ -22,15 +22,14 @@ class _Safe extends Parser { var errors = []; errors.add( - new SyntaxError( + SyntaxError( severity, errorMessage, args.scanner.lastSpan ?? args.scanner.emptySpan, ), ); - return new ParseResult( - args.trampoline, args.scanner, this, false, errors); + return ParseResult(args.trampoline, args.scanner, this, false, errors); } } diff --git a/packages/combinator/lib/src/combinator/to_list.dart b/packages/combinator/lib/src/combinator/to_list.dart index a73fa954..c2809975 100644 --- a/packages/combinator/lib/src/combinator/to_list.dart +++ b/packages/combinator/lib/src/combinator/to_list.dart @@ -1,26 +1,30 @@ part of lex.src.combinator; -class _ToList extends ListParser { +class _ToList extends ListParser { final Parser parser; _ToList(this.parser); @override - ParseResult> __parse(ParseArgs args) { + ParseResult> __parse(ParseArgs args) { var result = parser._parse(args.increaseDepth()); if (result.value is List) { - return (result as ParseResult>).change(parser: this); + return (result as ParseResult>).change(parser: this); } - return new ParseResult( + List values = []; + if (result.value != null) { + values.add(result.value!); + } + return ParseResult( args.trampoline, args.scanner, this, result.successful, result.errors, span: result.span, - value: [result.value], + value: values, ); } diff --git a/packages/combinator/lib/src/combinator/util.dart b/packages/combinator/lib/src/combinator/util.dart index e10d7f5f..cb5dcdc7 100644 --- a/packages/combinator/lib/src/combinator/util.dart +++ b/packages/combinator/lib/src/combinator/util.dart @@ -1,48 +1,48 @@ part of lex.src.combinator; /// A typed parser that parses a sequence of 2 values of different types. -Parser> tuple2(Parser a, Parser b) { +Parser> tuple2(Parser a, Parser b) { return chain([a, b]).map((r) { - return Tuple2(r.value![0] as A?, r.value![1] as B?); + return Tuple2(r.value?[0] as A, r.value?[1] as B); }); } /// A typed parser that parses a sequence of 3 values of different types. -Parser> tuple3(Parser a, Parser b, Parser c) { +Parser> tuple3(Parser a, Parser b, Parser c) { return chain([a, b, c]).map((r) { - return Tuple3(r.value![0] as A?, r.value![1] as B?, r.value![2] as C?); + return Tuple3(r.value?[0] as A, r.value?[1] as B, r.value?[2] as C); }); } /// A typed parser that parses a sequence of 4 values of different types. -Parser> tuple4( +Parser> tuple4( Parser a, Parser b, Parser c, Parser d) { return chain([a, b, c, d]).map((r) { return Tuple4( - r.value![0] as A?, r.value![1] as B?, r.value![2] as C?, r.value![3] as D?); + r.value?[0] as A, r.value?[1] as B, r.value?[2] as C, r.value?[3] as D); }); } /// A typed parser that parses a sequence of 5 values of different types. -Parser> tuple5( +Parser> tuple5( Parser a, Parser b, Parser c, Parser d, Parser e) { return chain([a, b, c, d, e]).map((r) { - return Tuple5(r.value![0] as A?, r.value![1] as B?, r.value![2] as C?, - r.value![3] as D?, r.value![4] as E?); + return Tuple5(r.value?[0] as A, r.value?[1] as B, r.value?[2] as C, + r.value?[3] as D, r.value?[4] as E); }); } /// A typed parser that parses a sequence of 6 values of different types. -Parser> tuple6(Parser a, +Parser> tuple6(Parser a, Parser b, Parser c, Parser d, Parser e, Parser f) { return chain([a, b, c, d, e, f]).map((r) { - return Tuple6(r.value![0] as A?, r.value![1] as B?, r.value![2] as C?, - r.value![3] as D?, r.value![4] as E?, r.value![5] as F?); + return Tuple6(r.value?[0] as A, r.value?[1] as B, r.value?[2] as C, + r.value?[3] as D, r.value?[4] as E, r.value?[5] as F); }); } /// A typed parser that parses a sequence of 7 values of different types. -Parser> tuple7( +Parser> tuple7( Parser a, Parser b, Parser c, @@ -51,7 +51,7 @@ Parser> tuple7( Parser f, Parser g) { return chain([a, b, c, d, e, f, g]).map((r) { - return Tuple7(r.value![0] as A?, r.value![1] as B?, r.value![2] as C?, - r.value![3] as D?, r.value![4] as E?, r.value![5] as F?, r.value![6] as G?); + return Tuple7(r.value?[0] as A, r.value?[1] as B, r.value?[2] as C, + r.value?[3] as D, r.value?[4] as E, r.value?[5] as F, r.value?[6] as G); }); } diff --git a/packages/combinator/test/common.dart b/packages/combinator/test/common.dart index 71dc6333..9ccc542b 100644 --- a/packages/combinator/test/common.dart +++ b/packages/combinator/test/common.dart @@ -1,3 +1,3 @@ import 'package:string_scanner/string_scanner.dart'; -SpanScanner scan(String text) => new SpanScanner(text); +SpanScanner scan(String text) => SpanScanner(text); diff --git a/packages/combinator/test/list_test.dart b/packages/combinator/test/list_test.dart index 26b0333e..8db60137 100644 --- a/packages/combinator/test/list_test.dart +++ b/packages/combinator/test/list_test.dart @@ -4,7 +4,7 @@ import 'common.dart'; main() { var number = chain([ - match(new RegExp(r'[0-9]+')).value((r) => int.parse(r.span!.text)), + match(RegExp(r'[0-9]+')).value((r) => int.parse(r.span!.text)), match(',').opt(), ]).first().cast(); diff --git a/packages/combinator/test/misc_test.dart b/packages/combinator/test/misc_test.dart index b3a141f9..4bce26fc 100644 --- a/packages/combinator/test/misc_test.dart +++ b/packages/combinator/test/misc_test.dart @@ -19,7 +19,7 @@ main() { }); test('check', () { - var parser = match(new RegExp(r'[A-Za-z]+')) + var parser = match(RegExp(r'[A-Za-z]+')) .value((r) => r.span!.length) .check(greaterThan(3)); expect(parser.parse(scan('helloworld')).successful, isTrue); @@ -27,8 +27,7 @@ main() { }); test('map', () { - var parser = - match(new RegExp(r'[A-Za-z]+')).map((r) => r.span!.length); + var parser = match(RegExp(r'[A-Za-z]+')).map((r) => r.span!.length); expect(parser.parse(scan('hello')).value, 5); }); diff --git a/packages/combinator/test/recursion_test.dart b/packages/combinator/test/recursion_test.dart index 688f44d3..4f1cdf17 100644 --- a/packages/combinator/test/recursion_test.dart +++ b/packages/combinator/test/recursion_test.dart @@ -6,12 +6,12 @@ void main() {} /* void main() { - var number = match(new RegExp(r'-?[0-9]+(\.[0-9]+)?')) + var number = match( RegExp(r'-?[0-9]+(\.[0-9]+)?')) .map((r) => num.parse(r.span.text)); var term = reference(); - var r = new Recursion(); + var r = Recursion(); r.prefix = [number]; @@ -32,7 +32,7 @@ void main() { term.parser = r.precedence(0); num parse(String text) { - var scanner = new SpanScanner(text); + var scanner = SpanScanner(text); var result = term.parse(scanner); print(result.span.highlight()); return result.value;