Skip to content

Commit

Permalink
Add a position combinator for the easy access of the current input po…
Browse files Browse the repository at this point in the history
…sition
  • Loading branch information
BjoernLoetters committed Jan 14, 2025
1 parent b942116 commit 7875980
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/main/java/jcombinators/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jcombinators.description.Negation;
import jcombinators.description.Empty;
import jcombinators.input.Input;
import jcombinators.position.Position;
import jcombinators.primitive.*;
import jcombinators.result.*;
import jcombinators.result.Error;
Expand Down Expand Up @@ -175,4 +176,11 @@ static <T> Parser<List<T>> sequence(final Parser<? extends T>... parsers) {
return new SequenceParser<>(sequence);
}

static <T> Parser<T> position(final Parser<Function<Position, T>> parser) {
return input -> {
final Position position = input.position;
return parser.apply(input).map(function -> function.apply(position));
};
}

}
30 changes: 30 additions & 0 deletions src/test/java/jcombinators/CombinatorTest.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package jcombinators;

import jcombinators.data.Tuple;
import jcombinators.input.Input;
import jcombinators.position.Position;
import jcombinators.result.Result;
import jcombinators.result.Success;
import org.junit.Test;

import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;

import static jcombinators.Parser.position;
import static jcombinators.common.StringParser.character;
import static jcombinators.common.StringParser.regex;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public final class CombinatorTest extends ParserTest {

Expand Down Expand Up @@ -218,4 +226,26 @@ public void commitChoiceNoBacktrackingTest() {
assertFailure(parser, "syntax error in Test 'commitChoiceNoBacktrackingTest' at line 1 and character 1: unexpected character 'b', expected the literal 'a'", "b");
}

@Test
public void positionParserCorrectPositionTest() {
final String contents = "line1\nline2\nline3\n";
final Input input = Input.of("test", contents);

final Parser<Function<Position, String>> parser = regex("line[0-9]\n").map(ignore -> position -> position.line + ":" + position.column);

final Parser<String> positionParser = position(parser);
final Result<String> firstResult = positionParser.apply(input);

assertTrue(firstResult.isSuccess());
assertEquals("1:1", firstResult.get().get());

final Result<String> secondResult = positionParser.apply(firstResult.rest);
assertTrue(secondResult.isSuccess());
assertEquals("2:1", secondResult.get().get());

final Result<String> thirdResult = positionParser.apply(secondResult.rest);
assertTrue(thirdResult.isSuccess());
assertEquals("3:1", thirdResult.get().get());
}

}

0 comments on commit 7875980

Please sign in to comment.