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

2,925 views
2,752 views

Published on

Published in: Technology
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,925
On SlideShare
0
From Embeds
0
Number of Embeds
330
Actions
Shares
0
Downloads
6
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide

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

  1. 1. Goでプログラミング言語 (の途中まで)を 作ろう esehara shigeo
  2. 2. お前 誰だ
  3. 3. esehara shigeo ただのWeb系プログラマー (Python使い)
  4. 4. Webプログラマーに ありがちな中二病
  5. 5. Lisp ※皆様がいるカンファレンスはGo Conです。安心してください。
  6. 6. Lispが持つ病 1. 関数型言語カッコイイ! 2. 関数型言語の元祖といえばLisp!カッ コイイ!(括弧なだけに) 3. コンピューターサイエンス、Artifact Intelligenceの分野でも活躍! Awesome! 4. Lispが使いこなせると構文木も自由自 在!
  7. 7. Lispは もっとも美しい 言語 ※皆様がいるカンファレンスはGo Conです。安心してください。
  8. 8. 全ての言語は S式を 信じられない 人間によって作ら れる
  9. 9. 「Lispはエリート向けの言語」
  10. 10. LL系プログラマーに ありがちな中二病
  11. 11. C言語 ※皆様がいるカンファレンスはGo Conです。安心してください。
  12. 12. C言語が持つ病 1. 「Lightweight Languageって所詮富豪 プログラミングだよねー」 2. 「Lightweight Languageって所詮ポイ ンタとかメモリアドレスとか知らないんで しょ」 3. 「Lightweight Languageってコンパイル のこととか所詮わからないんでしょ」
  13. 13. 屈辱ッ!
  14. 14. でもC言語は つらぽよ……
  15. 15. そんな貴方の ための!!
  16. 16. Go ※皆様がいるカンファレンスはGo Conです。安心してください。
  17. 17. 前置きは ここまで
  18. 18. そもそもプログラミング言語 処理ってなに?
  19. 19. How to Create Your Own Programming Language http://createyourproglang.com/
  20. 20. “The book I want to read.”
  21. 21. プログラミング言語処理の流れ 『Create your own language』より
  22. 22. 字句解析(Tokenize) とは?
  23. 23. 文字のカタマリ によって その文字が 何に属するのか を分析する
  24. 24. 例: 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
  25. 25. Goで 字句解析器を作ろう
  26. 26. packageに あるよ! > Tips: 困ったら公式のGoのpackageのソースを読みましょう
  27. 27. go/scanner
  28. 28. 使える http://www.oki-osk.jp/esc/golang/lisp.html
  29. 29. とはいえ、 このSourceを入れ替えて 使うのはつらいので
  30. 30. 自動 生成
  31. 31. Ragel :: State Machine Compiler
  32. 32. Ragel compiles executable finite state machines from regular languages. Ragel targets C, C++, ObjectiveC, C#, D, Java, Ruby, OCaml and Go.
  33. 33. そして
  34. 34. Rust班も頑張ってる(まだ非公式)
  35. 35. 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) }; ….
  36. 36. 二つの流れ どの文字の規則を トークンとして定義するか? トークンをどのように 管理するか?
  37. 37. 文字の規則とトークン # ---- Literal ---string = ("'" . (any - "'")* . "'")     |('"' . (any - '"')* . '"'); integer = digit+; atom = (alpha (alpha | digit)* ); # ---- Operator ---operator = "+" | "-" | "*" | "/";
  38. 38. Ragelによる図式化
  39. 39. トークンの処理 main := |* atom => { material := Ore{ Token: ATOM, Value: data[ts:te], } material.Research() ores = append(ores, material) };
  40. 40. トークンの管理方法 type Ore struct { Token Token // int Name string }
  41. 41. トークンの定義 const( //Special Token ILLEGAL Token = iota EOF COMMENT begin_define_literal ATOM STRING INTEGER end_define_literal ……… ) 参考: go/token
  42. 42. このように作った トークンの順序を 構文解析する
  43. 43. Goで 構文解析器を作ろう
  44. 44. toolに あるよ! >
  45. 45. go tool yacc Yacc is a version of yacc for Go. It is written in Go and generates parsers written in Go. (公式より)
  46. 46. yaccとは? Yet Another Compiler Compiler
  47. 47. 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 } } ...
  48. 48. 何してるの? トークンの順序を 解釈しやすいように再構築
  49. 49. 利用するトークンの定義 %token ATOM STRING %token ARG %token OPERATOR %token BINDER DEFINE %token ROUNDPAREN_O ROUNDPAREN_C
  50. 50. ここで一つ 問題が
  51. 51. Ragelで宣言したトークンと go yaccで宣言したトークンは お互いどういう対応に なってるかを知らない
  52. 52. 対応させましょう 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] }
  53. 53. もう一つ 問題が
  54. 54. Go yaccで宣言したトークンが どのような型になってるべきか を教えてないといけない
  55. 55. トークンの型定義 %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
  56. 56. あとは 抽象構文木を 作成しよう
  57. 57. 抽象構文木とは http://en.wikipedia.org/wiki/Abstract_syntax_tree
  58. 58. 抽象構文木 = Node = 配列の入れ子
  59. 59.
  60. 60. Goで 抽象構文木を歩こう
  61. 61. packageに あるよ! > Tips: 困ったら公式のGoのpackageのソースを読みましょう
  62. 62. go/ast Package ast declares the types used to represent syntax trees for Go packages. (公式より) ※実はPythonにも標準パッケージとしてあります
  63. 63. ネタが尽 きました
  64. 64. おまけ
  65. 65. 関数宣言の 管理
  66. 66. 関数宣言の管理とGlobal Environment http://www-inst.eecs.berkeley.edu/~cs61a/sp12/book/
  67. 67. Global Environment は一つ
  68. 68. シングルトン だ!
  69. 69. トークンの型定義 type Env interface{} type envs []Env var environment envs type EnvValue struct { Name string Val Env } func AccessEnv() *envs { return &environment }
  70. 70. DEMO
  71. 71. Go languageで大切なこと
  72. 72. 標準Package の ソースは 宝の山
  73. 73. さしずめこんな感じ
  74. 74. ご清聴 ありがとう ございました
  75. 75. https://github.com/ esehara/Perid

×