如何将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
相关产品推荐
相关产品推荐

