パーサのベース部分

あんまりRubyっぽくない書き方だけど,今のところほかに思いつかないのでそのまま。
aがnilの場合にa += b といった書き方ができないのが痛い。PHPだったら勝手に空文字列扱いにしてくれるのに。

パーサはネストありのものしか今のところ作っていませんが,ネストなしは簡単なので,まあいいでしょう。ただ,ちゃんとデバッグしてないです。正しくないフォーマットのものが来たら,問題起こす可能性大。無駄な検索をしていないので,実行速度は悪くないのではないかと思っています(ベンチマークはしてないけど)。

module Parser
  class Base
    def initialize (left = '<%', right = '%>', nest = true)
      @left = Regexp.new left
      @leftlen = left.length
      @right = Regexp.new right
      @rightlen = right.length
      @nest = nest
    end
    
    def parse(str)
      if @nest
         parse_with_nest(str)
      else
         parse_without_nest(str)
      end
    end

    
    def parse_with_nest(str)
       parenleft = StringScanner.new(str)
       parenright = StringScanner.new(str)
       length = str.length
       nestlevel = 0
       result = Array.new
       currentpos = 0
       parenleft.search_full(@left,true,false)
       parenright.search_full(@right,true,false)
       leftpos = parenleft.pos ? parenleft.pos : length
       rightpos = parenright.pos ? parenright.pos : length
      while (leftpos != length) || (rightpos != length)
        if nestlevel == 0 || leftpos < rightpos
          if ! result[nestlevel]
              result[nestlevel] = str[currentpos .. (leftpos-@leftlen-1)]
          else
              result[nestlevel] += str[currentpos .. (leftpos-@leftlen-1)]
          end
            nestlevel += 1
            currentpos = leftpos
          if parenleft.search_full(@left,true,false)
              leftpos = parenleft.pos
          else
              leftpos = length
          end  
        else
          if ! result[nestlevel]
              result[nestlevel] = str[currentpos .. (rightpos-@rightlen-1)]
          else
              result[nestlevel] += str[currentpos .. (rightpos-@rightlen-1)]
          end
           result[nestlevel-1] += self.exec result[nestlevel]
           result.pop
           nestlevel -= 1
           currentpos = rightpos
          if parenright.search_full(@right,true,false)
             rightpos = parenright.pos
          else
             rightpos = length
          end
        end
      end
       result[0] += str[currentpos .. length]
    end
    
    def exec str
       'exec(' + str + ')'
    end
    
  end
end



03 Nov, 2007 | General | | Andy
« Prev item - Next Item »
---------------------------------------------

Comments


No comments yet. You can be the first!


Leave comment

© 2007 yoursite.com | Designed by DesignsByDarren
Ported to Nucleus CMS: Suvoroff