{ function MakeAdd(description, attributes) { return { description: description, attributes: attributes || [] }; } function MakeAttributes(attributes) { return attributes.flatMap(attr => attr[1]); } } Add = desc:Description attributes:Attributes? { return MakeAdd(desc, attributes); } Description = chars:(!Attribute .)+ { return chars.map(c => c[1]).join(''); } Attributes = attributes:(_ Attribute)* { return MakeAttributes(attributes); } Attribute = Project / Priority / Tag Project = ("pro:" / "project:" / "+") value:Word { return { type: "project", value: value }; } Priority = "priority:" value:[HML] { return { type: "priority", value: value }; } Tag = "#" value:Word { return { type: "tag", value: value }; } Word = chars:[a-zA-Z0-9_-]+ { return chars.join(''); } _ = [ \\t]* EOF = !.