{"id":17139003,"url":"https://github.com/buroni/automata-golf","last_synced_at":"2025-04-13T10:02:19.422Z","repository":{"id":60312043,"uuid":"539932229","full_name":"Buroni/automata-golf","owner":"Buroni","description":"A domain-specific language (DSL) for parsing regular, context-free and recursively enumerable languages.","archived":false,"fork":false,"pushed_at":"2023-05-22T19:27:28.000Z","size":187,"stargazers_count":15,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T01:22:39.138Z","etag":null,"topics":["context-free","domain-specific-language","dsl","finite-state-machine","fsm","turing-machine"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Buroni.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":"2022-09-22T10:49:25.000Z","updated_at":"2024-06-19T03:03:47.000Z","dependencies_parsed_at":"2024-10-14T20:11:14.829Z","dependency_job_id":"e22ac7bb-9012-4a57-9fb5-f865c370c8fc","html_url":"https://github.com/Buroni/automata-golf","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Buroni%2Fautomata-golf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Buroni%2Fautomata-golf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Buroni%2Fautomata-golf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Buroni%2Fautomata-golf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Buroni","download_url":"https://codeload.github.com/Buroni/automata-golf/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248695335,"owners_count":21146953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["context-free","domain-specific-language","dsl","finite-state-machine","fsm","turing-machine"],"created_at":"2024-10-14T20:11:10.431Z","updated_at":"2025-04-13T10:02:19.369Z","avatar_url":"https://github.com/Buroni.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# automata-golf\n\nA domain-specific language (DSL) for parsing regular, context-free and recursively enumerable languages.\n\nIn `automata-golf`, a machine is defined by a series of path statements.\nThere's no need to explicitly define states or transitions.\n\nThe example below shows a machine with an initial state `s0`, which transitions\nvia `f` to and from the accepted state `s1` .\n\n\u003cimg width=\"519\" alt=\"Screenshot 2022-10-05 at 13 28 29\" src=\"https://user-images.githubusercontent.com/3934417/194060304-5931d456-66b7-4297-ba61-1b987a5000bb.png\"\u003e\n\n```\n# 1,2, and 3 are all equivalent:\n\n# 1\n.s0 -f\u003e (s1) -f\u003e s0;\n\n# 2\n.s0 \u003cf\u003e (s1);\n\n# 3\ns1 -f\u003e .s0;\ns0 \u003cf- (s1);\n```\n\nStarting states are prefixed with `.`; Success states are wrapped in `(` `)`.\n\n## Pattern matching\n\nRegex is supported for pattern matching\n\n```\n/^s[0-9]/ -g\u003e t1;\n```\n\n## Stacking transitions\n\nMultiple transitions from the same state can be stacked up:\n\n```\n.s0 -f\u003e -g\u003e -h\u003e s1;\n```\n\n## Pushdown automata\n\n`automata-golf` supports pushdown automota, i.e. a finite-state machine with\na stack and transitions that push/pop the stack.\n\nThe following transitions to `s1` on input `f` when `a` is top of the stack.\nUpon the transition, it pushes `b` to the stack.\n\n```\n.s0 -f[a:b]\u003e s1;\n```\n\n\u003cimg width=\"507\" alt=\"Screenshot 2022-10-05 at 13 35 39\" src=\"https://user-images.githubusercontent.com/3934417/194061616-49be2ba3-ca5b-48a7-9eb5-5c520bb6c1e1.png\"\u003e\n\n### Multiple stacks\n\n2-stack PDAs are supported, making them equivalent to Turing machines. See the\nexample and corresponding automaton diagram below.\n\n```\n.s0 -f[a:b, _:c]\u003e s1;\n```\n\n\u003cimg width=\"506\" src=\"https://i.imgur.com/Lct66bk.png\"/\u003e\n\n### Epsilon transitions\n\nEpsilon is represented by `_`. For example the following transitions to `s1`\nand pushes `$` to the second stack without consuming any input or popping either stack.\n\n```\n.s0 -_[_:_, _:$]\u003e (s1);\n\n# or equivalently:\n\n.s0 -[_, :$]\u003e (s1);\n```\n\n# Examples\n\n## Regular languages\n\nRegular languages can be captured using finite-state machines.\n\n### Odd binary numbers\n\nThe following program accepts all binary numbers ending in `1`\n\n```js\nconst { build } = require(\"./automata-golf/index.js\");\n\nconst { machine } = build(`\n.s0 -0\u003e -1\u003e s0 -1\u003e (s1);\n`);\n\nmachine.consume(\"10110\").inAcceptState(); // false\nmachine.consume(\"1011\").inAcceptState(); // true\n```\n\n\u003cimg width=\"542\" alt=\"Screenshot 2022-10-05 at 13 25 48\" src=\"https://user-images.githubusercontent.com/3934417/194059891-9494d69e-fdcc-4f84-9d19-05c327609e94.png\"\u003e\n\n### Self-driving robot\n\nThe following finite-state machine creates a robot that can be turned on and off,\nand switches direction when it collides.\n\n```js\nconst { build } = require(\"./automata-golf/index.js\");\n\nconst { machine } = build(`\n.off \u003cpush\u003e forward \u003ccollide\u003e backward -push\u003e off;\n`);\n\nmachine.consume([\"push\", \"collide\"]).state; // backward\n```\n\n## Context-free languages\n\nPushdown automota are required to parse context-free languages.\n\n### Odd-length palindromes\n\nThe following accepts all odd-length palindromes in the language `{a, b}`\n\n```js\nconst { build } = require(\"automata-golf/index.js\");\n\nconst { machine } = build(`\n.s0 -[:$]\u003e s1;\ns1 -a[:a]\u003e -b[:b]\u003e s1;\ns1 -a\u003e -b\u003e s2;\ns2 -a[a]\u003e -b[b]\u003e s2;\ns2 -[$]\u003e (s3); \n`);\n\nmachine.consume(\"abbba\").inAcceptState(); // true\nmachine.consume(\"abb\").inAcceptState(); // false\n```\n\nNote the program can be condensed to\n\n```\n.s0 -[:$]\u003e s1 -a[_:a]\u003e -b[:b]\u003e s1 -a\u003e -b\u003e s2 -a[a]\u003e -b[b]\u003e s2 -[$]\u003e (s3);\n```\n\n\u003cimg width=\"962\" alt=\"Screenshot 2022-10-05 at 13 27 33\" src=\"https://user-images.githubusercontent.com/3934417/194060144-a14c4114-08a5-4b30-8a07-a273357aa8ae.png\"\u003e\n\n## Recursively enumerable languages\n\nRecursively enumerable languages can be parsed by using a pushdown automaton with 2 stacks, equivalent to a Turing machine.\n\n### a\u003csup\u003en\u003c/sup\u003eb\u003csup\u003en\u003c/sup\u003ec\u003csup\u003en\u003c/sup\u003e\n\nThe following accepts input of the format a\u003csup\u003en\u003c/sup\u003eb\u003csup\u003en\u003c/sup\u003ec\u003csup\u003en\u003c/sup\u003e:\n\n```js\nconst { build } = require(\"automata-golf/index.js\");\n\nconst machine = build(`\n.s0 -a[:a]\u003e s0 -_\u003e s1 -b[a, :b]\u003e s1 -_\u003e s2 -c[_, b]\u003e (s2);\n`);\n\nmachine.consume(\"aabbcc\").inAcceptState(); // true\nmachine.consume(\"abbc\").inAcceptState(); // false\n```\n\n\u003cimg width=\"962\" src=\"https://i.imgur.com/cdBeBF4.png\"/\u003e\n\n## Build to JS\n\nThe machine can be written to a JS file\n\n```js\n// A.js\nconst { build } = require(\"automata-golf/index.js\");\nbuild(\".s0 -f\u003e (s1)\", { emitFile: \"./machine.js\" });\n\n// B.js\nconst machine = require(\"./machine.js\");\nmachine.consume(\"f\");\n```\n\n### Target\n\nSet `target` to `'browser'` to generate a machine that can be run in a browser\nenvironment:\n\n```js\nbuild(\".s0 -f\u003e (s1)\", { emitFile: \"./machine.js\", target: \"browser\" });\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fburoni%2Fautomata-golf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fburoni%2Fautomata-golf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fburoni%2Fautomata-golf/lists"}