Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/Ahnfelt/parsercombinator

A parser combinator for Java 8. Proof of concept.
https://github.com/Ahnfelt/parsercombinator

Last synced: 21 days ago
JSON representation

A parser combinator for Java 8. Proof of concept.

Awesome Lists containing this project

README

        

# parsercombinator
A parser combinator for Java 8. Working, but mostly a proof of concept.

```java
import static dk.ahnfelt.parsercombinator.Parsers.*;
```

```java
Parser parseFoo = string("foo");
parseFoo.parse("foo") // returns "foo"
parseFoo.parse("bar") // throws Parsers.Failure
```

```java
Parser parseIntegerMatch = regex("[0-9]+").map(m -> Integer.parseInt(m.group()));
parseFoo.parse("42") // returns "42"
parseFoo.parse("bar") // throws Parsers.Failure
```

```java
Parser> parseFooN = parseFoo.then(parseInteger);
parseFoo.parse("foo7") // returns ("foo", 7)
```

```java
Parser parseFooN2 = skip(parseFoo).then(parseInteger);
parseFooN2.parse("foo7") // returns 7
```

```java
Parser parseFooOrBar = choice(string("foo"), string("bar"));
parseFoo.parse("foo") // returns "foo"
parseFoo.parse("bar") // returns "bar"
parseFoo.parse("quux") // throws Parsers.Failure
```

```java
// Alternative version of the above
Parser parseFooOrBar2 =
regex("[a-z]+").
map(m -> m.group()).
filter(t -> t.equals("foo") || t.equals("bar"));
```

```java
Parser> parsePlus =
parseInteger.
skip(string("+")).
then(parseInteger);
Parser parseAndCompute = parsePlus.map(match((x, y) -> x + y));
parseAndCompute.parse("7+3") // returns 10
```

```java
Parser> parseList = parseInteger.zeroOrMore(string(","));
parseList.parse("1,2,4,8,16,32") // returns [1, 2, 4, 8, 16, 32]
```

```java
Parser parseToken = regex("\\s*([a-z0-9]+)\\s*").map(m -> m.group(1));
Parser keyword(String name) { return parseToken.filter(t -> t.equals(name)); }

// The nested pairs can get hairy - use .map(match(...)) to get rid of them before you have to write types like this:
Parser<, Optional>> parseIf =
skip(keyword("if")).then(parseToken).
skip(keyword("then")).then(parseToken).
then(skip(keyword("else")).then(parseToken).optional()).
skip(keyword("end"));

parseIf.parse("if x then y else z end") // returns (("x", "y"), Optional["z"])

Parser parseIfAndCompute =
parseIf.map(match((x, y, z) -> x.equals("true") ? y : z.orElse("void")));

parseIfAndCompute.parse("if true then y else z end") // returns "y"
parseIfAndCompute.parse("if false then y end") // returns "void"
```