深さを自由に表現できるリストをパースする
まず、どのような動作をすれば良いか書いてみる。
str=%([["A",["B"]],["C","1"]]) 希望する結果 リストをスタックに保存 そのための 結果 しながら管理する様子 命令 [] s0[] s[0]=[] [[]] [[]] s0[] s1[] s[1]=[] [[],[]] [["A"]] s0[] s1["A"] s[1].push("A") [[], ["A"]] [["A",[]]] s0[] s1["A"] s2[] s[2]=[] [[], ["A"],[]] [["A",["B"]]] s0[] s1["A"] s2["B"] s[2].push("B") [[], ["A"],["B"]] s0[] s1["A",["B"]] s[1].push(s.pop) [[], ["A", ["B"]]] s0[["A",["B"]]] s[0].push(s.pop) [[["A", ["B"]]]] [["A",["B"]],[]] s0[["A",["B"]]] s1[] s[1]=[] [[["A", ["B"]]], []] [["A",["B"]],["C"]] s0[["A",["B"]]] s1["C"] s[1].push("C") [[["A", ["B"]]], ["C"]] [["A",["B"]],["C","1"]] s0[["A",["B"]]] s1["C","1"] s[1].push("1") [[["A", ["B"]]], ["C", "1"]] s0[["A",["B"]],["C","1"]] s[0].push(s.pop) [["A", ["B"]], ["C", "1"]]
そのための命令 s[1]=[] : "[" と出会ったとき s[1].push(s.pop) : "]" と出会ったとき s[1].push("C") : 終わりの '"'と出会ったとき 終わりかはじめかはフラグで
class String def head; self[0].chr end def tail; self[1...(self.length)] end end class Array def head; self[0] end def tail; self[1...(self.length)] end end # str=%([["A",["B",["0-16-087"]]],["C","1","0-06-074"]]) str=%([["A",["B"]],["C","1"]]) def myEval(inString, out, n,tstr, flag) return out if inString.length==1 head = inString.head tail = inString.tail if head == '[' then n+=1 out[n]=[] p ["[[[[",n,out] myEval(tail, out, n, tstr, flag) elsif head == ']' then n-=1 out[n].push(out.pop) p ["]]]]",n,out] myEval(tail, out, n, tstr, flag) elsif head == ',' then myEval(tail, out, n,tstr, flag) elsif head == '"' then if flag then out[n].push(tstr) p ["push",n,out] myEval(tail, out, n, "", false) else myEval(tail, out, n, tstr, true) end else myEval(tail, out, n, (tstr + head) , true) end end p myEval(str, [] , -1,"" ,false).head
["[[[[", 0, [[]]] ["[[[[", 1, [[], []]] ["push", 1, [[], ["A"]]] ["[[[[", 2, [[], ["A"], []]] ["push", 2, [[], ["A"], ["B"]]] ["]]]]", 1, [[], ["A", ["B"]]]] ["]]]]", 0, [[["A", ["B"]]]]] ["[[[[", 1, [[["A", ["B"]]], []]] ["push", 1, [[["A", ["B"]]], ["C"]]] ["push", 1, [[["A", ["B"]]], ["C", "1"]]] ["]]]]", 0, [[["A", ["B"]], ["C", "1"]]]] [["A", ["B"]], ["C", "1"]]
位置を示す n は必要なくて末尾の要素に対する操作でよい。
def myEval(inString, out,tstr, flag) return out if inString.length==1 head = inString.head tail = inString.tail if head == '[' then out.push([]) myEval(tail, out, tstr, flag) elsif head == ']' then d = out.pop (out.last).push(d) myEval(tail, out, tstr, flag) elsif head == ',' then myEval(tail, out,tstr, flag) elsif head == '"' then if flag then (out.last).push(tstr) myEval(tail, out, "", false) else myEval(tail, out, tstr, true) end else myEval(tail, out, (tstr + head) , true) end end