Skip to content

Dimankarp/parserka

Repository files navigation

parserka

Описание

Parserka - библиотека LL парсер-комбинаторов.

Прообазом и основным референсом послужила библиотека Parsec - Parsec paper.

Parser

Тип парсера представляет из себя обёртку над функцией, принимающей состояние State i и возвращающее значение типа Consumed = Consumed | Empty. Фактически Consumed позволяет сделать LL(1) парсер.

newtype Parser i a = Parser
  {runParser :: State i -> Consumed i a}

Sequence Combinator

Комбинатор, связывающий последовательные парсеры в один (>>=) реализуется как метод класса монада.

Логика работы следующая: если парсер завершился удачно, то управление передаётся следующему парсерсу, иначе - возвращается ошибка первого парсера. При этом большую роль играет то, потребил ли первый парсер элементы входного потока (Consumed) или нет (Empty)

instance Monad (Parser i) where
  p >>= f =
    Parser
      ( \state -> case (runParser p state) of
          Empty r1 ->
            case (r1) of
              Ok x state1 _ -> (runParser (f x) state1)
              Error msg -> Empty (Error msg)
          Consumed r1 ->
            Consumed
              ( case (r1) of
                  Ok x state1 _ -> case (runParser (f x) state1) of
                    Consumed r2 -> r2
                    Empty r2 -> r2
                  Error msg -> Error msg
              )
      )

Choice Combinator

Комбинатор, описывающий выбор из 2-х парсеров - левоцентричен, но приоритезирует Consumed результаты.

Логика работы следующая: если парсер завершился удачно и принял значение из потока, то его результат возвращается, иначе на том же стейте запускается второй парсер, если он успешен, то его результат выводится.

instance Alternative (Parser i) where
  p <|> q =
    Parser
      ( \state -> case (runParser p state) of
          Empty (Error msg1) -> case (runParser q state) of
            Empty (Error msg2) -> mergeError msg1 msg2
            Empty (Ok x state' msg2) -> mergeOk x state' msg1 msg2
            consumed -> consumed
          Empty (Ok x state' msg1) -> case (runParser q state) of
            Empty (Error msg2) -> mergeOk x state' msg1 msg2
            Empty (Ok _ _ msg2) -> mergeOk x state' msg1 msg2
            consumed -> consumed
          consumed -> consumed
      )

...

YAMLparserka

YAMLparserka - лексер и парсер подмножества языка YAML, написанный при помощи библиотеки parserka.

Поддерживает основные типы YAML, гетерогенные словари и массивы, идентацию.

Использование:

stack run YAMLparserka -- file.yaml
$ cat test.yaml
---
# all markdown
MD013: false # Line length
MD007: # Unordered list indentation
  indent: 4
MD051: false # Link fragments should be valid

# slides
MD035: false # Horizontal rule style
MD033: 
  - "br"
  - "div"

# need to be removed
MD045: false # Images should have alternate text (alt text)
MD025: false # Multiple top-level headings in the same document
MD011: false # Reversed link syntax conflix with maths.

MD041: false # Required for course note

---
B: 256
...

stack run YAMLparserka -- test.yaml
...
{
 "MD007";{
          "indent";4
         }

 "MD011";False
 "MD013";False
 "MD025";False
 "MD033";[
          "br",
          "div",
         ]

 "MD035";False
 "MD041";False
 "MD045";False
 "MD051";False
}
{
 "B";256
}

About

Parsec inspired parser combinator written in Haskell

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published