cenotelie / hime

Apache License 2.0
27 stars 4 forks source link

Assign children name #101

Open stevefan1999-personal opened 11 months ago

stevefan1999-personal commented 11 months ago

Wouldn't it be nice if we could do:

        for_statement -> 'for'! '('! initial=(expression_statement | declaration) condition=expression_statement post_operation=expression? ')'! body=statement;

Instead of:

        for_statement_initial -> expression_statement | declaration;
        for_statement_condition -> expression_statement;
        for_statement_post_operation -> expression;
        for_statement_body -> statement;

        for_statement -> 'for'! '('! for_statement_initial for_statement_condition for_statement_post_operation? ')'! for_statement_body;
woutersl commented 11 months ago

It looks like you want sub rules, you can write this:

for_statement -> 'for'! '('!
    {expression_statement | declaration}
    {expression_statement} 
    {expression}?
')'! {statement};

This produces the same AST as the fully expanded form, except that the nodes for the sub rules are anonymous, i.e.:

for_statement
+-> <epsilon>
|       +-> expression_statement
+-> <epsilon>
|       +-> expression_statement
+-> <epsilon>
+-> <epsilon>
        +-> statement

If you want names on the sub rules, then in the current state you indeed have to fully expand the grammar.

IMO the expanded version is clearer than a more compact version, but YMMV.

woutersl commented 11 months ago

I forgot that you can also use virtual symbols and promote them if that's what you want :

for_statement -> 'for'! '('!
    {"initial"^ (expression_statement | declaration)}
    {"condition"^ expression_statement} 
    {"post_operation"^ expression?}
')'! {"body"^ statement};

will give you this:

for_statement
+-> "initial"
|       +-> expression_statement
+-> "condition"
|       +-> expression_statement
+-> "post_operation"
+-> "body"
        +-> statement
woutersl commented 11 months ago

If something like this is desirable:

for_statement -> 'for'! '('!
    initial=(expression_statement | declaration)
    condition=expression_statement
    post_operation=expression?
')'! body=statement;

It would be best to leverage the existing syntax for sub rules, expanded to look like this:

for_statement -> 'for'! '('!
    initial={expression_statement | declaration}
    condition={expression_statement}
    post_operation={expression?}
')'! body={statement};

The output AST would be the same:

for_statement
+-> "initial"
|       +-> expression_statement
+-> "condition"
|       +-> expression_statement
+-> "post_operation"
+-> "body"
        +-> statement
stevefan1999-personal commented 10 months ago

If something like this is desirable:

for_statement -> 'for'! '('!
    initial=(expression_statement | declaration)
    condition=expression_statement
    post_operation=expression?
')'! body=statement;

It would be best to leverage the existing syntax for sub rules, expanded to look like this:

for_statement -> 'for'! '('!
    initial={expression_statement | declaration}
    condition={expression_statement}
    post_operation={expression?}
')'! body={statement};

The output AST would be the same:

for_statement
+-> "initial"
|       +-> expression_statement
+-> "condition"
|       +-> expression_statement
+-> "post_operation"
+-> "body"
        +-> statement

This would be awesome as I could leverage these information for AST building