在IDEA中使用ANTLR4教程

<article class="baidu_pl">
        <div id="article_content" class="article_content clearfix csdn-tracking-statistics" data-pid="blog" data-mod="popu_307" data-dsm="post">
                                <div class="article-copyright">
                                      
                    版权声明:本文为博主原创文章,未经博主允许不得转载。                    https://blog.csdn.net/sherrywong1220/article/details/53697737                </div>
                                <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css">
                                            <div id="content_views" class="markdown_views">
                            <!-- flowchart 箭头图标 勿删 -->
                            <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg>
                            <p>Antlr 是一个基于 Java 开发的功能强大的语言识别工具,Antlr 以其简介的语法和高速的运行效率在这类工具中出类拔萃。当你需要开发一种领域语言时,语言可能像 Excel 中的公式一样复杂,也可能像本文中的例子一样简单(只有算术运算),这时你可以考虑使用 Antlr 来处理你的语言。</p>

<hr>

<h2 id="antlr-简介"><a name="t0"></a>Antlr 简介</h2>

<ol>
<li>ANTLR 语言识别的一个工具 (ANother Tool for Language Recognition ) 是一种语言工具,它提供了一个框架,可以通过包含 Java, C++, 或 C# 动作(action)的语法描述来构造语言识别器,编译器和解释器。 计算机语言的解析已经变成了一种非常普遍的工作,在这方面的理论和工具经过近 40 年的发展已经相当成熟,使用 Antlr 等识别工具来识别,解析,构造编译器比手工编程更加容易,同时开发的程序也更易于维护。</li>
<li>语言识别的工具有很多种,比如大名鼎鼎的 Lex 和 YACC,Linux 中有他们的开源版本,分别是 Flex 和 Bison。在 Java 社区里,除了 Antlr 外,语言识别工具还有 JavaCC 和 SableCC 等。</li>
<li>和大多数语言识别工具一样,Antlr 使用上下文无关文法描述语言。最新的 Antlr 是一个基于 LL(*) 的语言识别器。在 Antlr 中通过解析用户自定义的上下文无关文法,自动生成词法分析器 (Lexer)、语法分析器 (Parser) 和树分析器 (Tree Parser)。</li>
</ol>

<hr>

<h2 id="antlr-能做什么"><a name="t1"></a>Antlr 能做什么</h2>

<h3 id="编程语言处理"><a name="t2"></a>编程语言处理</h3>

<p>识别和处理编程语言是 Antlr 的首要任务,编程语言的处理是一项繁重复杂的任务,为了简化处理,一般的编译技术都将语言处理工作分为前端和后端两个部分。其中前端包括词法分析、语法分析、语义分析、中间代码生成等若干步骤,后端包括目标代码生成和代码优化等步骤。</p>

<p>Antlr 致力于解决编译前端的所有工作。使用 Anltr 的语法可以定义目标语言的词法记号和语法规则,Antlr 自动生成目标语言的词法分析器和语法分析器;此外,如果在语法规则中指定抽象语法树的规则,在生成语法分析器的同时,Antlr 还能够生成抽象语法树;最终使用树分析器遍历抽象语法树,完成语义分析和中间代码生成。整个工作在 Anltr 强大的支持下,将变得非常轻松和愉快。 <br>
文本处理</p>

<h3 id="文本处理"><a name="t3"></a>文本处理</h3>

<p>当需要文本处理时,首先想到的是正则表达式,使用 Anltr 的词法分析器生成器,可以很容易的完成正则表达式能够完成的所有工作;除此之外使用 Anltr 还可以完成一些正则表达式难以完成的工作,比如识别左括号和右括号的成对匹配等。</p>

<hr>

<h2 id="在idea中安装使用antlr"><a name="t4"></a>在IDEA中安装使用Antlr</h2>

<ol>
<li>在Settings-Plugins中安装ANTLR v4 grammar plugin</li>
<li>新建一个Maven项目,在pom.xml文件中添加ANTLR4插件和运行库的依赖。注意一定要用最新版的,依赖,不知道最新版本号的可以自己google一下maven antlr4。</li>
</ol>

