start = _ root:deriveTag _ { return root; } _ = [ \n\r\t]* value = deriveTag / array / tuple / string multipleItems = item:value? subsequentItems:("," value)* { return (item != null) ? [item].concat(subsequentItems.map(subsequentItem => subsequentItem[1])) : []; } deriveTag = "Derive(" items:multipleItems ")" { return {type: "deriveTag", items: items}; } array = "[" items:multipleItems "]" { return {type: "array", items: items}; } tuple = "(" items:multipleItems ")" { return {type: "tuple", items: items}; } string = '"' chars:stringCharacter* '"' { return chars.join(""); } stringCharacter = !('"' / "\\") char:. { return char; } // Prefer a non-backslash character... / stringEscapedQuote { return '"'; } // ... then an escaped quotation mark... / stringEscapedNewline{ return "\n"; } // ... then various escaped whitespace characters... / stringEscapedCarriageReturn{ return "\r"; } / stringEscapedTab{ return "\t"; } / !('"') char:. { return char; } // ... and finally any other character that doesn't terminate the string. stringEscapedQuote = '\\"' stringEscapedNewline = '\\n' stringEscapedCarriageReturn = '\\r' stringEscapedTab = '\\t'