xpeg
xtalにxpegという名前でPEGが入ります。svn上では一応実装されています。
PEGとは
http://ja.wikipedia.org/wiki/%E8%A7%A3%E6%9E%90%E8%A1%A8%E7%8F%BE%E6%96%87%E6%B3%95
- 並び: e1 >> e2
- 選択: e1 | e2
- ゼロ個以上の繰り返し: e*0
- 1個以上の繰り返し: e*1
- 1個以内の省略可能: e*-1
繰り返しは、一度マッチしたら離さない強欲な繰り返しです。
正規表現のように使いたい場合もあるでしょうから、正規表現の貪欲な繰り返し、非貪欲な繰り返しもサポートしています。
- 1個以上の貪欲な繰り返し: e/1
- 1個以上の非貪欲な繰り返し: e%1
これらは、*演算子と優先順位が等しいため選択されました。
とりあえず、使用例で雰囲気を。
String::splitにはxpegのパターンが渡せます。
,か:で区切りたい場合次のようにします。
str: "test,we:rwe,rr:rr,rr"; str.split("," | ":"){ it.p; } //test //we //rwe //rr //rr //rr
String::scanというメソッドも追加されました。
// lalphaとはaからzまでの範囲の文字にマッチするパターンである lalpha: "a".."z"; // degitとは 0から9までの範囲の文字にマッチするパターンである degit: "0".."9"; // many1_lalphaとは、1以上のlalphaにマッチするパターンである many1_lalpha: lalpha*1; // many0_degitとは、0以上のdegitにマッチするパターンである many0_degit: degit*0; // cap_many0_degitとは、many0_degitがマッチしたらkeyという名前でキャプチャするパターンである cap_many0_degit: cap(key: many0_degit); // patternとは、many1_alphaがマッチしたあと続けてcap_many0_degitがマッチするパターンである pattern: many1_lalpha >> cap_many0_degit; str:"a65,b,cser4,eeeee44"; str.scan(pattern){ it[""].p; // マッチした全体の文字列をp it["key"].p; // keyという名前でキャプチャした部分文字列をp "-----".p; } //a65 //65 //----- //b // //----- //cser4 //4 //----- //eeeee44 //44 //-----
文字列だけでなく、イテレータに適用もできます。
たとえば、下のソースは、整数45の次の要素をキャプチャしてpする例です。
[0,32,45,53,23,23,1123,43,45,3].each.scan(pred(|x|x==45) >> cap(n: any)){ it("n")[0].p; }
-
-
- -
-
なお、xpegはk.inabaさんのGreenPadのRSearchのソースをかなり参考にさせていただきました。
ありがとうございました。
http://www.kmonos.net/