gpt4 book ai didi

metaprogramming - 宏和字符串插值 (Julia)

转载 作者:行者123 更新时间:2023-12-04 06:55:44 25 4
gpt4 key购买 nike

假设我制作了这个简单的字符串宏

macro e_str(s)
return string("I touched this: ",s)
end

如果我将它应用于带有插值的字符串,我
获得:
julia> e"foobar $(log(2))"
"I touched this: foobar \$(log(2))"

而我想获得:
julia> e"foobar $(log(2))"
"I touched this: foobar 0.6931471805599453"

我必须对我的宏声明进行哪些更改?

最佳答案

最好在编译时解析字符串,而不是委托(delegate)给 Julia。基本上,将字符串放入 IOBuffer , 扫描字符串中的 $标志,并使用 parse每当它们出现时就起作用。

macro e_str(s)
components = []
buf = IOBuffer(s)
while !eof(buf)
push!(components, rstrip(readuntil(buf, '$'), '$'))
if !eof(buf)
push!(components, parse(buf; greedy=false))
end
end
quote
string($(map(esc, components)...))
end
end

这不适用于转义的 $字符,但这可以通过处理 \ 的一些小改动来解决还。我在这篇文章的底部包含了一个基本示例。

我这样写是因为字符串宏通常不用于模拟 Julia 字符串——带有常规字符串文字的常规宏更适合此目的。所以自己编写解析并没有那么糟糕,特别是因为它允许自定义扩展。如果您真的希望解析与 Julia 解析它的方式相同,您可以转义字符串然后重新解析它,正如@MattB 建议的那样:
macro e_str(s)
esc(parse("\"$(escape_string(s))\""))
end

结果表达式是 :string您可以转储和检查的表达式,然后按通常的方式进行分析。



字符串宏没有内置的插值工具。但是,可以手动实现此功能。请注意,如果不转义与周围字符串宏具有相同分隔符的字符串文字,则无法嵌入;也就是说,尽管 """ $("x") """是可能的, " $("x") "不是。相反,这必须转义为 " $(\"x\") " .

手动实现插值有两种方法:手动实现解析,或者让 Julia 进行解析。第一种方法更灵活,但第二种方法更容易。

手动解析
macro interp_str(s)
components = []
buf = IOBuffer(s)
while !eof(buf)
push!(components, rstrip(readuntil(buf, '$'), '$'))
if !eof(buf)
push!(components, parse(buf; greedy=false))
end
end
quote
string($(map(esc, components)...))
end
end

Julia 解析
macro e_str(s)
esc(parse("\"$(escape_string(s))\""))
end

此方法转义字符串(但请注意 escape_string 不会转义 $ 符号)并将其传递回 Julia 的解析器进行解析。必须转义字符串以确保 "\不影响字符串的解析。结果表达式是 :string表达式,可以为宏观目的检查和分解。

关于metaprogramming - 宏和字符串插值 (Julia),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39493808/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com