{"id":18632824,"url":"https://github.com/ftomassetti/javacc2antlr","last_synced_at":"2025-08-10T16:33:57.091Z","repository":{"id":38995638,"uuid":"114538751","full_name":"ftomassetti/JavaCC2ANTLR","owner":"ftomassetti","description":null,"archived":false,"fork":false,"pushed_at":"2022-10-18T13:09:06.000Z","size":1548,"stargazers_count":20,"open_issues_count":2,"forks_count":11,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-11T15:00:44.714Z","etag":null,"topics":["antlr","antlr4","javacc"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ftomassetti.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}},"created_at":"2017-12-17T13:33:09.000Z","updated_at":"2024-11-28T10:23:21.000Z","dependencies_parsed_at":"2023-01-19T16:31:14.943Z","dependency_job_id":null,"html_url":"https://github.com/ftomassetti/JavaCC2ANTLR","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ftomassetti/JavaCC2ANTLR","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ftomassetti%2FJavaCC2ANTLR","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ftomassetti%2FJavaCC2ANTLR/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ftomassetti%2FJavaCC2ANTLR/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ftomassetti%2FJavaCC2ANTLR/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ftomassetti","download_url":"https://codeload.github.com/ftomassetti/JavaCC2ANTLR/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ftomassetti%2FJavaCC2ANTLR/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269753934,"owners_count":24470495,"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-08-10T02:00:08.965Z","response_time":71,"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":["antlr","antlr4","javacc"],"created_at":"2024-11-07T05:13:27.802Z","updated_at":"2025-08-10T16:33:56.986Z","avatar_url":"https://github.com/ftomassetti.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JavaCC2ANTLR\n\n[![Build Status](https://travis-ci.org/ftomassetti/JavaCC2ANTLR.svg?branch=master)](https://travis-ci.org/ftomassetti/JavaCC2ANTLR)\n\nJavaCC is an old and venerable tool, used in so many projects. In recent years however ANTLR seems to have a growing community and\nthere are different tools to support ANTLR. Also, ANTLR can be used to generate a parser for so many target languages that\nare not supported by JavaCC.\n\nSo I hacked together this little project, in Kotlin.\n\nFor now it basically get a JavaCC grammar and produces a lexer and a parser ANTLR grammar which should hopefully be equivalent.\n\n## Generate ANTLR Lexer \u0026 Parser\n\nSimply look at the class `JavaCCToAntlrConverter`. It takes the file name of the JavaCC grammar and outputs\na Lexer and a parser Grammar.\n\n## Generate an ANTLR in memory\n\n```kotlin\nval file = File(\"src/test/resources/java.jj\")\nval grammarName = file.nameWithoutExtension.capitalize()\n\nval javaCCGrammar = loadJavaCCGrammar(file)\nval antlrGrammar = javaCCGrammar.convertToAntlr(grammarName)\nthis.genericParser = antlrGrammar.genericParser()\nval ast = genericParser.parse(\"class A { }\")\n```\n\n## Push/Pop Mode Commands\n\nJavaCC by default does not have a way for tokens to change the token manager lexical state with memory, like ANTLR provides\nwith the `pushMode` and `popMode` commands. For example, to parse as a single token a balanced set of parentheses such as\n`((()) ())` you might have the following JavaCC parser:\n```\nTOKEN_MGR_DECLS : {\n    static List\u003cInteger\u003e lexicalStateStack = new ArrayList\u003cInteger\u003e();\n\n    static void openParen() {\n        lexicalStateStack.add(curLexState);\n    }\n\n    static void closeParen() {\n        SwitchTo(lexicalStateStack.remove(lexicalStateStack.size() - 1));\n    }\n}\n\n\u003cDEFAULT, LEVEL1, LEVELN\u003e SKIP : {\n    \u003c \" \" \u003e\n}\n\n\u003cLEVELN\u003e MORE : {\n    \u003cLPAREN:    \"(\"\u003e { openParen(); }\n|   \u003cRPAREN:    \")\"\u003e { closeParen(); }\n}\n\nMORE : {\n    \u003c \"(\" \u003e { openParen(); } : LEVEL1\n}\n\n\u003cLEVEL1\u003e MORE : {\n    \u003c \"(\" \u003e { openParen(); } : LEVELN\n}\n\n\u003cLEVEL1\u003e TOKEN : {\n    \u003cBALANCED_PARENS: \")\" \u003e { closeParen(); } : DEFAULT\n}\n\nvoid Start(): {} { \u003cBALANCED_PARENS\u003e \u003cEOF\u003e }\n```\n\nHowever, the ANTLR lexer would not behave correctly because we cannot infer when, according to the `SwitchTo` statements\nexecuted as part of the actions, the corresponding ANTLR rules should use `mode`, `pushMode`, or `popMode` commands:\n\n```\nlexer grammar Lexer;\n\nSKIP0 : ' ' -\u003e skip ;\nMORE0 : '(' -\u003e more, mode(LEVEL1) ;\n\nmode LEVEL1;\nLEVEL1_SKIP0 : SKIP0 -\u003e skip ;\nMORE1 : '(' -\u003e more, mode(LEVELN) ;\nBALANCED_PARENS : ')' -\u003e mode(DEFAULT_MODE) ;\n\nmode LEVELN;\nLEVELN_SKIP0 : SKIP0 -\u003e skip ;\nLPAREN : '(' -\u003e more ;\nRPAREN : ')' -\u003e more ;  // PROBLEM: Cannot escape this mode!\n\n\nparser grammar Parser;\n\noptions { tokenVocab=Lexer; }\n\nstart :  BALANCED_PARENS EOF  ;\n```\n\nIn order to handle such actions, you must add the following fields to your `TOKEN_MGR_DECLS` with values set to the name\nof your functions that should map to `pushMode` and `popMode` commands respectively:\n\n```\nTOKEN_MGR_DECLS : {\n    ...\n    final static String pushStateFunc = \"openParen\";\n    final static String popStateFunc = \"closeParen\";\n}\n```\n\nNow the lexer gets generated correctly:\n\n```\nSKIP0 : ' ' -\u003e skip ;\nMORE0 : '(' -\u003e more, pushMode(LEVEL1) ;\n\nmode LEVEL1;\nLEVEL1_SKIP0 : SKIP0 -\u003e skip ;\nMORE1 : '(' -\u003e more, pushMode(LEVELN) ;\nBALANCED_PARENS : ')' -\u003e popMode ;\n\nmode LEVELN;\nLEVELN_SKIP0 : SKIP0 -\u003e skip ;\nLPAREN : '(' -\u003e more, pushMode(LEVELN) ;\nRPAREN : ')' -\u003e more, popMode ;\n```\n\n## Licensing\n\nThe project is made available under the Apache Public License V2.0. Please see the file called [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fftomassetti%2Fjavacc2antlr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fftomassetti%2Fjavacc2antlr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fftomassetti%2Fjavacc2antlr/lists"}