LPegの使い方 patternその1
こんにちは、びしょ〜じょです。無事『FLOWERS』夏篇を終わったことにより脳内が百合まみれっちゅ〜わけ。
春篇もさることながら、とんでもない百合でしたね。八重垣さんと孝崎さん人間的に不器用すぎる。 しかしそれ故に互いを認め合った時の、アレよ、最高。後半の八重垣さんに対し積極的になった孝崎さん可愛すぎるし弱ってたり素直だったりする八重垣さんも可愛いしもうやばいでしょ。
キャストも前作からのあやねると洲崎綾で、最っ高やな…。『chaleur』もいいし洲崎さんも歌うんだよな、いい…。
本当に最高でした、秋篇も非常に楽しみです。カラノショージョ3もあるしイノグレさまさまって感じ。
追伸 なんか今回沙沙貴姉妹以前より増してすごく可愛くなかったですか。ハグしてくれのところとか親友のところとか。
LPegとは
全く関係ないこというけど有名なLuaモジュールの一部のロゴってこんな感じでちんまりしてるよね。LuaTeXのロゴとかもアレだし。はい。
PEGのLua版。PEGは文脈自由文法の知り合いで曖昧性がない。詳しくは調べてください。
# LuaRocksにあるので簡単インストール
luarocks --local install lpeg
Luaの(サブセットの)処理系をMoonScriptで書くことになったので、本稿は使い方の備忘録となる。
まずpatternで文法を作る(らしい)(詳しく知らない)。
Pattern
MoonScript + LPeg的にはimport P, S, R, V, C from require "lpeg"
等とするのがいいが、説明のためlpeg = require "lpeg"
ってな感じに。
lpeg.P(val)
なかなかトリッキーな関数。
-
type(val) == "string"
pattern
^val
を返す。 -
type(val) == "table"
PEGを表現できる。渡されたPEGに基づくpatternを返す。
他にも渡された型によっていろいろできる。公式をご覧ください(丸投げ)。
lpeg.R(range)
正規表現的にいうと〜lpeg.R "09"
は[0-9]とかlpeg.R "az"
は[a-z]みたいな感じのpatternを返す。
lpeg.S(str)
正規表現的にいうとlpeg.S "+-/*%"
で[+-/*%]みたいな感じのpatternを返す。正規表現を見ると前項のlpeg.R
とで少々の混乱が生まれた。
lpeg.V(v)
文法を定義するとき、非終端記号を示すのに使われる。
演算子
文法について触れる前にpattern同士の演算子をよォ…。
pat * pat
連接を表す。PEGだと\(S\cdot{}E\)または\(SE\)みたいな感じになる。S * E
pat + pat
和集合。 PEGだと\(S/E\)となる。ここでひとまずPEGの説明をすると、この\(/\)は文脈自由文法でいうところの\(|\)に似ているが、異なる点は\(S\)に失敗すると\(E\)に適合するか調べ、\(S\)には戻らないところ。これがPEGの曖昧さを破壊している。
pat^n
patをn回以上繰り返す。nが負の数だと最小マッチになる。n == -1
のときはPEGの\(pat?\)(省略可能)になる。
(pat)
いつものグルーピング。
Grammer
lpeg.P
にtableを渡すことでPEGを定義できる。四則演算はこんな感じかしら。
space = lpeg.S' \t\n'
grammer = lpeg.P{
'Term'
Term: lpeg.V'Fact' * (space^0 * lpeg.S'+-' * space^0 * lpeg.V'Fact')^0
Fact: lpeg.V'Prm' * (space^0 * lpeg.S'*/%' * space^0 * lpeg.V'Prm')^0
Prm: lpeg.S'(' * space^0 * lpeg.V'Term' * space^0 * lpeg.S')' + lpeg.R'09'
}
PEG的にはこうなる。
渡すtableの1番目には開始記号を明示していする。
Tips
MoonScriptでLPegを使う際、想いがMoonScript処理系に伝わらないことがある。例えば\([0-9][a-z][A-Z]\)というものを書きたい時、
-- MoonScript
R '09' * R 'az' * R 'AZ'
とすると、Luaに落ちる時、曲解される。
-- Lua
R('09' * R('az' * R('AZ')))
フニ〜
-- MoonScript
R'09' * R'az' * R'AZ'
といった具合に関数と引数の間にスペースを入れないことで
-- Lua
R('09') * R('az') * R('AZ')
落ちたな(確信)。
Luaの純度を高めるため、LuLPegを使おうと考えている。見たところLPeg v0.12と同じ動きをちゃんとしてくれているようだ。
その1があるからってその2があるとか、そういう考えは捨てて欲しい。でも『FLOWERS』秋篇は5000%あるので、ある。