如何从JParsec中的有序解析器中提取所有值?

时间:2022-09-11 21:23:34

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:

我有一个JParsec解析器,它包含一些“较小”的解析器,我想提取用这些解析器解析的总值。让我们说:

//                          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, mapping 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:

但是,映射substituteDefinition解析器需要Map 接口实现,将最后一个排序的解析器description.optional()的结果传播到Map实现,并且传入的参数是String: ,definition>

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?

显然,我只能在这里提取description.optional()值,但我找不到达到digits4和digits2解析器结果的方法。我想知道:是否可以使用上述方法将digits4,digits2和description值提取到单个Definition对象中?我正在考虑一个“定义”构建器实现,并以某种方式将其传递给解析器链。或者应该重新思考,如果是,那又如何?

1 个解决方案

#1


2  

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(Parser ...解析器)不是您应该使用的组合子。根据要组合的解析器数量,您可以使用以下方法之一:

  • The overriden sequence() combinators from 2 to 5 parsers, to which you can apply the appropriate map(),
  • 覆盖2到5个解析器的sequence()组合子,你可以应用适当的map(),

  • The list() combinator which returns your parsers' results in a List<Object>,
  • list()组合器返回解析器的结果在List 中,

  • The array() combinator which returns an Object[]
  • 返回Object []的array()组合子

  • The tuple() combinators which return from 2 to 5-tuples.
  • 元组()组合子从2到5元组返回。

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.

对于分隔符标记,您可以从使用Parser.sepBy()或Parser.followedBy()中受益:这将允许您使用仅具有相关结果的较短序列()。

#1


2  

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(Parser ...解析器)不是您应该使用的组合子。根据要组合的解析器数量,您可以使用以下方法之一:

  • The overriden sequence() combinators from 2 to 5 parsers, to which you can apply the appropriate map(),
  • 覆盖2到5个解析器的sequence()组合子,你可以应用适当的map(),

  • The list() combinator which returns your parsers' results in a List<Object>,
  • list()组合器返回解析器的结果在List 中,

  • The array() combinator which returns an Object[]
  • 返回Object []的array()组合子

  • The tuple() combinators which return from 2 to 5-tuples.
  • 元组()组合子从2到5元组返回。

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.

对于分隔符标记,您可以从使用Parser.sepBy()或Parser.followedBy()中受益:这将允许您使用仅具有相关结果的较短序列()。