Goで言語処理系(の途中まで)を作ろう
Upcoming SlideShare
Loading in...5
×
 

Goで言語処理系(の途中まで)を作ろう

on

  • 2,199 views

 

Statistics

Views

Total Views
2,199
Views on SlideShare
1,918
Embed Views
281

Actions

Likes
5
Downloads
2
Comments
0

3 Embeds 281

https://twitter.com 197
http://connpass.com 81
http://bugrammer.hateblo.jp 3

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Goで言語処理系(の途中まで)を作ろう Goで言語処理系(の途中まで)を作ろう Presentation Transcript

  • Goでプログラミング言語 (の途中まで)を 作ろう esehara shigeo
  • お前 誰だ
  • esehara shigeo ただのWeb系プログラマー (Python使い)
  • Webプログラマーに ありがちな中二病
  • Lisp ※皆様がいるカンファレンスはGo Conです。安心してください。
  • Lispが持つ病 1. 関数型言語カッコイイ! 2. 関数型言語の元祖といえばLisp!カッ コイイ!(括弧なだけに) 3. コンピューターサイエンス、Artifact Intelligenceの分野でも活躍! Awesome! 4. Lispが使いこなせると構文木も自由自 在!
  • Lispは もっとも美しい 言語 ※皆様がいるカンファレンスはGo Conです。安心してください。
  • 全ての言語は S式を 信じられない 人間によって作ら れる
  • 「Lispはエリート向けの言語」
  • LL系プログラマーに ありがちな中二病
  • C言語 ※皆様がいるカンファレンスはGo Conです。安心してください。
  • C言語が持つ病 1. 「Lightweight Languageって所詮富豪 プログラミングだよねー」 2. 「Lightweight Languageって所詮ポイ ンタとかメモリアドレスとか知らないんで しょ」 3. 「Lightweight Languageってコンパイル のこととか所詮わからないんでしょ」
  • 屈辱ッ!
  • でもC言語は つらぽよ……
  • そんな貴方の ための!!
  • Go ※皆様がいるカンファレンスはGo Conです。安心してください。
  • 前置きは ここまで
  • そもそもプログラミング言語 処理ってなに?
  • How to Create Your Own Programming Language http://createyourproglang.com/
  • “The book I want to read.”
  • プログラミング言語処理の流れ 『Create your own language』より
  • 字句解析(Tokenize) とは?
  • 文字のカタマリ によって その文字が 何に属するのか を分析する
  • 例: Haskell 2010 Language Report literal -> integer | float | char | string digit -> ascDigit | uniDigit ascDigit -> 0 | 1 | … | 9 uniDigit -> any Unicode descimal decit decimal -> digit{digit} integer -> decimal
  • Goで 字句解析器を作ろう
  • packageに あるよ! > Tips: 困ったら公式のGoのpackageのソースを読みましょう
  • go/scanner
  • 使える http://www.oki-osk.jp/esc/golang/lisp.html
  • とはいえ、 このSourceを入れ替えて 使うのはつらいので
  • 自動 生成
  • Ragel :: State Machine Compiler
  • Ragel compiles executable finite state machines from regular languages. Ragel targets C, C++, ObjectiveC, C#, D, Java, Ruby, OCaml and Go.
  • そして
  • Rust班も頑張ってる(まだ非公式)
  • Ragelの書きかた # ---- Literal ---string = ("'" . (any - "'")* . "'")     |('"' . (any - '"')* . '"'); integer = digit+; atom = (alpha (alpha | digit)* ); # ---- Operator ---operator = "+" | "-" | "*" | "/"; main := |* atom => { material := Ore{ Token: ATOM, Value: data[ts:te], } material.Research() ores = append(ores, material) }; String => { material := Ore{ Token: STRING, Value: data[ts:te], } material.Research() ores = append(ores, material) }; ….
  • 二つの流れ どの文字の規則を トークンとして定義するか? トークンをどのように 管理するか?
  • 文字の規則とトークン # ---- Literal ---string = ("'" . (any - "'")* . "'")     |('"' . (any - '"')* . '"'); integer = digit+; atom = (alpha (alpha | digit)* ); # ---- Operator ---operator = "+" | "-" | "*" | "/";
  • Ragelによる図式化
  • トークンの処理 main := |* atom => { material := Ore{ Token: ATOM, Value: data[ts:te], } material.Research() ores = append(ores, material) };
  • トークンの管理方法 type Ore struct { Token Token // int Name string }
  • トークンの定義 const( //Special Token ILLEGAL Token = iota EOF COMMENT begin_define_literal ATOM STRING INTEGER end_define_literal ……… ) 参考: go/token
  • このように作った トークンの順序を 構文解析する
  • Goで 構文解析器を作ろう
  • toolに あるよ! >
  • go tool yacc Yacc is a version of yacc for Go. It is written in Go and generates parsers written in Go. (公式より)
  • yaccとは? Yet Another Compiler Compiler
  • go yaccの書きかた %type <val> ATOM, STRING, OPERATOR, BINDER, DEFINE %type <val> ARG %type <val> action, Expression %type <values> StringExpression, AtomExpression %% %{ package casting import ( "fmt" ".. /miner" ) %} %union { tok int val interface{} values Val box Box } %token ATOM STRING %token ARG %token OPERATOR BINDER DEFINE %token ROUNDPAREN_O ROUNDPAREN_C action: ATOM { var v Value v = Box{Type: ATOM, Value: $1,} yylex.(*lex).NewBox(v) } | Expression { if val, ok := $1.(Val); ok { yylex.(*lex).root = val } } ...
  • 何してるの? トークンの順序を 解釈しやすいように再構築
  • 利用するトークンの定義 %token ATOM STRING %token ARG %token OPERATOR %token BINDER DEFINE %token ROUNDPAREN_O ROUNDPAREN_C
  • ここで一つ 問題が
  • Ragelで宣言したトークンと go yaccで宣言したトークンは お互いどういう対応に なってるかを知らない
  • 対応させましょう var oretokens = [...]int { miner.ATOM: ATOM, miner.STRING: STRING, miner.OPERATOR: OPERATOR, miner.BINDER: BINDER, miner.ROUNDPAREN_O: ROUNDPAREN_O, miner.ROUNDPAREN_C: ROUNDPAREN_C, } func toToken(ore miner.Ore) int { return oretokens[ore.Token] }
  • もう一つ 問題が
  • Go yaccで宣言したトークンが どのような型になってるべきか を教えてないといけない
  • トークンの型定義 %union { tok int val interface{} values Val box Box } %type <val> ATOM, STRING, OPERATOR, BINDER, DEFINE %type <val> ARG %type <val> action, Expression %type <values> StringExpression, AtomExpression
  • あとは 抽象構文木を 作成しよう
  • 抽象構文木とは http://en.wikipedia.org/wiki/Abstract_syntax_tree
  • 抽象構文木 = Node = 配列の入れ子
  • Goで 抽象構文木を歩こう
  • packageに あるよ! > Tips: 困ったら公式のGoのpackageのソースを読みましょう
  • go/ast Package ast declares the types used to represent syntax trees for Go packages. (公式より) ※実はPythonにも標準パッケージとしてあります
  • ネタが尽 きました
  • おまけ
  • 関数宣言の 管理
  • 関数宣言の管理とGlobal Environment http://www-inst.eecs.berkeley.edu/~cs61a/sp12/book/
  • Global Environment は一つ
  • シングルトン だ!
  • トークンの型定義 type Env interface{} type envs []Env var environment envs type EnvValue struct { Name string Val Env } func AccessEnv() *envs { return &environment }
  • DEMO
  • Go languageで大切なこと
  • 標準Package の ソースは 宝の山
  • さしずめこんな感じ
  • ご清聴 ありがとう ございました
  • https://github.com/ esehara/Perid