{"id":1083,"date":"2012-04-20T09:00:00","date_gmt":"2012-04-20T09:00:00","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/2012\/10\/antlr-tutorial-hello-word.html"},"modified":"2012-10-21T23:28:43","modified_gmt":"2012-10-21T23:28:43","slug":"antlr-tutorial-hello-word","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html","title":{"rendered":"ANTLR Tutorial &#8211; Hello Word"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align: left\"><a href=\"http:\/\/antlr.org\/\">Antlr<\/a> stands for ANother Tool for Language Recognition. The tool is able to generate compiler or interpreter for any computer language. Besides obvious use, e.g. need to parse a real &#8216;big&#8217; programming language such as Java, PHP or SQL, it can help with smaller, more common tasks.  <\/p>\n<p>It is useful any time you need to evaluate expressions unknown at compile-time or to parse non-trivial user input or files in a weird format. Of course, it is possible to create custom hand made parser for any of these tasks. However, it usually takes much more time and effort. A little knowledge of a good parser generator may turn these time-consuming tasks into easy and fast exercises.  <a href=\"http:\/\/www.blogger.com\/blogger.g?blogID=8574118689743302986\" name=\"more\"><\/a> <\/p>\n<p>This post begins with a small demonstration of ANTLR usefulness. Then, we explain what ANTLR is and how does it work. Finally, we show how to compile a simple &#8216;Hello word!&#8217; language into an abstract syntax tree. The post explains also how to add error handling and how to test the language.   <\/p>\n<p><a href=\"http:\/\/meri-stuff.blogspot.com\/2011\/09\/antlr-tutorial-expression-language.html\">Next post<\/a> shows how to create a real expression language.  <\/p>\n<p><strong>Real Word Examples<\/strong><\/p>\n<p>ANTLR seems to be popular in open source word. Among others, it is used by   <a href=\"http:\/\/camel.apache.org\/\">Apache Camel<\/a>,   <a href=\"http:\/\/lucene.apache.org\/\">Apache Lucene<\/a>,   <a href=\"http:\/\/hadoop.apache.org\/\">Apache Hadoop<\/a>,   <a href=\"http:\/\/groovy.codehaus.org\/\">Groovy<\/a> and   <a href=\"http:\/\/www.hibernate.org\/\">Hibernate<\/a>. They all needed parser for a custom language. For example, Hibernate uses ANTLR to parse its query language HQL.  <\/p>\n<p>All those are big frameworks and thus more likely to need domain specific language than small application. The list of smaller projects using ANTLR is available on its   <a href=\"http:\/\/www.antlr.org\/showcase\/list\">showcase list<\/a>. We found also one   <a href=\"http:\/\/stackoverflow.com\/questions\/645468\/have-you-ever-effectively-used-lexer-parser-in-real-world-application\">stackoverflow<\/a> discussion on the topic.  <\/p>\n<p>To see where ANTLR could be useful and how it could save time, try to estimate following requirements:   <\/p>\n<ul>\n<li>Add formula calculator into an accounting system. It will calculate values of formulas such as <code>(10 + 80)*sales_tax<\/code>. <\/li>\n<li>Add extended search field into a recipe search engine. It will search for receipts matching expressions such as <code>(chicken and orange) or (no meat and carrot)<\/code>.<\/li>\n<\/ul>\n<p>Our safe estimate is a day and half including documentation, tests, and integration into the project. ANTLR is worth looking at if you are facing similar requirements and made significantly higher estimate.  <\/p>\n<p><strong>Overview<\/strong><\/p>\n<p>ANTLR is code generator. It takes so called grammar file as input and generates two classes: lexer and parser.  <\/p>\n<p>Lexer runs first and splits input into pieces called tokens. Each token represents more or less meaningful piece of input. The stream of tokes is passed to parser which do all necessary work. It is the parser who builds abstract syntax tree, interprets the code or translate it into some other form.  <\/p>\n<p>Grammar file contains everything ANTLR needs to generate correct lexer and parser. Whether it should generate java or python classes, whether parser generates abstract syntax tree, assembler code or directly interprets code and so on. As this tutorial shows how to build abstract syntax tree, we will ignore other options in following explanations.  <\/p>\n<p>Most importantly, grammar file describes how to split input into tokens and how to build tree from tokens. In other words, grammar file contains lexer rules and parser rules.   <\/p>\n<p>Each lexer rule describes one token:  <\/p>\n<pre class=\"brush:java\">TokenName: regular expression;   \r\n<\/pre>\n<p>Parser rules are more complicated. The most basic version is similar as in lexer rule:  <\/p>\n<pre class=\"brush:java\">ParserRuleName: regular expression;   \r\n<\/pre>\n<p>They may contain modifiers that specify special transformations on input, root and childs in result abstract syntax tree or actions to be performed whenever rule is used. Almost all work is usually done inside parser rules.  <\/p>\n<p><strong>Infrastructure<\/strong><\/p>\n<p>First, we show tools to make development with ANTLR easier. Of course, nothing of what is described in this chapter is necessary. All examples work with maven, text-editor and internet connection only.  <\/p>\n<p>ANTLR project produced   <a href=\"http:\/\/antlr.org\/works\/index.html\">stand alone IDE<\/a>,   <a href=\"http:\/\/antlreclipse.sourceforge.net\/\">Eclipse plugin<\/a> and   <a href=\"http:\/\/plugins.intellij.net\/plugin\/?id=953\">Idea plugin<\/a>. We did not found NetBeans plugin.   <\/p>\n<p><strong>ANTLRWorks<\/strong><\/p>\n<p>Stand alone ide is called   <a href=\"http:\/\/antlr.org\/works\/index.html\">ANTLRWorks<\/a>. Download it from the project   <a href=\"http:\/\/www.antlr.org\/download.html\">download page<\/a>. ANTLRWorks is a single jar file, use   <code>java -jar antlrworks-1.4.3.jar<\/code> command to run it.   <\/p>\n<p>The IDE has more features and is more stable than Eclipse plugin.  <\/p>\n<p><strong>Eclipse Plugin<\/strong><\/p>\n<p>Download and unpack ANTLR v3 from ANTLR   <a href=\"http:\/\/www.antlr.org\/download.html\">download page<\/a>. Then, install ANTLR plugin from Eclipse Marketplace:  <\/p>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a href=\"http:\/\/1.bp.blogspot.com\/-9VuJbnow5Gs\/TldIgee6owI\/AAAAAAAAAEs\/ydNprKq6cA0\/s1600\/InstallANTLRPluginFromMarketPlace.PNG\"><img decoding=\"async\" border=\"0\" height=\"316\" src=\"http:\/\/1.bp.blogspot.com\/-9VuJbnow5Gs\/TldIgee6owI\/AAAAAAAAAEs\/ydNprKq6cA0\/s320\/InstallANTLRPluginFromMarketPlace.PNG\" width=\"320\" \/><\/a><\/div>\n<p>Go to Preferences and configure ANTLR v3 installation directory:  <\/p>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a href=\"http:\/\/3.bp.blogspot.com\/-AjBtoDCRfzA\/TldJGEhRblI\/AAAAAAAAAE0\/pxaSQo_Zdzo\/s1600\/ConfigureEclipsePlugin.PNG\"><img decoding=\"async\" border=\"0\" height=\"329\" src=\"http:\/\/3.bp.blogspot.com\/-AjBtoDCRfzA\/TldJGEhRblI\/AAAAAAAAAE0\/pxaSQo_Zdzo\/s400\/ConfigureEclipsePlugin.PNG\" width=\"400\" \/><\/a><\/div>\n<p>To test the configuration, download   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/tree\/002-S001HelloWord\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\">sample grammar file<\/a> and open it in eclipse. It will be open it in ANTLR editor. The editor has three tabs:  <\/p>\n<ul>\n<li>Grammar &#8211; text editor with syntax highlighting, code completion and so on.<\/li>\n<li>Interpreter &#8211; compiles test expressions into syntax trees, may produce different result than generated parser. It tend to throw failed predicate exception on correct expressions.<\/li>\n<li>Railroad View &#8211; paints nice graphs of your lexer and parser rules.<\/li>\n<\/ul>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a href=\"http:\/\/3.bp.blogspot.com\/-ntxxW3g_1-E\/TldKXqWPOjI\/AAAAAAAAAE8\/nlzEv82vFBk\/s1600\/RailRoadView.PNG\"><img decoding=\"async\" border=\"0\" height=\"286\" src=\"http:\/\/3.bp.blogspot.com\/-ntxxW3g_1-E\/TldKXqWPOjI\/AAAAAAAAAE8\/nlzEv82vFBk\/s320\/RailRoadView.PNG\" width=\"320\" \/><\/a><\/div>\n<p><strong>An Empty Project &#8211; Maven Configuration<\/strong><\/p>\n<p>This chapter shows how to add ANTLR into a maven project. If you use Eclipse and do not have a m2eclipse plugin installed yet, install it from http:\/\/download.eclipse.org\/technology\/m2e\/releases update site. It will make your life much easier.  <\/p>\n<p><strong>Create Project<\/strong><\/p>\n<p>Create new maven project and specify maven-archetype-quickstart on &#8216;Select an Archetype&#8217; screen. If you do not use Eclipse, command   <code>mvn archetype:generate<\/code> achieves the same.  <\/p>\n<p><strong>Dependency<\/strong><\/p>\n<p>Add ANTLR dependency into   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/001-configured_antlr\/pom.xml#L18\">pom.xml<\/a>:     <\/p>\n<pre class=\"brush:xml\">  \r\n  \r\n   \r\n    \r\n    \r\n     org.antlr\r\n    \r\n    \r\n    \r\n     antlr\r\n    \r\n    \r\n    \r\n     3.3\r\n    \r\n   \r\n    \r\n     jar\r\n    \r\n    \r\n    \r\n     compile\r\n    \r\n  \r\n   \r\n\r\n  \r\n<\/pre>\n<p>Note: As ANTLR does not have history of being backward-compatible, it is better to specify required version.  <\/p>\n<p><strong>Plugins<\/strong><\/p>\n<p>Antlr maven plugin runs during generate-sources phase and generates both lexer and parser java classes from grammar (.g) files. Add it into   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/001-configured_antlr\/pom.xml#L35\">pom.xml<\/a>:    <\/p>\n<pre class=\"brush:xml\">  \r\n  \r\n   \r\n    org.antlr\r\n   \r\n  \r\n   \r\n    antlr3-maven-plugin\r\n   \r\n  \r\n   \r\n    3.3\r\n   \r\n  \r\n   \r\n    \r\n    \r\n      \r\n     \r\n      run antlr\r\n     \r\n      \r\n     \r\n      generate-sources\r\n     \r\n      \r\n     \r\n        \r\n      \r\n       antlr\r\n      \r\n      \r\n     \r\n    \r\n    \r\n  \r\n   \r\n\r\n  \r\n<\/pre>\n<p>Create   <code><a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/tree\/001-configured_antlr\/src\/main\/antlr3\">src\/main\/antlr3<\/a><\/code> folder. The plugin expects all grammar files in there.  <\/p>\n<p>Generated files are put into   <code>target\/generated-sources\/antlr3<\/code> directory. As this directory is not in default maven build path, we use build-helper-maven-plugin to add it there:    <\/p>\n<pre class=\"brush:xml\">  \r\n  \r\n   \r\n    org.codehaus.mojo\r\n   \r\n  \r\n   \r\n    build-helper-maven-plugin\r\n   \r\n  \r\n   \r\n    \r\n    \r\n      \r\n     \r\n      add-source\r\n     \r\n      \r\n     \r\n      generate-sources\r\n     \r\n      \r\n     \r\n        \r\n      \r\n       add-source\r\n      \r\n      \r\n     \r\n      \r\n     \r\n        \r\n      \r\n          \r\n       ${basedir}\/target\/generated-sources\/antlr3\r\n        \r\n      \r\n      \r\n     \r\n    \r\n    \r\n  \r\n   \r\n\r\n  \r\n<\/pre>\n<p>If you use eclipse, you have to update project configuration: right click on the project -&gt; &#8216;maven&#8217; -&gt; &#8216;Update Project Configuration&#8217;.  <\/p>\n<p><strong>Test It<\/strong><\/p>\n<p>Invoke maven to test project configuration: right click on the project -&gt; &#8216;Run As&#8217; -&gt; &#8216;Maven generate-sources&#8217;. Alternatively, use   <code>mvn generate-sources<\/code> command.  <\/p>\n<p>Build should be successful. Console output should contain antlr3-maven-plugin plugin output:  <\/p>\n<pre class=\"brush:java\">[INFO] --- antlr3-maven-plugin:3.3:antlr (run antlr) @ antlr-step-by-step ---\r\n[INFO] ANTLR: Processing source directory C:\\meri\\ANTLR\\workspace\\antlr-step-by-step\\src\\main\\antlr3\r\n[INFO] No grammars to process\r\nANTLR Parser Generator  Version 3.3 Nov 30, 2010 12:46:29\r\n<\/pre>\n<p>It should be followed by build-helper-maven-plugin plugin output:  <\/p>\n<pre class=\"brush:java\">[INFO] --- build-helper-maven-plugin:1.7:add-source (add-source) @ antlr-step-by-step ---\r\n[INFO] Source directory: C:\\meri\\ANTLR\\workspace\\antlr-step-by-step\\target\\generated-sources\\antlr3 added.\r\n<\/pre>\n<p>The result of this phase in located on github, tag   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/tree\/001-configured_antlr\/\">001-configured_antlr<\/a>.  <\/p>\n<p><strong>Hello Word<\/strong><\/p>\n<p>We will create simplest possible language parser &#8211; hello word parser. It builds a small abstract syntax tree from a single expression: &#8216;Hello word!&#8217;.   <\/p>\n<p>We will use it to show how to create a grammar file and generate ANTLR classes from it. Then, we will show how to use generated files and create an unit test.  <\/p>\n<p><strong>First Grammar File<\/strong><\/p>\n<p>Antlr3-maven-plugin searches   <code>src\/main\/antlr3<\/code> directory for grammar files. It creates new package for each sub-directory with grammar and generates parser and lexer classes into it. As we wish to generate classes into   <code><a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/tree\/002-S001HelloWord\/target\/generated-sources\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\">org.meri.antlr_step_by_step.parsers<\/a><\/code> package, we have to create   <code><a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/tree\/002-S001HelloWord\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\">src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers<\/a><\/code> directory.  <\/p>\n<p>Grammar name and file name must be identical. File must have .g suffix. Moreover, each grammar file begins with a grammar name declaration. Our   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/002-S001HelloWord\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S001HelloWord.g#L1\">S001HelloWord grammar<\/a> begins with following line:  <\/p>\n<pre class=\"brush:java\">grammar S001HelloWord;\r\n<\/pre>\n<p>eclaration is always followed by generator options. We are working on java project and wish to compile expressions into abstract syntax tree:  <div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush:java\">options {\r\n    \/\/ antlr will generate java lexer and parser\r\n    language = Java;\r\n    \/\/ generated parser should create abstract syntax tree\r\n    output = AST;\r\n}\r\n<\/pre>\n<p>Antlr does not generate package declaration on top of generated classes. We have to use   <code>@parser::header<\/code> and   <code>@lexer::header<\/code> blocks to enforce it. Headers must follow options block:  <\/p>\n<pre class=\"brush:java\">@lexer::header {\r\n  package org.meri.antlr_step_by_step.parsers;\r\n}\r\n\r\n@parser::header {\r\n  package org.meri.antlr_step_by_step.parsers;\r\n}\r\n<\/pre>\n<p>Each grammar file must have at least one lexer rule. Each lexer rule must begin with upper case letter. We have two rules, first defines a salutation token, second defines an endsymbol token. Salutation must be &#8216;Hello word&#8217; and endsymbol must be &#8216;!&#8217;.  <\/p>\n<pre class=\"brush:java\">SALUTATION:'Hello word';   \r\nENDSYMBOL:'!';\r\n<\/pre>\n<p>Similarly, each grammar file must have at least one parser rule. Each parser rule must begin with lower case letter. We have only one parser rule: any expression in our language must be composed of a salutation followed by an endsymbol.  <\/p>\n<pre class=\"brush:java\">expression : SALUTATION ENDSYMBOL;\r\n<\/pre>\n<p>Note: the order of grammar file elements is fixed. If you change it, antlr plugin will fail.  <\/p>\n<p><strong>Generate Lexer and Parser<\/strong><\/p>\n<p>Generate a lexer and parser from command line using   <code>mvn generate-sources<\/code> command or from Eclipse:  <\/p>\n<ul>\n<li>Right click on the project.<\/li>\n<li>Click &#8216;Run As&#8217;.<\/li>\n<li>Click &#8216;Maven generate-sources&#8217;.<\/li>\n<\/ul>\n<p>Antlr plugin will create   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/tree\/002-S001HelloWord\/target\/generated-sources\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\">target\/generated-sources\/antlr\/org\/meri\/antlr_step_by_step\/parsers<\/a> folder and place S001HelloWordLexer.java and S001HelloWordParser.java files inside.  <\/p>\n<p><strong>Use Lexer and Parser<\/strong><\/p>\n<p>Finally, we create compiler class. It has only one public method which:  <\/p>\n<ul>\n<li>calls generated lexer to split input into tokens,<\/li>\n<li>calls generated parser to build AST from tokens,<\/li>\n<li>prints result AST tree into console,<\/li>\n<li>returns abstract syntax tree.<\/li>\n<\/ul>\n<p>Compiler is located in   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/002-S001HelloWord\/src\/main\/java\/org\/meri\/antlr_step_by_step\/parsers\/S001HelloWordCompiler.java#L10\">S001HelloWordCompiler<\/a> class:  <\/p>\n<pre class=\"brush:java\">public CommonTree compile(String expression) {\r\n    try {\r\n      \/\/lexer splits input into tokens\r\n      ANTLRStringStream input = new ANTLRStringStream(expression);\r\n      TokenStream tokens = new CommonTokenStream( new S001HelloWordLexer( input ) );\r\n  \r\n      \/\/parser generates abstract syntax tree\r\n      S001HelloWordParser parser = new S001HelloWordParser(tokens);\r\n      S001HelloWordParser.expression_return ret = parser.expression();\r\n  \r\n      \/\/acquire parse result\r\n      CommonTree ast = (CommonTree) ret.tree;\r\n      printTree(ast);\r\n      return ast;\r\n    } catch (RecognitionException e) {\r\n      throw new IllegalStateException(\"Recognition exception is never thrown, only declared.\");\r\n  }\r\n<\/pre>\n<p>Note: Do not worry about RecognitionException exception declared on   <code>S001HelloWordParser.expression()<\/code> method. It is never thrown.  <\/p>\n<p><strong>Testing It<\/strong><\/p>\n<p>We finish this chapter with a small test case for our new compiler. Create   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/002-S001HelloWord\/src\/test\/java\/org\/meri\/antlr_step_by_step\/parsers\/S001HelloWordTest.java#L17\">S001HelloWordTest<\/a> class:  <\/p>\n<pre class=\"brush:java\">public class S001HelloWordTest {\r\n \/**\r\n  * Abstract syntax tree generated from \"Hello word!\" should have an \r\n  * unnamed root node with two children. First child corresponds to \r\n  * salutation token and second child corresponds to end symbol token.\r\n  * \r\n  * Token type constants are defined in generated S001HelloWordParser \r\n  * class.\r\n  *\/\r\n @Test\r\n public void testCorrectExpression() {\r\n  \/\/compile the expression\r\n  S001HelloWordCompiler compiler = new S001HelloWordCompiler();\r\n  CommonTree ast = compiler.compile(\"Hello word!\");\r\n  CommonTree leftChild = ast.getChild(0);\r\n  CommonTree rightChild = ast.getChild(1);\r\n\r\n  \/\/check ast structure\r\n  assertEquals(S001HelloWordParser.SALUTATION, leftChild.getType());\r\n  assertEquals(S001HelloWordParser.ENDSYMBOL, rightChild.getType());\r\n }\r\n\r\n}\r\n<\/pre>\n<p>The test will pass successfully. It will print abstract syntax tree to the console:  <\/p>\n<pre class=\"brush:java\">0 null\r\n  -- 4 Hello word\r\n  -- 5 !\r\n<\/pre>\n<p><strong>Grammar in IDE<\/strong><\/p>\n<p>Open S001HelloWord.g in editor and go to interpreter tab.   <\/p>\n<ul>\n<li>Highlight expression rule in top left view.<\/li>\n<li>Write &#8216;Hello word!&#8217; into top right view.<\/li>\n<li>Press green arrow in top left corner.<\/li>\n<\/ul>\n<p>Interpreter will generate parse tree:  <\/p>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a href=\"http:\/\/3.bp.blogspot.com\/-dp8GvKd_BkU\/TldKgra3r0I\/AAAAAAAAAFE\/ykwVLz8Q2Ac\/s1600\/hellowordast.png\"><img decoding=\"async\" border=\"0\" height=\"78\" src=\"http:\/\/3.bp.blogspot.com\/-dp8GvKd_BkU\/TldKgra3r0I\/AAAAAAAAAFE\/ykwVLz8Q2Ac\/s400\/hellowordast.png\" width=\"118\" \/><\/a><\/div>\n<p><strong>Copy Grammar<\/strong><\/p>\n<p>Each new grammar in this tutorial is based on previous one. We compiled a list of steps needed to copy an old grammar into a new one. Use them to copy an OldGrammar into a NewGrammar:   <\/p>\n<ul>\n<li>Copy <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S001HelloWord.g\">OldGrammar.g<\/a> to <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S002HelloWordWithErrorHandling.g\">NewGrammar.g<\/a> in the same directory.<\/li>\n<li>Change grammar declaration to <code>grammar NewGrammar;<\/code><\/li>\n<li><a href=\"http:\/\/www.blogger.com\/blogger.g?blogID=8574118689743302986#GenerateLexerandParser\">Generate<\/a> parser and lexer.<\/li>\n<li>Create new class <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/java\/org\/meri\/antlr_step_by_step\/parsers\/S002HelloWordWithErrorHandlingCompiler.java\">NewGrammarCompiler<\/a> analogous to previous <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/java\/org\/meri\/antlr_step_by_step\/parsers\/S001HelloWordCompiler.java\">OldGrammarCompiler<\/a> class.<\/li>\n<li>Create new test class <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/test\/java\/org\/meri\/antlr_step_by_step\/parsers\/S002HelloWordWithErrorHandlingTest.java\">NewGrammarTest<\/a> analogous to previous <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/test\/java\/org\/meri\/antlr_step_by_step\/parsers\/S001HelloWordTest.java\">OldGrammarTest<\/a> class.<\/li>\n<\/ul>\n<p><a href=\"http:\/\/www.blogger.com\/blogger.g?blogID=8574118689743302986\" name=\"ErrorHandling\"><\/a><strong>Error Handling<\/strong><\/p>\n<p>No task is really finished without an appropriate error handling. Generated ANTLR classes try to recover from errors whenever possible. They do report errors to the console, but there is no out-of-the box API to programmatically find about syntax errors.   <\/p>\n<p>This could be fine if we would build command line only compiler. However, lets assume that we are building a GUI to our language, or use the result as input to another tool. In such case, we need an API access to all generated errors.   <\/p>\n<p>In the beginning of this chapter, we will experiment with default error handling and create test case for it. Then, we will add a naive error handling, which will throw an exception whenever first error happens. Finally, we will move to the &#8216;real&#8217; solution. It will collect all errors in an internal list and provide methods to access them.   <\/p>\n<p>As a side product, the chapter shows how to:  <\/p>\n<ul>\n<li><a href=\"http:\/\/www.blogger.com\/blogger.g?blogID=8574118689743302986#ChangingCatchinParser\">add custom catch clause to parser rules<\/a>,<\/li>\n<li><a href=\"http:\/\/www.blogger.com\/blogger.g?blogID=8574118689743302986#AddMethodsandFieldstoGeneratedClasses\">add new methods and fields to generated classes<\/a>,<\/li>\n<li><a href=\"http:\/\/www.blogger.com\/blogger.g?blogID=8574118689743302986#OverridingGeneratedMethods\">override generated methods<\/a>.<\/li>\n<\/ul>\n<p><strong>Default Error Handling<\/strong><\/p>\n<p>First, we will try to parse various incorrect expressions. The goal is to understand default ANTLR error handling behavior. We will create test case from each experiment. All test cases are located in   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/test\/java\/org\/meri\/antlr_step_by_step\/parsers\/S001HelloWordExperimentsTest.java#L7\">S001HelloWordExperimentsTest<\/a> class.  <\/p>\n<p><strong>Expression 1<\/strong>:   <code>Hello word?<\/code> <\/p>\n<p>Result tree is very similar to the correct one:    <\/p>\n<pre class=\"brush:java\">0 null\r\n  -- 4 Hello word\r\n  -- 5 ?&lt;missing ENDSYMBOL&gt;\r\n<\/pre>\n<p>Console output contains errors:    <\/p>\n<pre class=\"brush:java\">line 1:10 no viable alternative at character '?'\r\nline 1:11 missing ENDSYMBOL at '&lt;eof&gt;'\r\n<\/pre>\n<p><a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/test\/java\/org\/meri\/antlr_step_by_step\/parsers\/S001HelloWordExperimentsTest.java#L10\">Test case<\/a>: following test case passes with no problem. No exception is thrown and abstract syntax tree node types are the same as in correct expression.  <\/p>\n<pre class=\"brush:java\">@Test\r\n public void testSmallError() {\r\n  \/\/compile the expression\r\n  S001HelloWordCompiler compiler = new S001HelloWordCompiler();\r\n  CommonTree ast = compiler.compile(\"Hello word?\");\r\n\r\n  \/\/check AST structure\r\n  assertEquals(S001HelloWordParser.SALUTATION, ast.getChild(0).getType());\r\n  assertEquals(S001HelloWordParser.ENDSYMBOL, ast.getChild(1).getType());\r\n }\r\n<\/pre>\n<p><strong>Expression 2<\/strong>:   <code>Bye!<\/code><\/p>\n<p>Result tree is very similar to the correct one:    <\/p>\n<pre class=\"brush:java\">0 null\r\n  -- 4 \r\n  &lt;missing&gt;\r\n   \r\n  -- 5 !\r\n\r\n  &lt;\/missing&gt;<\/pre>\n<p>Console output contains errors:  <\/p>\n<pre class=\"brush:java\">line 1:0 no viable alternative at character 'B'\r\nline 1:1 no viable alternative at character 'y'\r\nline 1:2 no viable alternative at character 'e'\r\nline 1:3 missing SALUTATION at '!'\r\n<\/pre>\n<p><a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/test\/java\/org\/meri\/antlr_step_by_step\/parsers\/S001HelloWordExperimentsTest.java#L21\">Test case<\/a>: following test case passes with no problem. No exception is thrown and abstract syntax tree node types are the same as in correct expression.    <\/p>\n<pre class=\"brush:java\">@Test\r\n public void testBiggerError() {\r\n  \/\/compile the expression\r\n  S001HelloWordCompiler compiler = new S001HelloWordCompiler();\r\n  CommonTree ast = compiler.compile(\"Bye!\");\r\n\r\n  \/\/check AST structure\r\n  assertEquals(S001HelloWordParser.SALUTATION, ast.getChild(0).getType());\r\n  assertEquals(S001HelloWordParser.ENDSYMBOL, ast.getChild(1).getType());\r\n }\r\n<\/pre>\n<p><strong>Expression 3<\/strong>:   <code>Incorrect Expression<\/code> <\/p>\n<p>Result tree has only root node with no childs:    <\/p>\n<pre class=\"brush:java\">0 \r\n<\/pre>\n<p>Console output contains a lot of errors:    <\/p>\n<pre class=\"brush:java\">line 1:0 no viable alternative at character 'I'\r\nline 1:1 no viable alternative at character 'n'\r\nline 1:2 no viable alternative at character 'c'\r\nline 1:3 no viable alternative at character 'o'\r\nline 1:4 no viable alternative at character 'r'\r\nline 1:5 no viable alternative at character 'r'\r\nline 1:6 no viable alternative at character 'e'\r\nline 1:7 no viable alternative at character 'c'\r\nline 1:8 no viable alternative at character 't'\r\nline 1:9 no viable alternative at character ' '\r\nline 1:10 no viable alternative at character 'E'\r\nline 1:11 no viable alternative at character 'x'\r\nline 1:12 no viable alternative at character 'p'\r\nline 1:13 no viable alternative at character 'r'\r\nline 1:14 no viable alternative at character 'e'\r\nline 1:15 no viable alternative at character 's'\r\nline 1:16 no viable alternative at character 's'\r\nline 1:17 no viable alternative at character 'i'\r\nline 1:18 no viable alternative at character 'o'\r\nline 1:19 no viable alternative at character 'n'\r\nline 1:20 mismatched input '&amp;ltEOF&gt;' expecting SALUTATION\r\n<\/pre>\n<p><a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/test\/java\/org\/meri\/antlr_step_by_step\/parsers\/S001HelloWordExperimentsTest.java#L32\">Test case<\/a>: we finally found an expression that results in different tree structure.    <\/p>\n<pre class=\"brush:java\">@Test\r\n public void testCompletelyWrong() {\r\n  \/\/compile the expression\r\n  S001HelloWordCompiler compiler = new S001HelloWordCompiler();\r\n  CommonTree ast = compiler.compile(\"Incorrect Expression\");\r\n\r\n  \/\/check AST structure\r\n  assertEquals(0, ast.getChildCount());\r\n }\r\n<\/pre>\n<p><strong>Error Handling in Lexer<\/strong><\/p>\n<p>Each lexer rule &#8216;RULE&#8217; corresponds to &#8216;mRULE&#8217; method in generated lexer. For example, our grammar has two rules:    <\/p>\n<pre class=\"brush:java\">SALUTATION:'Hello word';   \r\nENDSYMBOL:'!';\r\n<\/pre>\n<p>and generated lexer has two   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/target\/generated-sources\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S002HelloWordWithErrorHandlingLexer.java#L28\">corresponding methods<\/a>:    <\/p>\n<pre class=\"brush:java\">public final void mSALUTATION() throws RecognitionException {\r\n    \/\/ ...\r\n}\r\n\r\npublic final void mENDSYMBOL() throws RecognitionException {\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<p>Depending on what exception is thrown, lexer may or may not try to recover from it. However, each error ends in   <code>reportError(RecognitionException e)<\/code> method. Generated lexer inherits it:    <\/p>\n<pre class=\"brush:java\">public void reportError(RecognitionException e) {\r\n  displayRecognitionError(this.getTokenNames(), e);\r\n }\r\n<\/pre>\n<p>The result: we have to change either reportError or displayRecognitionError method in lexer.  <\/p>\n<p><strong>Error Handling in Parser<\/strong><\/p>\n<p>Our grammar has only one parser rule &#8216;expression&#8217;:  <\/p>\n<pre class=\"brush:java\">expression SALUTATION ENDSYMBOL;\r\n<\/pre>\n<p>The expression corresponds to   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/target\/generated-sources\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S002HelloWordWithErrorHandlingParser.java#L54\"><code>expression()<\/code><\/a> method in generated parser:    <\/p>\n<pre class=\"brush:java\">public final expression_return expression() throws RecognitionException {\r\n  \/\/initialization\r\n  try {\r\n    \/\/parsing\r\n  }\r\n  catch (RecognitionException re) {\r\n    reportError(re);\r\n    recover(input,re);\r\n    retval.tree = (Object) adaptor.errorNode(input, retval.start, input.LT(-1), re);\r\n  } finally {\r\n  }\r\n  \/\/return result;\r\n}\r\n<\/pre>\n<p>If an error happens, parser will:     <\/p>\n<ul>\n<li>report error to the console,<\/li>\n<li>recover from the error,<\/li>\n<li>add an error node (instead of an ordinary node) to the abstract syntax tree.<\/li>\n<\/ul>\n<p>Error reporting in parser is little bit more complicated than error reporting in lexer:    <\/p>\n<pre class=\"brush:java\">\/** Report a recognition problem.\r\n  *\r\n  *  This method sets errorRecovery to indicate the parser is recovering\r\n  *  not parsing.  Once in recovery mode, no errors are generated.\r\n  *  To get out of recovery mode, the parser must successfully match\r\n  *  a token (after a resync).  So it will go:\r\n  *\r\n  *   1. error occurs\r\n  *   2. enter recovery mode, report error\r\n  *   3. consume until token found in resynch set\r\n  *   4. try to resume parsing\r\n  *   5. next match() will reset errorRecovery mode\r\n  *\r\n  *  If you override, make sure to update syntaxErrors if you care about that.\r\n  *\/\r\n public void reportError(RecognitionException e) {\r\n  \/\/ if we've already reported an error and have not matched a token\r\n  \/\/ yet successfully, don't report any errors.\r\n  if ( state.errorRecovery ) {\r\n   return;\r\n  }\r\n  state.syntaxErrors++; \/\/ don't count spurious\r\n  state.errorRecovery = true;\r\n\r\n  displayRecognitionError(this.getTokenNames(), e);\r\n }\r\n<\/pre>\n<p>This time we have two possible options:    <\/p>\n<ul>\n<li>replace catch clause in a parser rule method by own handling,<\/li>\n<li>override parser methods.<\/li>\n<\/ul>\n<p><a href=\"http:\/\/www.blogger.com\/blogger.g?blogID=8574118689743302986\" name=\"ChangingCatchinParser\"><\/a><strong>Changing Catch in Parser<\/strong><\/p>\n<p>Antlr provides two ways how to change generated catch clause in the parser. We will create two new grammars, each demonstrates one way how to do it. In both cases, we will make parser exit upon first error.  <\/p>\n<p>First, we can add   <code>rulecatch<\/code> to   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S002HelloWordWithErrorHandling.g#L33\">parser rule<\/a> of new S002HelloWordWithErrorHandling grammar:  <\/p>\n<pre class=\"brush:java\">expression : SALUTATION ENDSYMBOL;\r\ncatch [RecognitionException e] {\r\n  \/\/Custom handling of an exception. Any java code is allowed.\r\n  throw new S002HelloWordError(\":(\", e);\r\n}\r\n<\/pre>\n<p>Of course, we had to add import of S002HelloWordError exception into   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S002HelloWordWithErrorHandling.g#L19\">headers block<\/a>:  <\/p>\n<pre class=\"brush:java\">@parser::header {\r\n  package org.meri.antlr_step_by_step.parsers;\r\n\r\n  \/\/add imports (see full line on Github)\r\n  import ... .S002HelloWordWithErrorHandlingCompiler.S002HelloWordError;\r\n}\r\n<\/pre>\n<p>The   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/java\/org\/meri\/antlr_step_by_step\/parsers\/S002HelloWordWithErrorHandlingCompiler.java#L31\">compiler class<\/a> is almost the same as before. It declares new exception: <\/p>\n<pre class=\"brush:java\">public class S002HelloWordWithErrorHandlingCompiler extends AbstractCompiler {\r\n\r\n  public CommonTree compile(String expression) {\r\n    \/\/ no change here\r\n  }\r\n\r\n  @SuppressWarnings(\"serial\")\r\n  public static class S002HelloWordError extends RuntimeException {\r\n    public S002HelloWordError(String arg0, Throwable arg1) {\r\n      super(arg0, arg1);\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>ANTLR will then replace default catch clause in expression rule method with our   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/target\/generated-sources\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S002HelloWordWithErrorHandlingParser.java#L91\">own handling<\/a>:     <\/p>\n<pre class=\"brush:java\">public final expression_return expression() throws RecognitionException {\r\n  \/\/initialization\r\n  try {\r\n    \/\/parsing\r\n  }\r\n  catch (RecognitionException re) {\r\n    \/\/Custom handling of an exception. Any java code is allowed.\r\n    throw new S002HelloWordError(\":(\", e); \r\n  } finally {\r\n  }\r\n  \/\/return result;\r\n}\r\n<\/pre>\n<p>As usually, the   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S002HelloWordWithErrorHandling.g#L1\">grammar<\/a>, the   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/java\/org\/meri\/antlr_step_by_step\/parsers\/S002HelloWordWithErrorHandlingCompiler.java#L8\">compiler class<\/a> and the   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/test\/java\/org\/meri\/antlr_step_by_step\/parsers\/S002HelloWordWithErrorHandlingTest.java#L8\">test class<\/a> are available on Github.  <\/p>\n<p>Alternatively, we can put   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S003HelloWordWithErrorHandling.g#L27\"><code>rulecatch<\/code><\/a> rule in between the header block and first lexer rule. This method is demonstrated in   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S003HelloWordWithErrorHandling.g#L1\">S003HelloWordWithErrorHandling<\/a> grammar:  <\/p>\n<pre class=\"brush:java\">\/\/change error handling in all parser rules\r\n@rulecatch {\r\n  catch (RecognitionException e) {\r\n    \/\/Custom handling of an exception. Any java code is allowed.\r\n    throw new S003HelloWordError(\":(\", e);\r\n  }\r\n}\r\n<\/pre>\n<p>We have to add import of   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S003HelloWordWithErrorHandling.g#L23\">S003HelloWordError<\/a> exception into headers block:  <\/p>\n<pre class=\"brush:java\">@parser::header {\r\n  package org.meri.antlr_step_by_step.parsers;\r\n\r\n  \/\/add imports (see full line on Github)\r\n  import ... .S003HelloWordWithErrorHandlingCompiler.S003HelloWordError;\r\n}\r\n<\/pre>\n<p>The   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/java\/org\/meri\/antlr_step_by_step\/parsers\/S003HelloWordWithErrorHandlingCompiler.java#L8\">compiler<\/a> class is exactly the same as in previous case. ANTLR will replace default catch clause in all   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/target\/generated-sources\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S003HelloWordWithErrorHandlingParser.java#L93\">parser rules<\/a>:     <\/p>\n<pre class=\"brush:java\">public final expression_return expression() throws RecognitionException {\r\n  \/\/initialization\r\n  try {\r\n    \/\/parsing\r\n  }\r\n  catch (RecognitionException re) {\r\n    \/\/Custom handling of an exception. Any java code is allowed.\r\n    throw new S003HelloWordError(\":(\", e); \r\n  } finally {\r\n  }\r\n  \/\/return result;\r\n}\r\n<\/pre>\n<p>Again, the   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S003HelloWordWithErrorHandling.g#L1\">grammar<\/a>, the   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/java\/org\/meri\/antlr_step_by_step\/parsers\/S003HelloWordWithErrorHandlingCompiler.java#L8\">compiler class<\/a> and the   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/test\/java\/org\/meri\/antlr_step_by_step\/parsers\/S003HelloWordWithErrorHandlingTest.java\">test class<\/a> are available on Github.  <\/p>\n<p>Unfortunately, this method has two disadvantages. First, it does not work in lexer, only in parser. Second, default report and recovery functionality works in a reasonable way. It attempts to recover from errors. Once it starts recovering, it does not generate new errors. Error messages are generated only if the parser is not in error recovery mode.  <\/p>\n<p>We liked this functionality, so we decided to change only default implementation of error reporting.  <\/p>\n<p><strong><a href=\"http:\/\/www.blogger.com\/blogger.g?blogID=8574118689743302986\" name=\"AddMethodsandFieldstoGeneratedClasses\"><\/a><br \/>\n Add Methods and Fields to Generated Classes<\/strong><\/p>\n<p>We will store all lexer\/parser errors in private list. Moreover, we will add two methods into generated classes:  <\/p>\n<ul>\n<li>hasErrors &#8211; returns true if at least one error occurred,<\/li>\n<li>getErrors &#8211; returns all generated errors.<\/li>\n<\/ul>\n<p>New fields and methods are added inside @members block:  <\/p>\n<pre class=\"brush:java\">@lexer::members {\r\n  \/\/everything you need to add to the lexer\r\n}\r\n\r\n@parser::members {\r\n  \/\/everything you need to add to the parser\r\n}\r\n<\/pre>\n<p>members blocks must be placed between header block and first lexer rule. The example is in grammar named   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S004HelloWordWithErrorHandling.g#L24\">S004HelloWordWithErrorHandling<\/a>:  <\/p>\n<pre class=\"brush:java\">\/\/add new members to generated lexer\r\n@lexer::members {\r\n  \/\/add new field\r\n  private List&lt;RecognitionException&gt; errors = new ArrayList &lt;RecognitionException&gt; ();\r\n  \r\n  \/\/add new method\r\n  public List&lt;RecognitionException&gt; getAllErrors() {\r\n    return new ArrayList&lt;RecognitionException&gt;(errors);\r\n  }\r\n\r\n  \/\/add new method\r\n  public boolean hasErrors() {\r\n    return !errors.isEmpty();\r\n  }\r\n}\r\n\r\n\/\/add new members to generated parser\r\n@parser::members {\r\n  \/\/add new field\r\n  private List&lt;RecognitionException&gt; errors = new ArrayList &lt;RecognitionException&gt; ();\r\n  \r\n  \/\/add new method\r\n  public List&lt;RecognitionException&gt; getAllErrors() {\r\n    return new ArrayList&lt;RecognitionException&gt;(errors);\r\n  }\r\n\r\n  \/\/add new method\r\n  public boolean hasErrors() {\r\n    return !errors.isEmpty();\r\n  }\r\n}\r\n<\/pre>\n<p>Both   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/target\/generated-sources\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S004HelloWordWithErrorHandlingLexer.java#L14\">generated lexer<\/a> and   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/target\/generated-sources\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S004HelloWordWithErrorHandlingParser.java#L46\">generated parser<\/a> contain all fields and methods written in members block.  <\/p>\n<p><a href=\"http:\/\/www.blogger.com\/blogger.g?blogID=8574118689743302986\" name=\"OverridingGeneratedMethods\"><\/a><strong>Overriding Generated Methods<\/strong><\/p>\n<p>To override a generated method, do the same thing as if you want to add a new one, e.g. add it inside @members block:  <\/p>\n<pre class=\"brush:java\">\/\/override generated method in lexer\r\n@lexer::members {\r\n  \/\/override method\r\n  public void reportError(RecognitionException e) {\r\n    errors.add(e);\r\n    displayRecognitionError(this.getTokenNames(), e);\r\n  }\r\n}\r\n\r\n\/\/override generated method in parser\r\n@parser::members {\r\n  \/\/override method\r\n  public void reportError(RecognitionException e) {\r\n    errors.add(e);\r\n    displayRecognitionError(this.getTokenNames(), e);\r\n  }\r\n}\r\n<\/pre>\n<p>The method reportError now overrides default behavior in both   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/target\/generated-sources\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S004HelloWordWithErrorHandlingLexer.java#L28\">lexer<\/a> and   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/target\/generated-sources\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S004HelloWordWithErrorHandlingParser.java#L60\">parser<\/a>.  <\/p>\n<p><strong>Collect Errors in Compiler<\/strong><\/p>\n<p>Finally, we have to change our compiler class. New version collects all errors after input parsing phase:   <\/p>\n<pre class=\"brush:java\">private List&lt;RecognitionException&gt; errors = new ArrayList&lt;RecognitionException&gt;();\r\n\r\npublic CommonTree compile(String expression) {\r\n  try {\r\n\r\n    ... init lexer ...\r\n  \r\n    ... init parser ...\r\n    ret = parser.expression();\r\n\r\n    \/\/collect all errors\r\n    if (lexer.hasErrors())\r\n      errors.addAll(lexer.getAllErrors());\r\n  \r\n    if (parser.hasErrors())\r\n      errors.addAll(parser.getAllErrors());\r\n  \r\n    \/\/acquire parse result\r\n    ... as usually ...\r\n  } catch (RecognitionException e) {\r\n    ...\r\n  }\r\n}\r\n  \r\n\/**\r\n* @return all errors found during last run\r\n*\/\r\npublic List&lt;RecognitionException&gt; getAllErrors() {\r\n  return errors;\r\n}\r\n<\/pre>\n<p>We must collect lexer errors after parser finished its work. The lexer is invoked from it and contain no errors before. As usually, we placed the   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/antlr3\/org\/meri\/antlr_step_by_step\/parsers\/S004HelloWordWithErrorHandling.g#L1\">grammar<\/a>, the   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/main\/java\/org\/meri\/antlr_step_by_step\/parsers\/S004HelloWordWithErrorHandlingCompiler.java#L11\">compiler class<\/a>, and the   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/blob\/003-S002-to-S004HelloWordWithErrorHandling\/src\/test\/java\/org\/meri\/antlr_step_by_step\/parsers\/S004HelloWordWithErrorHandlingTest.java#L7\">test class<\/a> on Github.   <\/p>\n<p>Download tag   <a href=\"https:\/\/github.com\/SomMeri\/antlr-step-by-step\/tree\/003-S002-to-S004HelloWordWithErrorHandling\">003-S002-to-S004HelloWordWithErrorHandling<\/a> of antlr-step-by-step project to find all three error handling methods in the same java project.  <\/p>\n<p><strong><i>Reference: <\/i><\/strong><a href=\"http:\/\/meri-stuff.blogspot.com\/2011\/08\/antlr-tutorial-hello-word.html\">ANTLR Tutorial &#8211; Hello Word<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a> Maria Jurcovicova at the <a href=\"http:\/\/meri-stuff.blogspot.com\/\">This is Stuff<\/a> blog.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Antlr stands for ANother Tool for Language Recognition. The tool is able to generate compiler or interpreter for any computer language. Besides obvious use, e.g. need to parse a real &#8216;big&#8217; programming language such as Java, PHP or SQL, it can help with smaller, more common tasks. It is useful any time you need to &hellip;<\/p>\n","protected":false},"author":203,"featured_media":47,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[435],"class_list":["post-1083","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-antlr"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>ANTLR Tutorial - Hello Word - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Antlr stands for ANother Tool for Language Recognition. The tool is able to generate compiler or interpreter for any computer language. Besides obvious\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"ANTLR Tutorial - Hello Word - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Antlr stands for ANother Tool for Language Recognition. The tool is able to generate compiler or interpreter for any computer language. Besides obvious\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2012-04-20T09:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-10-21T23:28:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/antlr-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Maria Jurcovicova\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Maria Jurcovicova\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"19 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html\"},\"author\":{\"name\":\"Maria Jurcovicova\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/fe8c21d37cb06cac89667ce9e690d6da\"},\"headline\":\"ANTLR Tutorial &#8211; Hello Word\",\"datePublished\":\"2012-04-20T09:00:00+00:00\",\"dateModified\":\"2012-10-21T23:28:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html\"},\"wordCount\":2475,\"commentCount\":5,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/antlr-logo.jpg\",\"keywords\":[\"ANTLR\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html\",\"name\":\"ANTLR Tutorial - Hello Word - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/antlr-logo.jpg\",\"datePublished\":\"2012-04-20T09:00:00+00:00\",\"dateModified\":\"2012-10-21T23:28:43+00:00\",\"description\":\"Antlr stands for ANother Tool for Language Recognition. The tool is able to generate compiler or interpreter for any computer language. Besides obvious\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/antlr-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/antlr-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/antlr-tutorial-hello-word.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"ANTLR Tutorial &#8211; Hello Word\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/fe8c21d37cb06cac89667ce9e690d6da\",\"name\":\"Maria Jurcovicova\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/036cc830ddb6b2d9385310d0eda5091365721bd14304c113c8548d6e508b5feb?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/036cc830ddb6b2d9385310d0eda5091365721bd14304c113c8548d6e508b5feb?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/036cc830ddb6b2d9385310d0eda5091365721bd14304c113c8548d6e508b5feb?s=96&d=mm&r=g\",\"caption\":\"Maria Jurcovicova\"},\"sameAs\":[\"http:\\\/\\\/meri-stuff.blogspot.com\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/Maria-Jurcovicova\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"ANTLR Tutorial - Hello Word - Java Code Geeks","description":"Antlr stands for ANother Tool for Language Recognition. The tool is able to generate compiler or interpreter for any computer language. Besides obvious","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html","og_locale":"en_US","og_type":"article","og_title":"ANTLR Tutorial - Hello Word - Java Code Geeks","og_description":"Antlr stands for ANother Tool for Language Recognition. The tool is able to generate compiler or interpreter for any computer language. Besides obvious","og_url":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2012-04-20T09:00:00+00:00","article_modified_time":"2012-10-21T23:28:43+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/antlr-logo.jpg","type":"image\/jpeg"}],"author":"Maria Jurcovicova","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Maria Jurcovicova","Est. reading time":"19 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html"},"author":{"name":"Maria Jurcovicova","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/fe8c21d37cb06cac89667ce9e690d6da"},"headline":"ANTLR Tutorial &#8211; Hello Word","datePublished":"2012-04-20T09:00:00+00:00","dateModified":"2012-10-21T23:28:43+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html"},"wordCount":2475,"commentCount":5,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/antlr-logo.jpg","keywords":["ANTLR"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html","url":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html","name":"ANTLR Tutorial - Hello Word - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/antlr-logo.jpg","datePublished":"2012-04-20T09:00:00+00:00","dateModified":"2012-10-21T23:28:43+00:00","description":"Antlr stands for ANother Tool for Language Recognition. The tool is able to generate compiler or interpreter for any computer language. Besides obvious","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/antlr-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/antlr-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/antlr-tutorial-hello-word.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"ANTLR Tutorial &#8211; Hello Word"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/fe8c21d37cb06cac89667ce9e690d6da","name":"Maria Jurcovicova","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/036cc830ddb6b2d9385310d0eda5091365721bd14304c113c8548d6e508b5feb?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/036cc830ddb6b2d9385310d0eda5091365721bd14304c113c8548d6e508b5feb?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/036cc830ddb6b2d9385310d0eda5091365721bd14304c113c8548d6e508b5feb?s=96&d=mm&r=g","caption":"Maria Jurcovicova"},"sameAs":["http:\/\/meri-stuff.blogspot.com\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/Maria-Jurcovicova"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/1083","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/203"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=1083"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/1083\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/47"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=1083"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=1083"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=1083"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}