狠狠撸

狠狠撸Share a Scribd company logo
新 ReVIEWパーサ
?
について
? ReVIEW開発者カンファレンス?2014/03/08
株式会社達人出版会
高橋征義
自己紹介
? 高橋征義 (@takahashim), ReVIEWコミッタ
? 古参Rubyist (1997年くらいから)
? ~2010年 Web制作会社のプログラマ
? @kdmsnrの同僚
? 2010年~ 電子書籍の制作と販売
(今日はこの話じゃなくて、実装の話)
本日のあらすじ
? パーサを書き換え中
? いろいろスッキリした(はず)
? わりと動いている(はず)
? そもそもの仕様を決めないとダメ
? すごく内部実装の技術的な話ですみません…
本発表の話題
? パーサ (Parser)
パーサとは

? 構文解析をするひと
? どこがブロックで、どこがインラインで…と
いうのを解析する

? ReVIEWではReVIEW::Compiler
? lib/review/compiler.rb
? …だけではなく、実はBuilderの中でも構文解析
しているのが問題だったり
== foo
XXXYYY
ZZZ
//list[foo1][foo2]{
AAA@<b>{BBB}CCC
DDD@<raw>{EEE{FFF}GGG}
IIIJJJ
//}
@<ruby>{KKK,LLL}
MMMNNN
== foo
Headline
XXXYYY
Paragraph
ZZZ
//list[foo1][foo2]{
BlockElement
AAA@<b>{BBB}CCC
DDD@<raw>{EEE{FFF}GGG}
IIIJJJ
//}
@<ruby>{KKK,LLL}
Paragraph
LLLMMM
== foo
XXXYYY
ZZZ
//list[foo1][foo2]{
AAA@<b>{BBB}CCC
DDD@<raw>{EEE{FFF}GGG}
IIIJJJ
//}
@<ruby>{KKK,LLL}
LLLMMM
※細かい要素に分割するだけ
→各要素をどう扱うかは
?パーサではなくBuilderが
?担当する

== foo
XXXYYY
ZZZ
//list[foo1][foo2]{
AAA@<b>{BBB}CCC
DDD@<raw>{EEE{FFF}GGG}
IIIJJJ
//}
@<ruby>{KKK,LLL}
LLLMMM
なぜ新パーサなのか
? 現状のパーサがいろいろつらい
? 拡張しづらい
? 「ブロックのネストをさせたい」etc
? 修正しづらい
? Builder/インラインごとにエンバグetc
? パーサから仕様がリバースできない
? (他に仕様があればいいんですが…)
? ReVIEW.jsみたいなのを作るにもつらそうな予感
つらい点
R::Compiler
<div class="emlist-code">
+
//emlist{
R::Builder <pre class="emlist">def foo(a)
def foo(a)
if a&gt;1
☆escape
if a>1
bar(a)
bar(a)
end
end
end</pre>
end
</div>
//}
つらい点
☆インラインを入れたい→escapeした文字列の連結
//emlist{
def foo(a)

if @<b>{a>1}
bar(a)
end
end
//}

<div class="emlist-code">
<pre class="emlist">def foo(a)
if <b>a&gt;1</b>
bar(a)
end
end</pre>
</div>
つらい点
☆ソースハイライトもしたい→unescape??
//emlist{
def foo(a)

if a>1
bar(a)
end
end
//}

<div class="emlist-code">
<pre class="emlist">def foo(a)
if a&gt;1
bar(a)
end
end</pre>
</div>

???
現パーサの問題点
? 正規表現で頑張っている
? パーサがReVIEW::Compilerと
ReVIEW::BuilderとReVIEW::*Builderに分割さ
れている

? 各Builderでの解析方法が統一されていない
(ような気がする)
新パーサの方針
? 基本的には書き直し
? ad hocな書き方をせず、ちゃんとパーサを実

装する(既存パーサライブラリor自作パーサ)

? ネストは実現できるようにしたい
? APIはあまり非互換にしない(変えすぎるとい
ろいろつらい)

? ReVIEW文法の再定義(明確化)も狙いたい
新パーサの現状
? kpegブランチで開発中(Github Issues #235)
? それなりに動くが、完璧ではない
新パーサの特徴
? パーサジェネレータ(PEG)を使って書き直し
? 実装としてはkpegを採用
? Ruby 1.8~2.1まで対応(してるといいな…)
? 外部gemへの依存なしで動く
? 現状はUTF-8のみだが、それ以外の文字コード
にも対応可能かも

? 現状のAPIに合わせている(kpegとしては不自
然かもしれないが、互換性は高いはず)
新パーサの実装
? lib/review/review.kpegで定義
? 生成されたパーサはlib/review/compiler.rb
になる(現状と同名のファイル)

? いったんAST(抽象構文木)を作成したあと、
それを元に各nodeに対する処理を呼び出す

? 処理内容は現状同様*Builderに書かれている
? *BuilderのAPIは一部非互換(inline_*)
== foo
XXXYYY
ZZZ
//list[foo1][foo2]{
AAA@<b>{BBB}CCC
DDD@<raw>{EEE{FFF}GGG}
IIIJJJ
//}
@<ruby>{KKK,LLL}
LLLMMM
root
Headline
level
2

Paragraph

Text

Text

Paragraph

Text
Text

InlineElement
foo

XXXYYY

ZZZ

name

contents
LLLMMM

ruby

Text
KKK

BlockElement

☆escapeは
ツリーを作った
後で行える

name
list

args
foo1

contents

Text
LLL

foo2

SinglelineContent

SinglelineContent

Text

InlineElement

Text

Text

AAA

BBB

CCC

DDD

SinglelineContent

Raw
EEE{FFF}GGG

Text
IIIJJJ
新パーサの課題

? パーサより文法が決まっていないのが課題
? 複雑なケースに対する処理がこれで正しいのか
どうかよく分からない

? //list[t1][@<b>{}]?
? highlightingとかの制御方法?具体的なルール
? インライン+ハイライトは死ぬ
? ReVIEWドキュメントの互換性は完璧ではない
(むしろ非互換にしたい)

? ReVIEW.jsとのマージ
リリーススケジュール
? 未定
? 今日の流れ次第で
? 2.0で?
? 1.xにはしない方が良さそう(互換性の問題
もあるし)
まとめ
? パーサを書き換え中
? いろいろスッキリした(はず)
? わりと動いている(はず)
? そもそもの仕様を決めないとダメ
? 良い機会なので整理したい

More Related Content

新?搁别痴滨贰奥パーサについて