You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将R语言中算术表达式的抽象语法树转换为函数调用形式?

算术表达式转嵌套函数调用形式

需求

给定算术表达式(例如 x + y*z),需要将其转换为嵌套函数调用的形式(例如 add(x, multiply(y, z)))。

现有思路

我找到一个生成抽象语法树(AST)的实用函数:

getAST <- function(ee) purrr::map_if(as.list(ee), is.call, getAST)
getAST(quote(x + y*z)) 
# [[1]]
# `+`
# 
# [[2]]
# x
# 
# [[3]]
# [[3]][[1]]
# `*`
# 
# [[3]][[2]]
# y
# 
# [[3]][[3]]
# z

可以用 rapply(result, as.character, how = "list") 将AST中的符号转换为字符类型。

待解决的问题

如何基于上述AST结果生成目标格式的函数调用?尤其是当表达式包含括号时,情况会更复杂,比如:

getAST(quote((x + y) * z)) 
# [[1]]
# `*`
# 
# [[2]]
# [[2]][[1]]
# `(`
# 
# [[2]][[2]]
# [[2]][[2]][[1]]
# `+`
# 
# [[2]][[2]][[2]]
# x
# 
# [[2]][[2]][[3]]
# y
# 
# 
# 
# [[3]]
# z

我不强制要求必须使用getAST函数,这只是一种可行思路,实际场景中表达式会更长。


无括号场景的可行方案

以下是我认为可行的无括号情况解决方案:

getAST <- function(ee) purrr::map_if(as.list(ee), is.call, getAST)

ast <- rapply(getAST(quote(x + y*z)), as.character, how = "list")

convertAST <- function(ast) {
  op <- switch(
    ast[[1]],
    "+" = "add",
    "-" = "subtract",
    "*" = "multiply",
    "/" = "divide"
  )
  left <- ast[[2]]
  right <- ast[[3]]
  if(is.character(left) && is.character(right)) {
    return(sprintf("%s(%s, %s)", op, left, right))
  }
  if(is.character(left)) {
    return(sprintf("%s(%s, %s)", op, left, convertAST(right)))
  }
  if(is.character(right)) {
    return(sprintf("%s(%s, %s)", op, convertAST(left), right))
  }
  return(sprintf("%s(%s, %s)", op, convertAST(left), convertAST(right)))
}

convertAST(ast)

内容的提问来源于stack exchange,提问作者Stéphane Laurent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 03:43:12