• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Goで言語処理系(の途中まで)を作ろう
 

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

on

  • 1,926 views

 

Statistics

Views

Total Views
1,926
Views on SlideShare
1,661
Embed Views
265

Actions

Likes
5
Downloads
2
Comments
0

3 Embeds 265

https://twitter.com 181
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