我正在尝试使用rascals visit语句匹配和删除两个语句。当然我还需要检查它们是否被使用,但在这种情况下,我不必担心。在下面的示例中,您可以看到两个tmp
变量,它们是已创建但未使用的变量(这是半伪Rust代码)。它们仅作为临时变量创建并释放。 (我试图在Java中创建equivelant,但它在翻译中丢失了一些上下文,例如重新声明tmp
)
{
let tmp : c_void = repository as c_void;
repository = MArray();
free(tmp);
let tmp : c_void = where_ as c_void;
where_ = MArray();
free(tmp);
}
这是我一直在玩的动作模式的简化版本的示例。使用这种模式,我认为第一个free
语句将匹配,但它显然是范围内的最后一个。我曾尝试以各种方式执行此操作,如语句计数器和各种不同的模式,但没有成功。
visit(crate){
case (Statements) `let tmp : c_void = <Identifier _> as c_void;
'<Statement* stmts>
'free(tmp);` =>
(Statements) `<Statement* stmts>`
}
最终产品应如下所示:
{
repository = MArray();
where_ = MArray();
}
修改:进度
我已经设法用以下代码做了我想做的事情(这仍然只是半伪锈):
crate = innermost visit(crate){
case (Statements) `let tmp : c_void = <Identifier _> as c_void;
'<Statement* stmts>
'free(tmp);
'<Statement* post_stmts>` =>
(Statements) `<Statement* stmts>
'<Statement* post_stmts>`
case (Statements) `<Statement* pre_stmts>
'let tmp : c_void = <Identifier _> as c_void;
'<Statement* stmts>
'free(tmp);` =>
(Statements) `<Statement* pre_stmts>
'<Statement* stmts>`
}
现在,这适用于tmp
个实例的单个范围匹配,但不会扩展到其他范围。我不确定为什么它不会继续匹配其他范围,尽管它使用innermost
匹配。 if
else
的一个例子适用于此。它匹配并更改tmp
分支中的if
个实例,但它不会继续进入else
分支以在那里匹配它们。
编辑:最终
现在似乎已经解决了。我想知道是否添加另一个案例会有所帮助,是的。显然,这不是未达到范围的问题,而是与范围内容不匹配的问题。以下是修改后的代码(我必须更改语句名称,因为Rascal抱怨重新声明Statement*
名称accros案例):
crate = innermost visit(crate){
case (Statements) `let mut tmp : *mut ::std::os::raw::c_void = <Identifier _> as (*mut ::std::os::raw::c_void);
'<Statement* stmts1>
'free(tmp);
'<Statement* stmts2>` =>
(Statements) `<Statement* stmts1>
'<Statement* stmts2>`
case (Statements) `<Statement* stmts3>
'let mut tmp : *mut ::std::os::raw::c_void = <Identifier _> as (*mut ::std::os::raw::c_void);
'<Statement* stmts4>
'free(tmp);` =>
(Statements) `<Statement* stmts3>
'<Statement* stmts4>`
case (Statements) `<Statement* stmts5>
'let mut tmp : *mut ::std::os::raw::c_void = <Identifier _> as (*mut ::std::os::raw::c_void);
'<Statement* stmts6>
'free(tmp);
'<Statement* stmts7>` =>
(Statements) `<Statement* stmts5>
'<Statement* stmts6>
'<Statement* stmts7>`
}
^(此示例是实际代码,不再是半伪代码。)
答案 0 :(得分:2)
在上次free(tmp)
之后没有占位符,因此最后`let tmp : c_void = <Identifier _> as c_void;
'<Statement* stmts1>
'free(tmp);
'<Statement* stmts2>`
匹配。可以使用这样的模式:
row_number()
我不知道你的例子的确切细节,但你可以尝试一下。