{"id":20840254,"url":"https://github.com/stefandeveloper/antlr-camp","last_synced_at":"2026-05-05T17:31:42.776Z","repository":{"id":105892456,"uuid":"213633603","full_name":"stefanDeveloper/antlr-camp","owner":"stefanDeveloper","description":"ANTLR camp gives you basic understandings of grammar","archived":false,"fork":false,"pushed_at":"2020-11-26T17:04:28.000Z","size":140,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-22T08:50:02.839Z","etag":null,"topics":["antlr","antlr4","camp","expression","expression-parser","hacktoberfest","hacktoberfest2019","java","spring","spring-boot","workshop"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":false,"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/stefanDeveloper.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":"2019-10-08T12:16:52.000Z","updated_at":"2021-02-20T22:10:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"99c260ec-23e5-4544-a098-fa75ee721a3f","html_url":"https://github.com/stefanDeveloper/antlr-camp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/stefanDeveloper/antlr-camp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanDeveloper%2Fantlr-camp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanDeveloper%2Fantlr-camp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanDeveloper%2Fantlr-camp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanDeveloper%2Fantlr-camp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stefanDeveloper","download_url":"https://codeload.github.com/stefanDeveloper/antlr-camp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanDeveloper%2Fantlr-camp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32660183,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-05T11:29:49.557Z","status":"ssl_error","status_checked_at":"2026-05-05T11:29:48.587Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["antlr","antlr4","camp","expression","expression-parser","hacktoberfest","hacktoberfest2019","java","spring","spring-boot","workshop"],"created_at":"2024-11-18T01:15:47.314Z","updated_at":"2026-05-05T17:31:42.772Z","avatar_url":"https://github.com/stefanDeveloper.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ANTLR4 Camp\n\n\u003e ANTLR4 Camp to get into touch with Lexer, Parser, Visitor and Listener\n\nIn this example you'll learn how to use Lexer and Parser to build up an expression grammar to calculate following results:\n\n```python\na = 5\nb = 6\nc = 7\n((a+b)/3-c)\n```\n\n## Agenda\n\n* Grammar\n* Lexer\n* Parser\n* Listener\n* Visitor\n* Error Strategy\n\n## Grammar\n\nA grammar is a subset of a language. Its following the syntax of a language and its limited by it as well.\n![alt text][grammar]\n\nA language is a set of valid sentences. A sentence is made up phrases. A Phrase is made up of subphrases and vocabulary symbols.\n![alt text][language]\n\n## Lexer\n\nLexer is the process of grouping characters into words or symbols. It tokenizes the input.\n\nTo define tokens:\n\n```python\nINT: [0-9]+;\nNEWLINE: '\\r'? '\\n';\n```\n\nLexer can be separated in own `Lexer.g4` file. Its defined by `lexer grammar name`.\n\n## Parser\n\nParser is the process of building up the data structure of a sentence. It recognizes languages.\n\n```python\nstat:\n    expr NEWLINE            # printExpr\n    | ID EQUAL expr NEWLINE # assign\n    | NEWLINE               # blank;\n```\n\nParser can be separated in own `parser.g4` file. Its defined by `parser grammar name`. Don't forget to reference the corresponding lexer file.\n\n```python\noptions {\n    tokenVocab = ExpressionLexer;\n    language = Java;\n}\n```\n\n## Listener\n\nThe generated Listener class provides enter and exit methods for each rule. It also defines where in the walk `ParseTreeWalker` calls the enter and exit method. \n\n```java\npublic class ExpressionParserListener extends ExpressionParserBaseListener\n```\n\n## Visitor\n\nThe generated Visitor class provides a controlled walk through our tree. It explicitly calls methods to visit children.\n\n```java\npublic class ExpressionParserVisitor extends ExpressionParserBaseVisitor\u003cInteger\u003e\n```\n\nImplementing visit funtions:\n\n```java\n@Override\npublic Integer visitPrintExpr(ExpressionParser.PrintExprContext ctx) {\n    Integer value = visit(ctx.expr());\n    log.info(\"Value:\" + value);\n    return 0;\n}\n```\n\nBe aware to enable visitor creation of grammars.\n\n```xml\n\u003cconfiguration\u003e\n    \u003csourceDirectory\u003e${basedir}/src/main/antlr4\u003c/sourceDirectory\u003e\n    \u003cvisitor\u003etrue\u003c/visitor\u003e\n\u003c/configuration\u003e\n```\n\n## Error Strategy\n\nTo define our on error strategy, we can extend the `BaseErrorListener. In general, only 4 different types of exceptions are thrown during the lexer and parser process.\n\n![alt text][error]\n\n```java\npublic class ExpressionErrorStrategy extends BaseErrorListener\n```\n\nTo set a custom error message, we can override the `syntaxError` function and handle each error message individually.\n\n```java\n@Override\npublic void syntaxError(Recognizer\u003c?, ?\u003e recognizer, Object o, int i, int i1, String s, RecognitionException e) {\n    super.syntaxError(recognizer, o, i, i1, \"Message\", e);\n}\n```\n\nBe aware, that the RecognitionException **can be null**!\n\nTo retrieve the offending and expected token of an exception, we can use the `Parser` or the `CommonToken`, see example below:\n\n```java\nhandleInputMismatchException((CommonToken) o, (Parser) recognizer);\n\nfinal String offendingToken = offendingSymbol.getText();\nfinal String expectedToken = parser.getExpectedTokens().toString(parser.getVocabulary());\n```\n\n[grammar]: ./internals/grammar.png \"Grammar and Language set\"\n[language]: ./internals/language.png \"Language content\"\n[error]: ./internals/error.png \"Throwable Exceptions\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefandeveloper%2Fantlr-camp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstefandeveloper%2Fantlr-camp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefandeveloper%2Fantlr-camp/lists"}