Как правило разбора PetitParser может сигнализировать об ошибке?
Я хочу правило разбора, которое распознает только числа от 0 до 32767. Я пробовал что-то вроде:
integerConstant
^ (#digit asParser min: 1 max: 5) flatten
==> [ :string | | value |
value := string asNumber.
(value between: 0 and: 32767)
ifTrue: [ value ]
ifFalse: [ **???** ]]
Но я понятия не имею, что написать для??? Я думал о возврате PPFailure, но это требует знания позиции потока.
1 ответ
Как вы подозреваете, вы можете заставить действие вернуть 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 ] ]