{"id":33934619,"url":"https://github.com/chuckcscccl/rustlr","last_synced_at":"2026-03-27T04:05:17.518Z","repository":{"id":38230032,"uuid":"425004962","full_name":"chuckcscccl/rustlr","owner":"chuckcscccl","description":"LR-style Parser Generator","archived":false,"fork":false,"pushed_at":"2025-05-28T21:23:06.000Z","size":4947,"stargazers_count":19,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-07T16:08:23.265Z","etag":null,"topics":["parser","parser-generator","rust"],"latest_commit_sha":null,"homepage":"https://chuckcscccl.github.io/rustlr_project/","language":"Rust","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/chuckcscccl.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,"zenodo":null}},"created_at":"2021-11-05T15:56:39.000Z","updated_at":"2025-05-28T21:23:09.000Z","dependencies_parsed_at":"2024-05-19T21:28:24.036Z","dependency_job_id":"6984c383-fe45-497d-a98d-efd89774e7cf","html_url":"https://github.com/chuckcscccl/rustlr","commit_stats":{"total_commits":387,"total_committers":3,"mean_commits":129.0,"dds":"0.15245478036175708","last_synced_commit":"85604f2523023ebc87e431258bc292f80478767b"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/chuckcscccl/rustlr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chuckcscccl%2Frustlr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chuckcscccl%2Frustlr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chuckcscccl%2Frustlr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chuckcscccl%2Frustlr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chuckcscccl","download_url":"https://codeload.github.com/chuckcscccl/rustlr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chuckcscccl%2Frustlr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31018546,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-27T03:51:26.850Z","status":"ssl_error","status_checked_at":"2026-03-27T03:51:09.693Z","response_time":164,"last_error":"SSL_read: 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":["parser","parser-generator","rust"],"created_at":"2025-12-12T13:51:40.773Z","updated_at":"2026-03-27T04:05:17.504Z","avatar_url":"https://github.com/chuckcscccl.png","language":"Rust","readme":"# **[rustlr](https://docs.rs/rustlr/latest/rustlr/index.html)**\n**LR-Style Parser Generator**\n\n**A [Tutorial](https://chuckcscccl.github.io/rustlr_project/) with several examples is available.**\n\n### New Version 0.6\n\nThis rewrite of key components consists of mainly internal changes except\nfor how the parser interacts with the lexical tokenizer.  Semantic actions\nin grammars can now make adjustments directly to the tokenizer.  The version\n0.5 style is preserved by giving the `rustlr` application the `-zc` option.\n\n-------------------\n\nBesides traditional LR and LALR parser generation, Rustlr supports the following\noptions\n\n1. An experimental feature that generates parsers for *[Selective Marcus-Leermakers grammars](https://hal.archives-ouvertes.fr/hal-00769668/document)*.  This is a larger class of unambiguous grammars than traditional LR.  For example, the following grammar\n\n```\n    S --\u003e a B c  |  A B d\n    B --\u003e b | B b\n    A --\u003e a\n```\n   \nis unambiguous but is **not** LR(k) because it cannot decide whether\nto reduce `a` to `A` with a fixed number of lookaheads.  However,\nrustlr can still generate a deterministic parser (without\nbacktracking) for this grammar (see the\n[Appendix](https://chuckcscccl.github.io/rustlr_project/appendix.html)\nof the tutorial).  Rustlr is the only practical parser generator that\nsupports this capability.\n\n2. The option of creating the abstract syntax data types and semantic actions from the grammar. Rustlr grammars contain a sub-language that controls how ASTs are to be generated. \n\n3. Support for choosing [bumpalo](https://docs.rs/bumpalo/latest/bumpalo/index.html) to create recursive ASTs that use references instead of smart pointers: this\nenables *deep pattern matching* on recursive structures.\n\n4. Recognizes regex-style operators `*`, `+` and `?` and generates Rust\nvectors and options to hold their semantic values.\n\n5. Generates a lexical scanner automatically from the grammar.\n\n6. Operator precedence and associativity declarations are also supported.\n\n7. The ability to train the parser, interactively or from script, for better error reporting.\n\n8. Generates parsers for Rust [and for F\\#](https://github.com/chuckcscccl/Fussless).  Rustlr is designed to promote typed functional programming languages in the creation of compilers and\nlanguage-analysis tools.  Parser generation for other such languages will\ngradually become available.\n\nRustlr aims to simplify the creation of precise and efficient parsers and\nwill continue to evolve and incorporate new features, though backwards\ncompatibility will be maintained as much as possible.\n\n\u003cp\u003e\n\n\n### Quick Example: Arithmetic Expressions and Their Abstract Syntax\n\nThe following are the contents of a Rustlr grammar, [`simplecalc.grammar`](https://github.com/chuckcscccl/rustlr/blob/main/examples/simplecalc/simplecalc.grammar):\n\n```\nauto\nterminals + * - / ; ( )   # verbatim terminal symbols\nvalterminal Int i32       # terminal symbol with value\nnonterminal E\nnonterminal T : E  # specifies that AST for T should merge into E\nnonterminal F : E\nnonterminal ExpList\nstartsymbol ExpList\nvariant-group-for E BinaryOp + - * /    # controls AST generation\ndefault E Int(0)  # controls AST generation\n\n# production rules:\nE --\u003e E + T  | E - T | T\nT --\u003e T * F | T / F | F\nF:Neg --\u003e - F                   # 'Neg' names enum variant in AST\nF --\u003e Int | ( E )\nExpList --\u003e E\u003c;+\u003e ;?    # ;-separated list with optional trailing ;\n\n\n!mod simplecalc_ast; // !-lines are injected verbatim into the parser\n!fn main()  {\n!  let mut scanner1 = simplecalclexer::from_str(\"10+-2*4; 9-(4-1);\");\n!  let mut parser1 = make_parser(scanner1);\n!  let parseresult = parse_with(\u0026mut parser1);\n!  let ast =\n!    parseresult.\n!    unwrap_or_else(|x| {\n!       println!(\"Parsing errors encountered; results not guaranteed..\");\n!       x\n!    });\n!  println!(\"\\nAST: {:?}\\n\",\u0026ast);\n!}//main\n```\n\nThe grammar recognizes one or more arithmetic expressions separated by\nsemicolons.  In addition to a parser, the grammar generates a lexical\nscanner from the declarations of terminal symbols.  It also created\nthe following abstract syntax types and the semantic actions that\nproduce instances of the types.\n```\n#[derive(Debug)]\npub enum E {\n  BinaryOp(\u0026'static str,LBox\u003cE\u003e,LBox\u003cE\u003e),\n  Int(i32),\n  Neg(LBox\u003cE\u003e),\n}\nimpl Default for E { fn default()-\u003eSelf { E::Int(0) } }\n\n#[derive(Default,Debug)]\npub struct ExpList(pub Vec\u003cLC\u003cE\u003e\u003e,);\n```\n[LBox](https://docs.rs/rustlr/latest/rustlr/generic_absyn/struct.LBox.html)\nand\n[LC](https://docs.rs/rustlr/latest/rustlr/generic_absyn/struct.LC.html)\nare structures that contain the line and column positions of the start\nof the AST constructs in the original source.  This information is\nautomatically inserted into the structures by the parser.  LBox\nencapsulates a Box and serves as a custom smart pointer while LC\ncontains the extra information in an exposed tuple.  Both `LBox\u003cT\u003e`\nand `LC\u003cT\u003e` implement `Deref\u003cT\u003e` and `DerefMut\u003cT\u003e`, thus carrying the\nextra information non-intrusively.\n\nRustlr generates AST types based on the grammar but special\ndeclarations can control the precise structure of these types.  A\nstruct is normally generated for nonterminal symbols with a single\nproduction while an enum is generated for nonterminals with multiple\nproductions, with a variant for each production.  However, the enum\nvariants generated from the productions for `T` and `F` are merged\ninto the type for `E` by the declarations `nonterminal T : E` and\n`nonterminal F : E`.  The `variant-group-for` declaration combined what\nwould-have-been four variants into one.  The `Neg` label on the unary\nminus rule separates that case from the \"BinaryOp\" variant group.\n\nRustlr AST types implement the Default trait so that a partial result is\nalways returned even when parse errors are encountered. A default variant\nis automatically generated for enums if none are specified with a `default`\ndirective.\n\nAll automatically generated AST types and semantic actions can be\nmanually overridden.\n\nSpecifying operator precedence and associativity instead of using the\n`T` and `F` categories is also supported.\n\nThe generated parser and lexer normally form a separate module.  However,\nfor this quick example we've injected a `main` directly into the parser\nto demonstrate how to invoke it.  To run this example,\n\n  1. Install rustlr as a command-line application: **`cargo install rustlr`**\n  \n  2. Create a Cargo crate for the sample and **`cargo add rustlr --no-default-features`**\n  in the crate.  Turning off default features will include\n  only the runtime parsing routines.\n  \n  3. save [the grammar](https://github.com/chuckcscccl/rustlr/blob/main/examples/simplecalc/simplecalc.grammar) in the crate as **`simplecalc.grammar`**.\n  The filename determines the names of the modules created, and must \n  have a `.grammar` suffix.\n  \n  4. Run the rustlr application in the crate with\n  \u003e  **`rustlr simplecalc.grammar -o src/main.rs`**\n  \n  5. **`cargo run`**\n\nThe expected output is\n```\nAST: ExpList([BinaryOp(\"+\", Int(10), BinaryOp(\"*\", Neg(Int(2)), Int(4))), BinaryOp(\"-\", Int(9), BinaryOp(\"-\", Int(4), Int(1)))])\n```\n\nRustlr can also be invoked from within Rust by calling the [rustlr::generate](https://docs.rs/rustlr/latest/rustlr/fn.generate.html) function.\n\n\u003cbr\u003e\n\n#### New in Version 0.6.5, 0.6.6\n\nThe ability to specify default variants for generated enums and\nstructs in the grammar, e.g. `default Expr Integer(0)`.  The keyword\n`default` should no longer name non-terminals.  A variant such as\n`Expr_Nothing` is still generated for enums if there are not explicit\n`default` overrides.\n\n#### New in Version 0.6.1, 0.6.2\n\nThe `-table` option stores the parse table to a binary file instead of\nan inlined static array.  Windows pathname compatibility issues fixed in 0.6.2.\n\n#### New in Version 0.6.0\n\nSemantic actions can now control the behavior of the lexical tokenizer.\n\n#### New in Version 0.5.0\n\nThe option to install only the runtime parser, without parser generation routines\n\n#### New in Versions 0.4.13\n\nBoxed labels such as `[x]` are now represented by LC instead of LBox during\nauto-generation.  \n\n#### New in Versions 0.4.11 and 0.4.12\n\nThe wildcard `_` token now carries the original text of the token as\nits semantic value by default.  The `variant-group` directive is now\ndeprecated (though still available) by `variant-group-for`.\n\n#### New in Version 0.4.10:\n\nWhen called from the [rustlr::generate](https://docs.rs/rustlr/latest/rustlr/fn.generate.html) function, rustlr can be made completely silent if given the\n`-trace 0` option.  All reports are logged and returned by the function.\n\n\n#### New in Version 0.4.9: Error logging option\n\nGiven a parser instance `parser1`, it's now possible to call\n`parser1.set_err_report(true)`, which will log parse errors internally\ninstead of printing them to stderr.  The error report can be retrieved\nby calling `parser1.get_err_report()`.\n\n#### New in Version 0.4.8: Conversion From Yacc/Bison Grammar.\n\nIf the rustlr executable is given a file path that ends in \".y\", it will\nattempt to convert a yacc/bison style grammar into rustlr's own grammar\nsyntax, stripping away all semantic actions and other language-specific\ncontent.  All other command-line options are ignored.\n\n\n\n\u003cbr\u003e\n\nPlease consult the [tutorial](https://chuckcscccl.github.io/rustlr_project/)\nfor further documentation.\n\n\n\n[1]:https://docs.rs/rustlr/latest/rustlr/lexer_interface/struct.StrTokenizer.html\n[2]:https://docs.rs/rustlr/latest/rustlr/generic_absyn/struct.LBox.html\n[3]:https://docs.rs/rustlr/latest/rustlr/generic_absyn/struct.LRc.html\n[4]:https://docs.rs/rustlr/latest/rustlr/zc_parser/struct.ZCParser.html#method.lbx\n[5]:https://docs.rs/rustlr/latest/rustlr/zc_parser/struct.StackedItem.html#method.lbox\n[sitem]:https://docs.rs/rustlr/latest/rustlr/zc_parser/struct.StackedItem.html\n[chap1]:https://cs.hofstra.edu/~cscccl/rustlr_project/chapter1.html\n[lexsource]:https://docs.rs/rustlr/latest/rustlr/lexer_interface/struct.LexSource.html\n[drs]:https://docs.rs/rustlr/latest/rustlr/index.html\n[tktrait]:https://docs.rs/rustlr/latest/rustlr/lexer_interface/trait.Tokenizer.html\n[tt]:https://docs.rs/rustlr/latest/rustlr/lexer_interface/struct.TerminalToken.html\n[rtk]:https://docs.rs/rustlr/latest/rustlr/lexer_interface/enum.RawToken.html\n[fromraw]:https://docs.rs/rustlr/latest/rustlr/lexer_interface/struct.TerminalToken.html#method.from_raw\n[nextsymfun]:https://docs.rs/rustlr/latest/rustlr/lexer_interface/trait.Tokenizer.html#tymethod.nextsym\n[zcp]:https://docs.rs/rustlr/latest/rustlr/zc_parser/struct.ZCParser.html\n[ttnew]:https://docs.rs/rustlr/latest/rustlr/lexer_interface/struct.TerminalToken.html#method.new\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchuckcscccl%2Frustlr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchuckcscccl%2Frustlr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchuckcscccl%2Frustlr/lists"}