3

I have strings, which describe mathematical formulas and I would like to convert it into lists of meaningful parts. The function ast_ does know how to parse it, to displays it as an Abstract Syntax Tree but does not return the AST. I am looking for a function which does return the tree.

bb <- "(media.urin_A + media.urin_B)/2"
lazyeval::ast_(rlang::parse_expr(bb))
> lazyeval::ast_(rlang::parse_expr(bb))
┗ ()
 ┗ `/
 ┗ ()
  ┗ `(
  ┗ ()
   ┗ `+
   ┗ `media.urin_A
   ┗ `media.urin_B
 ┗  2 
witek
  • 984
  • 1
  • 8
  • 25
  • 1
    The `ast()` function is just for printing. You can just run `as.list()` on the expression to turn it into a list which is basically the ast: `as.list(rlang::parse_expr(bb))`. What exactly do you want to do with the result that you can't do in it's current form? You can use `[]` and `[[]]` indexing into an expression. – MrFlick Feb 05 '20 at 20:35

1 Answers1

3

You can construct one recursively using as.list() and map_if from purrr:

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

# Example usage on expressions:
getAST( quote(log10(a+5)/b) )
# List of 3
#  $ : symbol /
#  $ :List of 2
#   ..$ : symbol log10
#   ..$ :List of 3
#   .. ..$ : symbol +
#   .. ..$ : symbol a
#   .. ..$ : num 5
#  $ : symbol b

# Example usage on strings:
getAST( str2lang("(media.urin_A + media.urin_B)/2") )
# List of 3
#  $ : symbol /
#  $ :List of 2
#   ..$ : symbol (
#   ..$ :List of 3
#   .. ..$ : symbol +
#   .. ..$ : symbol media.urin_A
#   .. ..$ : symbol media.urin_B
#  $ : num 2
Artem Sokolov
  • 13,196
  • 4
  • 43
  • 74