3

我想要一个只能识别 0 到 32767 之间数字的解析规则。我尝试了类似的方法:

integerConstant
  ^ (#digit asParser min: 1 max: 5) flatten
      ==> [ :string | | value |
            value := string asNumber.
            (value between: 0 and: 32767)
              ifTrue: [ value ]
              ifFalse: [ **???** ]]

但我不知道该为 ??? 写什么。我想过返回一个 PPFailure,但这需要知道流的位置。

4

1 回答 1

7

正如您所怀疑的,您可以使操作返回 PPFailure。虽然总的来说这不是很好的风格(混合了句法和语义分析),但有时它是有帮助的。在 PetitParser 的测试中有几个例子。PPXmlGrammar>>#element您在和处看到的良好用途PPSmalltalkGrammar>>#number

PPFailure 的位置只是 PetitParser 提供给它的用户(工具)的东西。它不是用于解析本身的东西,因此如果您感到懒惰,可以将其设置为 0。或者,您可以使用以下示例获取输入中的当前位置:

positionInInput
    "A parser that does not consume anything, that always succeeds and that 
     returns the current position in the input."

    ^ [ :stream | stream position ] asParser

integerConstant
    ^ (self positionInInput , (#digit asParser min: 1 max: 5) flatten) map: [ :pos :string |
        | value |
        value := string asNumber.
        (value between: 0 and: 32767)
           ifTrue: [ value ]
           ifFalse: [ PPFailure message: value , ' out of range' at: pos ] ]
于 2013-03-12T23:24:10.260 回答