如何自动给任意的Julia表达式加上括号 [英] How to automatically parenthesize an arbitrary Julia expression

查看:93
本文介绍了如何自动给任意的Julia表达式加上括号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出一个句法上有效的,但不是任意的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)

例如,对于最后一种情况,用全括号"表示:

:(((2 + 9) - ((8 * (8 ^ 7)) / 2)) == (8 + (8 / (1 ^ 2))))

还有别的吗?

解决方案

您需要一些代码以递归方式遍历引用的表达式.

我在这里举了一个示例,该示例适用于像+, -这样的中缀操作,如果您使用像f(a)

这样的函数调用,它将失败

每个表达式都有3个字段,分别是headtypargs,但是只有headargs有用,因为typ在大多数情况下大多是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)

Given a syntactically valid, but otherwise arbitrary, Julia expression, such as

3 - 4 > 1 & 2 + 2 == 4 | 10 - 5 > 2

or

2 + 9 - 8 * 8 ^ 7 / 2 == 8 + 8 / 1 ^ 2

...is there a convenient way to fully parenthesize the expression in a way consistent with Julia's standard parsing of it?

One approach that won't go far enough:

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)

For example, for the last case, by "full parenthesized" I mean:

:(((2 + 9) - ((8 * (8 ^ 7)) / 2)) == (8 + (8 / (1 ^ 2))))

Is there something else?

解决方案

You need some code to traverse the quoted expression recursively.

I have made an example here which works for infix operations like +, - and will fail if you use function calls like this f(a)

Each of the Expressions has 3 fields, head, typ, and args, but only head and args are usesful as typ is mostly Any most of the time. You can see this using

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表达式加上括号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