{"id":32363281,"url":"https://github.com/youngermaster/context-free-grammar-parser","last_synced_at":"2026-05-18T03:01:36.897Z","repository":{"id":319163997,"uuid":"1077829297","full_name":"Youngermaster/Context-Free-Grammar-Parser","owner":"Youngermaster","description":"LL(1) (Top-Down) and SLR(1) (Bottom-Up) parsers","archived":false,"fork":false,"pushed_at":"2025-10-16T21:24:25.000Z","size":153,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-17T22:59:01.173Z","etag":null,"topics":["ll1-parser","ocaml","python-parser","slr-parser"],"latest_commit_sha":null,"homepage":"","language":"Python","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/Youngermaster.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-16T19:56:07.000Z","updated_at":"2025-10-16T21:24:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Youngermaster/Context-Free-Grammar-Parser","commit_stats":null,"previous_names":["youngermaster/context-free-grammar-parser"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/Youngermaster/Context-Free-Grammar-Parser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Youngermaster%2FContext-Free-Grammar-Parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Youngermaster%2FContext-Free-Grammar-Parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Youngermaster%2FContext-Free-Grammar-Parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Youngermaster%2FContext-Free-Grammar-Parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Youngermaster","download_url":"https://codeload.github.com/Youngermaster/Context-Free-Grammar-Parser/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Youngermaster%2FContext-Free-Grammar-Parser/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280832271,"owners_count":26398965,"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","status":"online","status_checked_at":"2025-10-24T02:00:06.418Z","response_time":73,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["ll1-parser","ocaml","python-parser","slr-parser"],"created_at":"2025-10-24T16:35:36.937Z","updated_at":"2025-10-24T16:35:42.431Z","avatar_url":"https://github.com/Youngermaster.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Context-Free Grammar Parser - OCaml Implementation\n\nAn OCaml implementation of LL(1) and SLR(1) parsers for context-free grammars, as specified in the ST0270/SI2002 Formal Languages course project.\n\n## Author\n\n- Juan Manuel Young Hoyos\n\n## Project Overview\n\nThis implementation provides:\n\n1. Algorithms to compute FIRST and FOLLOW sets\n2. LL(1) predictive parser (Top-Down)\n3. SLR(1) parser (Bottom-Up)\n4. Interactive CLI for grammar analysis and string parsing\n\nThe implementation leverages OCaml's strong type system, pattern matching, and functional programming paradigms to create a clean, maintainable, and efficient parser.\n\n## System Requirements\n\n- **Operating System**: macOS Darwin 25.0.0 (compatible with Linux)\n- **OCaml Version**: 4.14+ or 5.x\n- **Build System**: Dune 3.0+\n- **Package Manager**: opam 2.0+\n\n## Installation\n\n### 1. Install OCaml and opam\n\n```bash\n# Install opam (OCaml package manager)\nbash -c \"sh \u003c(curl -fsSL https://opam.ocaml.org/install.sh)\"\n\n# Initialize opam\nopam init\n\n# Install OCaml compiler\nopam switch create 5.3.0\neval $(opam env)\n```\n\n### 2. Install Dependencies\n\n```bash\n# Install dune build system\nopam install dune\n\n# Install OCaml LSP and tools (optional, for development)\nopam install ocaml-lsp-server odoc ocamlformat utop\n```\n\n### 3. Build the Project\n\n```bash\ncd ocaml-implementation\neval $(opam env)\ndune build\n```\n\n## Running the Application\n\n### Basic Usage\n\n```bash\n# From the ocaml-implementation directory\neval $(opam env)\ndune exec ./main.exe\n```\n\n### With Input File\n\n```bash\ndune exec ./main.exe \u003c input.txt\n```\n\n### Using Here-Document\n\n```bash\ncat \u003c\u003c'EOF' | dune exec ./main.exe\n3\nS -\u003e S+T T\nT -\u003e T*F F\nF -\u003e (S) i\ni+i\n(i)\n(i+i)*i)\n\nEOF\n```\n\n## Input Format\n\n```plaintext\nn                              # number of non-terminals (n \u003e 0)\n\u003cnonterminal\u003e -\u003e \u003calternatives separated by spaces\u003e  # n lines\n\u003cstring1\u003e                      # strings to parse (optional)\n\u003cstring2\u003e\n\u003cempty line\u003e                   # terminates parsing\n```\n\n### Grammar Conventions\n\n- **Start symbol**: Always 'S'\n- **Non-terminals**: Capital letters (A-Z)\n- **Terminals**: NOT uppercase letters (lowercase, digits, symbols)\n- **Epsilon**: Represented as 'e'\n- **End marker**: '$' (automatically appended, not allowed as terminal)\n\n## Output Behavior\n\n### Case 1: Grammar is both LL(1) AND SLR(1)\n\n```plaintext\nSelect a parser (T: for LL(1), B: for SLR(1), Q: quit):\n```\n\n- Enter `T` for LL(1), `B` for SLR(1), or `Q` to quit\n- Parse strings until empty line, then re-prompt\n\n### Case 2: Grammar is LL(1) only\n\n```plaintext\nGrammar is LL(1).\n```\n\n- Accepts strings until empty line, then terminates\n\n### Case 3: Grammar is SLR(1) only\n\n```plaintext\nGrammar is SLR(1).\n```\n\n- Accepts strings until empty line, then terminates\n\n### Case 4: Grammar is neither LL(1) nor SLR(1)\n\n```plaintext\nGrammar is neither LL(1) nor SLR(1).\n```\n\n- Terminates immediately\n\nFor valid grammars, outputs `yes` if string is accepted, `no` otherwise.\n\n## Examples\n\n### Example 1: SLR(1) Grammar\n\n```bash\ncat \u003c\u003c'EOF' | dune exec ./main.exe\n3\nS -\u003e S+T T\nT -\u003e T*F F\nF -\u003e (S) i\ni+i\n(i)\n(i+i)*i)\n\nEOF\n```\n\n**Expected Output:**\n\n```bash\nGrammar is SLR(1).\nyes\nyes\nno\n```\n\n### Example 2: Both LL(1) and SLR(1)\n\n```bash\ncat \u003c\u003c'EOF' | dune exec ./main.exe\n3\nS -\u003e AB\nA -\u003e aA d\nB -\u003e bBc e\nT\nd\nadbc\na\n\nQ\nEOF\n```\n\n**Expected Output:**\n\n```bash\nSelect a parser (T: for LL(1), B: for SLR(1), Q: quit):\nyes\nyes\nno\nSelect a parser (T: for LL(1), B: for SLR(1), Q: quit):\n```\n\n### Example 3: Neither LL(1) nor SLR(1)\n\n```bash\ncat \u003c\u003c'EOF' | dune exec ./main.exe\n2\nS -\u003e A\nA -\u003e A b\nEOF\n```\n\n**Expected Output:**\n\n```plaintext\nGrammar is neither LL(1) nor SLR(1).\n```\n\n## Project Structure\n\n```bash\nocaml-implementation/\n├── dune-project          # Dune project configuration\n├── dune                  # Build configuration\n├── main.ml               # Entry point\n├── cli.ml/.mli           # Command-line interface\n├── grammar.ml/.mli       # Grammar data structures\n├── utils.ml/.mli         # Symbol types and utilities\n├── firstFollow.ml/.mli   # FIRST/FOLLOW set computation\n├── ll1.ml/.mli           # LL(1) predictive parser\n├── slr1.ml/.mli          # SLR(1) bottom-up parser\n└── README.md             # This file\n```\n\n## Implementation Highlights\n\n### Type Safety\n\nOCaml's algebraic data types provide compile-time guarantees:\n\n```ocaml\ntype symbol =\n  | Terminal of char\n  | Nonterminal of char\n  | Epsilon\n  | EndMarker\n```\n\n### Functional Algorithms\n\nFIRST and FOLLOW computation using immutable data structures and fixed-point iteration:\n\n```ocaml\nlet rec iterate first_map =\n  let new_first_map = compute_new_first first_map in\n  if changed first_map new_first_map then\n    iterate new_first_map\n  else\n    new_first_map\n```\n\n### Pattern Matching\n\nClean, exhaustive parsing logic:\n\n```ocaml\nmatch (ll1_result, slr1_result) with\n| (Some ll1, Some slr1) -\u003e interactive_mode ll1 slr1\n| (Some ll1, None) -\u003e print_endline \"Grammar is LL(1).\"\n| (None, Some slr1) -\u003e print_endline \"Grammar is SLR(1).\"\n| (None, None) -\u003e print_endline \"Grammar is neither LL(1) nor SLR(1).\"\n```\n\n## Comparison with Python Implementation\n\n### Advantages of OCaml\n\n1. **Type Safety**: Compile-time error detection vs runtime errors\n2. **Immutability**: Prevents accidental state mutations\n3. **Pattern Matching**: More concise and exhaustive than if/else chains\n4. **Performance**: Compiled to native code, significantly faster\n5. **Expressiveness**: Algebraic data types model grammar concepts naturally\n\n### Code Conciseness\n\nOCaml's type system and pattern matching reduce boilerplate:\n\n- Python: ~500 lines\n- OCaml: ~600 lines (including extensive comments and type signatures)\n\n### Maintainability\n\n- Strong static typing catches errors at compile time\n- Type inference reduces verbosity while maintaining safety\n- Module system provides clear separation of concerns\n\n## Development\n\n### Building\n\n```bash\ndune build\n```\n\n### Cleaning\n\n```bash\ndune clean\n```\n\n### Running Tests\n\n```bash\n# Test Example 1\ncat \u003c\u003c'EOF' | dune exec ./main.exe\n3\nS -\u003e S+T T\nT -\u003e T*F F\nF -\u003e (S) i\ni+i\n\nEOF\n\n# Expected: Grammar is SLR(1). / yes\n```\n\n### Formatting (if ocamlformat installed)\n\n```bash\ndune build @fmt\n```\n\n## Troubleshooting\n\n### \"command not found: dune\"\n\nRun `eval $(opam env)` to set up the OCaml environment in your current shell.\n\n### Build Errors\n\nMake sure you have OCaml 4.14+ or 5.x installed:\n\n```bash\nocaml --version\n```\n\n### Warning as Errors\n\nThe project is configured to suppress certain warnings (-w -32-27-33). If you want to see all warnings:\n\nEdit `dune` file and remove the `(flags (:standard -w -32-27-33))` line.\n\n## References\n\n- Aho, Alfred V. et al. \"Compilers: Principles, Techniques, and Tools\" (2nd Edition). Addison-Wesley, 2006.\n- [OCaml Manual](https://ocaml.org/manual/)\n- [Dune Documentation](https://dune.readthedocs.io/)\n\n## License\n\nMIT License - See LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyoungermaster%2Fcontext-free-grammar-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyoungermaster%2Fcontext-free-grammar-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyoungermaster%2Fcontext-free-grammar-parser/lists"}