dlang-community / Pegged

A Parsing Expression Grammar (PEG) module, using the D programming language.
534 stars 66 forks source link

Discarding all children should not dropping entire node. #200

Open Domain opened 8 years ago

Domain commented 8 years ago

This grammar:

BreakStmt < :'break' :';'

will drop the entire node, but I just want to drop all children.

Temtaime commented 8 years ago

You can use ^ to keep a BreakStmt, non ? All the nodes without children are discarded.

Domain commented 8 years ago

Keeping node result in wrong tree struct:

while(true){continue;break;}

    Zero:

    Program < Statement* :eoi
    Statement < BlockStmt / WhileStmt / ^ContinueStmt / ^BreakStmt
    BlockStmt < :"{" Statement* :"}"
    WhileStmt < :"while" :"(" Expr :")" Statement
    ContinueStmt < :"continue" :";"
    BreakStmt < :"break" :";"
    Expr < "true"
Zero [0, 29]["true"]
 +-Zero.Program [0, 29]["true"]
    +-Zero.Statement [0, 29]["true"]
       +-Zero.WhileStmt [0, 29]["true"]
          +-Zero.Expr [6, 10]["true"]
          +-Zero.ContinueStmt [12, 21][]
          |  +-and!(discard, discard) [12, 21][]
          +-Zero.BreakStmt [21, 27][]
             +-and!(discard, discard) [21, 27][]

What I want is:

    Zero:

    Program < Statement* :eoi
    Statement < BlockStmt / WhileStmt / ContinueStmt / BreakStmt
    BlockStmt < :"{" Statement* :"}"
    WhileStmt < :"while" :"(" Expr :")" Statement
    ContinueStmt < "continue" :";"
    BreakStmt < "break" :";"
    Expr < "true"
Zero [0, 29]["true", "continue", "break"]
 +-Zero.Program [0, 29]["true", "continue", "break"]
    +-Zero.Statement [0, 29]["true", "continue", "break"]
       +-Zero.WhileStmt [0, 29]["true", "continue", "break"]
          +-Zero.Expr [6, 10]["true"]
          +-Zero.Statement [11, 29]["continue", "break"]
             +-Zero.BlockStmt [11, 29]["continue", "break"]
                +-Zero.Statement [12, 21]["continue"]
                |  +-Zero.ContinueStmt [12, 21]["continue"]
                +-Zero.Statement [21, 27]["break"]
                   +-Zero.BreakStmt [21, 27]["break"]

Note that WhileStmt should have 2 children.