プログラミングと工作と

PythonとかPascalとかAVRマイコンとか、コンパイラつくったり電子工作なんかを楽しんでいるおっさんの記録

トークンを取得する関数をつくる準備

さて、もう一度生成規則を再掲すると

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 でどれにも該当しない入力の場合にエラーをはき出す関数を入れます。
実装はこれから。
これで動くはずですよね。
次回、実際に動かして試してみます。