2010-03-30 7 views
10

È possibile utilizzare l'estensione CPP sul codice Haskell che contiene stringhe di stringa multiple? Esistono altre tecniche di compilazione condizionale per Haskell?Estensione CPP e letterali multilinea in Haskell

Per esempio, prendiamo questo codice:

-- If the next line is uncommented, the program does not compile. 
-- {-# LANGUAGE CPP #-} 

msg = "Hello\ 
    \ Wor\ 
    \ld!" 

main = putStrLn msg 

Se io rimuovere il commento {-# LANGUAGE CPP #-}, quindi GHC confuta questo codice con un errore lessicale:

[1 of 1] Compiling Main    (cpp-multiline.hs, cpp-multiline.o) 

cpp-multiline.hs:4:17: 
    lexical error in string/character literal at character 'o' 

Utilizzando GHC 6.12.1, cpphs è disponibile .

Confermo che l'utilizzo del wrapper cpphs.compat e dell'opzione -pgmP cpphs.compat aiuta, ma mi piacerebbe avere una soluzione che non dipenda dagli script di shell personalizzati. -pgmP cpphs non funziona.

P.S. Devo usare un codice diverso per GHC < 6.12 e GHC> = 6.12, è possibile senza il preprocessore?

UPD. Oltre alla risposta accettata di Ganesh, ho anche scoperto che un'altra soluzione consiste nel mettere tutte le dichiarazioni condizionali in un modulo separato con {-# LANGUAGE CPP #-} e quindi evitare CPP nei moduli con stringhe multilinea.

+0

Perché non usare '" Hello "++" Wor "++" ld! "'? – kennytm

+0

Perché '" Hello \ whitespace + \ World! "' È Haskell 98. Perché c'è del codice attorno al quale lo usa. Perché '" ++ ++ 'richiede più spazio (e non mi piace il codice oltre 80 colonne). Infine, mi piacerebbe scrivere una patch senza re-wrapping e riformattando ogni stringa multilinea nel progetto. – sastanin

risposta

6

cpphs ora ha un'opzione --cpp sé, che a mio avviso rende lo script compat inutile: vedere le cpphs 1.3 entrata a http://haskell.org/cpphs/

Penso che avresti bisogno di passare -optP --cpp a GHC (così come -pgmP cpphs) per abilitare questo comportamento.

2

Sembra che gli indirizzi GHC manuale questo: Section 4.10.3.1 legge

A small word of warning: -cpp is not friendly to “string gaps”.. In other words, strings such as the following:

strmod = "\ 
\ p \ 
\ " 

don't work with -cpp; /usr/bin/cpp elides the backslash-newline pairs.

However, it appears that if you add a space at the end of the line, then cpp (at least GNU cpp and possibly other cpps) leaves the backslash-space pairs alone and the string gap works as expected.

+0

Grazie. Ho provato ad aggiungere spazi finali dopo \, ma cpp riporta solo un avviso 'backslash e newline separati da spazio', e il codice non viene ancora compilato. Uso di GNU cpp 4.4.3. – sastanin