2017-07-08 2 views
0

私はrascals visitステートメントで2つのステートメントを照合して削除しようとしています。もちろん、それらが使用されているかどうかを確認する必要もありますが、この場合は心配する必要はありません。下の例では、作成されたが使用されていない2つのtmpの変数が表示されています(これは半疑似錆コードです)。それらは一時変数として作成され、解放されます。2つのステートメントのアクションパターン

{ 
    let tmp : c_void = repository as c_void; 
    repository = MArray(); 
    free(tmp); 

    let tmp : c_void = where_ as c_void; 
    where_ = MArray(); 
    free(tmp); 
} 

(私はJavaでequivelantを作成しようとしましたが、それは例えばのような訳で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のマッチングを使用しているにもかかわらず、なぜ他のスコープでもマッチし続けるだけではないのか分かりません。 ifelseの例はこれに適しています。 ifブランチ内のtmpインスタンスと一致して変更されますが、ブランチに一致するようにelseブランチに継続しません。

編集:最終

これは今解決されているようです。別のケースを追加することが助けになるかどうかと私は思った。明らかに、スコープに到達しないという問題ではなく、スコープの内容に一致しないという問題でした。ここで(ラスカルは例accros再宣言Statement*名文句ので、私は文の名前を変更する必要がありました)働く修正コードは次のとおりです。

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

^(この例では、もはや、実際のコードではありません半擬似コードです。 )

答えて

2

最後のfree(tmp);の後にプレースホルダがないので、最後のfree(tmp)に一致するがあります。

`let tmp : c_void = <Identifier _> as c_void; 
'<Statement* stmts1> 
'free(tmp); 
'<Statement* stmts2>` 

あなたの例の詳細はわかりませんが、これを試すことができます。

+0

これは、tmpとそのフリーステートメントの最初のインスタンスでは動作しますが、2番目のインスタンスでは動作しないようです。私は一番内側の訪問を使っていて、一番外側を試しましたが、それはうまくいかないようです。 –

+0

私が試してみなければならない方法を示唆していただきありがとうございます。それはいくつかの変更を加えて機能しました。 –

+0

あなたが 'solve(crate){...現在の訪問コード...} 'で訪問をラップした場合、これが最も可能性が高いでしょう。リストの要素はすべて同じレベルにあるので、繰り返しリストではなくリストに一度しかマッチしないと仮定します。これを行うことができる他の方法もありますが、これは最も簡単な変更です。 –

関連する問題