diff --git a/packages/combinator/lib/src/combinator/advance.dart b/packages/combinator/lib/src/combinator/advance.dart index 49fcdb88..01506dc2 100644 --- a/packages/combinator/lib/src/combinator/advance.dart +++ b/packages/combinator/lib/src/combinator/advance.dart @@ -8,7 +8,7 @@ class _Advance extends Parser { @override ParseResult __parse(ParseArgs args) { - var result = parser._parse(args.increaseDepth())!.change(parser: this); + var result = parser._parse(args.increaseDepth()).change(parser: this); if (result.successful) args.scanner.position += amount; return result; } diff --git a/packages/combinator/lib/src/combinator/any.dart b/packages/combinator/lib/src/combinator/any.dart index 0c16a81d..616bf29d 100644 --- a/packages/combinator/lib/src/combinator/any.dart +++ b/packages/combinator/lib/src/combinator/any.dart @@ -8,7 +8,7 @@ part of lex.src.combinator; /// generate any error at all. Parser any(Iterable> parsers, {bool backtrack: true, errorMessage, SyntaxErrorSeverity? severity}) { - return new _Any(parsers, backtrack != false, errorMessage, + return _Any(parsers, backtrack != false, errorMessage, severity ?? SyntaxErrorSeverity.error); } @@ -26,14 +26,14 @@ class _Any 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, []); } var errors = []; int replay = args.scanner.position; for (var parser in inactive) { - var result = parser._parse(args.increaseDepth())!; + var result = parser._parse(args.increaseDepth()); if (result.successful) return result; @@ -45,7 +45,7 @@ class _Any extends Parser { if (errorMessage != false) { errors.add( - new SyntaxError( + SyntaxError( severity, errorMessage?.toString() ?? 'No match found for ${parsers.length} alternative(s)', @@ -54,13 +54,13 @@ class _Any extends Parser { ); } - return new ParseResult(args.trampoline, args.scanner, this, false, errors); + return ParseResult(args.trampoline, args.scanner, this, false, errors); } @override - ParseResult? __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { // Never called - return null; + throw ArgumentError("[Combinator] Invalid method call"); } @override diff --git a/packages/combinator/lib/src/combinator/cast.dart b/packages/combinator/lib/src/combinator/cast.dart index 6bd44f80..bc7280ad 100644 --- a/packages/combinator/lib/src/combinator/cast.dart +++ b/packages/combinator/lib/src/combinator/cast.dart @@ -7,7 +7,7 @@ class _Cast extends Parser { @override ParseResult __parse(ParseArgs args) { - var result = parser._parse(args.increaseDepth())!; + var result = parser._parse(args.increaseDepth()); return new ParseResult( args.trampoline, args.scanner, @@ -38,7 +38,7 @@ class _CastDynamic extends Parser { @override ParseResult __parse(ParseArgs args) { - var result = parser._parse(args.increaseDepth())!; + var result = parser._parse(args.increaseDepth()); return new ParseResult( args.trampoline, args.scanner, diff --git a/packages/combinator/lib/src/combinator/chain.dart b/packages/combinator/lib/src/combinator/chain.dart index 49cc8c1b..16af1658 100644 --- a/packages/combinator/lib/src/combinator/chain.dart +++ b/packages/combinator/lib/src/combinator/chain.dart @@ -18,7 +18,7 @@ class _Alt extends Parser { @override ParseResult __parse(ParseArgs args) { - var result = parser._parse(args.increaseDepth())!; + var result = parser._parse(args.increaseDepth()); return result.successful ? result : result.addErrors([ @@ -48,7 +48,7 @@ class _Chain extends ListParser { bool successful = true; for (var parser in parsers) { - var result = parser._parse(args.increaseDepth())!; + var result = parser._parse(args.increaseDepth()); if (!result.successful) { if (parser is _Alt) errors.addAll(result.errors); diff --git a/packages/combinator/lib/src/combinator/check.dart b/packages/combinator/lib/src/combinator/check.dart index 58416040..a9bfcc63 100644 --- a/packages/combinator/lib/src/combinator/check.dart +++ b/packages/combinator/lib/src/combinator/check.dart @@ -11,7 +11,7 @@ class _Check extends Parser { @override ParseResult __parse(ParseArgs args) { var matchState = {}; - var result = parser._parse(args.increaseDepth())!.change(parser: this); + var result = parser._parse(args.increaseDepth()).change(parser: this); if (!result.successful) return result; else if (!matcher.matches(result.value, matchState)) { diff --git a/packages/combinator/lib/src/combinator/combinator.dart b/packages/combinator/lib/src/combinator/combinator.dart index 10cbaf5d..08e1349e 100644 --- a/packages/combinator/lib/src/combinator/combinator.dart +++ b/packages/combinator/lib/src/combinator/combinator.dart @@ -67,9 +67,9 @@ class ParseArgs { /// A parser combinator, which can parse very complicated grammars in a manageable manner. abstract class Parser { - ParseResult? __parse(ParseArgs args); + ParseResult __parse(ParseArgs args); - ParseResult? _parse(ParseArgs args) { + ParseResult _parse(ParseArgs args) { var pos = args.scanner.position; if (args.trampoline.hasMemoized(this, pos)) @@ -86,7 +86,7 @@ abstract class Parser { } /// Parses text from a [SpanScanner]. - ParseResult? parse(SpanScanner scanner, [int depth = 1]) { + ParseResult parse(SpanScanner scanner, [int depth = 1]) { var args = ParseArgs(Trampoline(), scanner, depth); return _parse(args); } @@ -105,7 +105,7 @@ abstract class Parser { // TODO: Type issue /// Runs the given function, which changes the returned [ParseResult] into one relating to a [U] object. - Parser change(ParseResult Function(ParseResult?) f) { + Parser change(ParseResult Function(ParseResult) f) { return _Change(this, f); } @@ -140,8 +140,10 @@ abstract class Parser { /// Ensures this pattern is not matched. /// /// You can provide an [errorMessage]. - Parser negate({String? errorMessage, SyntaxErrorSeverity? severity}) => - _Negate(this, errorMessage, severity ?? SyntaxErrorSeverity.error); + Parser negate( + {String errorMessage = 'Negate error', + SyntaxErrorSeverity severity = SyntaxErrorSeverity.error}) => + _Negate(this, errorMessage, severity); /// Caches the results of parse attempts at various locations within the source text. /// @@ -153,7 +155,7 @@ abstract class Parser { /// Consumes `this` and another parser, but only considers the result of `this` parser. Parser and(Parser other) => then(other).change((r) { return ParseResult( - r!.trampoline, + r.trampoline, r.scanner, this, r.successful, @@ -176,7 +178,7 @@ abstract class Parser { /// The generated parser only runs once; repeated uses always exit eagerly. Parser safe( {bool backtrack: true, - String? errorMessage, + String errorMessage = "error", SyntaxErrorSeverity? severity}) => _Safe( this, backtrack, errorMessage, severity ?? SyntaxErrorSeverity.error); @@ -240,7 +242,7 @@ abstract class Parser { Parser space() => trail(RegExp(r'[ \n\r\t]+')); /// Consumes 0 or more instance(s) of this parser. - ListParser star({bool backtrack: true}) => + ListParser star({bool backtrack: true}) => times(1, exact: false, backtrack: backtrack).opt(); /// Shortcut for [chain]-ing two parsers together. @@ -259,10 +261,10 @@ abstract class Parser { /// an infinite amount of occurrences after the specified [count]. /// /// You can provide custom error messages for when there are [tooFew] or [tooMany] occurrences. - ListParser times(int count, + ListParser times(int count, {bool exact: true, - String? tooFew, - String? tooMany, + String tooFew = 'Too few', + String tooMany = 'Too many', bool backtrack: true, SyntaxErrorSeverity? severity}) { return _Repeat(this, count, exact, tooFew, tooMany, backtrack, diff --git a/packages/combinator/lib/src/combinator/compare.dart b/packages/combinator/lib/src/combinator/compare.dart index 49a39701..44a1ddd2 100644 --- a/packages/combinator/lib/src/combinator/compare.dart +++ b/packages/combinator/lib/src/combinator/compare.dart @@ -8,7 +8,7 @@ class _Compare extends ListParser { @override ParseResult> __parse(ParseArgs args) { - ParseResult> result = parser._parse(args.increaseDepth())!; + ParseResult> result = parser._parse(args.increaseDepth()); if (!result.successful) return result; result = result.change( diff --git a/packages/combinator/lib/src/combinator/fold_errors.dart b/packages/combinator/lib/src/combinator/fold_errors.dart index 5b838e6f..6d15c69a 100644 --- a/packages/combinator/lib/src/combinator/fold_errors.dart +++ b/packages/combinator/lib/src/combinator/fold_errors.dart @@ -8,7 +8,7 @@ class _FoldErrors extends Parser { @override ParseResult __parse(ParseArgs args) { - var result = parser._parse(args.increaseDepth())!.change(parser: this); + var result = parser._parse(args.increaseDepth()).change(parser: this); var errors = result.errors.fold>([], (out, e) { if (!out.any((b) => equal(e, b))) out.add(e); return out; diff --git a/packages/combinator/lib/src/combinator/index.dart b/packages/combinator/lib/src/combinator/index.dart index a3791333..6eb9eaf8 100644 --- a/packages/combinator/lib/src/combinator/index.dart +++ b/packages/combinator/lib/src/combinator/index.dart @@ -8,7 +8,7 @@ class _Index extends Parser { @override ParseResult __parse(ParseArgs args) { - ParseResult> result = parser._parse(args.increaseDepth())!; + ParseResult> result = parser._parse(args.increaseDepth()); Object? value; if (result.successful) diff --git a/packages/combinator/lib/src/combinator/longest.dart b/packages/combinator/lib/src/combinator/longest.dart index ae00c2c8..7028bd16 100644 --- a/packages/combinator/lib/src/combinator/longest.dart +++ b/packages/combinator/lib/src/combinator/longest.dart @@ -31,7 +31,7 @@ class _Longest extends Parser { var results = >[]; for (var parser in inactive) { - var result = parser._parse(args.increaseDepth())!; + var result = parser._parse(args.increaseDepth()); if (result.successful && result.span != null) results.add(result); @@ -66,7 +66,7 @@ class _Longest extends Parser { var results = >[]; for (var parser in parsers) { - var result = parser._parse(args.increaseDepth())!; + var result = parser._parse(args.increaseDepth()); if (result.successful) results.add(result); diff --git a/packages/combinator/lib/src/combinator/map.dart b/packages/combinator/lib/src/combinator/map.dart index 37acddd5..4dfb326d 100644 --- a/packages/combinator/lib/src/combinator/map.dart +++ b/packages/combinator/lib/src/combinator/map.dart @@ -8,8 +8,8 @@ class _Map extends Parser { @override ParseResult __parse(ParseArgs args) { - var result = parser._parse(args.increaseDepth())!; - return new ParseResult( + var result = parser._parse(args.increaseDepth()); + return ParseResult( args.trampoline, args.scanner, this, @@ -34,7 +34,7 @@ class _Map extends Parser { class _Change extends Parser { final Parser parser; - final ParseResult Function(ParseResult?) f; + final ParseResult Function(ParseResult) f; _Change(this.parser, this.f); diff --git a/packages/combinator/lib/src/combinator/max_depth.dart b/packages/combinator/lib/src/combinator/max_depth.dart index f9054132..1c28a9d2 100644 --- a/packages/combinator/lib/src/combinator/max_depth.dart +++ b/packages/combinator/lib/src/combinator/max_depth.dart @@ -7,7 +7,7 @@ class _MaxDepth extends Parser { _MaxDepth(this.parser, this.cap); @override - ParseResult? __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { if (args.depth > cap) { return new ParseResult(args.trampoline, args.scanner, this, false, []); } diff --git a/packages/combinator/lib/src/combinator/negate.dart b/packages/combinator/lib/src/combinator/negate.dart index 30a8c377..d49582d8 100644 --- a/packages/combinator/lib/src/combinator/negate.dart +++ b/packages/combinator/lib/src/combinator/negate.dart @@ -9,7 +9,7 @@ class _Negate extends Parser { @override ParseResult __parse(ParseArgs args) { - var result = parser._parse(args.increaseDepth())!.change(parser: this); + var result = parser._parse(args.increaseDepth()).change(parser: this); if (!result.successful) { return new ParseResult( diff --git a/packages/combinator/lib/src/combinator/opt.dart b/packages/combinator/lib/src/combinator/opt.dart index ac2b31c2..12083ed7 100644 --- a/packages/combinator/lib/src/combinator/opt.dart +++ b/packages/combinator/lib/src/combinator/opt.dart @@ -9,7 +9,7 @@ class _Opt extends Parser { @override ParseResult __parse(ParseArgs args) { var replay = args.scanner.position; - var result = parser._parse(args.increaseDepth())!; + var result = parser._parse(args.increaseDepth()); if (!result.successful) args.scanner.position = replay; @@ -37,7 +37,7 @@ class _ListOpt extends ListParser { @override ParseResult> __parse(ParseArgs args) { var replay = args.scanner.position; - ParseResult> result = parser._parse(args.increaseDepth())!; + ParseResult> result = parser._parse(args.increaseDepth()); if (!result.successful) args.scanner.position = replay; diff --git a/packages/combinator/lib/src/combinator/reduce.dart b/packages/combinator/lib/src/combinator/reduce.dart index ae2d7d14..951da47b 100644 --- a/packages/combinator/lib/src/combinator/reduce.dart +++ b/packages/combinator/lib/src/combinator/reduce.dart @@ -8,7 +8,7 @@ class _Reduce extends Parser { @override ParseResult __parse(ParseArgs args) { - ParseResult> result = parser._parse(args.increaseDepth())!; + ParseResult> result = parser._parse(args.increaseDepth()); if (!result.successful) return new ParseResult( diff --git a/packages/combinator/lib/src/combinator/reference.dart b/packages/combinator/lib/src/combinator/reference.dart index dd2b6b9b..aefa32d3 100644 --- a/packages/combinator/lib/src/combinator/reference.dart +++ b/packages/combinator/lib/src/combinator/reference.dart @@ -16,22 +16,26 @@ class Reference extends Parser { } @override - ParseResult? __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { if (_parser == null) throw new StateError('There is no parser assigned to this reference.'); return _parser!._parse(args); } @override - ParseResult? _parse(ParseArgs args) { + ParseResult _parse(ParseArgs args) { + if (_parser == null) + throw new StateError('There is no parser assigned to this reference.'); return _parser!._parse(args); } @override void stringify(CodeBuffer buffer) { - if (_parser == null) + if (_parser == null) { buffer.writeln('(undefined reference <$T>)'); - else if (!printed) _parser!.stringify(buffer); + } else if (!printed) { + _parser!.stringify(buffer); + } printed = true; buffer.writeln('(previously printed reference)'); } diff --git a/packages/combinator/lib/src/combinator/repeat.dart b/packages/combinator/lib/src/combinator/repeat.dart index be8b9c57..2ee452bd 100644 --- a/packages/combinator/lib/src/combinator/repeat.dart +++ b/packages/combinator/lib/src/combinator/repeat.dart @@ -1,63 +1,67 @@ part of lex.src.combinator; -class _Repeat extends ListParser { +class _Repeat extends ListParser { final Parser parser; final int count; final bool exact, backtrack; - final String? tooFew, tooMany; + final String tooFew; + final String tooMany; final SyntaxErrorSeverity severity; _Repeat(this.parser, this.count, this.exact, this.tooFew, this.tooMany, this.backtrack, this.severity); @override - ParseResult> __parse(ParseArgs args) { + ParseResult> __parse(ParseArgs args) { var errors = []; - var results = []; - var spans = []; + var results = []; + var spans = []; int success = 0, replay = args.scanner.position; ParseResult? result; do { result = parser._parse(args.increaseDepth()); - if (result!.successful) { + if (result.successful) { success++; - results.add(result.value); + if (result.value != null) { + results.add(result.value!); + } replay = args.scanner.position; } else if (backtrack) args.scanner.position = replay; - if (result.span != null) spans.add(result.span); + if (result.span != null) { + spans.add(result.span!); + } } while (result.successful); if (success < count) { errors.addAll(result.errors); errors.add( - new SyntaxError( + SyntaxError( severity, - tooFew ?? 'Expected at least $count occurence(s).', + tooFew, result.span ?? args.scanner.emptySpan, ), ); if (backtrack) args.scanner.position = replay; - return new ParseResult>( + return ParseResult>( args.trampoline, args.scanner, this, false, errors); } else if (success > count && exact) { if (backtrack) args.scanner.position = replay; - return new ParseResult>( - args.trampoline, args.scanner, this, false, [ - new SyntaxError( + return ParseResult>(args.trampoline, args.scanner, this, false, [ + SyntaxError( severity, - tooMany ?? 'Expected no more than $count occurence(s).', + tooMany, result.span ?? args.scanner.emptySpan, ), ]); } - var span = spans.reduce((a, b) => a!.expand(b!)); - return new ParseResult>( + var span = spans.reduce((a, b) => a.expand(b)); + return ParseResult>( args.trampoline, args.scanner, this, @@ -70,7 +74,7 @@ class _Repeat extends ListParser { @override void stringify(CodeBuffer buffer) { - var r = new StringBuffer('{$count'); + var r = StringBuffer('{$count'); if (!exact) r.write(','); r.write('}'); buffer diff --git a/packages/combinator/lib/src/combinator/safe.dart b/packages/combinator/lib/src/combinator/safe.dart index 8bac100e..6820d3ee 100644 --- a/packages/combinator/lib/src/combinator/safe.dart +++ b/packages/combinator/lib/src/combinator/safe.dart @@ -3,14 +3,14 @@ part of lex.src.combinator; class _Safe extends Parser { final Parser parser; final bool backtrack; - final String? errorMessage; + final String errorMessage; final SyntaxErrorSeverity severity; bool _triggered = false; _Safe(this.parser, this.backtrack, this.errorMessage, this.severity); @override - ParseResult? __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { var replay = args.scanner.position; try { @@ -21,16 +21,13 @@ class _Safe extends Parser { if (backtrack) args.scanner.position = replay; var errors = []; - if (errorMessage != null) { - // TODO: Custom severity for all errors? - errors.add( - new SyntaxError( - severity, - errorMessage, - args.scanner.lastSpan ?? args.scanner.emptySpan, - ), - ); - } + errors.add( + new SyntaxError( + severity, + errorMessage, + args.scanner.lastSpan ?? args.scanner.emptySpan, + ), + ); return new 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 a339db50..a73fa954 100644 --- a/packages/combinator/lib/src/combinator/to_list.dart +++ b/packages/combinator/lib/src/combinator/to_list.dart @@ -7,7 +7,7 @@ class _ToList extends ListParser { @override ParseResult> __parse(ParseArgs args) { - var result = parser._parse(args.increaseDepth())!; + var result = parser._parse(args.increaseDepth()); if (result.value is List) { return (result as ParseResult>).change(parser: this); diff --git a/packages/combinator/lib/src/combinator/value.dart b/packages/combinator/lib/src/combinator/value.dart index ab206187..b0612073 100644 --- a/packages/combinator/lib/src/combinator/value.dart +++ b/packages/combinator/lib/src/combinator/value.dart @@ -8,7 +8,7 @@ class _Value extends Parser { @override ParseResult __parse(ParseArgs args) { - var result = parser._parse(args.increaseDepth())!.change(parser: this); + var result = parser._parse(args.increaseDepth()).change(parser: this); return result.successful ? result.change(value: f(result)) : result; } diff --git a/packages/combinator/test/list_test.dart b/packages/combinator/test/list_test.dart index 64bf8fba..26b0333e 100644 --- a/packages/combinator/test/list_test.dart +++ b/packages/combinator/test/list_test.dart @@ -12,11 +12,11 @@ main() { test('sort', () { var parser = numbers.sort((a, b) => a!.compareTo(b!)); - expect(parser.parse(scan('21,2,3,34,20'))!.value, [2, 3, 20, 21, 34]); + expect(parser.parse(scan('21,2,3,34,20')).value, [2, 3, 20, 21, 34]); }); test('reduce', () { var parser = numbers.reduce((a, b) => a! + b!); - expect(parser.parse(scan('21,2,3,34,20'))!.value, 80); - expect(parser.parse(scan('not numbers'))!.value, isNull); + expect(parser.parse(scan('21,2,3,34,20')).value, 80); + expect(parser.parse(scan('not numbers')).value, isNull); }); } diff --git a/packages/combinator/test/match_test.dart b/packages/combinator/test/match_test.dart index d1406276..60504d93 100644 --- a/packages/combinator/test/match_test.dart +++ b/packages/combinator/test/match_test.dart @@ -4,13 +4,13 @@ import 'common.dart'; main() { test('match string', () { - expect(match('hello').parse(scan('hello world'))!.successful, isTrue); + expect(match('hello').parse(scan('hello world')).successful, isTrue); }); test('match start only', () { - expect(match('hello').parse(scan('goodbye hello'))!.successful, isFalse); + expect(match('hello').parse(scan('goodbye hello')).successful, isFalse); }); test('fail if no match', () { - expect(match('hello').parse(scan('world'))!.successful, isFalse); + expect(match('hello').parse(scan('world')).successful, isFalse); }); } diff --git a/packages/combinator/test/misc_test.dart b/packages/combinator/test/misc_test.dart index f90d5d83..b3a141f9 100644 --- a/packages/combinator/test/misc_test.dart +++ b/packages/combinator/test/misc_test.dart @@ -14,29 +14,29 @@ main() { }); test('change', () { - var parser = match('hello').change((r) => r!.change(value: 23)); - expect(parser.parse(scan('helloworld'))!.value, 23); + var parser = match('hello').change((r) => r.change(value: 23)); + expect(parser.parse(scan('helloworld')).value, 23); }); test('check', () { var parser = match(new RegExp(r'[A-Za-z]+')) .value((r) => r.span!.length) .check(greaterThan(3)); - expect(parser.parse(scan('helloworld'))!.successful, isTrue); - expect(parser.parse(scan('yo'))!.successful, isFalse); + expect(parser.parse(scan('helloworld')).successful, isTrue); + expect(parser.parse(scan('yo')).successful, isFalse); }); test('map', () { var parser = match(new RegExp(r'[A-Za-z]+')).map((r) => r.span!.length); - expect(parser.parse(scan('hello'))!.value, 5); + expect(parser.parse(scan('hello')).value, 5); }); test('negate', () { var parser = match('hello').negate(errorMessage: 'world'); - expect(parser.parse(scan('goodbye world'))!.successful, isTrue); - expect(parser.parse(scan('hello world'))!.successful, isFalse); - expect(parser.parse(scan('hello world'))!.errors.first.message, 'world'); + expect(parser.parse(scan('goodbye world')).successful, isTrue); + expect(parser.parse(scan('hello world')).successful, isFalse); + expect(parser.parse(scan('hello world')).errors.first.message, 'world'); }); group('opt', () { @@ -44,13 +44,13 @@ main() { var list = match('hel').then(match('lo')).opt(); test('succeeds if present', () { - expect(single.parse(scan('hello'))!.successful, isTrue); - expect(list.parse(scan('hello'))!.successful, isTrue); + expect(single.parse(scan('hello')).successful, isTrue); + expect(list.parse(scan('hello')).successful, isTrue); }); test('succeeds if not present', () { - expect(single.parse(scan('goodbye'))!.successful, isTrue); - expect(list.parse(scan('goodbye'))!.successful, isTrue); + expect(single.parse(scan('goodbye')).successful, isTrue); + expect(list.parse(scan('goodbye')).successful, isTrue); }); test('backtracks if not present', () { diff --git a/packages/combinator/test/value_test.dart b/packages/combinator/test/value_test.dart index 97ab3543..c987d10f 100644 --- a/packages/combinator/test/value_test.dart +++ b/packages/combinator/test/value_test.dart @@ -6,10 +6,10 @@ main() { var parser = match('hello').value((r) => 'world'); test('sets value', () { - expect(parser.parse(scan('hello world'))!.value, 'world'); + expect(parser.parse(scan('hello world')).value, 'world'); }); test('no value if no match', () { - expect(parser.parse(scan('goodbye world'))!.value, isNull); + expect(parser.parse(scan('goodbye world')).value, isNull); }); }