Haskell: парсинг escape-символов в одинарных кавычках - PullRequest
2 голосов
/ 15 февраля 2010

В настоящее время я делаю сканер для базового компилятора, который я пишу на Haskell. Одним из требований является то, что любой символ, заключенный в одинарные кавычки ('), преобразуется в символьный литерал (тип T_Char), и это включает escape-последовательности, такие как' \ 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"]

Может распознавать все остальное, но экранированные обратные косые черты перепутаны с экранированными одинарными кавычками. Это как-то связано с кодировками символов?

1 Ответ

5 голосов
/ 15 февраля 2010

Я не думаю, что с парсером что-то не так в отношении вашей проблемы. Для Хаскелла строка будет читаться как

abc '\' def

потому что у Haskell также есть экранированные строки. Поэтому, когда он достигает первой кавычки, cs содержит последовательность символов \' def. Очевидно, head cs является обратной косой чертой, поэтому он будет работать mkEscape.

В качестве аргумента приводится head (drop 1 cs), то есть ', поэтому mkEscape вернет T_Char '\'', что вы и видели.


Возможно, вам следует позвонить

scanner "abc '\\\\' def"

1-й уровень \ предназначен для интерпретатора Haskell, а 2-й уровень - для scanner.

...