如何自动给任意 Julia 表达式加上括号
How to automatically parenthesize an arbitrary Julia expression
给定一个语法上有效但任意的 Julia 表达式,例如
3 - 4 > 1 & 2 + 2 == 4 | 10 - 5 > 2
或
2 + 9 - 8 * 8 ^ 7 / 2 == 8 + 8 / 1 ^ 2
...是否有方便的方法完全括号表达式以符合 Julia 标准解析的方式?
一种方法还不够:
julia> parse("3 - 4 > 1 & 2+2 == 4 | 10 - 5 > 2")
:(3 - 4 > 1 & 2 + 2 == (4 | 10) - 5 > 2)
julia> parse("2 + 9 - 8 * 8 ^ 7 / 2 == 8 + 8 / 1 ^ 2")
:((2 + 9) - (8 * 8^7) / 2 == 8 + 8 / 1^2)
例如,对于最后一种情况,"full parenthesized" 我的意思是:
:(((2 + 9) - ((8 * (8 ^ 7)) / 2)) == (8 + (8 / (1 ^ 2))))
还有别的吗?
您需要一些代码来递归遍历引用的表达式。
我在这里做了一个例子,它适用于像 +, -
这样的中缀操作,如果你使用这样的函数调用将会失败 f(a)
每个表达式都有 3 个字段,head
、typ
和 args
,但只有 head
和 args
有用,因为 [=大多数时候 14=] 大多是 Any
。你可以使用
看到这个
expr = :(1+2*3)
typeof(expr)
fieldnames(expr)
expr.head
expr.args
# full solution
function bracketit(expr)
if expr isa Symbol
return string(expr)
elseif expr isa Expr
if expr.head == :call
return string("(",bracketit(expr.args[2]),expr.args[1],bracketit(expr.args[3]),")")
elseif expr.head == :comparison
return string("(",bracketit.(expr.args)...,")")
end
else
return(string(expr))
end
end
exprA = :(3 - 4 > 1 & 2 + 2 == 4 | 10 - 5 > 2)
bracketit(exprA) #((3-4)>((1&2)+2)==((4|10)-5)>2)
exprB = :(2 + 9 - 8 * 8 ^ 7 / 2 == 8 + 8 / 1 ^ 2) #(((2+9)-((8*(8^7))/2))==(8+(8/(1^2))))
bracketit(exprB)
给定一个语法上有效但任意的 Julia 表达式,例如
3 - 4 > 1 & 2 + 2 == 4 | 10 - 5 > 2
或
2 + 9 - 8 * 8 ^ 7 / 2 == 8 + 8 / 1 ^ 2
...是否有方便的方法完全括号表达式以符合 Julia 标准解析的方式?
一种方法还不够:
julia> parse("3 - 4 > 1 & 2+2 == 4 | 10 - 5 > 2")
:(3 - 4 > 1 & 2 + 2 == (4 | 10) - 5 > 2)
julia> parse("2 + 9 - 8 * 8 ^ 7 / 2 == 8 + 8 / 1 ^ 2")
:((2 + 9) - (8 * 8^7) / 2 == 8 + 8 / 1^2)
例如,对于最后一种情况,"full parenthesized" 我的意思是:
:(((2 + 9) - ((8 * (8 ^ 7)) / 2)) == (8 + (8 / (1 ^ 2))))
还有别的吗?
您需要一些代码来递归遍历引用的表达式。
我在这里做了一个例子,它适用于像 +, -
这样的中缀操作,如果你使用这样的函数调用将会失败 f(a)
每个表达式都有 3 个字段,head
、typ
和 args
,但只有 head
和 args
有用,因为 [=大多数时候 14=] 大多是 Any
。你可以使用
expr = :(1+2*3)
typeof(expr)
fieldnames(expr)
expr.head
expr.args
# full solution
function bracketit(expr)
if expr isa Symbol
return string(expr)
elseif expr isa Expr
if expr.head == :call
return string("(",bracketit(expr.args[2]),expr.args[1],bracketit(expr.args[3]),")")
elseif expr.head == :comparison
return string("(",bracketit.(expr.args)...,")")
end
else
return(string(expr))
end
end
exprA = :(3 - 4 > 1 & 2 + 2 == 4 | 10 - 5 > 2)
bracketit(exprA) #((3-4)>((1&2)+2)==((4|10)-5)>2)
exprB = :(2 + 9 - 8 * 8 ^ 7 / 2 == 8 + 8 / 1 ^ 2) #(((2+9)-((8*(8^7))/2))==(8+(8/(1^2))))
bracketit(exprB)