プログラミングと工作と

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

最後に、構文解析ファイルを分割した。

最後に残っていた、構文解析ファイルを分割してみた。
・・・self多すぎないですか?

トークンクラスでは、エラークラスの読み込みは特になにも意識せずに動作していたのですが、パーサクラスでは「定義されていないname 'e'が使われている」とPython先生に怒られた。
じゃあ、なぜトークンクラスでは問題なく使えるのだろう?
もしかして、トークンクラス内でエラークラスが呼ばれなかったから気づかなかっただけなのかな?
念の為、トークンクラス内のエラーも、「self.e.error()」に書き換えておこう。

よくわかっていない部分もあるが、とりあえず下のファイルで問題なく動作した。

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


class psr:

    def __init__(self, token, e):
        self.token = token
        self.e = e
        

    def ids(self):
        #global token
        temp = self.token.token
        if self.token.token in self.token.keyword:
            self.e.error(4)
        if self.token.next() not in [',', ':']:
            self.e.error(5)
        while self.token.token == ',':
            if self.token.next() in self.token.keyword:
                self.e.error(4)
            temp = temp + ',' + self.token.token
            self.token.next()
        return temp


    def var_stmts(self):
        #global token
        if self.token.token in self.token.keyword:
            self.e.error(4)
        self.ids()
        if self.token.token != ':':
            self.e.error(6)
        if self.token.next() not in ['int', 'integer', 'bool', 'boolean']:
            self.e.error(7)
        if self.token.next() != ';':
            self.e.error(8)
        if self.token.next() != 'begin':
            if self.token.token in self.token.keyword:
                self.e.error(9)
        if self.token.token not in self.token.keyword:
            self.var_stmts()
        
        
    def const_stmts(self):
        #global token
        if self.token.token in self.token.keyword:
            self.e.error(10)
        if self.token.next() != '=':
            self.e.error(11)
        x = self.token.next()
        if x in self.token.keyword:
            if not x.isdigit():
                if x != '+':
                    if x != '-':
                        if x != 'true':
                            if x != 'false':
                                self.e.error(12)
        #if x == ('+' or '-'):
        if x in ['+','-']:
            self.token.next()
            if not self.token.token.isdigit:
                self.e.error(13)
            x = x + self.token.token
        if self.token.next() != ';':
            self.e.error(8)
        if self.token.next() in self.token.keyword:
            if self.token.token != 'var':
                if self.token.token != 'begin':
                    self.e.error(14)
        if self.token.token not in self.token.keyword:
            self.const_stmts()


    def begin_end_stmt(self):
        #global token.token
        if self.token.token != 'begin':
            self.e.error(15)
        if self.token.next() != 'end':
            self.e.error(16)
        if self.token.next() != '.':
            self.e.error(17)
        self.token.next()


    def consts(self):
        #global token
        if self.token.token != 'const':
            self.e.error(18)
        if self.token.next() in self.token.keyword:
            self.e.error(10)
        self.const_stmts()
    

    def vars(self):
        #global token
        if self.token.token != 'var':
            self.e.error(19)
        if self.token.next() in self.token.keyword:
            self.e.error(4)
        self.var_stmts()


    def prog_stmt(self):
        #global token
        if self.token.token != 'program':
            self.e.error(20)
        self.token.next()
        if self.token.token in self.token.keyword:
            self.e.error(21)
        if self.token.next() != ';':
            self.e.error(8)
        self.token.next()


    def prog(self):
        #global token
        if self.token.token != 'program':
            self.e.error(20)
        self.prog_stmt()
        if self.token.token == 'const':
            self.consts()
        if self.token.token == 'var':
            self.vars()
        if self.token.token != 'begin':
            self.e.error(15)
        self.begin_end_stmt()
        if self.token.token != 'end_of_file':
            self.e.error(22)
        print(u'正常終了')


    def parser(self):
        self.token.next_char()
        if self.token.next() != 'program':
            self.e.error(20)
        self.prog()
        
        
これらの分割したファイルを呼び出す「main.py」を作った。

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

from err import *
from tkn import *
from psr import *

infile = open('test.p', 'r')
e = err()
token = tkn(infile, e)
psr = psr(token, e)

psr.parser()
infile.close()

このmain.pyファイルを実行すると、昨日までと同じように正常動作する。
でもなんか・・・クドいようですが、self 多すぎw
ほんとにこれが正解なのかな? 自信がないw