α置換
Posted feedbacks - Ruby
変数v0を全てv1に置換した後に, 文字列とヒアドキュメント内のv1をv0に戻す処理をしています.
テストに使用したファイルを生成するコードも添付します.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | def subst_var(file, v0, v1)
hdocr = '[-]?[\"\'`]?([A-Z]+)'
shared_reg = 's,;&|=+-*/[](){}'
former, latter = %w[@$^ .].map{|reg|
"#{shared_reg}#{reg}".each_char.inject(''){|a,b| "#{a}\\#{b}"}}
gsub, rev_gsub = [:to_a, :reverse].map{|meth|
proc{|s| s.gsub(*[v0, v1].__send__(meth))}}
open(file, 'r'){|f| f.read}.
gsub(/(?:^#{v0})?(?:[#{former}]#{v0})+[#{latter}]/, &gsub).
gsub(/".*"/, &rev_gsub).
gsub(/<<#{hdocr}(?:.|\s)+[^<]#{hdocr}/, &rev_gsub)
end
file = 'sample.rb'
puts subst_var(file, 'v0', 'v1')
open(file, 'w'){|f| f.write(<<EOF)}
v0+v0=v0
@v0 = 0
$v00, ^v0
"v0 v0 "
<<EOS
v0 v0
EOS
$v0, v0, v0
v0/v0*v0-v0+v0
EOF
|
Ripperを使ってみました。Ruby 1.9.0以上じゃないと動かないと思います。
AlphaConverter.newの第2引数以降で置換する変数を指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | require 'ripper'
class AlphaConverter<Ripper::Filter
def initialize(src, *vars)
super(src)
@alpha_dict = {}
vars.each do |o, n|
@alpha_dict[o] = n
end
end
def var_common(token, data)
if @alpha_dict[token] then
data << @alpha_dict[token]
else
data << token
end
end
def on_default(event, token, data)
data << token
end
# クラス変数
def on_cvar(token, data)
var_common(token, data)
end
# 大域変数
def on_gvar(token, data)
var_common(token, data)
end
# インスタンス変数
def on_ivar(token, data)
var_common(token, data)
end
# ローカル変数
def on_ident(token, data)
var_common(token, data)
end
end
print AlphaConverter.new(ARGF, ['event', 'ee'], ['@alpha_dict', '@ad']).parse('')
|

gandalf #6153() Rating-2/6=-0.33
標準入力から与えられたソースコードの変数名 を置換するプログラムを作ってください。 最近はリファクタリングツールなどの普及でこ のような需要は少ないかと思われますが、viな ど貧弱なエディタを使っているときに困る のが変数名の置換です。さすがに以下の例のよ うなプログラムは例としてしか書きませんが、 置換しようとしている変数名と同じ綴りの他の ものがプログラム中に出てくることはまれにあ ります。そこで、与えられたソースコードに現 れる変数だけを指定された名前に置換してくだ さい。 置換対象となるソースコードと使用言語は同じ ものを使ってください。与えられるソースコー ドは、完全なコンパイル単位、もしくはパース して意味が通る範囲のものどちらであってもか まいません。後者の場合、一番外側の変数だけ 置換できるようにしてください。 C言語での解答例をつけたかったのですが、と ても難しかったためまだ作成できていません。 ご容赦ください。 例 $ cat a.c /* a */ int foo() { struct a {int a;} a; #if FOO a.a = 1; #endif { int a; } return 0; } $ alpha -DFOO=1 b a < a.c /* a */ int foo() { struct a {int a;} b; #if FOO b.a = 1; #endif { int a; } return 0; }[ reply ]