2016-11-13 43 views
1

我有一個由幾個「小」分析器組成的JParsec分析器,我想提取用這些分析器解析的總值。假設:如何從JParsec中的序列解析器中提取所有值?

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

上面的一些解析器是啞元,用於分隔數據字段。虛擬解析器是substituteseparator,我不打算從它們中提取任何東西。然而,解析器的其餘部分使我感興趣:

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 

然而,map平的substituteDefinition解析器需要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解析器結果。我想知道:是否可以使用上述方法將digits4digits2description值提取到單個Definition對象中?我正在考慮一個Definition構建器實現,並將它通過解析器鏈以某種方式傳遞給。還是應該重新考慮,如果是的話,那麼如何?

回答

2

如果您想使用部分或全部解析器的返回值,那麼sequence(Parser<?> ... parsers)不是您應該使用的組合器。根據要合併解析器的數目,您可以使用一個:

  • 的重寫sequence() 2-5解析器組合程序,您可以向其中應用適當的map()
  • list()組合子返回你分析器導致List<Object>
  • array()組合子返回一個Object[]
  • tuple()組合子從2回到5元組。

對於分隔標記,你可以受益於使用Parser.sepBy()Parser.followedBy():這將讓你有唯一的相關結果的短sequence()

+0

它像一個魅力工作!非常感謝你!請再說一個問題:是否可以過濾掉''分析器?爲什麼我問:我正在提取像'l.get(2)','l.get(4)'和'l.get(6)'這樣的有效值,而且它看起來並不自然我。我的意思是,爲了分別用'l.get(0)','l.get(1)'和'l.get(2)'提取值,是否可以組合解析器的分隔符?我目前使用'list()'combinator。 –

+1

正如我在回答的最後一段中所建議的那樣,您可以執行'substitute.followedBy(separator)'而不是將兩個解析器按順序排列。 'followedBy'內解析器的返回值被忽略。 – insitu

+0

我會試一試。謝謝! –