Search code examples
rascalsubtree

Rascal MPL remove subtree in visit


How to replace a subtree with nothing in a visit?

In Pattern With Action, we see that

case red(l, r) => green(l, r)

replaces all red nodes with green nodes. I want to do something like

case red(l, r) => []

to remove all red nodes. Is that possible?


Solution

  • Interesting question. So if the abstract grammar is this:

    data MyNode
       = green(MyNode l, MyNode r)
       | red(MyNode l, MyNode r)
       | black()
       | white()
       ;
    

    Any visit is not allowed to change the type of the node it replaces. So a red node can become green, or black or white, but not "nothing". You could add a definition of nothing:

    data MyNode = nothing();
    

    And then rewrite all red nodes to nothing:

    case red(_,_) => nothing()
    

    So that's not really nothing :-)

    However, a more common case is to remove elements from a list. In abstract syntax trees for programming languages this often happens:

    data MyNode = nodes(list[MyNode] elements);
    

    For example if the list of statements of an if-then-else statement, etc.

    Now you can match on the list to remove elements:

    case nodes([*prefix, red(_,_), *postfix)]) => nodes([*prefix, *postfix])
    

    And now the red node is really gone.