petitparser / dart-petitparser

Dynamic parser combinators in Dart.
https://pub.dartlang.org/packages/petitparser
MIT License
453 stars 47 forks source link

Collecting Parsed result and passing it to next product #148

Closed Oualitsen closed 1 year ago

Oualitsen commented 1 year ago

Hello, I am using dart-petitparser and I wrote a grammar for graphql. The ultimate goal is to create dart objects (DTOs) and queries from a given schema. I wanted to know if there is a simple way to pass data from one production to the next one. Here is some conext: a graphql fragment is applied to a given Type (Say User, Car ...etc). When I parse a fragment I want to know on which type it is. On LL(1) we first parse the type name then parse the fragment block but I need to pass the type name to the fragment block production.

Here is how I am doing it right now:

`Parser fragmentDefinition() { late String name; late String onTypeName; late GQFragmentBlockDefinition block;

List<GQDirectiveValue>? directives;

return (ref1(token, "fragment") &
        identifier().map((value) => name = value) &
        ref1(token, "on") &
        identifier().map((value) => onTypeName = value) &
        directiveValueList().map((value) => directives = value) &
        fragmentBlock(onTypeName).map((value) => block = value))
    .map((value) {
  return GQFragmentDefinition(name, onTypeName, block, directives ?? []);
}).map((f) {
  addFragmentDefinition(f);
  return f;
});

}`

I don't know if this is the right way to pass the onTypeName to the fragmentBlock production. Tested it like that and it says that onTypeName is not initialized. This means that I have used it before it gets initialized. Any help would be very appreciated. If you need more clarifications I will be more than happy to add comments on this issue.

renggli commented 1 year ago

No, this is not how the library is supposed to be used. map might be called repeatedly (or not at all) and you might end with your state being overridden or unnecessarily retained. In your example, remove all the global state and the map-statements assigning the state in the sequence. The value of the map-statement over the sequence contains all the parsed values in an array.

Please have a look at the tutorial to see how values are parsed and passed up to calling rules. Also it might be helpful to study some examples, for example the URL parser or JSON parser.