<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tianyi Liu</title>
    <description>The latest articles on DEV Community by Tianyi Liu (@tinjiklau).</description>
    <link>https://dev.to/tinjiklau</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F592861%2Fee179b22-7b7a-460e-94a6-a71276068a81.jpg</url>
      <title>DEV Community: Tianyi Liu</title>
      <link>https://dev.to/tinjiklau</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tinjiklau"/>
    <language>en</language>
    <item>
      <title>Antlr4 parser generator Java tips</title>
      <dc:creator>Tianyi Liu</dc:creator>
      <pubDate>Tue, 09 Mar 2021 05:09:31 +0000</pubDate>
      <link>https://dev.to/tinjiklau/antlr4-parser-generator-java-tips-4kp8</link>
      <guid>https://dev.to/tinjiklau/antlr4-parser-generator-java-tips-4kp8</guid>
      <description>&lt;p&gt;I'm new to Antlr(and any other parser generators;_;), so it took me a while to get familiar with the parser, lexer and visitor. Here I note down some tips that might be helpful in the future.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Avoid multiple lexer rules that match the exact same pattern&lt;/strong&gt;, otherwise one of them will be never matched. In my parser, there are two nodes and a weight, where all of them are numbers, but I thought since they are different elements, I should use different lexer rules for each of them, like the following:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tuple
    : nodefrom weight nodeto
    ;
nodefrom: [0-9]+;
weight: [0-9]+;
nodeto: [0-9]+;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is causing mismatching. To avoid this, it's better to use only one Lexer rule for Integers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tuple
    : nodefrom weight nodeto
    ;
nodefrom: INT;
weight: INT;
nodeto: INT;
INT: [0-9]+;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Because there might be several operations involved in the grammar, so we need to add tags(#operator) for each one, which leads to a separate visitor function. 
For example,
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;expr
    : expr '*'         #aster
    | expr '.' expr    #concate 
    | expr '+' expr    #plus
    | tuple            #tup
    | '(' expr ')'     #parens
    ;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is part of my parser, which uses 3 operations, star, concatenation, and plus. With #aster, #concate and #or, it'll generate interfaces visitAster(), visitConcate() and visitPlus(), and then we can implement these operations separately. If we don't create these tags, there will be only one interface created, which is visitExpr().&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When implementing the methods for visitor class, we only need to focus on &lt;strong&gt;those ones that are related to the values we want to compute when traversing the parse tree&lt;/strong&gt;. For example, in my parse tree, each node is a tuple &lt;br&gt;
&lt;em&gt;(Node1, Weight_1, Weight_2, Node2)&lt;/em&gt;, and there are visit methods for each value. If the visitor I create only requires Weight_1 for computation, then I need to implement visitWeight_1() specifically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I found this visitor class is really convenient, &lt;strong&gt;where it generates a method for each parse rule automatically, and you can get the value of one node simply by ctx.ValueName()&lt;/strong&gt;. So when I write the code for visitor methods, I always run &lt;em&gt;grun Calc prog -gui calc.txt&lt;/em&gt; to open a visualized parse tree, and check the relationship between those nodes.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5q930afu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oogt3k50u1i5uxldskpc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5q930afu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oogt3k50u1i5uxldskpc.png" alt="A part of one parse tree"&gt;&lt;/a&gt;&lt;br&gt;
This is part of the parse tree I'm using. There are 6 elements in &lt;strong&gt;tuple&lt;/strong&gt;, &lt;em&gt;(nodef, wc, wd, nodet)&lt;/em&gt;(including parentheses). So if right now I want to get the value of &lt;em&gt;wc&lt;/em&gt; in the function &lt;em&gt;visitTuple(Parser.TupleContext ctx)&lt;/em&gt;, I can write something like &lt;em&gt;ctx.wc()&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Still working...&lt;/p&gt;

</description>
      <category>java</category>
      <category>antlr</category>
      <category>antlr4</category>
    </item>
  </channel>
</rss>
