Your SlideShare is downloading. ×
多値で簡単パーサーコンビネーター
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

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

3,530
views

Published on

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

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

Published in: Technology

0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,530
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
3
Comments
0
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. . . . . . . 多値で簡単 パーサーコンビネーター 鹿野 桂一郎 k16.shikano@gmail.com @golden_lucky 2010年11月27日
  • 2. . . . . . . TEX 作ってます。
  • 3. . . . . . . TEXとは Knuthの数式きれいなやつ
  • 4. . . . . . . TEXとは Knuthの数式きれいなやつ 立派なプログラミング言語
  • 5. . . . . . . TEXとは Knuthの数式きれいなやつ 立派なプログラミング言語?
  • 6. . . . . . . TEXとは Knuthの数式きれいなやつ 立派なプログラミング言語? チューリング完全
  • 7. . . . . . . TEXとは Knuthの数式きれいなやつ 立派なプログラミング言語? チューリング完全 Lispと同じく「拡張可能」な プログラミング言語
  • 8. . . . . . . § ¦ ¤ ¥広告 Paul Graham 著 野田 開 訳 2007 年 3 月発売 本体 3800 円 A5 判 440 頁 ISBN 978-4-274-06637-5
  • 9. . . . . . . TEXとは Knuthの数式きれいなやつ 立派なプログラミング言語 チューリング完全 Lispと同じく「拡張可能」な プログラミング言語
  • 10. . . . . . . TEXとは Knuthの数式きれいなやつ 立派なプログラミング言語 チューリング完全 Lispと同じく「拡張可能」な プログラミング言語 むかし萩谷先生がdisってた
  • 11. . . . . . . しかし、はっきりいって、Knuth は、コンピュ ータ・サイエンティストとしてはセンス・ゼロ、 要するに馬鹿である。それは、あの TeX という 処理系を見ればわかる。いったい、世の中に、 毎日 TeX で泣かされ続けている人は何人いるの だろうか。あんなふざけた処理系で、これほど 多くの人に使われているものは他にはない。 — “H 君への手紙:天才” より
  • 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. . . . . . . よくみたらBNFっぽい。 パーサーコンビネーター さえあれば なんとかなるかも
  • 14. . . . . . . パーサーの詩 パーサーは関数 文字列をもらって 結果と文字列をもどす 組のリストでもどす — Graham Hutton
  • 15. . . . . . . § ¦ ¤ ¥広告 Graham Hutton 著 山本 和彦 訳 2009 年 10 月発売 本体 2800 円 A5 判 232 頁 ISBN 978-4-274-06781-5
  • 16. . . . . . . パーサーの詩(再) パーサーは関数 文字列をもらって 結果と文字列をもどす 組のリストでもどす — Graham Hutton
  • 17. . . . . . . パーサーの詩(再) パーサーは関数 文字列をもらって 結果と文字列をもどす 組のリストでもどす — Graham Hutton 多値だ!
  • 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. . . . . . . パーサーの具体例 (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. . . . . . . パーサーの実行 (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. . . . . . . パーサーを組み合わせて使うには 標準のエラーでは、最初に試したパーサーで失敗した時点で 止まってしまうので、独自のコンディションを定義して使う。 (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. . . . . . . パーサーの選択 (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. . . . . . . パーサーの連結 (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. . . . . . . パーサーを繰り返し適用する (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. . . . . . . 正規表現だとつらいパースも簡単 (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. . . . . . . 元ネタはHaskellのParsec http://legacy.cs.uu.nl/daan/download/parsec/parsec.html parens :: Parser () parens = do{ char ’(’ ; parens ; char ’)’ ; parens } <|> return ()
  • 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. . . . . . . § ¦ ¤ ¥広告 Graham Hutton 著 山本 和彦 訳 2009 年 10 月発売 本体 2800 円 A5 判 232 頁 ISBN 978-4-274-06781-5
  • 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. . . . . . . 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. . . . . . . なにしてたんだっけ?
  • 32. . . . . . . なにしてたんだっけ? TEX 作ってます。
  • 33. . . . . . . TEX modoki https://github.com/k16shikano/tex-modoki
  • 34. . . . . . . TEX の原稿を HTML/CSS2.1で出力
  • 35. . . . . . . TEX の原稿を HTML/CSS2.1で出力 注:テキストフィルタじゃないです。(TEX のマクロ実装)
  • 36. . . . . . . § ¦ ¤ ¥広告 Daniel P. Friedman Matthias Felleisen 著 元吉文男・横山晶一 共訳 2010 年 10 月発売 本体 2800 円 A5 判 216 頁 ISBN 978-4-274-06826-3
  • 37. . . . . . . まとめ TEX modoki (Gaucheによる TEXの簡易実装) Parsec「のようなもの」 なら多値で作れる
  • 38. . . . . . . まとめ TEX modoki (Gaucheによる TEXの簡易実装) Parsec「のようなもの」 なら多値で作れる 後ろで本を売っています
  • 39. . . . . . . ありがとうございました。