プログラミングと工作と

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

気づいてみればなんてこと無い、間違いっていつもそう。

考えた。
けっこう長い間。
関数error()が実行されるということは、charに文字・数字・記号・改行などのエスケープ文字等どれでもない何かが入っていると言うことだ。
何が?何で?
いろいろ試したり考えこんだりしてやっとわかった。
気づいてみれば簡単でばかばかしいことなんだが、まあ問題ってだいたいそんなものですよね。
「スタート時点ではcharになにも入っていない空になっているじゃないか」
最初に char = next_char() を行えば全て解決しました↓


#!/usr/bin/python
# coding: utf-8

def error():
    print('error')


def next_char():
    global char
    char = infile.read(1)
    if not char:  #EOFなら(file.read()は、EOFを検出すると空を返す)
        char = 'end_of_file'
        return char
    return char
    

def next_token():
    global char, token
    token = ''
    while token == '':       
        if 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


digit = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
letter = ['A','B','C','D','E','F','G','H','I','J','K','L','M',
          'N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_',
          'a','b','c','d','e','f','g','h','i','j','k','l','m',
          'n','o','p','q','r','s','t','u','v','w','x','y','z']
spechar = [':', ',', ';', '.','=', '+', '-', '<', '>', '(', ')']
    

infile = open('test.p', 'r')
char = next_char() #←これで、charに最初の一文字を入れないといけなかった
while 1:
    token = next_token()
    if token == 'end_of_file':  
        print('EndOfFile')
        break
    print(token)
infile.close()

さて、このスクリプトに下の test.p ファイルを与えてみる。

program Pa;
var
    id1 : integer;
    id2 : boolean;
    hen : integer;
begin
end.

で、実行したのが以下

~/PasAvr$ python tokentest2.py
program
Pa
;
var
id1
:
integer
;
id2
:
boolean
;
hen
:
integer
;
begin
end
.
EndOfFile

やったー!ちゃんとトークンごとに読めてる!ファイルの終端も認識出来てるし完璧じゃないか。