Term
  = _ first:Factor rest:( _ ("|") _ r0:Term)? {
      return rest?{"type": "union","first":first,"rest":rest[3]}:first
    }

Factor
  = "(" _ expr:Term _ ")" arr:(_ '[]')* { return {"type":"parens","expr":expr,"arr":arr.length}; }
  / Literal

TypeParams ='<' first:Term  other:ExtraParam* '>' {return [first].concat(other)}
ExtraParam =',' r:Term {return r;}

Literal "name"
  = r:(char)+ tp:TypeParams? c:(_ '[]')* { return { "type":"name","params":tp, "value":r.join(""),"arr":(c.length)}; }

_ "whitespace"
  = [ \t\n\r]*

char=[A-Z] / '_' / '-' / '.'/[a-z]/ [0-9]