This is probably a general programming question but I am using Ruby as my
lang of choice hence a post to this group.
I am trying to convert a flat list (array) of tokens into a nested list
(hence the name UNflatten) using a simple rule:
Every token which looks like ‘(’ begins a nested list and the corresponding
’)’ token ends it … in a recursive fashion.
e.g:
[“a”, “(”,“b”, “)”] ==> [“a”,[ “b” ]]
[ “(”, “a”, “(”,“b”, “)”, “)”] ==> [[“a”,[“b”]]]
Of course, I also want a function (reflatten) which traverses the nested
list to generate the original back.
My first attempt looks like this (see code below).
Any suggestions to improve will be highly appreciated.
Right now I don’t care as much for the efficiency as for the ecomony of
expression.
Thanks,
– Shanko
···
def reflatten(list,left = ‘(’, right = ‘)’,accu=[],level = 0)
print level,'<=' if $DEBUG
p list, accu if $DEBUG
return accu if not list
if list.length < 1
print '.1.' if $DEBUG
accu += [right] if level > 0
return accu
else
e = list[0]
if e.type == list.type
print '.2.' if $DEBUG
accu = reflatten(e,left,right,accu + [left],level+1)
reflatten(list[1..-1],left,right,accu,level)
else
print '.3.' if $DEBUG
reflatten(list[1..-1],left,right,accu+[e],level)
end
end
end
def unflatten(list, left = ‘(’,right = ‘)’,accu = [], level = 0)
print level,’=>’ if $DEBUG
p list,accu if $DEBUG
return accu if list.length < 1
e = list[0]
if e == left
print '.1.' if $DEBUG
unflatten(list[1..-1],left,right,accu << [], level+1)
else
if e == right
if (level > 1) and (accu[-2].type == accu.type)
print '.2.' if $DEBUG
unflatten(list[1..-1],left,right,accu[0..-3] << (accu[-2] <<
accu[-1]),level-1)
else
print ‘.3.’ if $DEBUG
unflatten(list[1…-1],left,right,accu,level-1)
end
else
if level > 0
print ‘.4.’ if $DEBUG
unflatten(list[1…-1],left,right,accu[0…-2] << accu[-1] +
[e],level)
else
print ‘.5.’ if $DEBUG
unflatten(list[1…-1],left,right,accu+[e],level)
end
end
end
end
if $0 == FILE
s = "( ( ( a ( b ) ( ( c ) d ) ( e ) f ) ) )"
# s = "R ( b ( c ( ( a ( Z ) ) ( k ) ) d ) e ) ( a ( b ) ( c ( d ) ) e )
U ( d e ) B ( f ) Y "
puts s
t = s.split
u = unflatten(t)
p u
puts
r = reflatten(u)
p r
puts
puts r.join(" ")
end