<pre class="prettyprint" name="code"><code class="hljs xml has-numbering" οnclick="mdcp.copyCode(event)"><span class="hljs-tag">&lt;<span class="hljs-title">dependencies</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-title">dependency</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">groupId</span>&gt;</span>org.antlr<span class="hljs-tag">&lt;/<span class="hljs-title">groupId</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">artifactId</span>&gt;</span>antlr4-runtime<span class="hljs-tag">&lt;/<span class="hljs-title">artifactId</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">version</span>&gt;</span>4.5.3<span class="hljs-tag">&lt;/<span class="hljs-title">version</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-title">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">dependencies</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">build</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-title">plugins</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-title">plugin</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-title">groupId</span>&gt;</span>org.antlr<span class="hljs-tag">&lt;/<span class="hljs-title">groupId</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-title">artifactId</span>&gt;</span>antlr4-maven-plugin<span class="hljs-tag">&lt;/<span class="hljs-title">artifactId</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-title">version</span>&gt;</span>4.3<span class="hljs-tag">&lt;/<span class="hljs-title">version</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-title">executions</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-title">execution</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-title">id</span>&gt;</span>antlr<span class="hljs-tag">&lt;/<span class="hljs-title">id</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-title">goals</span>&gt;</span>
                            <span class="hljs-tag">&lt;<span class="hljs-title">goal</span>&gt;</span>antlr4<span class="hljs-tag">&lt;/<span class="hljs-title">goal</span>&gt;</span>
                        <span class="hljs-tag">&lt;/<span class="hljs-title">goals</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-title">phase</span>&gt;</span>none<span class="hljs-tag">&lt;/<span class="hljs-title">phase</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-title">execution</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-title">executions</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-title">configuration</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-title">outputDirectory</span>&gt;</span>src/test/java<span class="hljs-tag">&lt;/<span class="hljs-title">outputDirectory</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-title">listener</span>&gt;</span>true<span class="hljs-tag">&lt;/<span class="hljs-title">listener</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-title">treatWarningsAsErrors</span>&gt;</span>true<span class="hljs-tag">&lt;/<span class="hljs-title">treatWarningsAsErrors</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-title">configuration</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-title">plugin</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-title">plugins</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-title">build</span>&gt;</span><div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li></ul></pre>

<p><code>antlr4-maven-plugin</code>用于生产Java代码,<code>antlr4-runtime</code>则是运行时所需的依赖库。把<code>antlr4-maven-plugin</code>的<code>phase</code>设置成none,这样在Maven 的lifecycle种就不会调用ANTLR4。如果你希望每次构建生成文法可以将这个配置去掉。</p>

<ol>
<li>我们定义一个最简单的领域语言,从一个简单的完成算术运算的例子出发,详细说明 Antlr 的使用。首先我们需要在src\main\java中新建一个 Antlr 的文法文件, 一般以 .g4 为文件名后缀,命名为 Demo.g4 。</li>
</ol>

<hr>

<h2 id="表达式定义"><a name="t5"></a>表达式定义</h2>

<h3 id="文法定义"><a name="t6"></a>文法定义</h3>

<p>在这个文法文件 Demo.g4 中根据 Antlr 的语法规则来定义算术表达式的文法,文件的头部是 grammar 关键字,定义文法的名字,必须与文法文件文件的名字相同:</p>

<pre class="prettyprint" name="code"><code class="hljs  has-numbering" οnclick="mdcp.copyCode(event)">grammar Demo;<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre>

<p>为了简单起见,假设我们的自定义语言只能输入一个算术表达式。从而整个程序有一个语句构成,语句有表达式或者换行符构成。如清单 1 所示:</p>

<p><strong>清单1.程序和语句</strong></p>

<pre class="prettyprint" name="code"><code class="hljs perl has-numbering" οnclick="mdcp.copyCode(event)">prog: <span class="hljs-keyword">stat</span> 

<span class="hljs-keyword">stat</span>: expr 
  |NEWLINE 
;<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li></ul></pre>

<p>在 Anltr 中,算法的优先级需要通过文法规则的嵌套定义来体现,加减法的优先级低于乘除法,表达式 expr 的定义由乘除法表达式 multExpr 和加减法算符 (‘+’|’-‘) 构成;同理,括号的优先级高于乘除法,乘除法表达式 multExpr 通过原子操作数 atom 和乘除法算符 (‘*’|’/’) 构成。整个表达的定义如清单 2 所示:</p>

<p><strong>清单2.表达式</strong></p>

<pre class="prettyprint" name="code"><code class="hljs scss has-numbering" οnclick="mdcp.copyCode(event)">expr <span class="hljs-value">: multExpr ((<span class="hljs-string">'+'</span>|<span class="hljs-string">'-'</span>) multExpr)* 
;</span> 
multExpr <span class="hljs-value">: atom ((<span class="hljs-string">'*'</span>|<span class="hljs-string">'/'</span>) atom)* 
;</span> 
atom<span class="hljs-value">:  <span class="hljs-string">'('</span> expr <span class="hljs-string">')'</span> 
      | INT  
   | ID  
