Practice of Programming

プログラム とか Linuxとかの話題

ルールのパーサ

Glueはルールのパーサが弱すぎると思いたち、パーサ改良中。
今は、ハッシュも使えないし、メソッドをつなぐこともできない...のです。

でも、パーサを自分で作るのは大変過ぎるので、似たようなもの...と考えてたら、
TTとほぼ一緒だと思い付いて、Template::Parserから借りることにしました。


以下、TTのパーサ部分の正規表現

       $line =~/
                # strip out any comments
                (\#[^\n]*)
           |
                # a quoted phrase matches in $3
                (["'])                   # $2 - opening quote, ' or "
                (                        # $3 - quoted text buffer
                    (?:                  # repeat group (no backreference)
                        \\\\             # an escaped backslash \\
                    |                    # ...or...
                        \\\2             # an escaped quote \" or \' (match $1)
                    |                    # ...or...
                        .                # any other character
                    |   \n
                    )*?                  # non-greedy repeat
                )                        # end of $3
                \2                       # match opening quote
            |
                # an unquoted number matches in $4
                (-?\d+(?:\.\d+)?)       # numbers
            |
                # filename matches in $5
                ( \/?\w+(?:(?:\/|::?)\w*)+ | \/\w+)
            |
                # an identifier matches in $6
                (\w+)                    # variable identifier
            |   
                # an unquoted word or symbol matches in $7
                (   [(){}\[\]:;,\/\\]    # misc parenthesis and symbols
#               |   \->                  # arrow operator (for future?)
                |   [+\-*]               # math operations
                |   \$\{?                # dollar with option left brace
                |   =>                   # like '='
                |   [=!<>]?= | [!<>]     # eqality tests
                |   &&? | \|\|?          # boolean ops
                |   \.\.?                # n..n sequence
                |   \S+                  # something unquoted
                )                        # end of $7
            /gmxo


正規表現一つでなんとかしてるんだな。凄いね。
コメントに、 詳しくは、"Mastering Regular Expressions" 読んでって書いてた。
会社の中国人に買ってもらった英語版(表紙は中国語だけど。安いんですよ)はあるけど、読んでない。


詳説 正規表現 第2版


これだけじゃあれなんで、追記。


これは、whileで回して、処理しているのですが、処理の中で各要素をLITERAL,QUOTED,UNQUOTED,NUMBER,FILENAME,IDENTのようにわけていきます。

UNQUOTED,(,UNQUOTED,{,IDENT,hoge,UNQUOTED,=>,LITERAL,1,UNQUOTED,,,IDENT,hogehoge,UNQUOTED,=>,IDENT,aaaa,UNQUOTED,},UNQUOTED,,,UNQUOTED,{,IDENT,hoge,UNQUOTED,=>,IDENT,xxxx,UNQUOTED,},UNQUOTED,),UNQUOTED,.,IDENT,yyy,UNQUOTED,(,UNQUOTED,{,UNQUOTED,},UNQUOTED,),UNQUOTED,.,IDENT,bbb,UNQUOTED,(,UNQUOTED,$,IDENT,hogehgoe,UNQUOTED,)

カンマ区切りで並べると、こんな感じ。で、その後の処理はみてないけど、forかなんかでチェックしてるんじゃなかろうか、
というか、僕はそうしました。