模式与两个声明的行动

时间:2017-07-08 21:54:32

标签: rascal

我正在尝试使用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>`
}

^(此示例是实际代码,不再是半伪代码。)

1 个答案:

答案 0 :(得分:2)

在上次free(tmp)之后没有占位符,因此最后`let tmp : c_void = <Identifier _> as c_void; '<Statement* stmts1> 'free(tmp); '<Statement* stmts2>` 匹配。可以使用这样的模式:

row_number()

我不知道你的例子的确切细节,但你可以尝试一下。