3

在 PetitParser2 中,如何匹配一组封闭的标记,例如月份名称?例如(在伪代码中) [ :word | MonthNames anySatisfy: [ :mn | mn beginsWith: word ] ] asParser.

PPPredicateSequenceParser似乎有可能,但您似乎必须提前知道字符串的大小。我想我可以这样做:

| monthRules |
    monthRules := Array streamContents: [ :unamused: |
        MonthNames collect: [ :e | 
            s nextPut: e asString asPParser.
            s nextPut: (e first: 3) asPParser ] ].
    ^ PP2ChoiceNode withAll: monthRules

但我想知道是否有内置/直截了当的东西

4

2 回答 2

3

其他更笨拙且效率更低的选择是使用自定义块:

[ :context | 
    | position names |
    names := #('January' 'February' 'March' 'April').   
    position := context position.
    names do: [ :name | 
        (context next: name size) = name ifTrue: [  
            ^ name
        ] ifFalse: [ 
            context position: position
        ]
    ].
    ^ PP2Failure new
] asPParser parse: 'April'

不过我不建议这样做,因为 PP2 对块一无所知并且无法应用任何优化。

于 2019-11-29T07:58:41.950 回答
2

我建议对集合中的每个元素使用解析器:

monthsParser := 'January' asPParser / 
                'February' asPParser / 
                'March' asPParser.
monthsParser parse: 'January'

或者,从集合中创建选择解析器:

names := #('January' 'February' 'March' 'April').
monthsParser := PP2ChoiceNode withAll: (names collect: [ :l | 
                    l asPParser ]).
monthsParser parse: 'January'

PP2 的“优化”应该很快选择正确的替代方案。

于 2019-11-26T08:43:06.947 回答