Как правило разбора 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 ] ]
Другие вопросы по тегам