ifの処理つきパーサーのコード

ほぼ完全版(のつもり)。これで,各パーサーのクラスはスキン変数やテンプレート変数に相当する部分のparse_●●を書いていけばいいはずです。

ああっと,まだプラグイン呼び出すとこ書いてないけど,parse_●●がなかったときの処理としてrescue節に入れてあげればいいでしょう。そもそもまだプラグインのアーキテクチャを考えていないので,そこは後から加えます。


# ParserBase
require 'strscan'

module NCParser

  class Base

     yaml = YAML.load_file("config/database.yml")
     ENV['RAILS_ENV'] ||= 'development'
    @@execmode = ENV['RAILS_ENV']
    
    def initialize (left = '<%', right = '%>', nest = false)
      @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
       ifstack = Array.new
       ifstack[0] = Array.new
       @ifsituation = ifstack[0]
       currentpos = 0
      if parenleft.search_full(@left,true,false)
         leftpos = parenleft.pos
      else
         leftpos = length+1
      end
      if parenright.search_full(@right,true,false)
         rightpos = parenright.pos
      else
         rightpos = length+1
      end
      while (leftpos <= length) || (rightpos <= length)
        if nestlevel == 0 || leftpos < rightpos
          if @ifsituation.size == 0 || @ifsituation.last == 1
            if ! result[nestlevel]
                result[nestlevel] = str[currentpos , (leftpos-@leftlen-currentpos)]
            else
                result[nestlevel] += str[currentpos , (leftpos-@leftlen-currentpos)]
            end
          end
            ifstack.push Array.new
          @ifsituation = ifstack.last
            nestlevel += 1
            currentpos = leftpos
          if parenleft.search_full(@left,true,false)
              leftpos = parenleft.pos
          else
              leftpos = length+1
          end  
        else
          if @ifsituation.size == 0 || @ifsituation.last == 1
            if ! result[nestlevel]
                result[nestlevel] = str[currentpos , (rightpos-@rightlen-currentpos)]
            else
                result[nestlevel] += str[currentpos , (rightpos-@rightlen-currentpos)]
            end
          end
           result[nestlevel-1] += self.exec result[nestlevel]
           result.pop
           nestlevel -= 1
           ifstack.pop
          @ifsituation = ifstack.last
           currentpos = rightpos
          if parenright.search_full(@right,true,false)
             rightpos = parenright.pos
          else
             rightpos = length+1
          end
        end
      end
       result[0] += str[currentpos .. length]
    end

    def parse_without_nest(str)
       parenleft = StringScanner.new(str)
       parenright = StringScanner.new(str)
       length = str.length
       result = ''
       currentpos = 0
       leftpos = 0
       rightpos = 0
       @ifsituation = Array.new
       
      while (leftpos <= length) || (rightpos <= length)
         if parenleft.search_full(@left,true,false)
           leftpos = parenleft.pos
        else
           leftpos = length+1
        end
        begin
          if parenright.search_full(@right,true,false)
             rightpos = parenright.pos
          else
             rightpos = length+1
          end
        end while leftpos > rightpos
         if leftpos<=length && rightpos<=length
          if @ifsituation.size == 0 || @ifsituation.last == 1
              result += str[currentpos,(leftpos-@leftlen-currentpos)].to_s
          end
           result += self.exec str[leftpos..rightpos-@rightlen-1]
           currentpos = rightpos
           parenleft.pos = rightpos-1
        else
           result += str[currentpos,length-currentpos]
        end
      end
       result
     end
 
    def exec str
      str.rstrip!
      str.lstrip!
      str =~ /^(\w+)(?:\((.*)\))?$/m
      command = $1
      paramall = $2 ? $2 : ""
      params = paramall.split(/[\t\r\n\f\v]*,[\t\r\n\f\v]*/)
      params.unshift paramall
      begin
         send('do_'+command, params)
      rescue
        begin
           if @ifsituation.size == 0 || @ifsituation.last == 1
               send('parse_'+command, params)
           else
              ''
           end
        rescue
            debugout('<%'+command+'('+paramall+')%>')
        end
      end
    end
    
    def debugout str
      if @@execmode == 'production'
         ''
      else
         str
      end
    end

    def do_if(params)
      if self.check_conditions(params)
        @ifsituation.push(1)
      else
        @ifsituation.push(0)
      end
      ''
    end
    
    def do_ifnot(params)
      if self.check_conditions(params)
        @ifsituation.push(0)
      else
        @ifsituation.push(1)
      end
      ''
    end
    
    def do_else(params)
      case @ifsituation.last
      when 0
         @ifsituation[-1,1] = 1
      when 1
         @ifsituation[-1,1] = 2
      end
       ''
    end

    def do_elseif(params)
      case @ifsituation.last
      when 0
          if self.check_conditions(params)
            @ifsituation[-1,1] = 1
          else
            @ifsituation[-1,1] = 0
          end
      when 1
         @ifsituation[-1,1] = 2
       end
       ''
    end
    
    def do_elseifnot(params)
      case @ifsituation.last
      when 0
          if self.check_conditions(params)
            @ifsituation[-1,1] = 0
          else
            @ifsituation[-1,1] = 1
          end
      when 1
         @ifsituation[-1,1] = 2
       end
       ''
    end
    
    def do_endif(params)
      @ifsituation.pop
      ''
    end
    
  end
end



09 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