我正在为我在Haskell中编写的基本编译器制作一个扫描程序。其中一个要求是用单引号(')括起来的任何字符都被翻译成字符文字标记(类型为T_Char),这包括转义序列,如'\ n'和'\ t'。我已经定义了扫描仪功能的这一部分,它适用于大多数情况:
scanner ('\'':cs) | (length cs) == 0 = error "Illegal character!"
| head cs == '\\' = mkEscape (head (drop 1 cs)) : scanner (drop 3 cs)
| head (drop 1 cs) == '\'' = T_Char (head cs) : scanner (drop 2 cs)
where
mkEscape :: Char -> Token
mkEscape 'n' = T_Char '\n'
mkEscape 'r' = T_Char '\r'
mkEscape 't' = T_Char '\t'
mkEscape '\\' = T_Char '\\'
mkEscape '\'' = T_Char '\''
然而,当我在GHCi中运行时会出现这种情况:
Main> scanner "abc '\\' def"
[T_Id "abc", T_Char '\'', T_Id "def"]
它可以识别其他所有内容,但会使用转义的单引号与转义后的反斜杠混淆。这与字符编码有关吗?
答案 0 :(得分:5)
我认为解析器没有关于你的问题的任何问题。对于Haskell,该字符串将被读作
abc '\' def
因为Haskell也有字符串转义。因此,当它到达第一个引号时,cs
包含char序列\' def
。显然head cs
是反斜杠,因此会运行mkEscape
。
给出的论点是head (drop 1 cs)
,'
,因此mkEscape
将返回T_Char '\''
,这就是您所看到的。
也许你应该打电话给
scanner "abc '\\\\' def"
第一级\
用于Haskell解释器,第二级用于scanner
。