2010-02-15 4 views
2

Je suis en train de faire un scanner pour un compilateur de base que j'écris dans Haskell. L'une des exigences est que tout caractère entre guillemets simples (') soit traduit en jeton littéral de caractère (type T_Char), et ceci inclut des séquences d'échappement telles que' \ n 'et' \ t '. J'ai défini cette partie de la fonction du scanner qui fonctionne bien pour la plupart des cas:Haskell: Analyse des caractères d'échappement dans des guillemets simples

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 '\'' 

Cependant, cela arrive quand je le lance dans GHCi:

Main> scanner "abc '\\' def" 
[T_Id "abc", T_Char '\'', T_Id "def"] 

Il peut reconnaître tout le reste, mais obtient des backslashes échappés confondus avec des guillemets simples échappés. Est-ce quelque chose à voir avec les encodages de caractères?

Répondre

5

Je ne pense pas qu'il y ait quelque chose de mal avec l'analyseur concernant votre problème. Pour Haskell, la chaîne sera lue comme

abc '\' def 

parce que Haskell a aussi une chaîne d'échappement. Ainsi, lorsqu'il atteint le premier guillemet, cs contient la séquence de caractères \' def. De toute évidence, head cs est une barre oblique inverse, de sorte qu'il va exécuter mkEscape.

L'argument donné est head (drop 1 cs), qui est ', ainsi mkEscape renverra T_Char '\'', qui est ce que vous avez vu.


Peut-être que vous devriez appeler

scanner "abc '\\\\' def" 

Le 1er niveau de \ est pour l'interprète Haskell, et le 2ème niveau est pour scanner.

+0

Je vois. Cela signifie-t-il que cela fonctionnera bien si vous lisez un fichier plutôt que d'utiliser l'interpréteur? – benwad

+0

@benwad: Oui. _ – kennytm

Questions connexes