Во-первых, вам нужно определить свое абстрактное синтаксическое дерево, вероятно, как некоторые объявленные типы данных.Затем вы хотите определить ваши основные действия разбора.Например,
type ParseResult = Either String AST
type ParseState = (ParseResult, String)
Ваше действие синтаксического анализа является простым:
re, sq, ba, el :: ParseState -> ParseState
, где re
- это действие синтаксического анализатора верхнего уровня.
Может выглядеть конкретный шаг синтаксического анализакак это:
el (_, ('(':restOfInput)) = case re (Right restOfInput) of
err@(Left error, s) -> err
(result, ')':s) -> (El result, s)
(_, s) -> (Left "no closing parens", s)
el (_, input@(c:restOfInput)) = if lowerOrDigit c
then (El c, restOfInput)
else (Left "bad character", "")
Когда библиотека синтаксического анализа покупает вам много усилий, она обрабатывает все состояния синтаксического анализа и распространяет ошибки вверх по стеку вызовов.