CPP-Erweiterung und mehrzeilige Literale in Haskell
-
23-09-2019 - |
Frage
Ist es möglich, CPP-Erweiterung zu verwenden, um auf Haskell Code, der Literale mehrzeilige Zeichenfolge enthält? Gibt es andere bedingte Kompilierung Techniken für Haskell?
Zum Beispiel, nehmen wir diesen Code:
-- If the next line is uncommented, the program does not compile.
-- {-# LANGUAGE CPP #-}
msg = "Hello\
\ Wor\
\ld!"
main = putStrLn msg
Wenn ich uncomment {-# LANGUAGE CPP #-}
, dann GHC widerlegt diesen Code mit einem lexikalischen Fehler:
[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'
Mit GHC 6.12.1, cpphs verfügbar ist.
Ich bestätige, dass die Verwendung von cpphs.compat Wrapper und -pgmP cpphs.compat
Option hilft, aber ich möchte eine Lösung haben, die auf benutzerdefinierten Shell-Skripten abhängig ist. -pgmP cpphs
funktioniert nicht.
P. S. Ich brauche für GHC unterschiedlichen Code zu verwenden <6,12 und GHC> = 6,12, ist es möglich, ohne Präprozessor?
UPD . Neben der akzeptierte Antwort von Ganesh, fand ich auch, dass eine andere Abhilfe alle bedingten Erklärungen in einem separaten Modul mit {-# LANGUAGE CPP #-}
zu setzen und damit vermeiden CPP in den Modulen mit mehrzeiligen Strings.
Lösung
cpphs hat jetzt eine --cpp Option selbst, was ich denke, das compat Skript überflüssig macht: siehe cpphs 1.3 Eintrag unter http://haskell.org/cpphs/
Ich glaube, Sie müssen -optP --cpp
zu GHC passieren (wie auch -pgmP cpphs
) dieses Verhalten zu ermöglichen.
Andere Tipps
Es scheint, die GHC Bedienungsanleitung Adressen folgt aus: Abschnitt 4.10.3.1 liest
Ein kleines Wort der Warnung: -cpp ist nicht freundlich zu „string Lücken“ .. Mit anderen Worten, Strings wie folgt:
strmod = "\
\ p \
\ "
nicht mit -cpp arbeiten; / Usr / bin / cpp elides die Backslash-Newline-Paare.
Es scheint jedoch, dass, wenn Sie ein Leerzeichen am Ende der Zeile hinzufügen, dann CPP (zumindest GNU CPP und möglicherweise auch andere CPPS) verlassen die Backslash-Raum-Paare allein und die String-Lücke funktioniert wie erwartet.