2010-02-15 4 views
2

В настоящее время я делаю сканер для базового компилятора, который я пишу в Haskell. Одним из требований является то, что любой символ, заключенный в одинарные кавычки ('), преобразуется в символьный токен символа (тип T_Char), и это включает в себя escape-последовательности, такие как' \ n 'и' \ t '. Я определил эту часть функции сканера, который работает хорошо для большинства случаев:Haskell: Разбор символов пробела в одинарных кавычках

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"] 

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

ответ

5

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

abc '\' def 

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

Приведенное рассуждение является head (drop 1 cs), который ', таким образом mkEscape вернет T_Char '\'', что то, что вы видели.


Может быть, вы должны вызвать

scanner "abc '\\\\' def" 

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

+0

Я вижу. Означает ли это, что это будет хорошо работать при чтении файла вместо использования интерпретатора? – benwad

+0

@benwad: Да. _ – kennytm

Смежные вопросы