Categories
open all | close allTags
rake | スキンエンジン | JustPosted | デュアル・コア | rubygems | RESTful | 名称 | Subversion | ドキュメント | CSRF | 認証 | Migration | Aptana | テスト | フォーム | タグ | パソコン | Flash | 国際化 | カテゴリSearch
パーサのベース部分
あんまり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
Comments
No comments yet. You can be the first!