2013-03-12 42 views
3

我想,只有0和32767之间的数字识别解析规则,我想是这样的:PetitParser解析规则如何发出错误信号?

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

但我不知道该怎么写的???。我想回到PPFailure,但这需要知道流的位置。

回答

7

正如您怀疑的那样,您可以使该操作返回PPFailure。虽然通常这不是很好的风格(混合语法和语义分析),但它有时很有用。在PetitParser的测试中有几个例子。您在PPXmlGrammar>>#elementPPSmalltalkGrammar>>#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 ] ] 
+0

好吧,疯狂的解决方案,但工作:-)。你有没有特意写出“self positionInput”,还是你的意思是“positionInput”作为一个实例变量? – 2013-03-13 16:16:20

+0

您不需要循环中未使用的规则的实例变量。如果解析器'positionInInput'足够常见,它可以移到某个地方的工厂方法中,甚至在它自己的PPParser子类中。 – 2013-03-16 23:21:08