2

我有一个 JParsec 解析器,它由几个“较小”的解析器组成,我想提取用这些解析器解析的总值。比方说:

//                          V-- because of sequence()
private static final Parser<Object> definitionParser = sequence(
        substitute, separator, digits4, separator, digits2, separator, description.optional()
);

上面的一些解析器是虚拟的,用于分隔数据字段。虚拟解析器是substituteand separator,我不会从中提取任何东西。但是,其余的解析器让我感兴趣:

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

但是,mappingsubstituteDefinition解析器需要一个Map<Object, Definition>接口实现,将最后一个排序解析器的结果传播description.optional()Map实现,并且传入的参数是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
    }
});

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

4

2 回答 2

2

如果您想使用部分或全部解析器的返回值,则sequence(Parser<?> ... parsers)不是您应该使用的组合器。根据要组合的解析器数量,您可以使用以下之一:

  • sequence()从 2 到 5 个解析器的覆盖组合器,您可以对其应用适当的map(),
  • list()返回解析器结果的组合器为List<Object>,
  • array()返回一个的组合器Object[]
  • tuple()从 2 到 5 元组返回的组合器。

对于分隔符标记,您可以从使用Parser.sepBy()or中受益Parser.followedBy():这将允许您缩短sequence()只有相关结果的时间。

于 2016-11-14T16:50:49.447 回答
1

如今,sequence 使用的组合器。sequence 的最后一个参数可以是一个 lambda,您将从之前指定的解析器中获取所有结果。

所以你得到Parsers.sequence(parserA, parserB, parserC, (a, b, c) -> make_the_parser_result_using_a_b_c);

于 2019-06-14T15:48:07.233 回答