Reputation: 2589
I want a parse rule that only recognizes numbers between 0 and 32767. I tried something like:
integerConstant
^ (#digit asParser min: 1 max: 5) flatten
==> [ :string | | value |
value := string asNumber.
(value between: 0 and: 32767)
ifTrue: [ value ]
ifFalse: [ **???** ]]
But I have no idea what to write for the ???. I thought about return a PPFailure, but this requires knowing the stream position.
Upvotes: 4
Views: 196
Reputation: 8947
As you suspect, you can make the action return a PPFailure. While in general this is not good style (mixes syntactic and semantic analysis) it is sometimes helpful. In the tests of PetitParser there are a few examples. Good uses you see at PPXmlGrammar>>#element
and PPSmalltalkGrammar>>#number
.
The position of a PPFailure is just something PetitParser provides to its users (tools). It is not something used for the parsing itself, thus you can set it to 0 if you feel lazy. Alternatively you can fetch the current position in the input using the following example:
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 ] ]
Upvotes: 8