;</span><div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li></ul></pre>

<p>最后需要考虑的词法的定义,在 Antlr 中语法定义和词法定义通过规则的第一个字符来区别, 规定语法定义符号的第一个字母小写,而词法定义符号的第一个字母大写。算术表达式中用到了 4 类记号 ( 在 Antlr 中被称为 Token),分别是标识符 ID,表示一个变量;常量 INT,表示一个常数;换行符 NEWLINE 和空格 WS,空格字符在语言处理时将被跳过,skip() 是词法分析器类的一个方法。如清单 3 所示:</p>

<p><strong>清单 3. 记号定义</strong></p>

<pre class="prettyprint" name="code"><code class="hljs avrasm has-numbering" οnclick="mdcp.copyCode(event)"><span class="hljs-label">ID:</span>(<span class="hljs-string">'a'</span>..<span class="hljs-string">'z'</span>|<span class="hljs-string">'A'</span>..<span class="hljs-string">'Z'</span>)+<span class="hljs-comment">;</span>
<span class="hljs-label">INT:</span><span class="hljs-string">'0'</span>..<span class="hljs-string">'9'</span>+<span class="hljs-comment">;</span>
<span class="hljs-label">NEWLINE:</span><span class="hljs-string">'\r'</span>?<span class="hljs-string">'\n'</span><span class="hljs-comment">;</span>
<span class="hljs-label">WS:</span>(<span class="hljs-string">' '</span>|<span class="hljs-string">'\t'</span>|<span class="hljs-string">'\n'</span>|<span class="hljs-string">'\r'</span>)+{skip()<span class="hljs-comment">;};</span><div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li></ul></pre>

<p>Antlr 支持多种目标语言,可以把生成的分析器生成为 Java,C#,C,Python,JavaScript 等多种语言,默认目标语言为 Java,通过 options {language=?;} 来改变目标语言。我们的例子中目标语言为 Java。</p>

<p>整个Demo.g4文件内容如下:</p>

<pre class="prettyprint" name="code"><code class="hljs scss has-numbering" οnclick="mdcp.copyCode(event)">grammar Demo;

<span class="hljs-comment">//parser</span>
prog<span class="hljs-value">:stat
;</span>
stat<span class="hljs-value">:expr|NEWLINE
;</span>

expr<span class="hljs-value">:multExpr((<span class="hljs-string">'+'</span>|<span class="hljs-string">'-'</span>)multExpr)*
;</span>
multExpr<span class="hljs-value">:atom((<span class="hljs-string">'*'</span>|<span class="hljs-string">'/'</span>)atom)*
;</span>
atom<span class="hljs-value">:<span class="hljs-string">'('</span>expr<span class="hljs-string">')'</span>
    |INT
    |ID
;</span>

<span class="hljs-comment">//lexer</span>
ID<span class="hljs-value">:(<span class="hljs-string">'a'</span>..<span class="hljs-string">'z'</span>|<span class="hljs-string">'A'</span>..<span class="hljs-string">'Z'</span>)+;</span>
INT<span class="hljs-value">:<span class="hljs-string">'0'</span>..<span class="hljs-string">'9'</span>+;</span>
NEWLINE<span class="hljs-value">:<span class="hljs-string">'\r'</span>?<span class="hljs-string">'\n'</span>;</span>
WS<span class="hljs-value">:(<span class="hljs-string">' '</span>|<span class="hljs-string">'\t'</span>|<span class="hljs-string">'\n'</span>|<span class="hljs-string">'\r'</span>)+{skip();</span>};
<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li></ul></pre>

<hr>

<h2 id="运行antlr"><a name="t7"></a>运行ANTLR</h2>

<ol>
<li>右键Demo.g4,选择Configure ANTLR,配置output路径。</li>
</ol>

<p><img src="https://img3.doubanio.com/view/photo/photo/en2IjTkvxMclQWMdMnzxXA/124898500/x2405823644.jpg" alt="" title=""></p>

<ol>
<li>右键Demo.g4,选择Generate ANTLR Recognizer。可以看到生成结果结果。 <br>
其中Demo.tokens为文法中用到的各种符号做了数字化编号,我们可以不关注这个文件。DemoLexer是Antlr生成的词法分析器,DemoParser是Antlr 生成的语法分析器。</li>
</ol>

<p><img src="https://img1.doubanio.com/view/photo/photo/txb6xdb77rCUwllTjozhJw/124898500/x2405823647.jpg" alt="" title=""></p>

