Haskell:用单引号解析转义字符

ben*_*wad 2 parsing haskell character-encoding

我正在为我在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 '\''
Run Code Online (Sandbox Code Playgroud)

但是,当我在GHCi中运行它时会出现这种情况:

Main> scanner "abc '\\' def"
[T_Id "abc", T_Char '\'', T_Id "def"]
Run Code Online (Sandbox Code Playgroud)

它可以识别其他所有内容,但会将转义后的反斜杠与转义单引号混淆.这与字符编码有关吗?

ken*_*ytm 5

我认为解析器没有关于你的问题的任何问题.对于Haskell,该字符串将被读作

abc '\' def
Run Code Online (Sandbox Code Playgroud)

因为Haskell也有字符串转义.所以当它到达第一个引号时,cs包含char序列\' def.显然head cs是一个反斜杠,所以它会运行mkEscape.

给出的论证head (drop 1 cs)',因此mkEscape将返回T_Char '\'',这就是你所看到的.


也许你应该打电话

scanner "abc '\\\\' def"
Run Code Online (Sandbox Code Playgroud)

第一级\是Haskell解释器,第二级是scanner.