とりあえず昨日は文字列とそれ以外を切り分けたが、今日はそのつづき。文字列以外の要素はさらにスペースで分割して配列に入れてみる。
【Debug.Printの結果】
MsgBox "こんにちは""" & Name & """さん。" & vbNewLine & "お元気ですか?"
↓
memory(0)←[MsgBox]
memory(1)←["こんにちは"""]
memory(2)←[&]
memory(3)←[Name]
memory(4)←[&]
memory(5)←["""さん。"]
memory(6)←[&]
memory(7)←[vbNewLine]
memory(8)←[&]
memory(9)←["お元気ですか?"]
演算子とか丸カッコをどう区切ろうか悩んでいたが一晩寝たらスッキリ解決。スペースで区切る前にスペース付きに置換するのが一番簡単だった。
以下コード。
FindString関数の部分は、前回の記事から変更なしのためそちらを参照のこと。
Sub test() Dim Memory() As String st = "MsgBox ""こんにちは"""""" & Name & """"""さん。" & _ """ & vbNewLine & ""お元気ですか?""" Debug.Print st & vbNewLine & vbTab & "↓" buf = st sumlen = 0 ReDim Memory(0) Do While sumlen < Len(st) result = FindString(buf) sumlen = sumlen + Len(result) buf = Mid(st, sumlen + 1) If Left(result, 1) = """" Then Memory(UBound(Memory)) = result ReDim Preserve Memory(UBound(Memory) + 1) Else '文字列以外の項目をスペースでSplitする。 '演算子や丸カッコも分割点になるので、 'スペースで区切る前に先にそれらの記号の前後にスペースをつけておく。 'Splitの結果、Lengthが0なら無視 result = Replace(result, "&", " & ") result = Replace(result, "+", " + ") result = Replace(result, "-", " - ") result = Replace(result, ")", " ) ") result = Replace(result, "(", " ( ") result = Replace(result, "*", " * ") result = Replace(result, "/", " / ") result = Replace(result, "=", " = ") result = Replace(result, ",", " , ") result = Replace(result, "'", " ' ") result = Replace(result, vbTab, " ") Dim results() As String results = Split(result, " ") For i = 0 To UBound(results) If Trim(results(i)) <> "" Then Memory(UBound(Memory)) = Trim(results(i)) ReDim Preserve Memory(UBound(Memory) + 1) End If Next End If Loop 'ひとつMemoryを作りすぎるので、消す ReDim Preserve Memory(UBound(Memory) - 1) For i = 0 To UBound(Memory) Debug.Print "memory(" & i & ")←[" & Memory(i) & "]" Next i Debug.Print vbNewLine End Sub
ここまで完全に自己流。そのうち破綻するんじゃないかと思い、先日購入した「やさしいインタープリタの作り方入門」をちらっと除いみたところ、字句解析の部分はだいたい似たようなことをやっていてひと安心した。
あちらは切り分けながら要素の解析もしているが、こちらはとりあえず要素に切り分けて配列にぶち込んだだけ。まぁ切ってしまえばあとはなんとでもなるだろう。