使用 Alex 词法分析器我正在创建一个词法分析器来标记电子邮件“来自标头”。这是一个示例标题:
From: "John Doe" <john@doe.org>
“John Doe”被称为“显示名称”,我们假设它可以包含任何 ASCII 字符。
同样让我们假设电子邮件地址的部分可以由任何 ASCII 字符组成。
下面是我的 Alex 程序。当我在上面的“From header”上运行它时,我只得到一个令牌:
[TokenString "From: \"John Doe\" <john@doe.org>"]
显然这条规则:
$us_ascii_character+ { \s -> TokenString s }
优先于所有其他规则。为什么?
我认为优先级基于规则在我的程序中物理列出的顺序:检查输入字符串是否匹配第一个规则,如果不匹配则检查输入字符串是否匹配第二个规则,等等。不?
如何表达我的规则,以便词法分析器将“From header”标记为这些标记:
From, :, "John Doe", <, john, @, doe, ., org, >
并且显示名称和电子邮件部分可以包含任何 ASCII 字符?
这是我的亚历克斯词法分析器:
{
module Main (main) where
}
%wrapper "posn"
$digit = 0-9
$alpha = [a-zA-Z]
$us_ascii_character = [\t\n\r\ !\"\#\$\%\&\'\(\)\*\+\,\-\.\/0123456789\:\;\<\=\>\?\@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\DEL]
tokens :-
$white+ ;
\(.*\) ;
From { \s -> TokenFrom }
: { \s -> TokenColon }
" { \s -> TokenQuote }
\< { \s -> TokenLeftAngleBracket }
> { \s -> TokenRightAngleBracket }
@ { \s -> TokenAtSign }
\. { \s -> TokenPeriod }
$us_ascii_character+ { \s -> TokenString s }
{
-- Each action has type :: String -> Token
-- The token type:
data Token =
TokenFrom |
TokenColon |
TokenQuote |
TokenLeftAngleBracket |
TokenRightAngleBracket |
TokenAtSign |
TokenPeriod |
TokenString String
deriving (Eq,Show)