Search code examples
javaparsingjparsec

How to return a List from jparsec without using .between()


I'm working on a simple parser using the JParsec library and want to parse the following:

some, list, of, things

This is easily done with with parser.sepBy(Scanners.isChar(',') but fails to parse in a larger document unless I wrap it inside a between.

Ultimately I'm wanting to parse something along the lines of:

implements some.java.Interface, some.other.Interface {
  ...
}

However I can't find a magic combination to say "sepBy X until (but not consuming Y)" or even "sepBy X until failure".

Am I missing something simple here?


Solution

  • There is a more or less complete Java parser in the examples directory which implements that kind of stuff. The trick is to include your parser for a list of things inside a sequence, or combined with next() with another parSer for the body between curly braces, assuming curly braces cannot occur within your list's elements.

    Here is the classDef method from org.codehaus.jparsec.examples.java.parser.DeclarationParser:

     static Parser<Declaration> classDef(Parser<Modifier> mod, Parser<Member> member) {
       return curry(ClassDef.class).sequence(
           mod.many(), term("class"), Terminals.Identifier.PARSER, TYPE_PARAMETERS.optional(),
           term("extends").next(ELEMENT_TYPE_LITERAL).optional(),
           term("implements").next(ELEMENT_TYPE_LITERAL.sepBy1(term(","))).optional(),
           body(member));
     }
    

    The part you are interested in is term("implements").next(ELEMENT_TYPE_LITERAL.sepBy1(term(","))).optional(). Notice this fragment is an optional part of a sequence of parsers whose returned elements are used to create a ClassDef AST object.