neogeny / TatSu

竜 TatSu generates Python parsers from grammars in a variation of EBNF
https://tatsu.readthedocs.io/
Other
408 stars 48 forks source link

Node missing children with nested dict #286

Closed joshtgl closed 1 year ago

joshtgl commented 2 years ago

I recently updated to a newer version of TatSu and found differing results which I was not sure if they were expected. The change in behavior is a result of the following commit: https://github.com/neogeny/TatSu/commit/d0fe7b8806c678adcfb8aeae100b08add66b70c3

In the previous behavior, parent nodes with nested dictionary attributes (with other nodes within these dictionaries) would be listed as children to the parent node. After the commit above, only a single level of mappings is checked for children. The JSON output shows an example node with the missing child:

{ "__class__": "Parent", "attribute": { "subattribute" { "subsubattribute" { "__class__": "MissingChild" } } "foundattribute" { "__class__": "FoundChild" } } }

apalala commented 2 years ago

There isn't enough information in that note to understand the issue.

But yes. The AST returned from a rule was flattened to resolve a number of ambiguities and to allow for consistent model building. To have nested dictionaries, the expression should me moved to its own rule.

To move to a different implementation there needs to be a discussion about the benefits, and the implementation itself must be proposed.

joshtgl commented 2 years ago

As a quick example with modifying calc_model.ebnf https://github.com/neogeny/TatSu/blob/master/examples/calc/grammars/calc_model.ebnf

Modify the following rules:

expression
    =
    | add:addition
    | sub:subtraction
    | term:term
    ;

term
    =
    | mul:multiplication
    | div:division
    | factor:factor
    ;

With parsing the example 3 + 5 * ( 10 - 20 ), calling children() on the Add model node in the outputted model will be empty in 5.7+ and will include the Multiply model node in 5.6 and earlier.

def parse_example():
    grammar = open('grammars/calc_model.ebnf').read()

    parser = tatsu.compile(grammar, asmodel=True)
    model = parser.parse('3 + 5 * ( 10 - 20 )')
    print(model['add'].children())
    # 5.7+: []
    # 5.6 and earlier: [<tatsu.synth.Multiply object at ...>]
apalala commented 2 years ago

Checking...

apalala commented 1 year ago

Can you check on this again, @joshtgl ? I have some time to work in TatSu now.

apalala commented 1 year ago

I'm closing this as not reproducible. Feel free to post again.