如何使用嵌入字符串标记字符串?

时间:2013-05-15 16:45:39

标签: regex haskell lexical-analysis alex

我正在学习如何使用名为Alex 1 的Haskell词法分析器工具。

我正在尝试为此字符串实现词法分析器(电子邮件“From:”标题):

From: "John Doe" <john@doe.org>

我想把它分解成这个令牌列表:

[
  From,
  DisplayName "John Doe",
  Email,
  LocalName "john",
  Domain "doe.org"
]

以下是我的实施。如果字符串不包含显示名称,它可以正常工作。也就是说,这很好用:

let s = "From: <john@doe.org>"
alexScanTokens s

但是,当我包含显示名称时,我收到以下错误消息:

[From*** Exception: lexical error

也就是说,这会导致错误:

let s = "From: \"John Doe\" <john@doe.org>"
alexScanTokens s

我猜我的Alex程序的这一部分导致错误:

\"[a-zA-Z ]+\"      { \s -> DisplayName (init (tail s)) }

Alex中,左侧是正则表达式:

\"[a-zA-Z ]+\"

,右侧是找到与正则表达式匹配的字符串时要采取的操作:

{ \s -> DisplayName (init (tail s)) }

关于问题可能是什么的任何想法?

这是我的词法分析器程序:

{
module Main (main) where
}

%wrapper "basic"

$digit = 0-9            -- digits
$alpha = [a-zA-Z]       -- alphabetic characters

tokens :-

  $white+                    ;
  From:                     { \s -> From }
  \"[a-zA-Z ]+\"            { \s -> DisplayName (init (tail s)) }
  \<                        { \s -> Email }
  [$alpha]+@                 { \s -> LocalPart (init s) }
  [$alpha\.]+>               { \s -> Domain (init s) }

{
-- Each action has type :: String -> Token

-- The token type:
data Token =
    From                               |
    DisplayName String                 |
    Email                              |
    LocalPart String                   |
    Domain String       
    deriving (Eq,Show)

main = do
  s <- getContents
  print (alexScanTokens s)
}

1 可以在以下网址找到“Alex”词法分析工具:http://www.haskell.org/alex/doc/html/introduction.html

1 个答案:

答案 0 :(得分:7)

这是"John Doe"中造成麻烦的空间。

Whitespace is ignored in character sets,如[a-zA-Z ]。要包含空格,您需要使用反斜杠来逃避它,例如: [a-zA-Z\ ]

另外,我不禁注意到词法分析器可能是这项工作的错误工具。考虑使用例如编写适当的解析器Parsec