Concurrent Clean : 正規表現

なんか、参考ページのパーザの書き方が間違ってるくさいんですけど・・・

"([A)]\()"

見たいなのが通らない気がする。
そうでなくても、ちょっとアレなので、後でいろいろ直していかないとダメっぽいな。

      • -

そして、正規表現文字列のコンパイル処理の記述を完了した。
悩まされたエラーメッセージは、

Start = {a \\ a <-:lst}
  where
    lst = [1,2,3]

というプログラムに対して、

"Array" no instance available of type [] Int

というメッセージが、lstの行に対して表示されるのに、間違っているのは配列内包表記の方だったというところ。
よくよく考えれば、そういいたくなる気持ちも分からんではないが・・・

      • -

そういうわけで、なんとなくできました。なんかまだグループを含む式のコンパイルが上手く行かないとかありますが。

Start = (res, map (map ((%) text)) res)
  where
    text = "deaaaabcd"
    res = text searches re "a*a|b"

とかやると、

([[(2,5)],[(6,6)]],[["aaaa"],["b"]])

という結果になります。reの代わりにre_with_msgを使うと、コンパイルエラー時にエラーメッセージを標準エラーに吐きます。
って、今書きながら思ったのですが、これはおかしいですね。"a*a"は常に失敗するはずですよ。むむむ。ああ、"b"も一つ拾い損ねているし。拾い忘れてないです。

      • -

でもまあ、こういうのを書きながら、せっかくコンパイル言語なのに、正規表現コンパイルが実行時まで遅延されているのは無駄なことだとか思ったりしていました。

      • -

引数の順序を変えることにした。

    res = re "a*|b" searches text

あと、toBool的な関数を用意して、

filter (toBool o ((searches) re "a*|b")) text_list

みたいな使い方ができるようになればかなり便利じやないか?

      • -

グループやクラスのコンパイルでエラーになるバグは添え字の取り扱いの問題だけでした。というわけで、

"[a-z]*"
"[a-z]-([0-9][0-9]|[a-z]*)"

みたいなものもOKになりました。

"[^0-9]*"

がバグるんですが・・・
ところで、今のコードのままでは、greedy matchにならないことに気づいて、もうちょっとちゃんとやるには、アルゴリズムの調査をきちんとやった方がいいのかもと思い始めている次第です。
正規表現って、古典的なのに、さらっとググってもアルゴリズムの解説ページとかってあまりないですねぇ。まぁ、最近はそんなことも気にならなくなりましたが。

      • -

あれ、perlでも、

perl -e '$_="aaaab"; print "OK" if m/a*a/;'

で、"OK"になるよ?
そういうものだっけ? それならそれでいいんだけど・・・
py***nでも、

>>> re.compile('(a*a)').match('aaaab').expand(r'\1')
'aaaa'
      • -

空文字列にマッチして空回りしていました。
そういえば、perlは空文字列にマッチするという仕様があったような気がするのですが、s///の時だけだっけ?
とにかく、空文字列とマッチしないように修正。