{"id":21125960,"url":"https://github.com/shimpe/scparco","last_synced_at":"2026-02-19T17:01:51.189Z","repository":{"id":170232990,"uuid":"646047756","full_name":"shimpe/scparco","owner":"shimpe","description":"Quark providing parser combinators for supercollider","archived":false,"fork":false,"pushed_at":"2024-10-02T20:44:31.000Z","size":787,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-19T16:25:49.149Z","etag":null,"topics":["parsing","sclang","supercollider"],"latest_commit_sha":null,"homepage":"","language":"SuperCollider","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shimpe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-27T05:49:36.000Z","updated_at":"2025-10-11T01:01:10.000Z","dependencies_parsed_at":"2024-02-17T18:32:09.781Z","dependency_job_id":"44f263ed-aa37-4afd-843d-4dc4cf4be898","html_url":"https://github.com/shimpe/scparco","commit_stats":null,"previous_names":["shimpe/scparco"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/shimpe/scparco","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shimpe%2Fscparco","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shimpe%2Fscparco/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shimpe%2Fscparco/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shimpe%2Fscparco/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shimpe","download_url":"https://codeload.github.com/shimpe/scparco/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shimpe%2Fscparco/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29623546,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T13:04:20.082Z","status":"ssl_error","status_checked_at":"2026-02-19T13:03:33.775Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["parsing","sclang","supercollider"],"created_at":"2024-11-20T04:38:36.958Z","updated_at":"2026-02-19T17:01:51.157Z","avatar_url":"https://github.com/shimpe.png","language":"SuperCollider","funding_links":[],"categories":[],"sub_categories":[],"readme":"# scparco\n\n\u003cimg src=\"https://github.com/shimpe/scparco/blob/main/image/logo.png?raw=true\" width=\"250\" height=\"250\"/\u003e\nGPLv3 Library of parser combinators for supercollider. It can be used with text (modeled as a string) or binary data (contained in an Int8Array).\n\nExample of parsing binary data from a sysex message:\n\n```smalltalk\n(\nvar t = Int8Array[0xF7, 0x00, 0x01, 0x41, 0xF0]; // contrived example containing only manufacturer's id\nvar startOfSysex = ScpParserFactory.makeBinaryLiteralInt8ArrayParser(Int8Array[0xF7]);\nvar manufacturerId = ScpParserFactory.makeBinaryUIntParser(8).chain({\n\t\t| result |\n\t\t// using chain we can influence the next parser:\n\t\t// if the first byte is 0x00, two more bytes will follow with the manufacturer id\n\t\t// otherwise, the byte value itself is already the manufacturer's id\n\t\tif (result == 0) {\n\t\t\t// extract extended ID and tag it as \\manufacturerId in the parse result\n\t\t\tScpParserFactory.makeBinaryUIntParser(16).map(ScpMapFactory.tag(\\manufacturerId));\n\t\t} {\n\t\t\t// current byte value is already the ID; tag it as \\manufacturerId in the parse result\n\t\t\tScpSucceedParser(result).map(ScpMapFactory.tag(\\manufacturerId));\n\t\t}\n});\nvar sysexParser = ScpSequenceOf([startOfSysex, manufacturerId]).map({|result| result[1] }); // keep only manufacturer's id\nvar result = sysexParser.run(t);\nresult.result.postcs;\n)\n```\n\nA non-trivial example for parsing and evaluating a mathematical expresssion from text:\n\n```smalltalk\n(\n// simple calculator\n// first the parser\nvar numberParser = ScpParserFactory.makeFloatParser.map({|x| (\\type : \\number, \\value : x) });\nvar operatorParser = ScpChoice([ScpStrParser(\"+\"), ScpStrParser(\"-\"), ScpStrParser(\"*\"), ScpStrParser(\"/\")]);\nvar betweenBrackets = ScpParserFactory.makeBetween(ScpStrParser(\"(\"), ScpStrParser(\")\"));\nvar expression = ScpParserFactory.forwardRef(Thunk({\n\tScpChoice([\n\t\tnumberParser,\n\t\toperationParser\n\t])\n}));\nvar operationParser = betweenBrackets.(ScpSequenceOf([\n\toperatorParser,\n\tScpParserFactory.makeWs,\n\texpression,\n\tScpParserFactory.makeWs,\n\texpression\n])).map({ |results| (\\type: \\operation, \\value : (\\op : results[0], \\a : results[2], \\b : results[4]) ) });\n\n// then an evaluator to perform the actual calculations based on the parsing result\nvar evaluate = {\n\t| node |\n\tif (node[\\type] == \\number) {\n\t\tnode[\\value];\n\t} {\n\t\tif (node[\\type] == \\operation) {\n\t\t\tif (node[\\value][\\op].compare(\"+\") == 0) {\n\t\t\t\tthisFunction.(node[\\value][\\a]) + thisFunction.(node[\\value][\\b]); //recursion\n\t\t\t} {\n\t\t\t\tif (node[\\value][\\op].compare(\"-\") == 0) {\n\t\t\t\t\tthisFunction.(node[\\value][\\a]) - thisFunction.(node[\\value][\\b]);\n\t\t\t\t} {\n\t\t\t\t\tif (node[\\value][\\op].compare(\"*\") == 0) {\n\t\t\t\t\t\tthisFunction.(node[\\value][\\a]) * thisFunction.(node[\\value][\\b]);\n\t\t\t\t\t} {\n\t\t\t\t\t\tif (node[\\value][\\op].compare(\"/\") == 0) {\n\t\t\t\t\t\t\tthisFunction.(node[\\value][\\a]) / thisFunction.(node[\\value][\\b]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n};\n\nvar interpreter = {\n\t| program |\n\t// first parse the program, then evaluate it\n\tvar parseResult = expression.run(program);\n\tif (parseResult.isError) {\n\t\t\"Invalid program\".postln;\n\t\tnil;\n\t} {\n\t\tevaluate.(parseResult.result);\n\t}\n};\n\n// try it out\nvar program = \"(+ (* 10 2) (-       (/50 3) 2))\";\nvar result = interpreter.(program);\nresult.debug(\"result of the calculation\");\n)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshimpe%2Fscparco","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshimpe%2Fscparco","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshimpe%2Fscparco/lists"}