bread-n-butter icon indicating copy to clipboard operation
bread-n-butter copied to clipboard

API Proposal: parser.flatten

Open hillin opened this issue 3 years ago • 3 comments

It's very easy to create parsers which generates recursively nested values. When writing a lexer, we'd expect the output to be a flat (1D) array of tokens (or bnb.ParseNodes). So I find myself constantly mapping the parse result with a flatten function:

type Node = bnb.ParseNode<string, string>;
type NodeOrArrayOfNode = Node | NodeOrArrayOfNode[];

function flatten(nodes: NodeOrArrayOfNode) {
  const result: Node[] = [];
  function addNode(node: NodeOrArrayOfNode) {
    if (Array.isArray(node)) {
      for (const innerNode of node) {
        addNode(innerNode);
      }
    } else {
      result.push(node);
    }
  }

  addNode(nodes);
  return result;
}

// usage:
const parser = bnb
  .text('a')
  .node('a')
  .and(bnb.text('b').node('b'))
  .or(bnb.text('c').node('c'))  // => [bnb.ParseNode<"a", "a">, bnb.ParseNode<"b", "b">] | bnb.ParseNode<"c", "c">
  .map(flatten);  // => bnb.ParseNode<string, string>[]

It would be great if this mechanism is provided as a method of bnb.Parser.

This also helps make sense of the inferred type information, otherwise it would quickly collapse into a pile of gibberish (for instance, in the example above, for such a simple parser, the type yielded before the map call is already not quite readable).

hillin avatar Dec 07 '21 12:12 hillin

Could you give me a more complete example? I haven't really found myself wanting this

wavebeem avatar Dec 09 '21 04:12 wavebeem

e.g.

// without flatten
bnb.text('1').and(bnb.text('2')).and(bnb.text('3')).parse('123')
// => [["1","2"],"3"]
// the nested array is obviously hard to deal with

// with flatten
bnb.text('1').and(bnb.text('2')).and(bnb.text('3')).flatten().parse('123')
// => ['1', '2', '3']

hillin avatar Dec 16 '21 05:12 hillin

Yeah, so repeated and should be replaced with all instead. Maybe that could be more obvious in the docs? all links to and but and doesn't link to all

wavebeem avatar Dec 16 '21 18:12 wavebeem