Categories
open all | close allTags
国際化 | スキンエンジン | 名称 | アクセス制御 | rake | テスト | フォーム | ドキュメント | Subversion | タグ | OpenID | Aptana | モデル | Migration | パソコン | Flash | CSRF | デュアル・コア | RESTful | 認証Search
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
Comments
No comments yet. You can be the first!