-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.R
38 lines (34 loc) · 861 Bytes
/
parser.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#' Parse s-expression
#'
#' @param s s-expression
parse <- function(s) {
read_from(tokenize(s), 1)[[1]]
}
tokenize <- function(s) {
s <- gsub("\\(", " ( ", s)
s <- gsub("\\)", " ) ", s)
s <- sub("^\\s+", "", s)
strsplit(s, "\\s+")[[1]]
}
read_from <- function(tokens, i) {
if (tokens[i] == "(") {
L <- list()
i <- i + 1 # skip "("
if (length(tokens) < i) stop("unexpected EOF while reading")
while (tokens[i] != ")") {
res <- read_from(tokens, i)
L <- append(L, res[1])
i <- res[[2]]
}
i <- i + 1 # skip ")"
return(list(L, i))
} else if (tokens[i] == ")") {
stop("unexpected )")
} else {
return(list(atom(tokens[i]), i + 1))
}
}
atom <- function(token) {
num <- suppressWarnings(as.numeric(token))
if (is.na(num)) token else num
}