50 lines
996 B
Text
50 lines
996 B
Text
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
|