S-expressions
func sexpr(txt) {
txt.trim!
if (txt.match(/^\((.*)\)$/s)) {|m|
txt = m[0]
}
else {
die "Invalid: <<#{txt}>>"
}
var w
var ret = []
while (!txt.is_empty) {
given (txt.first) {
when('(') {
(w, txt) = txt.extract_bracketed('()');
w = sexpr(w)
}
when ('"') {
(w, txt) = txt.extract_delimited('"')
w.sub!(/^"(.*)"/, {|s1| s1 })
}
else {
txt.sub!(/^(\S+)/, {|s1| w = s1; '' })
}
}
ret << w
txt.trim_beg!
}
return ret
}
func sexpr2txt(String e) {
e ~~ /[\s"\(\)]/ ? do { e.gsub!('"', '\\"'); %Q("#{e}") } : e
}
func sexpr2txt(expr) {
'(' + expr.map {|e| sexpr2txt(e) }.join(' ') + ')'
}
var s = sexpr(%q{
((data "quoted data" 123 4.5)
(data (!@# (4.5) "(more" "data)")))
})
say s # dump structure
say sexpr2txt(s) # convert back
Output:
[["data", "quoted data", "123", "4.5"], ["data", ["!@#", ["4.5"], "(more", "data)"]]]
((data "quoted data" 123 4.5) (data (!@# (4.5) "(more" "data)")))
Last updated