2019-04-01から1ヶ月間の記事一覧

コンパイラ作成(25) 関数名のチェック

今回の目標 前回同様、コンパイルエラーの検出。 // 関数の呼び出し int main() { print(answer()); } int answer() { // Answer to the Ultimate Question of Life, the Universe, and Everything return 42; } int answer() { // Answer to the Ultimate Q…

コンパイラ作成(24) 予約語

今回の目標 今回は予約語のチェック。これもっと前にやっとくべきだったよね。 // 予約語のチェック int main() { puts("Error"); } int return() { } 関数名に予約語。 // 予約語のチェック int main() { int: } ラベルに予約語 // 予約語のチェック int ma…

コンパイラ作成(23) 等価演算子

今回の目標 今回は等号の演算子を追加するよ。 // 等価演算子 int main() { print((3 + 4) * 2 / (9 - 2) == 2); } 等価演算子って言い方あんま使わないよね。 Lexerクラス SYMBOLの処理のところに”==”を追加するよ。 # operatorの切り出し elsif m = @line[…

コンパイラ作成(22) 減算除算

今回の目標 今回は減算と除算の追加。 // 四則演算 main() { print((3 + 4) * 2 / (9 - 2)); } これで加減乗除が揃うよ。 expr 今回、式の処理を大幅に変更することにした。初めはすっきりしてたルーチンが色々やってるうちにごちゃごちゃしちゃったんで、今…

コンパイラ作成(21) 式中の関数

今回の目標 前に関数の呼び出しできるようにしたけど、式の中に関数書けなかった。今回はその辺を攻めてみるよ。 // 関数の呼び出し int main() { print(answer()); } int answer() { // Answer to the Ultimate Question of Life, the Universe, and Everyt…

Haskellのお勉強(3) アッカーマン関数

再帰の例 久しぶりにHaskellのお勉強。昔々何かの本で読んだアッカーマン関数を思い出して書いてみたよ。もちろん関数の定義なんて覚えてないんで、ググって調べたよ。アッカーマン関数 - Wikipedia import System.Environment import Text.Printf ackermann…

コンパイラ作成(20) コメント

今回の目標 式の解析に飽きたんで、いきなりだけどコメント機能を追加することにしたよ。 // コメントだよ main() { return 42; // ここもコメント } C++スタイルの一行コメント。 C言語のコメント C言語のコメントは本来/* ~~~*/の形式だけど、mycではサポ…

コンパイラ作成(19) 括弧

今回の目標 引き続き式の構文解析。今回は括弧だよ。 main() { print((42)); print((4 + 2) * 3); print((4 + 2) + 3); print(5 * (4 + 2)); print(5 + (4 + 2)); print((5 + 7) * (4 + 2)); print((5 + 7) + (4 + 2)); print(5 * (4 + 2) * 3); print(5 + (…

コンパイラ作成(18) 式の解析の改良

今回の目標 今回は演算子の優先順位を正しく評価するよう頑張るよ。 main() { print(2 * 3 + 5); print(2 + 3 * 5); } 問題なのは二番目の方で、電卓式計算になっちゃってたやつね。 バグ発見 本題に行く前にもう一点なんだけど、式の解析を組み込んだ時から…

コンパイラ作成(17) 細かな修正

symlink 前回、いろいろなパターンでテストをしてて思ったんだけど、一々clang呼び出すのが面倒くさいよ。てことで楽ができるようにするよ。まずはsymlink。 ~$ cd /usr/local/bin /usr/local/bin$ sudo ln -s /home/xxx/myc/myc.rb myc /usr/local/bin$syml…

コンパイラ作成(16) ちょっと複雑な式

今回の目標 前回の続きで式の解析だけど、ちょっとだけ複雑な式に挑戦するよ。 main() { print(32 + 47 + 12 + 6); print(32 * 47 * 12); } 複雑って言ってもちょっとだけだよ。それと前回作ったいい加減な式の処理をもうちょっとまともにしたいなあ。 expr …

コンパイラ作成(15) 簡単な式

今回の目標 今まで避けてた式の構文解析に挑戦してみるよ。 main() { print(32 + 47); print(32 * 47); } 当面演算子は+と*だけにするつもり。この二つがちゃんとできれば他の演算子は比較的簡単に追加できるんじゃないかな。 Clang先輩 まずはClangのアセン…

コンパイラ作成(14) goto文

今回の目標 最近Haskellに浮気してて、こっち全然進めてなかったよ。新しいこと始めると、前にやってたのをほっぽり出しちゃう癖は駄目だなあ。ちょっとだけ反省。ってことでコンパイラの作成に戻るよ。 でなんだけど、今回の目標はgoto文にしたよ。一番簡単…

Haskellのお勉強(2) 文字列のsplit

split ちょっとずつHaskellに馴染んでいくためのいいかげんなお勉強。今日のお題は文字列のsplitだよ。あんちょこにググってみたらそのものの例があったんで試してみるよ。参考にしたのはHow to split a string in Haskell? - Stack Overflow。 import Syste…

Haskellのお勉強(1) Hello, World!

Hello, World! 唐突にHaskellに手を出してみた。GHCのインストールしたんで、まずはハロワから。 main = do putStrLn "Hello, World!" GHCには普通のコンパイラghcコマンドのほかにghciやrunghcがあるけど、ちょこちょこっと試すだけなんでrunghcを使ってい…

コンパイラ作成(13) データ型モデル

clangのアセンブリコード 組み込み関数printのコンパイルをするときに勉強した、clangのアセンブリコードをもう一回眺めてみたよ。 .text .intel_syntax noprefix .file "c.myc" .globl main # -- Begin function main .p2align 4, 0x90 .type main,@functio…

コンパイラ作成(12) 関数の定義と呼出

今回の目標 前回のハロワの時に関数を定義してそれを呼びたいなって思ったんで、今回はそれに挑戦してみるよ。 main() { puts("Hi everyone!"); puts("Are you ready?"); sub(); } sub() { puts("Let's go!"); } 関数の定義 まずは関数の定義から。以前作っ…