替换+副作用
问题描述:
在访问一个编译单元时---在给定的条件下 - 我想应用一个转换(使用=>运算符)并计算相同转换应用于给定编译的次数单元。替换+副作用
我能够使用一种“全局模块变量”来执行该操作,但我确信可以在单个访问表达式中组合替换和操作。那可能吗?它使用的是本地变量,并用insert
块
module MultiCatch
import lang::java::\syntax::Java18;
import ParseTree;
import IO;
import Map;
import Type;
import List;
// sure, I don't like global variables.
//
// However I could not find a way to perform both
// a replacement and count the number of times
// it was applied in the same compilation unit.
int numberOfOccurences = 0;
/**
* Refactor a try-catch statement to use the
* MultiCatch construct of Java 7.
*/
public tuple[int, CompilationUnit] refactorMultiCatch(CompilationUnit unit) {
numberOfOccurences = 0;
CompilationUnit cu = visit(unit) {
case (TryStatement)`try <Block b1> <Catches c1>` => (TryStatement)`try <Block b1> <Catches mc>`
when mc := computeMultiCatches(c1)
};
return <numberOfOccurences, cu>;
}
/*
* Based on a simple notion of similarity,
* this function calculates the possible
* occurences of MultiCatch.
*/
private Catches computeMultiCatches(cs){
map [Block, tuple[list[CatchType], VariableDeclaratorId, Block] ] mCatches =();
visit(cs){
case(CatchClause)`catch (<CatchType t> <VariableDeclaratorId vId>) <Block b>` :{
if (b in mCatches){
<ts, vId, blk> = mCatches[b];
ts += t;
mCatches[b] = <ts, vId, blk>;
numberOfOccurences += 1;
}
else{
mCatches[b] = <[t], vId, b>;
}
}
}
return generateMultiCatches([mCatches[b] | b <- mCatches]);
}
/*
* Creates a syntactic catch clause (either a simple one or
* a multicatch).
*
* This is a recursive definition. The base case expects only
* one tuple, and than it returns a single catch clause. In the
* recursive definition, at least two tuples must be passed as
* arguments, and thus it returns at least two catches clauses
* (actually, one catch clause for each element in the list)
*/
private Catches generateMultiCatches([<ts, vId, b>]) = {
types = parse(#CatchType, intercalate("| ", ts));
return (Catches)`catch(<CatchType types> <VariableDeclaratorId vId>) <Block b>`;
};
private Catches generateMultiCatches([<ts, vId, b>, C*]) = {
catches = generateMultiCatches(C);
types = parse(#CatchType, intercalate("| ", ts));
return (Catches)`catch(<CatchType types> <VariableDeclaratorId vId>) <Block b> <CatchClause+ catches>`;
};
答
一种方式操作:
module MultiCatch
import lang::java::\syntax::Java18;
import ParseTree;
import IO;
import Map;
import Type;
import List;
/**
* Refactor a try-catch statement to use the
* MultiCatch construct of Java 7.
*/
public tuple[int, CompilationUnit] refactorMultiCatch(CompilationUnit unit) {
int numberOfOccurences = 0; /* the type is superfluous */
CompilationUnit cu = visit(unit) {
case (TryStatement)`try <Block b1> <Catches c1>` : {
numberOfOccurences += 1;
mc = computeMultiCatches(c1)
insert (TryStatement)`try <Block b1> <Catches mc>`;
}
};
return <numberOfOccurences, cu>;
}
- 的
{...}
块允许匹配之后所要执行多个语句; - 局部变量现在只存在于refactorMultiCatch的框架中;
-
insert
声明与之前的=>
箭头具有相同的效果; - 由于比赛
:=
总是成功的,我改变了when
条款成一个简单的分配新建分配FY
也有在流氓共享状态信息,其他更复杂的方式,但我个人更喜欢有状态无法逃避的词汇范围的功能。
这真是太棒了。谢谢! –