<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>编程语言 on lfkdsk's Blog</title><link>https://blog.lfkdsk.org/tags/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/</link><description>Recent content in 编程语言 on lfkdsk's Blog</description><generator>Hugo</generator><language>cn</language><lastBuildDate>Sat, 25 Jun 2016 22:33:35 +0000</lastBuildDate><atom:link href="https://blog.lfkdsk.org/tags/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/index.xml" rel="self" type="application/rss+xml"/><item><title>学习制作一门有趣的编程语言－0x04</title><link>https://blog.lfkdsk.org/make-new-language-4/</link><pubDate>Sat, 25 Jun 2016 22:33:35 +0000</pubDate><guid>https://blog.lfkdsk.org/make-new-language-4/</guid><description>&lt;h2 id="几种常用算法">几种常用算法&lt;/h2>
&lt;p>我们日常会用正则表达式的时候，我们会发现正则表达式用了非常精简的语法就能概括多种输入串的特征，&lt;/p></description></item><item><title>学习制作一门有趣的编程语言－0x03</title><link>https://blog.lfkdsk.org/make-new-language-3/</link><pubDate>Wed, 01 Jun 2016 22:28:06 +0000</pubDate><guid>https://blog.lfkdsk.org/make-new-language-3/</guid><description>&lt;h2 id="分析一个c语言的lex--yacc-程序">分析一个C语言的Lex &amp;amp; Yacc 程序&lt;/h2>
&lt;p>&lt;code>博客地址&lt;/code>： &lt;a href="http://lfkdsk.github.io">http://lfkdsk.github.io&lt;/a>&lt;br>
&lt;code>代码地址&lt;/code>： &lt;a href="https://github.com/lfkdsk/CodeParse">https://github.com/lfkdsk/CodeParse&lt;/a>&lt;/p>
&lt;p>本节我们来分析一个能匹配C语言的Lex &amp;amp; Yacc 程序&lt;/p>
&lt;blockquote>
&lt;p>&lt;code>Lex文件&lt;/code>:http://www.lysator.liu.se/c/ANSI-C-grammar-l.html&lt;/p>
&lt;p>&lt;code>Yacc文件&lt;/code>:http://www.lysator.liu.se/c/ANSI-C-grammar-y.html&lt;/p>
&lt;/blockquote>
&lt;p>也可以直接在我的github代码地址中进行下载。&lt;/p>
&lt;h3 id="先来分析lex文件">先来分析Lex文件&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>D			[&lt;span style="color:#ae81ff">0&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">9&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>L			[a&lt;span style="color:#f92672">-&lt;/span>zA&lt;span style="color:#f92672">-&lt;/span>Z_]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>H			[a&lt;span style="color:#f92672">-&lt;/span>fA&lt;span style="color:#f92672">-&lt;/span>F0&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">9&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>E			[Ee][&lt;span style="color:#f92672">+-&lt;/span>]&lt;span style="color:#f92672">?&lt;/span>{D}&lt;span style="color:#f92672">+&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">FS&lt;/span>			(f&lt;span style="color:#f92672">|&lt;/span>F&lt;span style="color:#f92672">|&lt;/span>l&lt;span style="color:#f92672">|&lt;/span>L)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">IS&lt;/span>			(u&lt;span style="color:#f92672">|&lt;/span>U&lt;span style="color:#f92672">|&lt;/span>l&lt;span style="color:#f92672">|&lt;/span>L)&lt;span style="color:#f92672">*&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>首先定义了一些正则式，这些正则的功能都是一目了然的。他们都不是完整的功能性的定义，而是为了下文组装方便的。其中&lt;code>FS&lt;/code> \ &lt;code>IS&lt;/code> 的作用是在数字跟在后面的尾缀（浮点型、无符号、长整形之类的）。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#34;/*&amp;#34;&lt;/span>			{ &lt;span style="color:#a6e22e">comment&lt;/span>(); }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>第16行匹配了C语言的注释开始，并且调用了&lt;code>comment()&lt;/code>函数。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">comment&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#66d9ef">char&lt;/span> c, c1;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>loop:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#66d9ef">while&lt;/span> ((c &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">input&lt;/span>()) &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#e6db74">&amp;#39;*&amp;#39;&lt;/span> &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> c &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#a6e22e">putchar&lt;/span>(c);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#66d9ef">if&lt;/span> ((c1 &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">input&lt;/span>()) &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#e6db74">&amp;#39;/&amp;#39;&lt;/span> &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> c &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#a6e22e">unput&lt;/span>(c1);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#66d9ef">goto&lt;/span> loop;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#66d9ef">if&lt;/span> (c &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		&lt;span style="color:#a6e22e">putchar&lt;/span>(c1);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>comment()&lt;/code>函数只做了一件事就是找到这个注释的结尾以判断这真的是一个注释，因为是注释，函数没有返回值，lex里面也没有对应的调用。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#34;auto&amp;#34;&lt;/span>			{ &lt;span style="color:#a6e22e">count&lt;/span>(); &lt;span style="color:#66d9ef">return&lt;/span>(AUTO); }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#34;break&amp;#34;&lt;/span>			{ &lt;span style="color:#a6e22e">count&lt;/span>(); &lt;span style="color:#66d9ef">return&lt;/span>(BREAK); }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#34;case&amp;#34;&lt;/span>			{ &lt;span style="color:#a6e22e">count&lt;/span>(); &lt;span style="color:#66d9ef">return&lt;/span>(CASE); }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#34;char&amp;#34;&lt;/span>			{ &lt;span style="color:#a6e22e">count&lt;/span>(); &lt;span style="color:#66d9ef">return&lt;/span>(CHAR); }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#34;const&amp;#34;&lt;/span>			{ &lt;span style="color:#a6e22e">count&lt;/span>(); &lt;span style="color:#66d9ef">return&lt;/span>(CONST); }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>18-49行定义了C语言的内置关键字他们都调用了一个&lt;code>count()&lt;/code>返回了一个对应的Token。&lt;/p></description></item><item><title>学习制作一门有趣的编程语言－0x02</title><link>https://blog.lfkdsk.org/make-new-language-2/</link><pubDate>Wed, 01 Jun 2016 12:13:17 +0000</pubDate><guid>https://blog.lfkdsk.org/make-new-language-2/</guid><description>&lt;blockquote>
&lt;p>&lt;code>博客地址&lt;/code>： &lt;a href="http://lfkdsk.github.io">http://lfkdsk.github.io&lt;/a>&lt;br>
&lt;code>代码地址&lt;/code>： &lt;a href="https://github.com/lfkdsk/CodeParse">https://github.com/lfkdsk/CodeParse&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;h3 id="为计算器添加一些新功能">为计算器添加一些新功能&lt;/h3>
&lt;blockquote>
&lt;p>&lt;code>本节代码&lt;/code>：&lt;a href="https://github.com/lfkdsk/CodeParse/tree/master/make_new_language_demo/calc_with_table">CalcWithTable&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;p>上次我们使用Lex &amp;amp; Yacc制作了一个能够处理优先级的计算器，其中的优先级的设定是通过修改文法
，将优先级提升，这次重写这个计算器并添加一些新的功能。&lt;/p>
&lt;h4 id="先看lex文件">先看Lex文件&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-C" data-lang="C">&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">%&lt;/span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;#34;y.tab.h&amp;#34;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;math.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;#34;link_list.h&amp;#34;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">%&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">%%&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#75715e">/* 这段正则和之前都有所不同 明显的增加了对于科学技术法的支持 */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>([&lt;span style="color:#ae81ff">0&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">9&lt;/span>]&lt;span style="color:#f92672">+|&lt;/span>([&lt;span style="color:#ae81ff">0&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">9&lt;/span>]&lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">\&lt;/span>.[&lt;span style="color:#ae81ff">0&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">9&lt;/span>]&lt;span style="color:#f92672">+&lt;/span>)([eE][&lt;span style="color:#f92672">-+&lt;/span>]&lt;span style="color:#f92672">?&lt;/span>[&lt;span style="color:#ae81ff">0&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">9&lt;/span>]&lt;span style="color:#f92672">+&lt;/span>)&lt;span style="color:#f92672">?&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		 &lt;span style="color:#75715e">/* 转换为double类型 */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> yylval.dval &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">atof&lt;/span>(yytext);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/* 我把它打印出来 */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;number : %s &lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>, yytext);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> NUMBER;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[ &lt;span style="color:#960050;background-color:#1e0010">\&lt;/span>t] ;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#75715e">/* 这里提供了对于字母和字母组合的识别 这是对于变量名的识别匹配 */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[A&lt;span style="color:#f92672">-&lt;/span>Za&lt;span style="color:#f92672">-&lt;/span>z][A&lt;span style="color:#f92672">-&lt;/span>Za&lt;span style="color:#f92672">-&lt;/span>z0&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">9&lt;/span>]&lt;span style="color:#f92672">*&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		 &lt;span style="color:#75715e">/* addNode(char *)是link_list.c中的函数 将变量名和对应的参数存储在一个链表中 */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>		 &lt;span style="color:#75715e">/* 返回值为对应的指针 */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> yylval.name &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">addNode&lt;/span>(yytext);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printLink&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">/* 返回的Token指变量名 */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> NAME;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#34;$&amp;#34;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">\&lt;/span>n &lt;span style="color:#f92672">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>. {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> yytext[&lt;span style="color:#ae81ff">0&lt;/span>];
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">%%&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这段代码和之前的区别不大，但是我们明显的为它增加了一个功能，就是识别变量名。&lt;/p></description></item><item><title>学习制作一门有趣的编程语言－0x01</title><link>https://blog.lfkdsk.org/make-new-language-1/</link><pubDate>Fri, 27 May 2016 08:37:20 +0000</pubDate><guid>https://blog.lfkdsk.org/make-new-language-1/</guid><description>&lt;h3 id="熟悉一下lex-和-yacc的用法">熟悉一下Lex 和 Yacc的用法&lt;/h3>
&lt;blockquote>
&lt;p>&lt;code>博客地址&lt;/code>： &lt;a href="http://lfkdsk.github.io">http://lfkdsk.github.io&lt;/a>
&lt;code>代码地址&lt;/code>： &lt;a href="https://github.com/lfkdsk/CodeParse">https://github.com/lfkdsk/CodeParse&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>&lt;code>tips&lt;/code>：阅读此篇需要一定的C语言基础和正则表达式的知识&lt;/p>
&lt;/blockquote>
&lt;p>首先上一篇提到了第一步的工作是要使用 Lex 和 Yacc 进行编写，所以说第一步首先简单的学习一下 Lex &amp;amp; Yacc 的用法，Lex &amp;amp; Yacc 是一套很古老的编译生成套件，大约在上个世纪80年代就有了。但是并不过时，我们今天生成编译程序仍然能够用得上。Lex &amp;amp; Yacc 如果简单的概括来说，Lex 负责词法分析，就是把输入串的纯字符转化为 &lt;code>词法记号流&lt;/code>， 而 Yacc 负责语法分析，将&lt;code>词法记号流&lt;/code>处理成一种树形结构，叫做语法分析树的数据结构中。至此简单来讲的前端工作就基本完成了，代码就有机会被转换成一种&lt;code>三地址代码&lt;/code>的形式，经过&lt;code>优化器&lt;/code>的优化生成机器指令就可以运行在机器中了。&lt;/p>
&lt;blockquote>
&lt;p>&lt;code>词法记号&lt;/code>：一般被称作Token，是指对于输入串的内容进行词素分类，比如说数字、字符串、保留字（关键字）、保留字之间还有不同的 Token&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>&lt;code>三地址代码&lt;/code>：一些语言转换机制的中间形式，每行代码只有三个对象（两个运算分量、一个操作符组成），转换这种形式能够便于机器指令的生成。&lt;/p>
&lt;/blockquote>
&lt;p>刚才说了这么多那Lex &amp;amp; Yacc帮我们做了什么呢？答案是在我们代码的辅助下几乎都做了，首先在前端方面，根据Lex &amp;amp; Yacc 进行了词法和语法分析，在后端代码被直接生成了C语言代码，借助C语言优秀的编译链可以轻松的生成的程序。&lt;/p>
&lt;p>&lt;img src="https://blog.lfkdsk.org/make-new-language-1/parser_page.png" alt="parser_page">&lt;/p>
&lt;h3 id="具体使用">具体使用&lt;/h3>
&lt;p>上面我们介绍了Lex &amp;amp; Yacc的功能，毫无疑问Lex &amp;amp; Yacc是非常完美的编译生成程序，接下来我们来介绍一下Lex &amp;amp; Yacc的用法。&lt;/p>
&lt;blockquote>
&lt;p>&lt;code>推荐书籍&lt;/code>:O&amp;rsquo;Relly出版的 Lex &amp;amp; Yacc 是一本介绍 Lex 和 Yacc功能非常好的书，1994年出版，我在图书馆淘到了2002年的第二版。&lt;/p>
&lt;/blockquote>
&lt;h4 id="lex">Lex:&lt;/h4>
&lt;p>&lt;img src="https://blog.lfkdsk.org/make-new-language-1/lex_page.png" alt="lex_page">&lt;/p>
&lt;p>Lex的使用方法如图所示，分为三个区域：&lt;/p>
&lt;ul>
&lt;li>定义部分：和普通的C语言程序区别不大，存放定义，和在接下来Lex生成的程序中使用的变量和方法的导入。&lt;/li>
&lt;li>规则部分：规则部分起始于&amp;quot;%%&amp;ldquo;符号，终止于&amp;rdquo;%%&amp;ldquo;符号，通过书写正规式匹配文法符号，其中使用C程序处理匹配内容，接收到的符号保存在yytext[]中。&lt;/li>
&lt;li>子程序部分：最后一个%%后面的内容是用户子程序部分，可以包含用C语言编写的子程序，而这些子
程序可以用在前面的动作中，这样就可以达到简化编程的目的。这里需要注意的是，当编译时不带-ll选项时，是必须加入main函数和yywrap（见后文）。&lt;/li>
&lt;/ul>
&lt;p>只说概念不太直观，我们来写一段程序来试验一下，这个程序我们只用到了Lex。&lt;/p>
&lt;p>1.首先是定义区：&lt;/p>
&lt;p>​
​	%{&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;stdio.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">unsigned&lt;/span> charCount &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>, wordCount &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>, lineCount &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">%&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">/* 这里是一个替换的规则 */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">/* 不是 空格、制表符、换行符的非空内容 */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>word [&lt;span style="color:#f92672">^&lt;/span> &lt;span style="color:#960050;background-color:#1e0010">\&lt;/span>t&lt;span style="color:#960050;background-color:#1e0010">\&lt;/span>n]&lt;span style="color:#f92672">+&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>eol &lt;span style="color:#960050;background-color:#1e0010">\&lt;/span>n
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这部分很简单我们导入来C的基础输入输出库，定义了几个全局变量字符数，单词数、行数。
定义了两个规则，第一个代表单词（所有空格、制表符、换行符取反的非空集），一个是输入结束匹配换行符。
2.规则区：&lt;/p></description></item></channel></rss>