两个语句的动作模式

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>`

我不知道你的例子的具体细节,但你可以试一试。