【问题标题】:Regular expressions versus lexical analyzers in HaskellHaskell 中的正则表达式与词法分析器
【发布时间】:2010-06-21 22:26:37
【问题描述】:

我开始使用 Haskell,我正在尝试使用 Alex 工具来创建正则表达式,但我有点迷茫;我的第一个不便是编译部分。我必须如何使用 Alex 编译文件?然后,我认为我必须将 alex 生成的模块导入到我的代码中,但不确定。如果有人可以帮助我,我将非常感激!

【问题讨论】:

  • 这甚至是一个正则表达式问题吗?如果是这样,如果您标记它regex,您可能会得到更多回复。不过,它似乎没有,所以如果你重新命名它,也许你会得到更多的回复,比如“Alex 在 Haskell 中的问题”(有Alex 标签吗?需要吗?)
  • 我个人一直使用 Antlr 进行正则表达式工作,尤其是使用 AntlrWorks,它允许您可视化和可视化调试正则表达式。不过,这个问题也可能对你有帮助……stackoverflow.com/questions/1364259/…

标签: regex haskell lexical-analysis alex


【解决方案1】:

您可以在 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 进行这种正则表达式匹配的一个很好的结果是性能很好,因为正则表达式引擎是静态编译的。它也可以作为使用 cabal 构建的常规 Haskell 库公开。完整实现见bytestring-lexing

关于何时使用词法分析器而不是正则表达式匹配器的一般建议是,如果您有要匹配的词位的语法,就像我对浮点数所做的那样,请使用 Alex。如果您不这样做,并且结构更加临时,请使用正则表达式引擎。

【讨论】:

  • 谢谢唐斯图尔特,这就是我一直在寻找的,因为我真正想做的是创建一个词法和语法分析器,这就是我试图创建正则表达式的原因......谢谢大家,你们都帮了很多忙:)
  • 对不起,如果我打扰了你,但你能解释一下最后一行“d 的 case strtod (B.unsafeTake n str) -> d seq Just $! (d , rest )",因为我不明白
  • 哦,那只是在词位上运行'strtod',然后严格返回结果。
  • 我拿了你的代码来看看结果如何,但它给了我一个错误,这就是为什么我想了解看看它有什么问题
  • 从 Alex 示例目录中获取代码,该目录位于 Alex 的源 tarball 中。
【解决方案2】:

为什么要使用 alex 创建正则表达式? 如果你只想做一些正则表达式匹配等,你应该看看 regex-base 包。

【讨论】:

  • 我真正想做的是一个词法和句法分析器,这就是我与 alex 合作的原因:)
【解决方案3】:

如果你想要的是普通的 Regex,API 在text.regex.base 中指定。然后是实现 text.regex.Posixtext.regex.pcre 和其他几个。 Haddoc 文档有点薄,但是Real World Haskell, chapter 8. 中描述了基础知识@ 987654325@ 中描述了一些更深入的内容。

【讨论】:

  • 我真正想做的是一个词法和句法分析器,这就是我与 alex 合作的原因:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
  • 1970-01-01
相关资源
最近更新 更多