Skip to content

Commit

Permalink
Fix before, followedBy and surroundedBy #25
Browse files Browse the repository at this point in the history
In PetitParser 4.1.0, the type argument of `pick` was removed.
To ensure type safety, this commit adds a new parser class
for parsers that have an ignored prefix and suffix instead of
using `pick` and `seq`.
  • Loading branch information
just95 committed Apr 18, 2021
1 parent c6bc51f commit 4f68283
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 27 deletions.
2 changes: 1 addition & 1 deletion lib/src/util/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ export 'parser/late.dart';
export 'parser/or_failure.dart';
export 'parser/pair.dart';
export 'parser/separated_without.dart';
export 'parser/seq_pick.dart';
export 'parser/surrounded.dart';
24 changes: 0 additions & 24 deletions lib/src/util/parser/seq_pick.dart

This file was deleted.

112 changes: 112 additions & 0 deletions lib/src/util/parser/surrounded.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
library toml.src.util.parser.surrounded;

import 'package:petitparser/petitparser.dart';

import '../iterable/where_not_null.dart';

/// Extension for utility methods to construct [SurroundedParser]s.
extension SurroundedParserExtension<T> on Parser<T> {
/// Returns a new parser for the sequence of the receiver and [other] parser
/// that discards the result of the receiver.
Parser<S> before<S>(Parser<S> other) => SurroundedParser(other, prefix: this);

/// Returns a new parser for the sequence of the receiver and [other] parser
/// that discards the result of the [other] parser.
Parser<T> followedBy(Parser other) => SurroundedParser(this, suffix: other);

/// Returns a new parser that parses the [prefix] before the receiver
/// followed by the [suffix].
///
/// The result of the returned parser is the result of the receiver. The
/// result of the prefix and suffix are discarded.
///
/// The [suffix] defaults to the [prefix].
Parser<T> surroundedBy(Parser prefix, [Parser? suffix]) => SurroundedParser(
this,
prefix: prefix,
suffix: suffix ?? prefix,
);
}

/// A parser that delegates to a parser with an optional prefix and suffix.
///
/// The results of the prefix and suffix are discarded.
class SurroundedParser<T> extends DelegateParser<T, T> {
/// The optional prefix parser.
Parser? prefix;

/// The optional suffix parser.
Parser? suffix;

/// Creates a new parser that accepts the sequence of the given [prefix],
/// [delegate] and [suffix] but returns the result of the [delegate].
SurroundedParser(Parser<T> delegate, {this.prefix, this.suffix})
: super(delegate);

@override
Result<T> parseOn(Context context) {
// Parse prefix if any.
var prefix = this.prefix;
if (prefix != null) {
var prefixResult = prefix.parseOn(context);
if (prefixResult.isFailure) {
return prefixResult.failure(prefixResult.message);
}
context = prefixResult;
}

// Parse the delegate.
var result = delegate.parseOn(context);
if (result.isFailure) return result.failure(result.message);
context = result;

// Parse suffix if any.
var suffix = this.suffix;
if (suffix != null) {
var suffixResult = suffix.parseOn(context);
if (suffixResult.isFailure) {
return suffixResult.failure(suffixResult.message);
}
context = suffixResult;
}

// Return the value of the delegate.
return context.success(result.value);
}

@override
int fastParseOn(String buffer, int position) {
// Parse prefix if any.
position = prefix?.fastParseOn(buffer, position) ?? position;
if (position == -1) return position;

// Parse delegate.
position = delegate.fastParseOn(buffer, position);
if (position == -1) return position;

// Parse suffix if any.
return suffix?.fastParseOn(buffer, position) ?? position;
}

@override
List<Parser> get children =>
[prefix, delegate, suffix].whereNotNull().toList();

@override
SurroundedParser<T> copy() => SurroundedParser<T>(
delegate,
prefix: prefix,
suffix: suffix,
);

@override
void replace(Parser source, Parser target) {
super.replace(source, target);
if (source == prefix) {
prefix = target;
}
if (source == suffix) {
suffix = target;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
library toml.test.util.parser.seq_pick_test;
library toml.test.util.parser.surrounded_test;

import 'package:test/test.dart';
import 'package:petitparser/petitparser.dart';

import 'package:toml/src/util/parser/seq_pick.dart';
import 'package:toml/src/util/parser/surrounded.dart';

void main() {
group('SequencePickParserExtension', () {
Expand Down

0 comments on commit 4f68283

Please sign in to comment.