再帰によるパースは大きいテキストでこけるので再帰しないバージョン。
Imports System Imports System.Collections.Generic ' Ruby の Fixnum っぽいクラス Public Class Fixnum Private num_ As Integer Public Sub New(ByVal n As Integer) Me.num_ = n End Sub Public Property Value() As String Get Return Me.num_ End Get Set(ByVal val As String) Me.num_ = val End Set End Property Public Function Inc() Me.num_ += 1 Return Me.num_ End Function Public Function Dec() Me.num_ -= 1 Return Me.num_ End Function Public Function isZero() Return Me.num_ = 0 End Function Public Function isNonZero() Return Not isZero() End Function End Class Public Class ListObject Private Lstr As New List(Of Object) Sub New() Me.Lstr = New List(Of Object) Lstr.Add(Nothing) End Sub Public Function Head() Return Lstr(0) End Function Public Function Last() Return Lstr(Lstr.Count - 2) End Function Public Function Last2() Return Lstr(Lstr.Count) End Function Public Sub Clear() Lstr.Clear() Lstr.Add(Nothing) End Sub Public Function Tail() Dim Tarray() As Object = New Object(Lstr.Count) {} Dim i As Object Dim TailList As New ListObject Lstr.CopyTo(1, Tarray, 0, Lstr.Count - 1) TailList.Clear() For Each i In Tarray TailList.Push(i) Next i Return TailList End Function Public Sub Push(ByRef value As Object) Lstr(Lstr.Count - 1) = value Lstr.Add(Nothing) End Sub Public Sub Pop() If Lstr.Count > 1 Then Lstr.Remove(Nothing) Lstr(Lstr.Count - 1) = Nothing End If End Sub Public Function Show() Return "{" + AllList(Me) + "}" End Function Private Function AllList(ByRef list As ListObject) If IsNothing(list.Head) Then Return "" Else Return Tostr(list.Head()) + sPace(list.Tail) + AllList(list.Tail) End If End Function Private Function IsNothing(ByRef cell As Object) If TypeOf cell Is ListObject Then Return False Else If cell = Nothing Then Return True Else Return False End If End If End Function Private Function Tostr(ByRef cell As Object) If TypeOf cell Is ListObject Then Return cell.Show Else If TypeOf cell Is String Then Return """" + cell + """" Else Return cell.ToString End If End If End Function Private Function sPace(ByRef list As ListObject) If IsNothing(list.Head) Then Return "" Else Return "," End If End Function End Class Module Module1 Function StringToList(ByVal inString As String) Dim out As New ListObject Dim Str As String = "" Dim flag As Boolean = False Dim CharArray As Char() = New Char(inString.Length) {} Dim cnt As Fixnum = New Fixnum(inString.Length) Dim ch As Char inString.CopyTo(0, CharArray, 0, inString.Length) For Each ch In CharArray cnt.Dec() System.Console.Write("ch:" & ch & " ") If cnt.isZero Then System.Console.WriteLine(out.Show) Return out.Head Else ' "[" のときは末尾に空のリストを追加 If ch = "[" Then Dim ls As New ListObject out.Push(ls) System.Console.WriteLine(out.Show) Continue For ' "]" のときは末尾の要素を一段ネストの低いリストに追加 ElseIf ch = "]" Then Dim last As ListObject = out.Last out.Pop() Dim last2 As ListObject = out.Last out.Pop() last2.Push(last) out.Push(last2) System.Console.WriteLine(out.Show) Continue For ' "," は何もしない ElseIf ch = "," Then System.Console.WriteLine(out.Show) Continue For ' スペースは文字列フラグが立っているときだけ文字列に追加 ElseIf ch = " " Then If flag Then Str += ch End If System.Console.WriteLine(out.Show) Continue For ' """" は文字列フラグが立っているときは文字列の終了 ' 末尾のリストに文字列を追加。文字列のワークエリアをクリア ElseIf ch = """" Then If flag Then Dim ls As New ListObject ls = out.Last ls.Push(Str) out.Pop() out.Push(ls) Str = "" flag = False System.Console.WriteLine(out.Show) Continue For Else ' 文字列フラグが立っていないので文字列の開始 flag = True System.Console.WriteLine(out.Show) Continue For End If Else ' 文字列に1文字追加 Str += ch System.Console.WriteLine(out.Show) Continue For End If End If Next ch Return out.Head End Function Sub Main() Dim Lstr As String = "[[""A"",[""B""]],[[[""C""],""D""],""1""]]" Dim r As New ListObject r = StringToList(Lstr) Console.WriteLine("in :" & Lstr) ' in :[["A",["B"]],[[["C"],"D"],"1"]] System.Console.WriteLine("out :" & r.Show) ' out :{{"A",{"B"}},{{{"C"},"D"},"1"}} System.Console.WriteLine("Head:" & r.Head.Show) ' Head:{"A",{"B"}} System.Console.WriteLine("Tail:" & r.Tail.Show) ' Tail:{{{{"C"},"D"},"1"}} End Sub End Module
パースする様子。
ch:[ {{}} ch:[ {{},{}} ch:" {{},{}} ch:A {{},{}} ch:" {{},{"A"}} ch:, {{},{"A"}} ch:[ {{},{"A"},{}} ch:" {{},{"A"},{}} ch:B {{},{"A"},{}} ch:" {{},{"A"},{"B"}} ch:] {{},{"A",{"B"}}} ch:] {{{"A",{"B"}}}} ch:, {{{"A",{"B"}}}} ch:[ {{{"A",{"B"}}},{}} ch:[ {{{"A",{"B"}}},{},{}} ch:[ {{{"A",{"B"}}},{},{},{}} ch:" {{{"A",{"B"}}},{},{},{}} ch:C {{{"A",{"B"}}},{},{},{}} ch:" {{{"A",{"B"}}},{},{},{"C"}} ch:] {{{"A",{"B"}}},{},{{"C"}}} ch:, {{{"A",{"B"}}},{},{{"C"}}} ch:" {{{"A",{"B"}}},{},{{"C"}}} ch:D {{{"A",{"B"}}},{},{{"C"}}} ch:" {{{"A",{"B"}}},{},{{"C"},"D"}} ch:] {{{"A",{"B"}}},{{{"C"},"D"}}} ch:, {{{"A",{"B"}}},{{{"C"},"D"}}} ch:" {{{"A",{"B"}}},{{{"C"},"D"}}} ch:1 {{{"A",{"B"}}},{{{"C"},"D"}}} ch:" {{{"A",{"B"}}},{{{"C"},"D"},"1"}} ch:] {{{"A",{"B"}},{{{"C"},"D"},"1"}}} ch:] {{{"A",{"B"}},{{{"C"},"D"},"1"}}}
今のところリストの中味は全部文字列。