Регулярные выражения против лексических анализаторов в Haskell

Я начинаю с Haskell и пытаюсь использовать инструмент Alex для создания регулярных выражений, и я немного растерялся; Моим первым неудобством была компиляция. Как мне сделать, чтобы скомпилировать файл с Алексом? Затем я думаю, что мне нужно импортировать в мой код модули, которые генерирует alex, но не уверен. Если кто-то может мне помочь, я был бы очень признателен!

3 ответа

Вы можете указать функции регулярного выражения в Alex.

Вот, например, регулярное выражение в Alex, чтобы соответствовать числам с плавающей запятой:

$space       = [\ \t\xa0]
$digit       = 0-9
$octit       = 0-7
$hexit       = [$digit A-F a-f]

@sign        = [\-\+]
@decimal     = $digit+
@octal       = $octit+
@hexadecimal = $hexit+
@exponent    = [eE] [\-\+]? @decimal

@number      = @decimal
             | @decimal \. @decimal @exponent?
             | @decimal @exponent
             | 0[oO] @octal
             | 0[xX] @hexadecimal

lex :-

   @sign? @number { strtod }

Когда мы сопоставляем число с плавающей запятой, мы отправляем функцию синтаксического анализа, чтобы работать с этой захваченной строкой, которую мы можем затем обернуть и представить пользователю как функцию синтаксического анализа:

readDouble :: ByteString -> Maybe (Double, ByteString)
readDouble str = case alexScan (AlexInput '\n' str) 0 of
    AlexEOF            -> Nothing
    AlexError _        -> Nothing
    AlexToken (AlexInput _ rest) n _ ->
       case strtod (B.unsafeTake n str) of d -> d `seq` Just $! (d , rest)

Хорошим следствием использования Alex для сопоставления с регулярным выражением является то, что производительность хорошая, так как механизм регулярных выражений компилируется статически. Он также может быть представлен как обычная библиотека на Haskell, созданная с помощью Cabal. Для полной реализации см. Bytestring-lexing.

Общий совет о том, когда использовать лексер вместо сопоставителя регулярных выражений, заключается в том, что, если у вас есть грамматика для лексем, которые вы пытаетесь сопоставить, как я сделал для плавающей запятой, используйте Alex. Если вы этого не сделаете, и структура более специальная, используйте движок регулярных выражений.

Почему вы хотите использовать alex для создания регулярных выражений? Если все, что вам нужно, это сделать какое-то сопоставление с регулярным выражением и т.д., вы должны взглянуть на пакет регулярного выражения.

Если вам нужен обычный Regex, API указывается в text.regex.base. Затем идут реализации text.regex.Posix, text.regex.pcre и несколько других. Документация по Haddoc немного скудна, однако основы описаны в Real World Haskell, глава 8. В этом вопросе SO описываются некоторые более глубокие вопросы.

Другие вопросы по тегам