トークンを取得する関数をつくる準備
さて、もう一度生成規則を再掲すると
1. SPEC_SYM → '=' | ';' | ':' | ',' | '.' | '+' | '-'
2. NON_KEY_ID → ALPHA ALPHANUMS
3. ALPHA → 'a' | 'b' | 'c' |・・・|'x' | 'y' | 'z' | '_'
'A' | 'B' | 'C' |・・・|'X' | 'Y' | 'Z' |
4. NUM → '0' | '1' | '2' |・・・|'8' | '9'
5. ALPHANUM → ALPHA | NUM
6. ALPHANUMS → ALPHANUM ALPHANUMS
→ λ
7. NUMS → NUM NUMS
→ λ
8. TOKEN → NON_KEY_ID | SPEC_SYM | NUMS
これをプログラムに落としていくと、
例えば
NUMS → NUM NUMS
→ λ
の部分は、
if char == digit:
token = char
char = next_char()
while char in digit:
token = token + char
char = next_char()
と言った感じでしょうか。
- digit というのが、0〜9までの数字のsetとかlistとか
- charが現在読み込んでいるソースプログラムの一文字
- next_char()がこの前つくった次の一文字
読み込んだ文字が数字なら、
次の文字を読み込んで
文字が数字の間はtokenに足していく
という流れです。
この調子でNON_KEY_IDとSPEC_SYMについても作っていけばtokenを得る関数の出来上がり!
さっそく作ってみましょう。
def next_token():
token = ''
while token == '':
elif char in spechar:
token = char
char = next_char()
elif char in letter:
token = char
char = next_char()
while char in (letter + digit):
token = token + char
char = next_char()
elif char in digit:
token = char
char = next_char()
while char in digit:
token = token + char
char = next_char()
elif char in ['\r', '\n', '\t', ' ']:
char = next_char()
elif char == 'end_of_file':
token = 'end_of_file'
else:
error()
return token
生成規則では、トークンは NON_KEY_ID | SPEC_SYM | NUMS
だけなんですが、実際にはソースファイルにはいらない空白や改行記号などを読み飛ばす必要があります。それが、上の
elif char in ['\r', '\n', '\t', ' ']:
の部分です。
'\r'がキャリッジリターン、'\n'が改行、'\t'がタブ、' 'がスペース
で、これらの記号が来れば読み飛ばします(next_char())。
end_of_fileは、文字どおりファイルの終端に達したら、「もう終わりですよ」と知らせるためのもの。
最後の else でどれにも該当しない入力の場合にエラーをはき出す関数を入れます。
実装はこれから。
これで動くはずですよね。
次回、実際に動かして試してみます。