Skip to content

Ahnfelt/parsercombinator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 

Repository files navigation

parsercombinator

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

import static dk.ahnfelt.parsercombinator.Parsers.*;
Parser<String> parseFoo = string("foo");
parseFoo.parse("foo") // returns "foo"
parseFoo.parse("bar") // throws Parsers.Failure
Parser<Integer> parseIntegerMatch = regex("[0-9]+").map(m -> Integer.parseInt(m.group()));
parseFoo.parse("42") // returns "42"
parseFoo.parse("bar") // throws Parsers.Failure
Parser<Pair<String, Integer>> parseFooN = parseFoo.then(parseInteger);
parseFoo.parse("foo7") // returns ("foo", 7)
Parser<Integer> parseFooN2 = skip(parseFoo).then(parseInteger);
parseFooN2.parse("foo7") // returns 7
Parser<String> parseFooOrBar = choice(string("foo"), string("bar"));
parseFoo.parse("foo") // returns "foo"
parseFoo.parse("bar") // returns "bar"
parseFoo.parse("quux") // throws Parsers.Failure
// Alternative version of the above
Parser<String> parseFooOrBar2 = 
    regex("[a-z]+").
    map(m -> m.group()).
    filter(t -> t.equals("foo") || t.equals("bar"));
Parser<Pair<Integer, Integer>> parsePlus = 
    parseInteger.
    skip(string("+")).
    then(parseInteger);
Parser<Integer> parseAndCompute = parsePlus.map(match((x, y) -> x + y));
parseAndCompute.parse("7+3") // returns 10
Parser<List<Integer>> parseList = parseInteger.zeroOrMore(string(","));
parseList.parse("1,2,4,8,16,32") // returns [1, 2, 4, 8, 16, 32]
Parser<String> parseToken = regex("\\s*([a-z0-9]+)\\s*").map(m -> m.group(1));
Parser<String> 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<<Pair<Pair<String, String>, Optional<String>>> 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<String> 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"

About

A parser combinator for Java 8. Proof of concept.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages