neogeny / TatSu

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

Node missing children with nested dict #300

Closed joshtgl closed 10 months ago

joshtgl commented 1 year ago

New issue made, originally posted in https://github.com/neogeny/TatSu/issues/286.

calc_model.ebnf

@@grammar::Calc

start
    =
    expression $
    ;

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

addition::Add
    =
    left:term op:'+' ~ right:expression
    ;

subtraction::Subtract
    =
    left:term op:'-' ~ right:expression
    ;

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

multiplication::Multiply
    =
    left:factor op:'*' ~ right:term
    ;

division::Divide
    =
    left:factor '/' ~ right:term
    ;

factor
    =
    | subexpression
    | number
    ;

subexpression
    =
    '(' ~ @:expression ')'
    ;

number::int
    =
    /\d+/
    ;

Code to check children:

import tatsu
grammar = open('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 ...>]

The commit https://github.com/neogeny/TatSu/commit/d0fe7b8806c678adcfb8aeae100b08add66b70c3 also modified such that only single level dicts/lists with Node values are added as children, where before mapping and list types were recursively checked for children. In the example above, model['add'].right becomes a dict with value {'term': {'mul': {'__class__': 'Multiply' ... because term nodes are now dict's instead of single entries.

apalala commented 1 year ago

I think that the current behavior is the one with the least surprise.

Maybe yo could write a unit test or pull request with the behavior you expect?