PEG in PEG

できた!

>>> print data

    A <- "a" A? "b"
    B <- "b" B? "c"
    S <- &(A !"b") "a"+ B !"c"

>>> e.Grammar.match(data)
[('A', Sequence(ExactMatcher('a'), Optional(Ref('A')), ExactMatcher('b'))), ('B', Sequence(ExactMatcher('b'), Optional(Ref('B')), ExactMatcher('c'))), ('S', Sequence(AndPredicate(Sequence(Ref('A'), NotPredicate(ExactMatcher('b')))), OneOrMore(ExactMatcher('a')), Ref('B'), NotPredicate(ExactMatcher('c'))))]/58
>>> build_env(_.value)
A
Sequence(ExactMatcher('a'), Optional(Ref('A')), ExactMatcher('b'))
B
Sequence(ExactMatcher('b'), Optional(Ref('B')), ExactMatcher('c'))
S
Sequence(AndPredicate(Sequence(Ref('A'), NotPredicate(ExactMatcher('b')))), OneOrMore(ExactMatcher('a')), Ref('B'), NotPredicate(ExactMatcher('c')))
<simple_peg_2.Environment object at 0x022165B0>
>>> env = _
>>> env.S.match("aaabbbccc")
'aaabbbccc'/9

でも、モジュールに名前空間が1個決めうちで存在するので、そこは直さないとね。
直したらこの手書きパーサを使って「PEGで定義されたPEGの文法」を読み込んでパーサを作って、それをつかって「PEGで定義されたPEGの文法」を読み込んで…

PEG

nishiohirokazu2007-11-24

あー。なんかトークン間のスペースを明示的に指定しないと行けない点をけなされるPEGだけど、それはトークンの区切り方が「一番メジャーな方法一つに決めうち」ではない、という逆の見方もできるんだ。

というのは、今見ていたPEGによるPEGの定義では、コメントや改行を区切りに含めていた。それもすごくシンプルでわかりやすく書ける。

Spacing <- (Space / Comment)*
Comment <- ’#’ (!EndOfLine .)* EndOfLine
Space <- ’ ’ / ’\t’ / EndOfLine
EndOfLine <- ’\r\n’ / ’\n’ / ’\r’

式を書いていて長くなってくると、適宜折り返してコメントをつけて見やすくしたくなるよね。そういうことが簡単にサポートできる。yaccとかでどうやってやるのかは僕は詳しくないけども、下のような式はRubyで-3を返すので、きっと実装が難しいんだと思う。

x = (1 
  - 2 
  - 3)

JavaScriptPythonPerlは正しく-4を返した。

中継

ラボに勉強会を中継する設備があればいいのにと思った。Python Developers Campを中継したみたいなアレ。

まぁそれはさておき、明日のPEG勉強会
http://www.coins.tsukuba.ac.jp/~i021216/diary/?date=20071121
をなんかうまいこと配信できないかなぁとか考えているわけです。

USBカメラ+ustreamで声拾えるかなぁ。発表資料はたぶん読めないよね。

まぁ中継するかしないかさておき、当日は
http://www.lingr.com/room/parsing
でチャットしてると思う。

今日の一枚

うちの加湿器。蒸気式。水タンクは2リットルの大容量。
部屋の暖房も同時にできる。ただしフィルター式とかに比べると頻繁にお手入れをしないといけない。一日に何回か中にたまった黒い液体を始末しないと行けない。
1日に1つずつ業務用杜仲茶のパックを消費する。数日に一回は全体を掃除しないと行けない。