Haskell 中的 CPP 扩展和多行文字

发布于 2024-08-27 03:58:17 字数 1006 浏览 9 评论 0原文

是否可以在包含多行字符串文字的 Haskell 代码上使用 CPP 扩展? Haskell 还有其他条件编译技术吗?

例如,让我们看一下这段代码:

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

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

main = putStrLn msg

如果我取消注释 {-# LANGUAGE CPP #-},那么 GHC 就会用词法错误反驳这段代码:

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

Using GHC 6.12.1, cpphs is available。

我确认使用 cpphs.compat 包装器和-pgmP cpphs.compat 选项有帮助,但我希望有一个不依赖于自定义 shell 脚本的解决方案。 -pgmP cpphs 不起作用。

PS 我需要对 GHC < 使用不同的代码6.12 且 GHC >= 6.12,是否可以不用预处理器?

UPD。除了 Ganesh 接受的答案之外,我还发现另一种解决方法是将所有条件声明放在带有 {-# LANGUAGE CPP #-} 的单独模块中,从而避免在具有多行的模块中使用 CPP字符串。

Is it possible to use CPP extension on Haskell code which contains multiline string literals? Are there other conditional compilation techniques for Haskell?

For example, let's take this code:

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

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

main = putStrLn msg

If I uncomment {-# LANGUAGE CPP #-}, then GHC refutes this code with a lexical error:

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

Using GHC 6.12.1, cpphs is available.

I confirm that using cpphs.compat wrapper and -pgmP cpphs.compat option helps, but I'd like to have a solution which does not depend on custom shell scripts. -pgmP cpphs does not work.

P.S. I need to use different code for GHC < 6.12 and GHC >= 6.12, is it possible without preprocessor?

UPD. In addition to the accepted answer of Ganesh, I also found that another workaround is to put all conditional declarations in a separate module with {-# LANGUAGE CPP #-} and thus avoid CPP in the modules with multiline strings.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤千羽 2024-09-03 03:58:17

cpphs 现在本身有一个 --cpp 选项,我认为这使得 compat 脚本变得不必要:请参阅 http:// /haskell.org/cpphs/

我认为您需要将 -optP --cpp 传递给 GHC (以及 -pgmP cpphs)才能启用这种行为。

cpphs now has a --cpp option itself, which I think makes the compat script unnecessary: see the cpphs 1.3 entry at http://haskell.org/cpphs/

I think you'd need to pass -optP --cpp to GHC (as well as -pgmP cpphs) to enable this behaviour.

只为守护你 2024-09-03 03:58:17

GHC 用户手册似乎解决了这个问题: 第 4.10.3.1 节 内容如下

警告:-cpp 对“字符串间隙”不友好。换句话说,如下字符串:

strmod = "\
\ p \
\ "

不与-cpp一起使用; /usr/bin/cpp 省略反斜杠-换行符对。

但是,如果您在行尾添加空格,则 cpp(至少是 GNU cpp 以及可能的其他 cpp)会单独保留反斜杠-空格对,并且字符串间隙将按预期工作。

It seems the GHC user manual addresses this: Section 4.10.3.1 reads

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.

掌心的温暖 2024-09-03 03:58:17

决定是

strmod = "\
 p \
 "

反斜杠后不需要空格,并且行开头不需要反斜杠。

The decision is

strmod = "\
 p \
 "

No spaces after backslash needed plus no backslash needed at the line begin.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文