多値で簡単パーサーコンビネーター

4,085 views

Published on

Shibuya.lisp TT#6 でのライトニングトーク資料

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

No Downloads
Views
Total views
4,085
On SlideShare
0
From Embeds
0
Number of Embeds
2,558
Actions
Shares
0
Downloads
6
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

多値で簡単パーサーコンビネーター

  1. 1. . . . . . . 多値で簡単 パーサーコンビネーター 鹿野 桂一郎 k16.shikano@gmail.com @golden_lucky 2010年11月27日
  2. 2. . . . . . . TEX 作ってます。
  3. 3. . . . . . . TEXとは Knuthの数式きれいなやつ
  4. 4. . . . . . . TEXとは Knuthの数式きれいなやつ 立派なプログラミング言語
  5. 5. . . . . . . TEXとは Knuthの数式きれいなやつ 立派なプログラミング言語?
  6. 6. . . . . . . TEXとは Knuthの数式きれいなやつ 立派なプログラミング言語? チューリング完全
  7. 7. . . . . . . TEXとは Knuthの数式きれいなやつ 立派なプログラミング言語? チューリング完全 Lispと同じく「拡張可能」な プログラミング言語
  8. 8. . . . . . . § ¦ ¤ ¥広告 Paul Graham 著 野田 開 訳 2007 年 3 月発売 本体 3800 円 A5 判 440 頁 ISBN 978-4-274-06637-5
  9. 9. . . . . . . TEXとは Knuthの数式きれいなやつ 立派なプログラミング言語 チューリング完全 Lispと同じく「拡張可能」な プログラミング言語
  10. 10. . . . . . . TEXとは Knuthの数式きれいなやつ 立派なプログラミング言語 チューリング完全 Lispと同じく「拡張可能」な プログラミング言語 むかし萩谷先生がdisってた
  11. 11. . . . . . . しかし、はっきりいって、Knuth は、コンピュ ータ・サイエンティストとしてはセンス・ゼロ、 要するに馬鹿である。それは、あの TeX という 処理系を見ればわかる。いったい、世の中に、 毎日 TeX で泣かされ続けている人は何人いるの だろうか。あんなふざけた処理系で、これほど 多くの人に使われているものは他にはない。 — “H 君への手紙:天才” より
  12. 12. . . . . . . たとえばTEXの「数値」の定義 <数値> −→ <余分な符号><符号なし数値> <余分な符号> −→ <余分な空白> | <余分な符号><プラスまたはマイナス><余分な符号> <符号なし数値> −→ <ノーマルな整数><変換した整数> <ノーマルな整数> −→ <内部整数> | <整数定数><余分な空白を 1 つ> | ’12 <8 進定数><余分な空白を 1 つ> | "12 <16 進定数><余分な空白を 1 つ> | ‘12 <文字トークン><余分な空白を 1 つ> <整数定数> −→ <数字> | <数字><整数定数> <8 進定数> −→ <8 進数字> | <8 進数字><8 進定数> <16 進定数> −→ <16 進数字> | <16 進数字><16 進定数> <8進数字> −→ 012 | 112 | 212 | 312 | 412 | 512 | 612 | 712 <数字> −→ <8 進数字> | 812 | 912 <16 進数字> −→ <数字> | A11 | B11 | C11 | D11 | E11 | F12 | A12 | B12 | C12 | D12 | E12 | F12 <余分な空白を 1 つ> −→ <空白トークン> | <空> <変換した整数> −→ <内部寸法> | <内部グルー>
  13. 13. . . . . . . よくみたらBNFっぽい。 パーサーコンビネーター さえあれば なんとかなるかも
  14. 14. . . . . . . パーサーの詩 パーサーは関数 文字列をもらって 結果と文字列をもどす 組のリストでもどす — Graham Hutton
  15. 15. . . . . . . § ¦ ¤ ¥広告 Graham Hutton 著 山本 和彦 訳 2009 年 10 月発売 本体 2800 円 A5 判 232 頁 ISBN 978-4-274-06781-5
  16. 16. . . . . . . パーサーの詩(再) パーサーは関数 文字列をもらって 結果と文字列をもどす 組のリストでもどす — Graham Hutton
  17. 17. . . . . . . パーサーの詩(再) パーサーは関数 文字列をもらって 結果と文字列をもどす 組のリストでもどす — Graham Hutton 多値だ!
  18. 18. . . . . . . Gaucheでナイーブに実装 文字のリストが述語を満たしたら結果と残りを返す関数、を 返す。 (define (make-parser pred) (lambda (ts) (cond ((null? ts) (error "no character" ts)) ((pred (car ts)) (values (car ts) (cdr ts))) (else (error "doesn’t match" ts)))))
  19. 19. . . . . . . パーサーの具体例 (define anychar (make-parser char?)) (define (char-parser char) (make-parser (pa$ char=? char))) (define (char-set-parser charset) (make-parser (pa$ char-set-contains? charset))) (define space1 (char-set-parser #[s])) (define nill (lambda (ts) (values ’() ts)))
  20. 20. . . . . . . パーサーの実行 (define (run parser str) (receive (matched rest) (parser (string->list str)) (values (list->string matched) (list->string rest)))) gosh> (run (char-parser #a) "abc") "a" "bc"
  21. 21. . . . . . . パーサーを組み合わせて使うには 標準のエラーでは、最初に試したパーサーで失敗した時点で 止まってしまうので、独自のコンディションを定義して使う。 (define-condition-type <parser-error> <error> #f) (define (make-parser pred) (lambda (ts) (cond ((null? ts) (error <parser-error> "no character" ts)) ((pred (car ts)) (values (list (car ts)) (cdr ts))) (else (error <parser-error> "doesn’t match" ts)))))
  22. 22. . . . . . . パーサーの選択 (define-syntax parser-or (syntax-rules (error) ((_) (lambda (ts) (values ’() ts))) ((_ p) (lambda (ts) (p ts))) ((_ p1 p2 ...) (lambda (ts) (guard (e ((<parser-error> e) ((parser-or p2 ...) ts))) (p1 ts))))))
  23. 23. . . . . . . パーサーの連結 (define-syntax parser-cont (syntax-rules () ((_) (lambda (ts) (values ’() ts))) ((_ p) (lambda (ts) (p ts))) ((_ p1 p2 ...) (lambda (ts) (receive (match-p1 rest-p1) (p1 ts) (receive (match-p2 rest-p2) ((parser-cont p2 ...) rest-p1) (values ‘(,@match-p1 ,@match-p2) rest-p2)))))))
  24. 24. . . . . . . パーサーを繰り返し適用する (define (parser-many p) (lambda (ts) (let R ((match ’()) (rest ts)) (guard (e ((<parser-error> e) (values match rest))) (receive (m r) (p rest) (R (append match m) r)))))) (define (parser-many1 p) (parser-cont p (parser-many p)))
  25. 25. . . . . . . 正規表現だとつらいパースも簡単 (define parser-group (parser-or (parser-cont (char-parser #{) (parser-or (parser-many1 (char-set-parser #[^{}])) parser-group) (char-parser #}) parser-group) nill)) gosh> (run parser-group "{{abc}123}rest") "{{abc}123}" "rest"
  26. 26. . . . . . . 元ネタはHaskellのParsec http://legacy.cs.uu.nl/daan/download/parsec/parsec.html parens :: Parser () parens = do{ char ’(’ ; parens ; char ’)’ ; parens } <|> return ()
  27. 27. . . . . . . Parsecだと意味も付加できる http://legacy.cs.uu.nl/daan/download/parsec/parsec.html nesting :: Parser Int nesting = do{ char ’(’ ; n <- nesting ; char ’)’ ; m <- nesting ; return (max (n+1) m) } <|> return 0
  28. 28. . . . . . . § ¦ ¤ ¥広告 Graham Hutton 著 山本 和彦 訳 2009 年 10 月発売 本体 2800 円 A5 判 232 頁 ISBN 978-4-274-06781-5
  29. 29. . . . . . . モナド風インターフェイス (define-syntax parser-do (syntax-rules (<- return in) ((_ return <r>) (lambda (ts) (values <r> ts))) ((_ return <r> in <x1> <- p1) (lambda (ts) (receive (match-p1 rest-p1) (p1 ts) (let ((<x1> match-p1)) (values <r> rest-p1))))) ((_ return <r> in <x1> <- p1 <x2> <- p2 ...) (lambda (ts) (receive (match-p1 rest-p1) (p1 ts) (let ((<x1> match-p1)) (receive (match-p2 rest-p2) ((parser-do return <r> in <x2> <- p2 ... ) rest-p1) (let ((<x2> match-p2)) (values match-p2 rest-p2)))))))))
  30. 30. . . . . . . Parsecの例題も移植可能 (define count-nest (parser-or (parser-do return (max (+ n 1) m) in op <- (char-parser #{) n <- count-nest cp <- (char-parser #}) m <- count-nest) (lambda (ts) (values 0 ts)))) gosh> (count-nest (string->list "{{}}{{{}}}")) 3 ()
  31. 31. . . . . . . なにしてたんだっけ?
  32. 32. . . . . . . なにしてたんだっけ? TEX 作ってます。
  33. 33. . . . . . . TEX modoki https://github.com/k16shikano/tex-modoki
  34. 34. . . . . . . TEX の原稿を HTML/CSS2.1で出力
  35. 35. . . . . . . TEX の原稿を HTML/CSS2.1で出力 注:テキストフィルタじゃないです。(TEX のマクロ実装)
  36. 36. . . . . . . § ¦ ¤ ¥広告 Daniel P. Friedman Matthias Felleisen 著 元吉文男・横山晶一 共訳 2010 年 10 月発売 本体 2800 円 A5 判 216 頁 ISBN 978-4-274-06826-3
  37. 37. . . . . . . まとめ TEX modoki (Gaucheによる TEXの簡易実装) Parsec「のようなもの」 なら多値で作れる
  38. 38. . . . . . . まとめ TEX modoki (Gaucheによる TEXの簡易実装) Parsec「のようなもの」 なら多値で作れる 後ろで本を売っています
  39. 39. . . . . . . ありがとうございました。

×