challenge α置換

標準入力から与えられたソースコードの変数名
を置換するプログラムを作ってください。
最近はリファクタリングツールなどの普及でこ
のような需要は少ないかと思われますが、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;
}

Posted feedbacks - Haskell

GHC6.8.1にパーサーとprettyprintのライブラリがあったのを発見したので、途中まで作ってみました。 ppという名前をpopに、popをppに置き換えるようになっています。 もう少しがんばらなくてはいけないところ: 1.入力ソースがprettyprintされてしまうので、アルファ置換以外の変更が起きてしまう。(改行、インデントが変わってしまう、コメントが保持されない) 2.スコープ管理がされていない。 3.ネームスペースに関する処理が入っていない…(Data.Stack.popは置換されるべきではないけれど、pop, Main.popはされるべき...) コメントの問題はパーサーの機能不足なので、解決には違うアプローチが必要です...パーサーがサポートしてくれれば、簡単ですが… 2,3に関してはパーサーのサポートはあるので、コードを書くだけなんですが...誰かやってください...
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module Main where

import Language.Haskell.Syntax
import Language.Haskell.Parser
import Language.Haskell.Pretty
import Data.Generics

pp :: ParseResult HsModule -> String
pp (ParseOk hsm) = prettyPrint hsm
pp _ = "parse failed"

repl :: ParseResult HsModule -> ParseResult HsModule
repl (ParseOk hsm) = ParseOk $ (everywhere (mkT conversion)) hsm
    where
        conversion :: HsName -> HsName
        conversion (HsIdent "pp") = HsIdent "pop"
        conversion (HsIdent "pop") = HsIdent "pp"
        conversion pop = pop
repl a = a

main :: IO ()
main 
  = do mod <- getContents
       putStr $ pp $ repl $ parseModule mod

Index

Feed

Other

Link

Pathtraq

loading...