aro*_*oyc 10 python type-conversion abstract-syntax-tree julia
Julia中有什么东西相当于literal_eval包ast(Abstract Syntax Tree)提供的Python 吗?
其(literal_eval)描述摘要:
此函数仅评估Python文字结构:字符串,字节,数字,元组,列表,字符串,集合,布尔值,以及
None可用于安全地评估来自不受信任来源的字符串,而无需自行解析值.它无法评估任意复杂的表达式,例如涉及运算符或索引.
Ste*_*ski 14
没有等价物,尽管你可以通过解析代码然后递归地确保在评估它之前在结果表达式中只有某些句法形式,从而可以很容易地编写一个.但是,与许多基本类型及其语法和行为内置且不可更改的Python不同,Julia的"内置"类型只是用户定义的类型,恰好在系统启动之前定义.让我们来探索一下会发生什么,例如,当你使用矢量文字语法时:
julia> :([1,2,3]) |> dump
Expr
head: Symbol vect
args: Array{Any}((3,))
1: Int64 1
2: Int64 2
3: Int64 3
typ: Any
julia> f() = [1,2,3]
f (generic function with 2 methods)
julia> @code_lowered f()
CodeInfo(:(begin
nothing
return (Base.vect)(1, 2, 3)
end))
julia> methods(Base.vect)
# 3 methods for generic function "vect":
vect() in Base at array.jl:63
vect(X::T...) where T in Base at array.jl:64
vect(X...) in Base at array.jl:67
Run Code Online (Sandbox Code Playgroud)
所以[1,2,3]只是一种语法形式,它被降低为对Base.vect函数的调用,即Base.vect(1,2,3).现在,我们将来可能会"封锁"某些函数,以便无法以任何方式添加任何子方法或覆盖其行为,但目前修改Base.vect某些参数集的行为是完全可能的:
julia> function Base.vect(a::Int, b::Int, c::Int)
warn("SURPRISE!")
return invoke(Base.vect, Tuple{Any,Any,Any}, a, b, c)
end
julia> [1,2,3]
WARNING: SURPRISE!
3-element Array{Int64,1}:
1
2
3
Run Code Online (Sandbox Code Playgroud)
由于数组文字在Julia中是可重载的,因此它并不是纯粹的文字语法.当然,我不建议做我刚做的事 - "惊喜!" 不是你想在程序中间看到的东西 - 但它是可能的,因此在这个问题意义上语法不是"安全的".在Python或JavaScript(或大多数脚本语言)中用文字表达的一些其他构造在Julia中是显式函数调用,例如构造字典:
julia> Dict(:foo => 1, :bar => 2, :baz => 42)
Dict{Symbol,Int64} with 3 entries:
:baz => 42
:bar => 2
:foo => 1
Run Code Online (Sandbox Code Playgroud)
这只是Dict对具有三对对象参数的类型的函数调用,而不是文字语法.在a => b对语法本身也只是一个函数调用一个特殊的语法=>运营商,这是对的别名Pair类型:
julia> dump(:(a => b))
Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol =>
2: Symbol a
3: Symbol b
typ: Any
julia> :foo => 1.23
:foo=>1.23
julia> =>
Pair
julia> Pair(:foo, 1.23)
:foo=>1.23
Run Code Online (Sandbox Code Playgroud)
整数文字怎么样?当然那些都是安全的!嗯,是的,不.小整数文字当前是安全的,因为它们在解析器中直接转换为Int值,没有任何可重载的入口点(将来可能会改变,但允许用户代码选择不同的整行文字行为).但是,足够大的整数文字会降低为宏调用,例如:
julia> :(18446744073709551616)
:(@int128_str "18446744073709551616")
Run Code Online (Sandbox Code Playgroud)
对于Int64类型而言太大的整数文字被降低为带有包含整数数字的字符串参数的宏调用,允许宏解析字符串并返回一个适当的整数对象 - 在这种情况下是一个Int128值 - 将被拼接到抽象中语法树.但您可以为这些宏定义新行为:
julia> macro int128_str(s)
warn("BIG SUPRISE!")
9999999999999999
end
julia> 18446744073709551616
WARNING: BIG SUPRISE!
9999999999999999
Run Code Online (Sandbox Code Playgroud)
从本质上讲,朱莉娅没有有意义的"安全文字子集".从哲学上讲,Julia与Python非常不同:Julia不是在具有用户定义类型无法访问的特殊功能的固定类型集中构建,而是在语言中包含足够强大的机制,可以从内部构建语言 - 一个过程被称为"自举".这些强大的语言机制与Julia程序员一样,对Julia的程序员也是如此.这就是朱莉娅的灵活性和力量的来源.但是,强大的力量带来了巨大的责任和所有......所以除非你有一个非常好的理由,否则不要做我在这个答案中所做的任何事情:)
为了回到原来的问题,使用Julia语法为安全文字对象构造创建解析器最好的方法是为Julia的子集实现解析器,以不能重载的方式赋予文字通常的含义.例如,这个安全的语法子集可以包括数字文字,字符串文字,数组文字和Dict构造函数.但是使用JSON语法并使用Julia的JSON包解析它可能更实际.
| 归档时间: |
|
| 查看次数: |
450 次 |
| 最近记录: |