两个语句的动作模式
Pattern with action for two statements
我正在尝试用 rascals visit 语句匹配并删除两个语句。当然,我还需要检查它们是否被使用,但在这种情况下,我不必担心。在下面的示例中,您可以看到创建但未使用的两个 tmp
变量(这是半伪 Rust 代码)。它们仅作为临时变量创建并释放。 (我试图在 Java 中创建等价物,但它在翻译中丢失了一些上下文,例如 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();
}
编辑:进度
我已经成功地用下面的代码做了我想做的(这仍然只是半伪 Rust):
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
的一个例子就适合这个。它匹配并更改 if
分支中的 tmp
个实例,但它不会继续进入 else
分支以在那里匹配它们。
编辑:最终
这似乎已经解决了。我想知道添加另一个案例是否有帮助,是的。显然不是没有达到范围的问题,而是范围内容不匹配的问题。这是修改后的有效代码(我不得不更改语句名称,因为 Rascal 抱怨重新声明 Statement*
名称 accros cases):
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>`
}
^(这个例子是实际代码,不再是半伪代码。)
最后一个 free(tmp);
后没有占位符,所以最后一个 free(tmp)
有 匹配。可以使用这样的模式:
`let tmp : c_void = <Identifier _> as c_void;
'<Statement* stmts1>
'free(tmp);
'<Statement* stmts2>`
我不知道你的例子的具体细节,但你可以试一试。
我正在尝试用 rascals visit 语句匹配并删除两个语句。当然,我还需要检查它们是否被使用,但在这种情况下,我不必担心。在下面的示例中,您可以看到创建但未使用的两个 tmp
变量(这是半伪 Rust 代码)。它们仅作为临时变量创建并释放。 (我试图在 Java 中创建等价物,但它在翻译中丢失了一些上下文,例如 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();
}
编辑:进度
我已经成功地用下面的代码做了我想做的(这仍然只是半伪 Rust):
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
的一个例子就适合这个。它匹配并更改 if
分支中的 tmp
个实例,但它不会继续进入 else
分支以在那里匹配它们。
编辑:最终
这似乎已经解决了。我想知道添加另一个案例是否有帮助,是的。显然不是没有达到范围的问题,而是范围内容不匹配的问题。这是修改后的有效代码(我不得不更改语句名称,因为 Rascal 抱怨重新声明 Statement*
名称 accros cases):
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>`
}
^(这个例子是实际代码,不再是半伪代码。)
最后一个 free(tmp);
后没有占位符,所以最后一个 free(tmp)
有 匹配。可以使用这样的模式:
`let tmp : c_void = <Identifier _> as c_void;
'<Statement* stmts1>
'free(tmp);
'<Statement* stmts2>`
我不知道你的例子的具体细节,但你可以试一试。