プログラミング言語作成ハンズオンに参加してきた #lang_impl
プログラミング言語作成ハンズオンに参加してきました。楽しかったです!
プログラミング言語を作成したことがないので、こういう勉強会で教えてもらえるのはすごくありがたいです。
午前中はざっとプログラミング言語処理系についての説明。その後、今回のハンズオン用に作られたnubという言語を拡張していきます。
やったこと
- 午前中の説明に出てきた内容と用意されたソースコードの対応を考える
- ANTLRというものを使っておりこれが何かを考える。これはパーサジェネレータで、g4ファイルを元にパーサを生成してくれる。最初はANTLRというものがパーサそのもの?などと何も分かっていない勘違いをしていたのだが、NubParserクラスが自動生成されているようだったので、勘違いに気がついた
- 用意されたコードの役割をざっと把握できたので、最初に累乗演算子
**
を導入。これは+
や*
を参考にして、とくに問題なくできた - 次に、文字列リテラルを導入。test-inputディレクトリに用意されていた string.nub を実行できるようにした
- その次は、Stringに対して指定した位置にある文字を取得するindexOf関数をnub言語で実装できるようにすることに
- Stringを文字の配列っぽい感じで扱いたい
- そもそも配列がないので作らないと
- よくわからなかったので、ペアで実装することに
- 文法はLispを真似て
cons
car
cdr
を作る - まずは
cons
。文法ファイルをいじる。なんかどの辺に書けばいいのだろうか悩む。専用の抽象構文木を作ったけどBinaryOperator使えばよかったのかも。インタプリタ( Evaluatorクラス )では、長さが2のObject[]
で実装 - 次は
car
cdr
。これも文法ファイルのどの辺に書けばいいのか悩む。。処理の優先順位をどうしたいかで決めればいいのかなぁ。単項演算子のための抽象構文木を作って対応 - ペアができた。
println(car(cons(1, cons(2, 3))))
こんな風に書ける - Stringリテラルの実装を作ったペアで表現するようにした。
"Hello"
は(H(e(l(l(o)))))
といった風に - indexOf関数を定義できるようになった
- 最後は文字列の長さを返すlength関数をnubで作れるようにすることに
- 空のペアかどうかを調べる
isNil
という文法を導入 - length関数を定義できるようになった
- 空のペアかどうかを調べる
というわけで実装したものです。
全体的に
nubという言語を拡張するということだったが、上に書いた通り自分は cons
car
cdr
でペアを作れるようにした。だけど、拡張というのはこういうことでいいのか、自分がやってることは正しいのか?というのが不安でした。実装に夢中になってしまったけど、チューターの方にもっと聞けばよかったかもしれない。
あとは、今回やってみて思ったのは、プログラミング言語の作成というのはインタプリタの実装も含んでいるのだなぁということでした。なぜかは分からないけど、仕様が決まっているインタプリタが読めるような何かを出力するイメージを持っていました。でも、インタプリタも一緒に作るんだなぁ。文法・抽象構文木、それからインタプリタを実装するときに、今どれを実装しているのか、という頭の切り替えをしっかりやらないとごちゃごちゃしてくるなぁと感じました。これは水島さんがブログ記事で書いてるメタとベタの話と近いことを言ってるのかもしれないです。
プログラミング言語作成ハンズオンを開催しました - kmizuの日記
おわりに
もうちょっと色々いじってみたいなぁ、とりあえず以下のことはやってみたいです。
この勉強会のおかげでもっと踏み込んでみたいなぁという気持ちになりました、ありがとうございました!
GRUBの設定でカーネルが認識するメモリ容量を制限する
もう年末です。今年のISUCONではpixivさんの社内ISUCONで練習させていただきました。
その時に気になったことがありまして。インスタンスタイプがc4.largeなのにメモリが1Gしかなくて、なんでかなーと。
$ free -m total used free shared buffers cached Mem: 998 236 762 12 11 105 -/+ buffers/cache: 119 879 Swap: 0 0 0 $ cat /proc/meminfo MemTotal: 1022972 kB
c4.largeのメモリは3.75GBのはずですが、1Gしか認識されていません。
どこかで制限しているのだろうけど・・・OSが認識していない、OSが起動する前に制限してる?ブートローダー?と思ったらそうでした。
/boot/grub/grub.cfg
を確認すると、 mem=1G
という記述があります!
linux /boot/vmlinuz-3.16.0-4-amd64 root=UUID=e0f20fc2-3ca6-416b-8907-4050fe6120ab ro mem=1G init=/bin/systemd console=hvc0 console=ttyS0
この設定を変えてみます。 /boot/grub/grub.cfg
を直接変更するのではなく、 /etc/default/grub
を編集します。
参考 GRUB を設定する 〜 GRUB 2 編 - いますぐ実践! Linuxシステム管理 / Vol.202
/etc/default/grub
を確認してみると
$ cat /etc/default/grub | grep GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX_DEFAULT="init=/bin/systemd console=hvc0 console=ttyS0" GRUB_CMDLINE_LINUX="mem=1G"
ありますねー、 mem=1G
という記述が。 GRUB_CMDLINE_LINUX
にはカーネルの起動パラメータを記述できます。ここに起動パラメータを記述してOSが認識するメモリ容量を制限していました。
GRUB_CMDLINE_LINUX
から mem=1G
の記述を消して、以下のコマンド実行します。
$ sudo update-grub Generating grub configuration file ... Found linux image: /boot/vmlinuz-3.16.0-4-amd64 Found initrd image: /boot/initrd.img-3.16.0-4-amd64 done
再度 /boot/grub/grub.cfg
を確認してみると mem=1G
がなくなっています。
linux /boot/vmlinuz-3.16.0-4-amd64 root=UUID=e0f20fc2-3ca6-416b-8907-4050fe6120ab ro init=/bin/systemd console=hvc0 console=ttyS0
インスタンスを再起動して、確認してみると
$ free -m total used free shared buffers cached Mem: 3774 245 3529 16 11 109 -/+ buffers/cache: 124 3650 Swap: 0 0 0 $ cat /proc/meminfo MemTotal: 3865596 kB
使用できるメモリが増えました!
JJUG CCC Fall 2016 で Spring のソースコードを読んだことについて話してきた #jjug_ccc
SpringはどうやってDIしているのか?というタイトルで話してきました。
資料はこちらです。
資料を書いている時にいろいろ迷ったのですが、Springのソースコードを淡々と話すスタイルにしました。過去にはSeasarやGoogle Guiceを使うことが多くて、Spring暦は1年ちょっとくらいです。Springを使い始めた時、 @ComponentScan
書いて @Component
書いて @Autowired
書いておけばDIされて便利だなぁと思って何となくソースコードを読んだら、想像以上に読むのが大変でした。Springが裏で泥臭いことをやってくれていたり色々な機能を提供してくれていたので、後々参考になるようにまとめました。
Springを使っている前提で話しを進めました。が、使ったことのない人も聞いて頂いていたようで、Springを使ってる人向けであることを発表の説明文でもっと強調しておくべきだったなぁと反省しております。。
Springにどういう機能があるとか、どうやって使うとかはこの本と公式ドキュメントを読むのが良いと思います。
Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発
- 作者: 株式会社NTTデータ
- 出版社/メーカー: 翔泳社
- 発売日: 2016/07/21
- メディア: 大型本
- この商品を含むブログ (1件) を見る
個人的には、ブログをよく参考にさせて頂いている方達にお礼ができてよかったなぁ。
スタッフのみなさん、楽しいイベントをありがとうございました!