Регулярные выражения против лексических анализаторов в 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 описываются некоторые более глубокие вопросы.