<ol>
<li>调用分析器。新建一个Main.java。</li>
</ol>

<pre class="prettyprint" name="code"><code class="hljs cs has-numbering" οnclick="mdcp.copyCode(event)"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>(String expr) throws Exception{

        <span class="hljs-comment">//对每一个输入的字符串,构造一个 ANTLRStringStream 流 in</span>
        ANTLRInputStream <span class="hljs-keyword">in</span> = <span class="hljs-keyword">new</span> ANTLRInputStream(expr);

        <span class="hljs-comment">//用 in 构造词法分析器 lexer,词法分析的作用是产生记号</span>
        DemoLexer lexer = <span class="hljs-keyword">new</span> DemoLexer(<span class="hljs-keyword">in</span>);

        <span class="hljs-comment">//用词法分析器 lexer 构造一个记号流 tokens</span>
        CommonTokenStream tokens = <span class="hljs-keyword">new</span> CommonTokenStream(lexer);

        <span class="hljs-comment">//再使用 tokens 构造语法分析器 parser,至此已经完成词法分析和语法分析的准备工作</span>
        DemoParser parser = <span class="hljs-keyword">new</span> DemoParser(tokens);

        <span class="hljs-comment">//最终调用语法分析器的规则 prog,完成对表达式的验证</span>
        parser.prog();
    }<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li></ul></pre>

<p>完整Main.java代码:</p>

<pre class="prettyprint" name="code"><code class="hljs cs has-numbering" οnclick="mdcp.copyCode(event)">import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.ANTLRInputStream;

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> Main {

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>(String expr) throws Exception{

        <span class="hljs-comment">//对每一个输入的字符串,构造一个 ANTLRStringStream 流 in</span>
        ANTLRInputStream <span class="hljs-keyword">in</span> = <span class="hljs-keyword">new</span> ANTLRInputStream(expr);

        <span class="hljs-comment">//用 in 构造词法分析器 lexer,词法分析的作用是产生记号</span>
        DemoLexer lexer = <span class="hljs-keyword">new</span> DemoLexer(<span class="hljs-keyword">in</span>);

        <span class="hljs-comment">//用词法分析器 lexer 构造一个记号流 tokens</span>
        CommonTokenStream tokens = <span class="hljs-keyword">new</span> CommonTokenStream(lexer);

        <span class="hljs-comment">//再使用 tokens 构造语法分析器 parser,至此已经完成词法分析和语法分析的准备工作</span>
        DemoParser parser = <span class="hljs-keyword">new</span> DemoParser(tokens);

        <span class="hljs-comment">//最终调用语法分析器的规则 prog,完成对表达式的验证</span>
        parser.prog();
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(String[] args) throws Exception{

        String[] testStr={
                <span class="hljs-string">"2"</span>,
                <span class="hljs-string">"a+b+3"</span>,
                <span class="hljs-string">"(a-b)+3"</span>,
                <span class="hljs-string">"a+(b*3"</span>
        };

        <span class="hljs-keyword">for</span> (String s:testStr){
            System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"Input expr:"</span>+s);
            run(s);
        }
    }
}<div class="hljs-button {2}" data-title="复制"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li></ul></pre>

<ol>
<li>运行Main.java <br>
当输入合法的的表达式时,分析器没有任何输出,表示语言被分析器接受;当输入的表达式违反文法规则时,比如“a + (b * 3”,分析器输出 line 0:-1 mismatched input ‘’ expecting ‘)’;提示期待一个右括号却遇到了结束符号。 <br>
<img src="https://img1.doubanio.com/view/photo/photo/PMOQz21qT_zFsp8nh9lE7A/124898500/x2405823648.jpg" alt="" title=""></li>
</ol>

<hr>

<h2 id="文法可视化"><a name="t8"></a>文法可视化</h2>

<ol>
<li>打开Antlr Preview。</li>
<li>在Demo.g4中选中一个语法定义符号,如expr。右键选中的符合,选择Text Rule expr。 <br>
<img src="https://img1.doubanio.com/view/photo/photo/0zTTzvFbOiai_8GRwOho8g/124898500/x2405823649.jpg" alt="" title=""></li>
<li>在ANTLR Preview中选择input,输入表达式,如a+b*c+4/2。则能显示出可视化的文法。 <br>
<img src="https://img3.doubanio.com/view/photo/photo/kfLbHe2Ts0PlkRHgysgXIw/124898500/x2405823651.jpg" alt="" title=""></li>
</ol>            </div>
                        <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-258a4616f7.css" rel="stylesheet">
                      </div>
    </article>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值