Search code examples
rcran

Parse a string with (dots) arguments


Is there a way to parse a string with arguments into a list of language objects? For example:

> query <- "mpg, cyl, hp:vs"
> eval(parse(text=paste0("dplyr:::dots(", query, ")")))
[[1]]
mpg

[[2]]
cyl

[[3]]
hp:vs

But that is ugly, can result in code injection, etc. Is there a way to parse the query part separately without injecting it into R code? I would really like to use the native parser and avoid manually modifying the code using string manipulation, because the arguments can contain code or comma's in themselves. For example:

query2 <- "foo, 'flip,flop', function(x){print('foo', x)}"
eval(parse(text=paste0("dplyr:::dots(", query2, ")")))

should yield:

[[1]]
foo

[[2]]
[1] "flip,flop"

[[3]]
function(x) {
    print("foo", x)
}

Solution

  • # First, create a string that represents a function call
    string <- paste0("c(", query, ")")
    
    # Next, parse it, and extract the function call
    call <- parse(text = string)[[1]]
    
    # Finally, remove the first element (`c`) and
    # convert to a list
    as.list(call[-1])
    

    No code is evaluated so you should be safe from code-injection. (Although of course there could be buffer overrun bugs in parse)