t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

Webで動くVBAチュートリアルを作りたい その3

とりあえず昨日は文字列とそれ以外を切り分けたが、今日はそのつづき。文字列以外の要素はさらにスペースで分割して配列に入れてみる。

 

【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

ここまで完全に自己流。そのうち破綻するんじゃないかと思い、先日購入した「やさしいインタープリタの作り方入門」をちらっと除いみたところ、字句解析の部分はだいたい似たようなことをやっていてひと安心した。

あちらは切り分けながら要素の解析もしているが、こちらはとりあえず要素に切り分けて配列にぶち込んだだけ。まぁ切ってしまえばあとはなんとでもなるだろう。

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。