2015-06-01から1ヶ月間の記事一覧
さて、ここ数日作ってきたメソッドを組み合わせて、記号表クラスのファイル「sym.py」を作ってみた。#!/usr/bin/python# coding: utf-8class sym: def __init__(self, token, e): self.symbol = {} self.e = e self.token = token def check_int(self, st): …
もうひとつメソッドを作ったので紹介します。昨日紹介したリテラルをチェックする時、整数かどうかを調べるのですが、整数の前に - (マイナス)の符号が付いている場合があります。これを普通に .isdigit で調べると false になって整数じゃないと判断されて…
構文解析中に記号表を作成する時、ちょっと調べる必要が発生することがあります。そのひとつが、値のチェックです。変数などの名前を指定して、その名前はどの値を持つかを返すメソッドを作ります。処理の流れは次の様にします。def which_value(self, name)…
実際にどのように記号表を実装するかを考えます。記号表自体はただのディクショナリなので特に難しいことをする必要はありません。ただ、トークンと同様にあちこちで参照されるので、やはり別ファイルのクラスとしてつくります。まずは、記号表に キー:値 …
さて、記号表にはどのように値を入れていくのか、実際の例で見ていきます。例えば、ソースプログラムで次の様な宣言があったとします。var id : integer; 変数「id」を整数として宣言しています。この宣言から、次のような記号表symbol(ディクショナリ)を…
超ロングな一本ファイルをさけるために取り組んでいたファイル分割も一段落したので、ついに新しい領域へと突入します!新しい攻略対象とは・・・「記号表」●記号表ってなに? プログラム中では、変数やら定数やら関数やら、いろんな宣言をして利用します。…
最後に残っていた、構文解析ファイルを分割してみた。・・・self多すぎないですか?トークンクラスでは、エラークラスの読み込みは特になにも意識せずに動作していたのですが、パーサクラスでは「定義されていないname 'e'が使われている」とPython先生に怒…
もうひとつ、最近覚えたことをメモしておきます。それは、エラークラスを呼び出してエラー表示を実行したら、そこでプログラムを終了させる方法です。分割する前は、エラー関数の最後でソースファイルをクローズしていました。ファイルをクローズするので構…
昨日のプログラムですが、ひとつ覚えたので忘れないうちにメモしときます。今まで、構文解析中に、読み込んだソースプログラムのtokenを表示していたのですが、print()文は、表示後自動的に改行するのでtokenが一行にひとつづつズラッと表示されていた。出来…
ついにトークンクラスの分離に成功した!ていうか、「self.」多すぎ。予約語などの定義もトークンファイルに入れた。これがベストかはわからないけど、メインプログラムがスッキリするのでいいかな、と。分離した「tkn.py」ファイルを下に示す。#!/usr/bin/p…
唐突に会社を変わることになり、今日は不動産屋を回っていた。 さらに、突然いい物件があったので今日「ここにします!」って決めてきた。そんなわけでバタバタしてて、まったくプログラム書けてない。 これから引っ越しもあるから開発スピード落ちるだろう…
今日は送別会でお酒飲んで遅くなった。プログラム書く力が残っていないので、今後のファイル分割案だけ書いておこう。 エラークラスファイル トークンクラスファイル 構文解析クラスファイル 今ここまでしか実験していないけど、これに、さらに次のファイル…
昨日の分割したエラー関数にちょっとした追加を行った。エラーが出たら、プログラムを停止するようにsysのインポートを行いsys.exit()を追加した。実は、最初プログラムの止め方がわからなくて、僕の持っているPython本3冊を調べてもわからなかった。しょう…
token関数の前に、簡単なエラー関数を分割化してみました。#!/usr/bin/python# coding: utf-8class err: def error(self, er): if er == 1: e = u" 突然ファイルの終端になっています" elif er == 2: e = u" }はトークンの始まりには出来ません" elif er == …
昨日に引き続き、ファイル分割のテストをしてみた。「tkn.py」ファイルは同じ。class tke: token = '' def gettoken(self, tok): self.token = tokそして、別ファイル「classtest.py」を以下の様に変更した。from tkn import *def c(): token.gettoken('test…
Python本を読みつつ見様見真似でテスト用tokenクラスを作って見た。class tke: token = '' def gettoken(self, tok): self.token = tokこれを「tkn.py」というファイル名で保存する。そして、別ファイル「classtest.py」を以下の内容で作った。from tkn impo…
エラー処理は意味不明な現象が多すぎてちょっと一時撤退。まあ、本質的な部分じゃないから、と言い訳しつつ先に進んでしまいます。コンパイラを作っていてもうひとつ気になっていたのが、ファイルの長さです。こないだ完成した、なにもしない・宣言を受理す…
ちくちくとエラー処理の確認をしていたら、やはり出てきました。へんなところ。例えば、***ソースプログラム↓program test;const yes = true; no = false; small = + # ←定数の値を'+'にしてみた big = 123456;var id1 : integer; id2 : boolean; hen : inte…
今日は、ソースプログラムが間違っていた場合。コンパイラは、ソースプログラム中に文法的・意味的な間違いを発見し、何らかのエラー処理をする必要があります。間違いを自動的に修正したりするすごいヤツもいたりしますが、僕がつくるのはエラーを指摘して…
さて、昨日のスクリプトにテスト用の以下のソースプログラムを解析させた。program test;const yes = true; no = false; small = 0; big = 123456;var id1 : integer; id2 : boolean; hen : integer; x, y, z : int;beginend.実行結果が下になります。~/PasA…
全部くっつけたらこうなった。#!/usr/bin/python# coding: utf-8def error(err): if err == 1: e = u" 突然ファイルの終端になっています" elif err == 2: e = u" }はトークンの始まりには出来ません" elif err == 3: e = u" 誤った記号が使用されています" …
最後かな? IDS行きます。いつものように、今日書く部分の文法規則↓8. IDS → NON_KEY_ID (',' IDS | λ)def ids(token): temp = token if token in KEYWORD: エラー:予約語が変数名に使われてるよ! if next_token() != ',': if token != ':': エラー:ここ…
今日はVAR_STMTS行きます。いつものように、今日書く部分の文法規則↓7. VAR_STMTS → IDS ':' TYPE ';' (VAR_STMTS | λ)def var_stmts(): global token if token in KEYWORD: エラー:予約語が変数名に使われてるよ! x = ids() if token != ':': エラー:':'…
次はCONST_STMTS行きます。ここが出来れば、VAR_STMTSも出来たようなものです。6. CONST_STMTS → NON_KEY_ID '=' NON_KEY_ID | LITdef const_stmts(token): if token in KEYWORD: エラー:予約語が定数名に使われてるよ! if next_token() != '=': エラー:…
今日は、3・4番めの文法規則3. CONSTS → 'const' CONST_STMTS → λ4. VARS → 'var' VAR_STMTS → λ を書いてみます。ほぼ同じなので、ほぼコピペでいけますね。def consts(token): global token if token != 'const': エラー:キーワード'const'がないよ! i…
さてさて、2番めの文法規則2. PROG_STMS → 'program' NON_KEY_ID ';'を書いてみましょう。def prog_stmt(token): global token if token != 'program': エラー:キーワード'program'がないよ! next_token() if token not in NON_KEY_ID: エラー:プログラ…
最初に、作成する構文解析器の文法を定義します。定義しますと言ってはいますが、本に定義されたものをトレースしていくのです。その文法が↓ 1. PROG → PROG_STMT CONSTS VARS BEGIN_END STMT 2. PROG_STMS → 'program' NON_KEY_ID ';' 3. CONSTS → 'const' …
さて、今日から新展開!構文解析器の作成に移ります。英語でいうと「パーサ」と言うそうです。パーサは、昨日まで作っていたトークン関数からトークンを受け取り、ソースプログラムが言語(ココではPascalもどき)の文法規則を満足しているかどうかを確かめ…
仕上げとして、ソースファイル中のコメント処理を入れてみた。Pascalは、{と}の間にある文字をコメントとして処理する。なので、その間の文字と{}自身を読み飛ばすようにした。 また、一行コメントも便利なので処理に追加した。Pascalの進化系Delphiは、c++…
考えた。けっこう長い間。関数error()が実行されるということは、charに文字・数字・記号・改行などのエスケープ文字等どれでもない何かが入っていると言うことだ。何が?何で?いろいろ試したり考えこんだりしてやっとわかった。気づいてみれば簡単でばかば…