{"id":38149587,"url":"https://github.com/gtr/parsley","last_synced_at":"2026-01-16T23:00:31.406Z","repository":{"id":41538848,"uuid":"343935296","full_name":"gtr/parsley","owner":"gtr","description":":herb: pratt parser for ivy in rust","archived":false,"fork":false,"pushed_at":"2022-10-23T17:43:54.000Z","size":24,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-05-15T19:30:08.114Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gtr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-02T22:53:24.000Z","updated_at":"2022-07-03T18:50:08.000Z","dependencies_parsed_at":"2023-01-19T23:34:23.864Z","dependency_job_id":null,"html_url":"https://github.com/gtr/parsley","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/gtr/parsley","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtr%2Fparsley","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtr%2Fparsley/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtr%2Fparsley/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtr%2Fparsley/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gtr","download_url":"https://codeload.github.com/gtr/parsley/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtr%2Fparsley/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28487077,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T22:54:02.790Z","status":"ssl_error","status_checked_at":"2026-01-16T22:50:10.344Z","response_time":107,"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":[],"created_at":"2026-01-16T23:00:16.130Z","updated_at":"2026-01-16T23:00:31.377Z","avatar_url":"https://github.com/gtr.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# parsley :herb:\n\nImplementing the Pratt parsing algorithm in Rust. I decided to use the \nfollowing BNF grammar which is also the proposed new syntax for my programming\nlanguage, [Ivy](https://github.com/gtr/ivy).\n\n```html\n\u003cstatement\u003e ::= \u003cexpression\u003e ';' ;\n\n\u003cexpression\u003e ::= \u003cletExpr\u003e      [ ]\n               | \u003cmutExpr\u003e      [ ]\n               | \u003cfnExpr\u003e       [x]\n               | \u003cifExpr\u003e       [x]\n               | \u003cpubExpr\u003e      [x]\n               | \u003cdataExpr\u003e     [x]\n               | \u003cstructStmt\u003e   [ ]\n               | \u003cpackageStmt\u003e  [x]\n               | \u003cimportStmt\u003e   [x]\n               | \u003cmatchExpr\u003e    [x]\n               | \u003cwhileExpr\u003e    [x]\n               | \u003cdoExpr\u003e       [x]\n               | \u003creturnExpr\u003e   [x]\n               | \u003cor\u003e           [ ]\n               | \u003ctupleAny\u003e ;   [x]\n\n\u003cletExpr\u003e       ::= 'let'['mut']? [\u003csymbol\u003e|\u003ctupleSymbols\u003e] ['::'\u003ctypeFn\u003e]?'='\u003cexpression\u003e;\n\u003cmutExpr\u003e       ::= 'mut' [ \u003csymbol\u003e | \u003caccess\u003e ] '=' \u003cexpression\u003e ;\n\u003cfnExpr\u003e        ::= \u003cfnAnon\u003e | \u003cfnSignature\u003e | \u003cfnDeclaration\u003e ;\n\u003cifExpr\u003e        ::= 'if' \u003cexpression\u003e 'then' \u003cexpression\u003e [ 'else' \u003cexpression\u003e ]? ;\n\u003cpubExpr\u003e       ::= 'pub' [ \u003cfnSignature\u003e | \u003cfnDeclaration\u003e | \u003ctypeExpr\u003e | \u003cstructStmt\u003e ] ;\n\u003cdataExpr\u003e      ::= 'data' \u003csymbol\u003e [ \u003cdataGenerics\u003e ]? '(' \u003cdataVariants\u003e ')' ;\n\u003cstructStmt\u003e    ::= \u003cstructAnon\u003e | \u003cstructDeclaration\u003e ;\n\u003cpackageStmt\u003e   ::= 'package' \u003csymbol\u003e ;\n\u003cimportStmt\u003e    ::= 'import' [ \u003cstring\u003e | \u003ctupleStrings\u003e ] ;\n\u003cmatchExpr\u003e     ::= 'match' \u003cor\u003e 'with' '(' [ \u003cmatchBranch\u003e ]* ')' ;\n\u003cwhileExpr\u003e     ::= 'while' \u003cor\u003e '{' [ \u003cstatement\u003e ]* '}' ;\n\u003cdoExpr\u003e        ::= 'do' '{' [ \u003cstatement\u003e ]* '}' ;\n\u003creturnExpr\u003e    ::= 'return' \u003cexpression\u003e ;\n\n\u003c!-- [x] Functions --\u003e\n\u003cfnAnon\u003e        ::= 'fn' \u003cfnArgs\u003e [ ':' \u003ctypeFn\u003e ]? '=\u003e' \u003cexpression\u003e ;\n\u003cfnSignature\u003e   ::= 'fn' \u003csymbol\u003e '::' \u003ctypeFn\u003e ;\n\u003cfnDeclaration\u003e ::= 'fn' \u003csymbol\u003e \u003cfnArgs\u003e [ ':' \u003ctypeFn\u003e ]? '=\u003e' \u003cexpression\u003e ;\n\n\u003c!-- [ ] Function Arguments --\u003e\n\u003cfnArgs\u003e        ::= '(' [ \u003cfnArgsTyped\u003e [ ',' \u003cfnArgsTyped\u003e ]* ]? ')' ;\n\u003cfnArgsTyped\u003e   ::= \u003csymbol\u003e [ ':' \u003ctypeFn\u003e ] ? ;\n\n\u003c!-- [x] Data Type Branches --\u003e\n\u003cdataGenerics\u003e  ::= '\u003c' \u003csymbol\u003e [',' \u003csymbol\u003e ]* '\u003e' ; ;\n\u003cdataVariants\u003e  ::= [ '|' ]? \u003cdataItem\u003e [ '|' \u003cdataItem\u003e ]* ;\n\u003cdataItem\u003e      ::= \u003csymbol\u003e [ '::' \u003ctypeFn\u003e ]? ;\n\n\u003c!-- [ ] Structs --\u003e\n\u003cstructAnon\u003e        ::= 'struct'          '(' \u003cstructFields\u003e ')' ;\n\u003cstructDeclaration\u003e ::= 'struct' \u003csymbol\u003e '(' \u003cstructFields\u003e ')' ;\n\u003cstructFields\u003e      ::= \u003cstructField\u003e [ ',' \u003cstructField\u003e ]* [ ',' ]? ;\n\u003cstructField\u003e       ::= \u003csymbol\u003e '::' \u003ctypeFn\u003e ;\n    \n\u003c!-- [x] Match Branches --\u003e\n\u003cmatchBranch\u003e   ::= '|' \u003cexpression\u003e '-\u003e' \u003cexpression\u003e\n\n\u003c!-- [x] Type Literals --\u003e\n\u003ctypeFn\u003e    ::= \u003ctypeCmpst\u003e [ '-\u003e' \u003ctypeCmpst\u003e ]? ;\n\u003ctypeCmpst\u003e ::= \u003ctypeLst\u003e | \u003csymbol\u003e '\u003c' [ \u003ctypeLst\u003e [ ',' \u003ctypeLst\u003e ]* ] '\u003e' ;\n\u003ctypeLst\u003e   ::= \u003ctypeTuple\u003e | '[' \u003ctypeFn\u003e ']' ;\n\u003ctypeTuple\u003e ::= \u003ctype\u003e | '(' \u003ctypeFn\u003e [ ',' \u003ctypeFn\u003e ]* ')' ;\n\u003ctype\u003e      ::= [ 'mut' ]? \u003csymbol\u003e  ;\n\n\u003c!-- [x] Binary \u0026 Unary Expressions, Operator Precedence --\u003e\n\u003cor\u003e            ::= \u003cand\u003e [ '||' \u003cand\u003e ]* ;\n\u003cand\u003e           ::= \u003cequality\u003e [ '\u0026\u0026' \u003cequality\u003e ]* ;\n\u003cequality\u003e      ::= \u003ccomparison\u003e [ ( '==' | '!=' ) \u003ccomparison\u003e ]* ;\n\u003ccomparison\u003e    ::= \u003caddition\u003e [ ( '\u003e' | '\u003e=' | '\u003c' | '\u003c=' ) \u003caddition\u003e ]* ;\n\u003caddition\u003e      ::= \u003cmult\u003e [ ( '+' | '-' )  \u003cmult\u003e ]* ;\n\u003cmult\u003e          ::= \u003cunary\u003e  [ ( '*' | '/' ) \u003cunary\u003e ]* ;\n\u003cunary\u003e         ::= ( '!' | '-' ) \u003ccallExpr\u003e | \u003ccallExpr\u003e ;\n\n\u003c!-- [ ] Call \u0026 Access Expressions --\u003e\n\u003ccallExpr\u003e      ::= \u003caccessAttr\u003e | \u003caccessAttr\u003e \u003ctuple\u003e ;\n\u003caccessAttr\u003e    ::= \u003caccessIndx\u003e [ '.' \u003ccallExpr\u003e ]* ;\n\u003caccessIndx\u003e    ::= \u003cfactor\u003e [ '[' \u003cor\u003e ']' ]* ;\n\n\u003c!-- [x] Factors \u0026 tuples --\u003e\n\u003cfactor\u003e    ::= '(' [ \u003cor\u003e ]? ')' \n              | \u003ctuple\u003e \n              | \u003clistExpr\u003e \n              | \u003catom\u003e ;\n\u003ctuple\u003e     ::= '(' \u003cexpression\u003e [ ',' \u003cexpression\u003e ]* ')' ;\n\n\u003c!-- [x] List Literals --\u003e\n\u003clistExpr\u003e      ::= \u003clistSplit\u003e | \u003clistLiteral\u003e ;\n\u003clistLiteral\u003e   ::= '[' [ \u003clistItems\u003e ]? ']' ;\n\u003clistSplit\u003e     ::= '[' \u003csymbol\u003e '|' \u003csymbol\u003e ']' ;\n\u003clistItems\u003e     ::= \u003cexpression\u003e [ ',' \u003cexpression\u003e ]* ;\n\n\u003c!-- [x] Tuples --\u003e\n\u003ctupleAny\u003e      ::= '(' \u003cexpression\u003e [ ','  \u003cexpression\u003e ]* ')' ;\n\u003ctupleSymbols\u003e  ::= '(' \u003csymbol\u003e [ ',' \u003csymbol\u003e ]* [ ',' ]? ')' ;\n\u003ctupleStrings\u003e  ::= '(' \u003cstring\u003e [ ',' \u003cstring\u003e ]* [ ',' ]? ')' ;\n    \n\u003c!-- [x] Atoms --\u003e\n\u003catom\u003e  ::= \u003cinteger\u003e\n          | \u003csymbol\u003e \n          | \u003cstring\u003e ;\n```\n\n## Example\n\nThe following Ivy code: \n\n```haskell\nfn factorial :: Int -\u003e Int;\nfn factorial (0) =\u003e 1;\nfn factorial (n) =\u003e n * factorial(n - 1);\n```\n\nIs equivalent to the following vector of tokens:\n```rust\n// fn factorial :: Int -\u003e Int;\nnew_token(TokenType::Fn),\nnew_token(TokenType::Symbol(format!(\"factorial\"))),\nnew_token(TokenType::DoubleColon),\nnew_token(TokenType::Symbol(format!(\"Int\"))),\nnew_token(TokenType::Arrow),\nnew_token(TokenType::Symbol(format!(\"Int\"))),\nnew_token(TokenType::Semicolon),\n\n// fn factorial (0) =\u003e 1;\nnew_token(TokenType::Fn),\nnew_token(TokenType::Symbol(format!(\"factorial\"))),\nnew_token(TokenType::LParen),\nnew_token(TokenType::Integer(0)),\nnew_token(TokenType::RParen),\nnew_token(TokenType::EqArrow),\nnew_token(TokenType::Integer(1)),\nnew_token(TokenType::Semicolon),\n\n// fn factorial (n) =\u003e n * factorial(n - 1);\nnew_token(TokenType::Fn),\nnew_token(TokenType::Symbol(format!(\"factorial\"))),\nnew_token(TokenType::LParen),\nnew_token(TokenType::Symbol(format!(\"n\"))),\nnew_token(TokenType::RParen),\nnew_token(TokenType::EqArrow),\nnew_token(TokenType::Symbol(format!(\"n\"))),\nnew_token(TokenType::Star),\nnew_token(TokenType::Symbol(format!(\"factorial\"))),\nnew_token(TokenType::LParen),\nnew_token(TokenType::Symbol(format!(\"n\"))),\nnew_token(TokenType::Minus),\nnew_token(TokenType::Integer(1)),\nnew_token(TokenType::RParen),\nnew_token(TokenType::Semicolon),\n```\n\nAnd results in the following syntax tree:\n\n```\n[root]\n  0: [fn signature]\n    name: [Symbol 'factorial']\n    type: [-\u003e]\n      lhs: [Symbol 'Int']\n      rhs: [Symbol 'Int']\n  1: [fn declaration]\n    name: [Symbol 'factorial']\n    args: [Int '0']\n    value: [Int '1']\n  2: [fn declaration]\n    name: [Symbol 'factorial']\n    args: [Symbol 'n']\n    value: [*]\n      lhs: [Symbol 'n']\n      rhs: [call]\n        lhs: [Symbol 'factorial']\n        arg: [-]\n            lhs: [Symbol 'n']\n            rhs: [Int '1']\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgtr%2Fparsley","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgtr%2Fparsley","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgtr%2Fparsley/lists"}