パソコン活用研究5番街(Visual Basic、Excel(VBA)、BASIC プログラミング研究)

入力データが整数かどうか判定する
(準備中)

空白を区切りとして入力されたデータから整数に合致するデータを抜きだして表示し、整数以外のデータ(文字)
があった場合はそこで処理を停止するようなプログラムを考えてみます。

こういう字句解析のプログラムはいろいろなところで応用がききますので。

正規表現の使えるプログラム言語(perl,ruby,python等)なら正規表現でマッチさせるコードをたった1行書くだけ
なんですが(−>整数を表す正規表現と有限オートマトン参照)
旧BASICでは正規表現が使えませんので地道に字句解析のプログラムを書くことになります。

プログラムとしてはほぼ有限オートマトンと実装するというような感じになります。
正規表現とか有限オートマトンの具体的な理解が深まるというメリットもあるので、BASICでやってみるのも
一興ではあります。

今回は、
空白を区切りとして入力されたデータから整数に合致するデータを抜きだして表示し、整数以外のデータ(文字)
があった場合はそこで処理を停止するようなプログラム
とします。
なお、整数として許容する形を以下の通りとします。
(整数の定義)
・0はOKだが、-0, +0 という形式は許容しない。
・先頭に0は付けることは許容しない。00, 03, 050 という表現は許容しない。
・負を表す- はOkだが、正の数には+を付けることは許容しない。

その場合の正規表現は以下の通りで、正規表現の使えるプログラム言語ならあっさり解決なんですが・・。
/^0$|^([\-]?[1-9])[0-9]*$/

この整数にマッチする有限オートマトン

○の中の数字は、状態を表しており以下のProgramの変数typeの値になります。
0・・初期状態
1・・1文字目に0が来た状態。今回は00というような表現を許さないので、先頭に0が来た場合は2文字目があったらエラーにします。
2・・1文字目が1〜9 or 2文字目以降が0〜9の状態
3・・1文字目にマイナス(-)が来た場合。次の文字は1〜9のみ許容します。-0という表現は許容しません。



以下のプログラムは、N88互換Basic for Windowsを使っています。
MS系のBasicならほぼ「どのBasicでもそのまま動作すると思います。

このプログラム(regexp_int.bas)では、
入力された文字列(a$に入力)を先頭から1文字づつ読み取って、整数にマッチするかどうか判定しながら
整数にマッチすればトークン化する(token$)という、いわゆるlexcal analyserみたいなことをやっています。

ひとつひとつの動作を可視化するために、
読み取った文字が、上記の状態0〜3のどれに当たるかを表示していきます。
(例)
0:type : 1
読み取った文字: type : 状態(0〜3 10はエラー)

読み込みが終了すると(エラーが発生した場合はエラー発生直前まで)、トークン化した結果を表示します。

5 dim token$(20)
10 input a$
14 'type 0・・初期状態 1・・1文字目0 2・・1文字目0以外の数値 3・・1文字目- 5・・演算子 10・・エラー
15 n=0:type=0 'type 0・・初期状態 1・・1文字目0 2・・1文字目0以外の数値 3・・1文字目- 10・・エラ
20 l=len(a$)
30 for i=1 to l
40 moji$=mid$(a$,i,1)
50 if type=3 then gosub 2500: goto 85
60 if type=2 then gosub 2000: goto 85
65 if type=1 then gosub 1500: goto 80
70 if type=0 then gosub 1000
80 if moji$=" " then type=0 : print moji$;":type:";type '空白が連続していてもtype=0を継続
85 if type=10 then print moji$;":type:";"error":goto 100
90 next
100 for i=1 to n
110 print "token";i;":";token$(i)
120 next
130 if type=10 then print "error"
500 end

1000 type=10 'いったん全てerror type=10 としておく
1010 if (asc(moji$)>=&H31 and asc(moji$)<=&H39) then n=n+1: type=2
1020 if moji$="-" then n=n+1: type=3
1030 if moji$="0" then n=n+1: type=1
1040 'if (moji$="+" or moji$="*" or moji$="/") then n=n+1: gosub 1300
1045 if moji$=" " then type=0
1050 if type>0 and type<10 then token$(n)=token$(n)+moji$:print moji$;":type:";type '空白文字の出力は80行で行うのでここではパス
1070 return

1500 if moji$=" " then type=0 else type=10
1510 return
2000 if (asc(moji$)>=&H30 and asc(moji$)<=&H39) then type=2: token$(n)=token$(n)+moji$ else if moji$=" " then type=0 else type=10
2020 if type=2 or type=0 then print moji$;":type:";type
2030 return
2500 if (asc(moji$)>=&H31 and asc(moji$)<=&H39) then type=2 else type=10
2510 if type=2 then token$(n)=token$(n)+moji$: print moji$;"type:";type
2520 return





さて、せっかくここまで作ったので、このプログラムを活用して、四則演算の計算機にまで
発展させてみたいと思います。
まずは、今回のプログラムを活用して、入力された文字列(式)の字句解析を行いトークン化する
ところまでをやってみます。=>「計算機を作ってみる(字句解析)


TOP PAGE >Basic活用研究目次