I have a JParsec parser that consists of a few "smaller" parsers, and I would like to extract the total value parsed with those parsers. Let's say:
// V-- because of sequence()
private static final Parser<Object> definitionParser = sequence(
substitute, separator, digits4, separator, digits2, separator, description.optional()
);
Some of the parsers above are dummy and are used to delimit data fields. The dummy parsers are substitute
and separator
, and I'm not going to extract anything from them. However, the rest of the parsers makes the interest to me:
private static final Parser<Short> digits4 = ...; // 4 hex digits, just a short value
private static final Parser<Byte> digits2 = ...; // 2 hex digits, just a byte value
private static final Parser<String> description = ...; // arbitrary string
However, map
ping the substituteDefinition
parser requires a Map<Object, Definition>
interface implementation propagating the result of the very last sequenced parser description.optional()
to the Map
implementation, and the incoming argument is a String
:
private static final Parser<Definition> definitionParser = sequence(
substitute, separator, digits4, separator, digits2, separator, description.optional()
).map(new Map<Object, Definition>() {
@Override
public Definition map(final Object o) {
... o is a String here because description.optional() is the last one
}
});
Obviously, I can only extract description.optional()
value here, but I can't find a way to reach the digits4
and digits2
parsers results. I'm wondering: is it possible to extract digits4
, digits2
and description
values into a single Definition
object using the approach above? I was thinking of a Definition
builder implementation and passing it through the parsers chain somehow too. Or should it be rethought, and if so, then how?
If you want to use the return values of some or all of your parsers, then sequence(Parser<?> ... parsers)
is not the combinator you should use. Depending on the number of parsers you want to combine, you can use one of:
sequence()
combinators from 2 to 5 parsers, to which you can apply the appropriate map()
,list()
combinator which returns your parsers' results in a List<Object>
,array()
combinator which returns an Object[]
tuple()
combinators which return from 2 to 5-tuples.For separator tokens, you could benefit from using Parser.sepBy()
or Parser.followedBy()
: This would allow you to have a shorter sequence()
with only relevant results.