<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>编译 on bystander&#39;s blog</title>
    <link>http://blog.leaver.me/tags/%E7%BC%96%E8%AF%91/</link>
    <description>Recent content in 编译 on bystander&#39;s blog</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Thu, 27 Sep 2012 15:55:32 +0000</lastBuildDate>
    <atom:link href="http://blog.leaver.me/tags/%E7%BC%96%E8%AF%91/rss.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>JavaCC入门教程及相关资源</title>
      <link>http://blog.leaver.me/2012/09/27/javacc%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E5%8F%8A%E7%9B%B8%E5%85%B3%E8%B5%84%E6%BA%90/</link>
      <pubDate>Thu, 27 Sep 2012 15:55:32 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/27/javacc%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E5%8F%8A%E7%9B%B8%E5%85%B3%E8%B5%84%E6%BA%90/</guid>
      <description>&lt;p&gt;今天下午翻译了一篇简单的文章后。就去看JavaCC的东西了。。然后就找到了一篇&lt;a href=&#34;http://www.engr.mun.ca/~theo/JavaCC-Tutorial/javacc-tutorial.pdf&#34;&gt;入门教程&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后之前我是找到了一篇翻译过来的的&lt;a href=&#34;https://sites.google.com/site/beariceshome/the-javacc-tutorial&#34;&gt;某熊的战略储备基地&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;从头到尾读了一遍英文的。感觉还是英文的写的要好一些。建议对照着翻译看英文。JavaCC也就那么回事。。&lt;/p&gt;
&lt;p&gt;同时在在这目测百慕大群岛的什么工程与应用科学学院找到了一些其他的文档。其中一篇是&lt;a href=&#34;http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-screen-faq.pdf&#34;&gt;JavaCC-FAQ&lt;/a&gt;很好。基本上有关JavaCC的问题都有解释。&lt;/p&gt;
&lt;p&gt;在FAQ里，看到了一个关于&lt;a href=&#34;http://www.j-paine.org/jjtree.html&#34;&gt;JJTree&lt;/a&gt;的介绍，写的不错。建议看看。&lt;/p&gt;
&lt;p&gt;还有一个是国外某学校的编译原理课程的&lt;a href=&#34;http://scg.unibe.ch/download/lectures/cc/&#34;&gt;ppt下载&lt;/a&gt;，好象是以JavaCC作为工具的。还没认真看。&lt;/p&gt;
&lt;p&gt;还有一篇&lt;a href=&#34;http://www.cnblogs.com/Gavin_Liu/archive/2009/03/07/1405029.html&#34;&gt;JavaCC 研究与应用&lt;/a&gt;    ，写的平常。不过是中文版的。&lt;/p&gt;
&lt;p&gt;最后。千万不要忘了&lt;a href=&#34;http://javacc.java.net/doc/&#34;&gt;官方文档&lt;/a&gt;。也包括你下载的JavaCC里面的Demo。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Eclipse安装JavaCC</title>
      <link>http://blog.leaver.me/2012/09/17/eclipse%E5%AE%89%E8%A3%85javacc/</link>
      <pubDate>Mon, 17 Sep 2012 18:26:35 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/17/eclipse%E5%AE%89%E8%A3%85javacc/</guid>
      <description>&lt;p&gt;　　今年的编译原理课程上机实践是讲这个的。。要求用JavaCC来做一个简单的解释器。今天总算是有点时间找找文档先把这个安装了。安装过程很简单。。&lt;/p&gt;
&lt;p&gt;　　1.希望你已经安装了Eclipse。。。&lt;/p&gt;
&lt;p&gt;　　2.去&lt;a href=&#34;http://sourceforge.net/projects/eclipse-javacc/&#34;&gt;sourceforge&lt;/a&gt;该项目主页下载javaCC压缩包&lt;/p&gt;
&lt;p&gt;　　3.下载完成后解压到你的Eclipse根目录。会提示覆盖plugins和features。直接覆盖即可。&lt;/p&gt;
&lt;p&gt;　　4.测试一下是否成功。具体步骤就是，打开eclipse，新建一个空java项目。然后对着项目点击右键new-&amp;gt;other-&amp;gt;javaCC-&amp;gt;javaCC template file。然后选择命名空间。包名。和文件名就可以了。这个地方的什么的是由你建立的java项目决定的。所以你可以先把java项目设置好，然后直接选就可以了。。&lt;/p&gt;
&lt;p&gt;　　5.点击运行。选择java application。控制台输出　　
　　&lt;pre class=&#34;lang:java decode:true &#34; &gt;Reading from standard input&amp;hellip;　　
　　Enter an expression like &amp;ldquo;1+(2+3)*4;&amp;rdquo;:&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;　　完成。。。&lt;/p&gt;
&lt;p&gt;Update:其实吧。这里安装的是JavaCC的插件。但是已经可以进行开发了。可能你需要一个例子来开始。或者你不喜欢eclipse。那么去&lt;a href=&#34;http://javacc.java.net&#34;&gt;JavaCC&lt;/a&gt;的项目下载你喜欢的即可。我下的是javacc-5.0.zip 里面有例子。可以参考。&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQLServer超时时间已到解决和一套控件库</title>
      <link>http://blog.leaver.me/2012/07/13/sqlserver%E8%B6%85%E6%97%B6%E6%97%B6%E9%97%B4%E5%B7%B2%E5%88%B0%E8%A7%A3%E5%86%B3%E5%92%8C%E4%B8%80%E5%A5%97%E6%8E%A7%E4%BB%B6%E5%BA%93/</link>
      <pubDate>Fri, 13 Jul 2012 08:36:56 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/13/sqlserver%E8%B6%85%E6%97%B6%E6%97%B6%E9%97%B4%E5%B7%B2%E5%88%B0%E8%A7%A3%E5%86%B3%E5%92%8C%E4%B8%80%E5%A5%97%E6%8E%A7%E4%BB%B6%E5%BA%93/</guid>
      <description>&lt;p&gt;　　在最近的一个程序中，因为频繁的操作数据库，莫名的出现了如下的错误：&lt;/p&gt;
&lt;p&gt;　　超时时间已到。超时时间已到，但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用，并且达到了最大池大小。&lt;/p&gt;
&lt;p&gt;　　说明: 执行当前 Web 请求期间，出现未处理的异常。请检查堆栈跟踪信息，以了解有关该错误以及代码中导致错误的出处的详细信息。&lt;/p&gt;
&lt;p&gt;　　异常详细信息: System.InvalidOperationException: 超时时间已到。超时时间已到，但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用，并且达到了最大池大小。&lt;/p&gt;
&lt;p&gt;　　按理说这应该是没有关闭数据库连接或者dataset，可是查了一下。发现都关了啊。遂可以表述为原因不明，但是通过在数据库连接字符串中添加max pool size=512  这个数字可以自己设。就可以了&lt;/p&gt;
&lt;p&gt;　　这篇文章短是短了点。。好吧。那顺带分享一套非常精美的C#控件。
&lt;a href=&#34;http://115.com/file/dptqnr63#RadControls-WinForms-2012-2-608-Dev.msi&#34;&gt;RadControls-For-WinForms 控件2012&lt;/a&gt;
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/24794_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/35b3a6023ad34c4bab5564678dffabbcdd53a5da.jpg&#34; title=&#34;wpf&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;http://115.com/file/e79q6pju#RadControls-for-WPF-2012-2-0607-Dev.msi&#34;&gt;RadControls-for-WPF控件2012&lt;/a&gt;
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/24793_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/c3f1eeb8b01e38643d7ce0d2e2716bba20285943.jpg&#34; title=&#34;winform&#34;&gt;&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>属性文法</title>
      <link>http://blog.leaver.me/2012/06/08/%E5%B1%9E%E6%80%A7%E6%96%87%E6%B3%95/</link>
      <pubDate>Fri, 08 Jun 2012 21:31:13 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/08/%E5%B1%9E%E6%80%A7%E6%96%87%E6%B3%95/</guid>
      <description>&lt;p&gt;　　我们知道，许多编译程序采用属性文法和语法制导翻译方法对语义处理工作进行比较规范和抽象的描述。&lt;/p&gt;
&lt;p&gt;　　而一个属性文法包含一个上下文无关文法和一系列文法规则，语义规则是指：对于文法的每个产生式都配备了一组属性的计算规则&lt;/p&gt;
&lt;p&gt;　　语义规则附在文法的每个产生式上，而语法制导翻译是指在语法分析过程中，完成附加在所使用的产生式上的语义规则描述的动作。&lt;/p&gt;
&lt;p&gt;　　·语法制导：基于语法分析中用到的文法产生式&lt;/p&gt;
&lt;p&gt;　　·翻译：完成语义分析的各项功能，不仅指生成中间代码&lt;/p&gt;
&lt;p&gt;　　形式上讲，一个属性文法是一个三元组，A＝（G，V，F），其中G是一个上下文无关文法；V是有穷的属性集，每个属性与文法的一个终结符或非终结符关联，属性加工的过程即是语义处理的过程。F是关于属性的属性断言或一组属性的计算规则（称为语义规则）。断言或语义规则与一个规则式关联，只引用该规则式左端或右端的终结符或非终结符关联的属性。形式化的东西看看就好，后面给出具体例子分析。&lt;/p&gt;
&lt;p&gt;　　&lt;div&gt;既然称之为属性文法，那么什么属性呢。这些属性代表与文法符号相关信息，比如它的类型、值、代码序列、符号表内容等等。属性与变量一样，可以进行计算和传递。可以类比我们平时写代码时候一些成员变量。。属性又分为综合属性和继承属性。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;　　&lt;div&gt;n在一个属性文法中，对应于每个产生式A→a都有一套与之相关联的语义规则，每条规则的形式为：&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;　　b:=f(c1,c2,…,ck)，只有在已知 c1-ck 值的基础上，才能计算属性值 b， 称属性 b 依赖于属性 c1-ck，至于c1-ck依赖于哪个，就得看由c1-ck在左侧的规则了。也就是看下面的规则了。&lt;/p&gt;
&lt;p&gt;　　这里，f是一个函数，而且或者&lt;/p&gt;
&lt;p&gt;　　1. b是A的一个综合属性并且c1,c2,…,ck是产生式右边文法符号的属性，或者&lt;/p&gt;
&lt;p&gt;　　2. b是产生式右边某个文法符号的一个继承属性并且c1,c2,…,ck 是A或产生式右边任何文法符号的属性。  属性b依赖于属性c1,c2,…,ck。&lt;/p&gt;
&lt;p&gt;　　属性文法中常用记号N·t表示与非终结符号N相关联的属性t。&lt;/p&gt;
&lt;p&gt;　　&lt;div&gt;注意：¨终结符只有综合属性，由词法分析器提供&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;　　&lt;div&gt;¨非终结符既可有综合属性也可有继承属性，文法开始符号的所有继承属性作为属性计算前的初始值&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;　　¨在语法树中，一个结点的综合属性的值由其子结点的属性值确定。一个结点的继承属性由此结点的父结点和/或兄弟结点的某些属性确定&lt;/p&gt;
&lt;p&gt;　　根据包含的属性类型，属性文法分为：S-属性文法和L-属性文法&lt;/p&gt;
&lt;p&gt;　　S-属性文法是仅包括综合属性的属性文法；L -属性文法是包括综合属性和继承属性的属性文法。&lt;/p&gt;
&lt;p&gt;　　给出一个简单的实例说明上面的内容：&lt;/p&gt;
&lt;p&gt;　　&lt;div&gt;考虑非终结符A，B和C，其中，A有一个继承属性a和一个综合属性b，B有综合属性c，C有继承属性d。产生式A→BC可能有规则&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;　　C.d:=B.c+1&lt;/p&gt;
&lt;p&gt;　　A.b:=A.a+B.c&lt;/p&gt;
&lt;p&gt;　　而属性A.a和B.c在其它地方计算&lt;/p&gt;
&lt;p&gt;　　为什么是这样的，因为此时A就是A，B是X1，C是X2，对于d来说，他是产生式右部C的一个属性，c是右部B的属性，属性d依赖于属性c，和1，所以它是C的继承属性，对于c来说，他是产生式右部B的一个属性，但是c不依赖于d，而是d依赖于c所以c属性类型无法确定，对于b，他是A的一个属性，并且a是A的属性，c是产生式右部的属性，所以b是A的综合属性，而对于a，因为不能确定a属性依赖于那个属性，所以。无法得知。从上面我可以得出一个规律，对于一个属性规则来说，一条规则只能确定其左侧的属性类型，而右侧的属性需要由一个由他在左侧的规则来确定。比如，可以看到上面的规则中，c和a都不能确定，就是因为在规则右侧。&lt;/p&gt;
&lt;p&gt;　　此部分可能理解不够深刻，如有错误欢迎指正。&lt;/p&gt;
&lt;p&gt;　　参考：&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://jpkc.hdu.edu.cn/computer/byyl/online/5-2.htm&#34;&gt;http://jpkc.hdu.edu.cn/computer/byyl/online/5-2.htm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://metc.gdut.edu.cn/compile/nandian/n-8.htm&#34;&gt;http://metc.gdut.edu.cn/compile/nandian/n-8.htm&lt;/a&gt;
　　&lt;/p&gt;</description>
    </item>
    <item>
      <title>LR(1)项目集规范簇的构造</title>
      <link>http://blog.leaver.me/2012/06/02/lr1%E9%A1%B9%E7%9B%AE%E9%9B%86%E8%A7%84%E8%8C%83%E7%B0%87%E7%9A%84%E6%9E%84%E9%80%A0/</link>
      <pubDate>Sat, 02 Jun 2012 03:50:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/02/lr1%E9%A1%B9%E7%9B%AE%E9%9B%86%E8%A7%84%E8%8C%83%E7%B0%87%E7%9A%84%E6%9E%84%E9%80%A0/</guid>
      <description>&lt;p&gt;　　首先我们知道LR(0)的项目的形式是[A→α·β ]这样的.而在LR(1)中的项目形式是[A→α·β ，a ]，其中A→α·β 为LR(0)项目，称为心，a为终结符或#，称为向前搜索符。对归约项目[A→α·,a]，仅当前输入符号是a时，才能用A→α进行归约。一会将会看到具体的例子。&lt;/p&gt;
&lt;p&gt;　　课本上给出的规则是：我将要对照着规则来说明，这里要强调一下，&amp;quot;,&amp;lsquo;在这里是分隔符。不是终结符。他是一个标志，&lt;/p&gt;
&lt;p&gt;　　以S′→·S，#属于初始项目集中，把&amp;rsquo;#&amp;lsquo;号作为向前搜索符，表示活前缀为γ(若γ是有关S产生式的某一右部)要归约成S时，必须面临输入符为&amp;rsquo;#&amp;lsquo;号才行。因此对初始项目S′→·S，# 求闭包后再用转换函数逐步求出整个文法的LR(1)项目集族。具体构造步骤如下：&lt;/p&gt;
&lt;p&gt;　(1) 构造LR(1)项目集的闭包函数。&lt;/p&gt;
&lt;p&gt;　　a) I 的任何项目都属于CLOSURE(I)
　　b) 若有项目[A→α·Bβ,a ]属于CLOSURE(I)，B→γ是文法中的产生式，β∈V*，b∈FIRST(βa)， 则[B→·γ,b]也属于CLOSURE(I)中。
　　c) 重复b)直到CLOSURE(I)不再增大为止。&lt;/p&gt;
&lt;p&gt;　　(2) 转换函数的构造&lt;/p&gt;
&lt;p&gt;　　LR(1)转换函数的构造与LR(0)的相似，GO(I,X)＝CLOSURE(J)　其中I是LR(1)的项目集，X是文法符号：
　　J={任何形如[A→αX·β,a]的项目 | [A→α·Xβ,a]∈I}&lt;/p&gt;
&lt;p&gt;　　例如下列文法G′为：&lt;/p&gt;
&lt;p&gt;　　(0) S′→S
　　(1) S→aAd　　
　　(2) S→bAc　　
　　(3) S→aec
　　(4) S→bed
　　(5) A→e　
　　构造他的LR(1)项目集规范簇。&lt;/p&gt;
&lt;p&gt;　　以I0=CLOSURE（S′→·S，#）开始。运算。若有项目[A→α·Bβ,a ]属于CLOSURE(I)，B→γ是文法中的产生式，β∈V*，b∈FIRST(βa)， 则[B→·γ,b]也属于CLOSURE(I)中。此时，我们可以把S看成B，#看成a，然后需要求FIRST集合，此时没有β，a为#，所以FIRST（#）中只有一个b=#，而S有四个产生式。所有四个产生式加上#都是在I0中，最终求得的I0项目集为&lt;/p&gt;
&lt;p&gt;　　{　
　　S′→·S,#　　
　　S→·aAd,#　　
　　S→·bAc,#　　
　　S→·aec,#　　
　　S→·bed,#　　
　　}&lt;/p&gt;
&lt;p&gt;　　然后使用GO函数来构造I1，从J={任何形如[A→αX·β,a]的项目 | [A→α·Xβ,a]∈I}我们可以知道I1的核（最初的产生式）就是这里的J，然后呢。X是I（也就是我们的I0）中的·后面的符号，也就是输入符。。可以看到在I0中，X可以为S，a，b，我们先以I1=GO(I0,S)=CLOSURE( S′→S·,# )，注意，·号已经前进了。因为J是I输入进一的项目，求I1，发现·后面没符号了，所以闭包就是他自己了。最终求得的I1的项目集为：&lt;/p&gt;
&lt;p&gt;　　{S′→S·,# }&lt;/p&gt;
&lt;p&gt;　　我们上一步是用的I1=GO(I0,S)来求得，我们求I2的时候使用GO（I0，a）来求，此时X就是a了。然后我们吧I0中符合的项目中的·后移一位得到J然后对J求闭包，就是I2了。此处J=S→a·Ad,# 和S→a·ec,#&lt;/p&gt;
&lt;p&gt;　　I2=GO(I0,a)=CLOSURE(S→a·Ad,# S→a·ec,#)，然后又回到了求闭包了。&lt;/p&gt;
&lt;p&gt;　　对于S→a·ec,#，因为输入符下一位是一个终结符，也就是说没有B→γ这样的产生式，所以这个就不用继续向下求闭包了，闭包就是他自己嘛。然后关键是S→a·Ad,# 此处的A相当于规则中的B，d相当于规则中的β，A→e存在。为了确定这个心的向前搜索符，我们根据规则需要求b∈FIRST(βa)，这里也就是求First(d#),显然结果为b=d，规则中指出[B→·γ,b]也属于CLOSURE(I)，所以可以确定A→·e,d也在I2中。。&lt;/p&gt;
&lt;p&gt;　　最终I2的项目集为&lt;/p&gt;
&lt;p&gt;　　{
　　S→a·Ad,#　　
　　S→a·ec,#　　
　　A→·e,d　　
　　}&lt;/p&gt;
&lt;p&gt;　　到这里，关键点就说完了。只需要继续求GO(I0,b)，然后求GO（I1，X），GO（I2，X）等等。X的确定前面已经说了，就是I1，I2的·后面的符号。就行了。。当然像此处的I1，·后面已经没付好了，所以GO（I1，X）就不用求了。。&lt;/p&gt;
&lt;p&gt;　　这种东西还是要自己手动练习的。所以我给出最终的全部项目集规范簇，大家按照这个步骤来做一做。看看结果对不对吧。
　　&lt;table border=&#34;1px&#34;  rules=all&gt;&lt;tr&gt;&lt;td&gt;
　  I0： S′→·S,#
　　　 　S→·aAd,#
　　　 　S→·bAc,#
　　　 　S→·aec,#
　　　 　S→·bed,#&lt;/td&gt;&lt;td&gt;
　　I1： S′→S·,#&lt;/td&gt;&lt;td&gt;
　　I2： S→a·Ad,#
　　　 　S→a·ec,#
　　　 　A→·e,d&lt;/td&gt;&lt;td&gt;
　　I3： S→b·Ac,#
　 　　　S→b·ed,#
　 　　　A→·e,c&lt;/td&gt;&lt;tr&gt;&lt;td&gt;
　　I4： S→aA·d,#&lt;/td&gt;&lt;td&gt;
I5： S→ae·c,#
　 　    A→e·,d &lt;/td&gt;&lt;td&gt;
I6： S→bA·c,# &lt;/td&gt;&lt;td&gt;
I7： S→be·d,#
　 　   A→e·,c &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
I8： S→aAd·,# &lt;/td&gt;&lt;td&gt;
I9： S→aec·,# &lt;/td&gt;&lt;td&gt;
I10：S→bAc·,# &lt;/td&gt;&lt;td&gt;
I11：S→bed·,# &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p&gt;　　构造的过程很繁琐。有点暴力计算的意思。不过，真正算起来步骤还是比较少的。&lt;/p&gt;</description>
    </item>
    <item>
      <title>VS2010 编译安装boost库</title>
      <link>http://blog.leaver.me/2012/05/24/vs2010-%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85boost%E5%BA%93/</link>
      <pubDate>Thu, 24 May 2012 11:39:55 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/24/vs2010-%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85boost%E5%BA%93/</guid>
      <description>&lt;p&gt;实践是最好的办法。。学习C++，想试试线程，然后打算用boost库，结果boost库编译差点吓到我。。没看到比较完整的安装教程。。一直耽搁。今天动手。完成了。方法记录如下：
1.下载boost
从boost官网( &lt;a href=&#34;http://www.boost.org&#34;&gt;http://www.boost.org&lt;/a&gt; )上下载最新的boost版本，现在最新是1.49版本，解压到自定义目录(我解压到了D:/program files,最终的目录结构是D:\Program Files\boost_1_49_0)&lt;/p&gt;
&lt;p&gt;2.编译安装&lt;/p&gt;
&lt;p&gt;在D:\Program Files\boost_1_49_0的目录下，有一个bootstrap.bat文件，直接双击运行。就会在同目录生成b2.exe；bjam.exe两个文件。&lt;/p&gt;
&lt;p&gt;3.设定编译环境
修改user-config.jam (D:\Program Files\boost_1_49_0\tools\build\v2\user-config.jam) 的MSVC configuration&lt;/p&gt;
&lt;h1 id=&#34;msvc-configuration&#34;&gt;MSVC configuration&lt;/h1&gt;
&lt;h1 id=&#34;configure-msvc-default-version-searched-for-in-standard-locations-and-path&#34;&gt;Configure msvc (default version, searched for in standard locations and PATH).&lt;/h1&gt;
&lt;h1 id=&#34;using-msvc-&#34;&gt;using msvc ;&lt;/h1&gt;
&lt;p&gt;在上面这段的下面直接添加如下的文字。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;using msvc : 10.0 : :/wd4819/D_CRT_SECURE_NO_DEPRECATE/D_SCL_SECURE_NO_DEPRECATE/D_SECURE_SCL=0 ;&lt;/pre&gt;
&lt;p&gt;保存关闭。&lt;/p&gt;
&lt;p&gt;4.开始编译
点击开始-&amp;gt;所有程序-&amp;gt;“Microsoft Visual Studio 2010”，指向“Visual Studio tools(工具)”，然后单击“Visual Studio 2010 command prompt（命令提示）” 使用cd切换到D:\Program Files\boost_1_49_0目录。这个就不说了
然后输入如下的代码：&lt;/p&gt;
&lt;pre class=&#34;lang:sh decode:true  crayon-selected&#34;&gt;b2 toolset=msvc-10.0 architecture=x86 instruction-set=i686 address-model=32 link=static 
variant=debug,release threading=multi runtime-link=shared --without-python --without-mpi 
--without-wave --without-graph --without-math --without-serialization stage&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;解释一下命令的意思：
1.toolset：表示编译器工具，我安装的是VS2010，所以是msvc-10(如果你是VS2005，可以使用msvc-8.0 VS2008是msvc-9.0)
2.architecture：表示架构，也就是你的CPU架构，x86,x64，因为我安装的是win7 32位，所以使用了x86的架构
3.instruction-set：表示指令集，依然是8086指令集
4.address-model：表示地址长度为32位
5.link：表示生成动态/静态链接库，动态链接库是shared，静态链接库是static，一般都会编译成静态库，因为给出程序的时候打包boost的库会非常庞大
6.variant：表示生成的Debug或者release版本，一般情况下会两种版本都会编译出来的
7.threading：表示单/多线程编译，一般我们的程序都会用到多线程，所以选择了multi
8.runtime-link：表示动态/静态链接C/C++运行时库(C/C++ Runtime)，我们选择了动态链接
9.without/with：表示不需要编译/需要编译哪些库，一些自己不用的库可以无需编译
10.stage/install：stage表示只生成库文件(DLL和Lib)，install还会生成包含头文件的include目录，推荐使用stage，因为boost_1_49\boost中就是boost库完整的头文件，所以无需再拷贝一份出来。编译出来的库会放在stage文件夹中
这样一份完整的boost库就生成了，剩下就是直接使用到项目中了。&lt;/p&gt;
&lt;p&gt;其实编译的具体命令都是可以自己写的。如果你需要编译所有。只需要使用下面的这行代码
b2 &amp;ndash;toolset=msvc-10.0 &amp;ndash;build-type=complete
就可以了。&lt;/p&gt;
&lt;p&gt;不出问题的话。就开始编译了。。登个半个多小时吧。就会完成了。
5.设置vs
打开vs，新建一个工程。然后工程属性。配置属性-&amp;gt;C/C++ ，附加包含目录
填上
D:\Program Files\boost_1_49_0;%(AdditionalIncludeDirectories)
这个是最终的结果，你也可以手动添加&lt;/p&gt;
&lt;p&gt;在左侧选择链接器-&amp;gt;附加库目录，填上
D:\Program Files\boost_1_49_0\stage\lib;%(AdditionalLibraryDirectories)
就可以了。&lt;/p&gt;
&lt;p&gt;6.测试
在你新建的工程里输入如下的代码。运行成功就说明可以了&lt;/p&gt;
&lt;pre class=&#34;lang:c++ decode:true &#34;&gt;#include &amp;lt;boost/thread/thread.hpp&amp;gt;
#include &amp;lt;iostream&amp;gt;

void hello()
{
        std::cout &amp;lt;&amp;lt;
        &#34;Hello world, I&#39;m a thread!&#34;
        &amp;lt;&amp;lt; std::endl;
}

int main(int argc, char* argv[])
{
        boost::thread thrd(&amp;amp;hello);
        thrd.join();
        return 0;
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;参考：
&lt;a href=&#34;http://www.cppfans.org/1317.html&#34;&gt;http://www.cppfans.org/1317.html&lt;/a&gt;
&lt;a href=&#34;http://www.cnblogs.com/ComputerG/archive/2011/03/10/1979730.html&#34;&gt;http://www.cnblogs.com/ComputerG/archive/2011/03/10/1979730.html&lt;/a&gt;
&lt;a href=&#34;http://www.cppblog.com/shaker/archive/2011/11/30/33583.html&#34;&gt;http://www.cppblog.com/shaker/archive/2011/11/30/33583.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>一个简单实例的LR分析过程</title>
      <link>http://blog.leaver.me/2012/05/14/%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E5%AE%9E%E4%BE%8B%E7%9A%84lr%E5%88%86%E6%9E%90%E8%BF%87%E7%A8%8B/</link>
      <pubDate>Mon, 14 May 2012 11:38:49 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/14/%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E5%AE%9E%E4%BE%8B%E7%9A%84lr%E5%88%86%E6%9E%90%E8%BF%87%E7%A8%8B/</guid>
      <description>&lt;p&gt;　　经过前面两篇文章。已经讲清楚了LR语法分析中最重要的分析表的构造过程。先补充一个小问题，就是LR(0)项目的分类&lt;/p&gt;
&lt;p&gt;　　根据圆点所在的位置和圆点后是终结符还是非终结符或为空把项目分为以下几种：&lt;/p&gt;
&lt;p&gt;　　移进项目： 形如 A→α .a β ，a是终结符, a ,b∈V* 以下同
　　待约项目：A→α .B β , 其中B是非终结符　
　　归约项目：A→α . 表明产生式已分析完成。　
　　接受项目：形如 S’→S .　　
　　特别的。A→ε的LR(0)项目只有A→ • 是归约项目&lt;/p&gt;
&lt;p&gt;　　因为LR分析表的构造前面两篇文章已经讲的很清楚了，所以这个题目重要是解释一下如何使用分析表来构造，分析表的构造也许你得自己参考前面两篇文章来构造了。题目来自网络。&lt;/p&gt;
&lt;p&gt;　　好，下面看题目，已知文法G[S]：&lt;/p&gt;
&lt;p&gt;　　(1) S → aAcBe
　　(2) A → b　
　　(3) A → Ab　　
　　(4) B → d&lt;/p&gt;
&lt;p&gt;　　写出对输入串 abbcde#的LR分析 过程。&lt;/p&gt;
&lt;p&gt;　　在分析的时候，因为我们的手工分析，所以还需要一个表来记录我们的步骤。否则记不住啊。该表共需7列。行数不定。做到哪是哪。&lt;/p&gt;
&lt;p&gt;　　&lt;pre lang=&#34;php&#34;&gt; 步骤   符号栈   输入符号栈     动作   状态栈    ACTION    GOTO &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;　　其中，步骤就是从1向下递增。符号栈用来保存运算中的结果，初始为#，输入符号栈保存输入串，初始值为给定的。动作里面就是用来注释是进行移进，还是规约。状态栈就是保持LR分析表的那个状态了。Action 和Goto同理&lt;/p&gt;
&lt;p&gt;　　通过前两篇文章的步骤，此题可以构造出如下的一张LR分析表&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21467_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5b2465bb8d435fab286faf6634217380656ce008.jpg&#34; title=&#34;lr分析表&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　分析表中有Si和rj大家都知道的。s是shift的缩写，也就是移进，r是reduce的缩写，也就是规约。规约是推导的逆操作，大家都懂。&lt;/p&gt;
&lt;p&gt;　　先来看看在进行分析的时候s和j操作的规则&lt;/p&gt;
&lt;p&gt;　　Si:移进，把i移入到状态栈，把a移入到文法符号栈。其中i，j表示状态号。&lt;/p&gt;
&lt;p&gt;　　ri:归约，用第i个产生式归约，同时状态栈与符号栈退出相应个符号，并把GOTO表相应状态和第i个产生式的左部非终结符入栈。&lt;/p&gt;
&lt;p&gt;　　文法中有A→β的产生式，若β的长度为r(即|β|=r)，则从状态栈和文法符号栈中自栈顶向下去掉r个符号，即栈指针P减去r。并把A移入文法符号栈内，Sj=GOTO[Si，A]移进状态栈，其中Si为修改指针后的栈顶状态。&lt;/p&gt;
&lt;p&gt;　　当归约到文法符号栈中只剩文法的开始符号S时，并且输入符号串已结束即当前输入符是&amp;rsquo;#&amp;rsquo;，则为分析成功。&lt;/p&gt;
&lt;p&gt;　　然后使用我们将要使用的辅助表来分析吧，为了简单。我还是直接给出答案。然后分析一下典型的情况。&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21466_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d6565babf03f2f230fb9d8933518bc1cb55bf7cc.jpg&#34; title=&#34;分析结果&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　第一步，符号栈中是#，输入符号串就是给定的要分析的串，状态栈因为从0开始，所以状态栈直接填0，大家都知道，LR分析是从左到右扫描的。所以心里想着一根指针p，p首先指向输入串的a，然后我们查分析表的（0，a）,0就是状态0，a就是指针的当前字符。分析表中的（0，a）是s2，填入第一步的action，并且动作列填入移进，根据规则，将2入状态栈，a入符号栈，&lt;/p&gt;
&lt;p&gt;　　进入第二步，指针p肯定要前进一步了，所以输入符号串就进入b了。此步同上一步，不多解释。&lt;/p&gt;
&lt;p&gt;　　关键是进入第三步后，此时，符号栈中为#ab，输入符号串是bcde#，状态栈是024，此时去查表，差的是（4，b），4是状态栈顶，b是p指针的当前位置。发现是r2，根据规则，用第二条产生式(2) A → b来规约。把动作栏先填了，同时状态栈与符号栈退出相应个符号，也即是说，把状态栏的栈顶4，退出来，同时符号栈的b也退出，心里想着，不填表，并把GOTO表相应状态和第i个产生式的左部非终结符入栈。Goto表需要查的是(2,A)=3,2是r2的2，A是第二个产生式的左部嘛。所以，就把3入状态栈，A入符号栈。&lt;/p&gt;
&lt;p&gt;　　后面的都是一样的。不解释了。要想学懂编译原理。多动手是必需的。你也手工试试吧。&lt;/p&gt;
&lt;p&gt;参考：
　　 &lt;a href=&#34;http://leaver.me/archives/574.html&#34;&gt;http://leaver.me/archives/574.html&lt;/a&gt;
　　 &lt;a href=&#34;http://leaver.me/archives/548.html&#34;&gt;http://leaver.me/archives/548.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>LR(0)和SLR分析表的构造</title>
      <link>http://blog.leaver.me/2012/05/13/lr0%E5%92%8Cslr%E5%88%86%E6%9E%90%E8%A1%A8%E7%9A%84%E6%9E%84%E9%80%A0/</link>
      <pubDate>Sun, 13 May 2012 10:45:13 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/13/lr0%E5%92%8Cslr%E5%88%86%E6%9E%90%E8%A1%A8%E7%9A%84%E6%9E%84%E9%80%A0/</guid>
      <description>&lt;p&gt;　　&lt;a href=&#34;http://leaver.me/archives/548.html&#34;&gt;上篇文章中&lt;/a&gt;，我已经说到了，LR(0)分析表是LR(0)分析器的重要组成部分，它是总控程序分析动作的依据，他是由LR(0)项目集规范族来进行构造的。他的结构主要有两个部分ACTION 和GOTO&lt;/p&gt;
&lt;p&gt;　　先看看指导原则，可以直接跳过，看例题的时候可以返回来对照参考。&lt;/p&gt;
&lt;p&gt;　　假设已构造出LR(0)项目集规范族为：C={I0,I1, … , In}，其中Ik为项目集的名字，k为状态名，令包含S′→·S项目的集合Ik的下标k为分析器的初始状态。那么分析表的ACTION表和GOTO表构造步骤为：&lt;/p&gt;
&lt;p&gt;　　① 若项目A→α·aβ属于Ik且转换函数GO(Ik,a)= Ij，当a为终结符时则置ACTION[k,a]为Sj。　
　　② 若项目A→α· 属于Ik，则对任何终结符a 和&amp;rsquo;#&amp;lsquo;号置ACTION[k,a]和ACTION[k,#]为&amp;quot;rj&amp;quot;，j为在文法G′中某产生式A→α的序号。
　　③ 若GO(Ik,A)＝Ij，则置GOTO[k,A]为&amp;quot;j&amp;quot;，其中A为非终结符。　
　　④ 若项目S′→S·属于Ik，则置ACTION[k,#]为&amp;quot;acc&amp;quot;，表示接受。
　　⑤ 凡不能用上述方法填入的分析表的元素，均应填上&amp;quot;报错标志&amp;quot;。为了表的清晰我们仅用空白表示错误标志。&lt;/p&gt;
&lt;p&gt;　　上篇文章的例题是这样的：LR（0）项目集规范簇也已经算出来了，共有6个I，从I0-I5，最终构造的LR(0)的分析表共7行，包括标题行，也就是ACTION和GOTO，然后是状态行，状态行和ACTION的交处分割成三列，分别是终结符号，和#终结符。也就是分割多少列取决于终结符的数目，GOTO列是非终结符，分割多少列也取决于非终结符的数目。，然后就是具体的6个状态了，画出表的结构后，如下，先不用管表的内容怎么写。&lt;/p&gt;
&lt;p&gt;　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21422_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/0f0ac59f4cab73039ae7f5aecb327def5665da13.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　然后对照构造原则来填写表，这时你会发现要一个个从那么多的GO函数和I项目组中找对应的式子实在太难了，看不清楚，这时候，我们用GO函数把LR(0)项目集规范族连成一个识别该文法所产生的活前缀的DFA，有点像流程图了，首先把各个I项目画出来，然后需要把他们的关系表示出来，关系由GO函数确定，比如I5=GO(I2, S)，则在I2和I5之间画一个箭头，由I2指向I5，线上写上S，由括号里的第二个值确定，此题构造的DFA如下图，很简单吧。&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21397_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34; title=&#34;识别活前缀的DFA&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　&lt;span style=&#34;font-family: Verdana, Arial, Helvetica, sans-serif;&#34;&gt;&lt;span style=&#34;font-size: 12px; line-height: normal;&#34;&gt;然后我们正式开始吧。第一条指导规则说到， 若项目A→α·aβ属于Ik且转换函数GO(Ik,a)= Ij，当a为终结符时则置ACTION[k,a]为Sj，我们先考察对于I0，发现S-&amp;gt;·aS属于I0，且GO(I0,a)=I1,所有我们ACTION[0,a]置为S1.同理S-&amp;gt;·bS属于I0，GO(I0,b)=I2，所以ACTION[0,b]置为S2。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;　　再来看第二条规则，若项目A→α· 属于Ik，则对任何终结符a 和&amp;rsquo;#&amp;lsquo;号置ACTION[k,a]和ACTION[k,#]为&amp;quot;rj&amp;quot;，j为在文法G′中某产生式A→α的序号，也就是说这里的j可不是I项目的标号，而是增广文法&lt;/p&gt;
&lt;p&gt;　　(0)S’→S　
　　(1)S→aS　
　　(2)S→bS
　　(3)S→a&lt;/p&gt;
&lt;p&gt;　　的标号，从0-3啦。我们考察I1，发现S→·aS属于I1，且GO(I1,a)=I1，所以应该置1和a的交的格子为S1，但是此时运用第二条规则会发现S-&amp;gt;a·也属于I1，则又应该置ACTION[1,a]为=r3，ACTION[1,#]为r3，这样就发生了冲突。这是因为大多数文法不能满足LR(0)文法的条件，对于此冲突，我们不能确定看到S-&amp;gt;a的时候是规约还是移进，有些文法是可以直接构造的，为此，此处不能够早LR(0)分析表了，我们构造经过改进后得到了一种新的SLR(1)文法，并没有什么太大差别，主要就是解决冲突。&lt;/p&gt;
&lt;p&gt;　　解决冲突的指导原则如下：&lt;/p&gt;
&lt;p&gt;　* 假设一个LR（0）项目集规范族中有如下项目集合：&lt;/p&gt;
&lt;p&gt;　　{X → α.bβ，A → γ.，B → δ.}&lt;/p&gt;
&lt;p&gt;　　即存在移进-归约冲突和归约-归约冲突&lt;/p&gt;
&lt;p&gt;　　* 如果FOLLOW（A）∩ FOLLOW（B）∩ {b} =ф，则可以如下来解决冲突（假设当前符号是 a ）：　
　　1、若 a = b，则移进
　　2、若 a∈ FOLLOW（A），则用产生式 A → γ归约　
　　3、若 a∈ FOLLOW（B），则用产生式 B → δ归约　
　　4、否则，报错&lt;/p&gt;
&lt;p&gt;　　此处的冲突发生时，当前符号是a，并且此时项目集中无B推导式，且指导规则中的b在此处其实是S-&amp;gt;.aS中的a，所以计算Follow(S)∩ {a} ，发现为空，所以可以解决冲突，因为此时，当前符号是a，此处规则中的b也是a，所以，移进，也就是置ACTION[1,a]为=S1，运用分析表的ACTION表和GOTO表构造步骤的第一步，而不是置为r3，所以冲突解决。&lt;/p&gt;
&lt;p&gt;　　然后再看构造步骤中的第三步，若GO(Ik,A)＝Ij，则置GOTO[k,A]为&amp;quot;j&amp;quot;，其中A为非终结符。此题中，只有S为非终结符，看DFA中的I0，发现GO(I0,S)＝I3，所以置GOTO[0,S]为3，ok&lt;/p&gt;
&lt;p&gt;　　第四个步骤，若项目S′→S·属于Ik，则置ACTION[k,#]为&amp;quot;acc&amp;quot;，很简单，DFA中，I3符合，所以置ACTION[3,#]为&amp;quot;acc&amp;quot;。到此解释完了&lt;/p&gt;
&lt;p&gt;　　反复运用，直到填完表。&lt;/p&gt;
&lt;p&gt;　　完成后的表如图一所示。太复杂了。脑子烧糊了都，下篇有机会的话介绍如何使用来进行分析。其实剩下的部分不怎么难了。应该可以看得懂了&lt;/p&gt;
&lt;p&gt;　　参考：&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://metc.gdut.edu.cn/compile/nandian/n-7.htm&#34;&gt;http://metc.gdut.edu.cn/compile/nandian/n-7.htm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://jpkc.hdu.edu.cn/computer/byyl/online/4-3.htm&#34;&gt;http://jpkc.hdu.edu.cn/computer/byyl/online/4-3.htm&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>LR(0)项目集规范族的构造</title>
      <link>http://blog.leaver.me/2012/05/12/lr0%E9%A1%B9%E7%9B%AE%E9%9B%86%E8%A7%84%E8%8C%83%E6%97%8F%E7%9A%84%E6%9E%84%E9%80%A0/</link>
      <pubDate>Sat, 12 May 2012 10:38:38 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/12/lr0%E9%A1%B9%E7%9B%AE%E9%9B%86%E8%A7%84%E8%8C%83%E6%97%8F%E7%9A%84%E6%9E%84%E9%80%A0/</guid>
      <description>&lt;p&gt;　　此文略长。我也没想到这写起来这么多，但对构造过程绝对清楚，一步步慢慢看吧。&lt;/p&gt;
&lt;p&gt;　　LR的第一个L和LL的第一个L含义相同，即从左到右扫描句子 ，第二个R表示Right most最右推导。&lt;/p&gt;
&lt;p&gt;　　在通常的描述中，后面还有一个括号里面的数字如，LR(0)、LR(1)这样，括号里面的数字表示用于决策所需的后续token分词数。&lt;/p&gt;
&lt;p&gt;　　首先看一下LR分析器的模型图&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21392_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34; title=&#34;LR模型&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　可惜看出，LR分析器最关键的部分就是 LR分析表了，而LR分析表的构建是由已构造出的LR(0)项目集规范族来进行构造的。LR分析法貌似是不要求掌握的，而且这部分比我想象的还要复杂，今天看了好多。才勉强搞清楚这个项目集规范族的构造，但是用来锻炼思维确实不错啊。&lt;/p&gt;
&lt;p&gt;　　项目集，那么字面上看就是项目的集合了，项目是什么呢。这个也确实不好说，书上是说在文法G中每个产生式的右部适当位置添加一个圆点构成LR(0)项目，举个例子吧。&lt;/p&gt;
&lt;p&gt;　　比如对于&lt;/p&gt;
&lt;p&gt;　　A-&amp;gt;xyz&lt;/p&gt;
&lt;p&gt;　　这条产生式可以构造的LR(0)项目就有4个&lt;/p&gt;
&lt;p&gt;　　A-&amp;gt;.xyz    A-&amp;gt;x.yz    A-&amp;gt;xy.z     A-&amp;gt;xyz.&lt;/p&gt;
&lt;p&gt;　　这样很清楚了吧，就是用.分割。这个分割产生的四个项目在进行真正的语法分析的时候对应不同的操作，比如规约还是移位。这里不讨论。重点是项目集规范族的构造，&lt;/p&gt;
&lt;p&gt;　　在知道了LR(0)项目后，可以来看看项目集规范族的定义，&lt;/p&gt;
&lt;p&gt;　　对于构成识别一个文法活前缀的DFA项目集(状态)的全体我们称之为这个文法的LR(0)项目集规范族。至于什么是活前缀呢，定义如下&lt;/p&gt;
&lt;p&gt;　　对于任一文法G[S]，若S’经过任意次推导得到αAω，继续经过一次推导得到![]}/images/6b23dd171a1f672514a2dbb29175df032a1f63d4.gif)αβω，若γ&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;是αβ的前缀，则称γ是G的一个活前缀。&lt;/p&gt;
&lt;p&gt;　　现在知道了LR(0)项目，了解了活前缀，和项目集规范族的定义，还须引入LR(0)项目集的闭包函数CLOSURE和状态转换函数GO两个概念，先给出数学上的定义，如果你觉得麻烦可以跳过，后面会给出一道例题。&lt;/p&gt;
&lt;p&gt;　　① 闭包函数CLOSURE(I)的定义如下：&lt;/p&gt;
&lt;p&gt;　　a）I的项目均在CLOSURE(I)中。&lt;/p&gt;
&lt;p&gt;　　b）若A→α·Bβ属于CLOSURE(I)，则每一形如B→·γ的项目也属于CLOSURE(I)。&lt;/p&gt;
&lt;p&gt;　　c）重复b)直到不出现新的项目为止。即CLOSURE(I)不再扩大。&lt;/p&gt;
&lt;p&gt;　　② 转换函数GO(I，X)的定义：&lt;/p&gt;
&lt;p&gt;　　GO(I，X)＝CLOSURE(J)&lt;/p&gt;
&lt;p&gt;　　其中：I为包含某一项目的状态，就是前面我们说的那四个了。，X为一文法符号，X∈(VN∪VT)，J＝{任何形如A→αX·β的项目| A→α·Xβ属于I}。&lt;/p&gt;
&lt;p&gt;　　这样就可以使用闭包函数和转换函数构造文法G′的LR(0)项目集规范族，其步骤如下：&lt;/p&gt;
&lt;p&gt;　　  a）置项目S′→·S为初态集的核，然后对核求闭包，CLOSURE({S′→·S}）得到初态的项目集。
　　  b）对初态集或其它所构造的项目集应用转换函数GO(I，X)=CLOSURE(J)，求出新状态J的项目集。
　　  c）重复b）直到不出现新的项目为止。&lt;/p&gt;
&lt;p&gt;　　开始拿个例题来说明，定义没例题看起来看难了。&lt;/p&gt;
&lt;p&gt;　　&lt;strong&gt;&lt;em&gt;例题：对于下列文法，S→aS|bS|a，构造该文法的LR(0)项目集规范族&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　思路就是利用闭包函数CLOSURE和转换函数GO来构造。通过计算函数CLOSURE和GO得到文法的LR(0)项目集规范族，而GO函数则把LR(0)项目集规范族连成一个识别该文法所产生的活前缀的DFA。DFA大家都知道，有穷自动机。&lt;/p&gt;
&lt;p&gt;　　(1)将文法G(S)拓广为G(S’)也就是该文法的增广文法，目的是使语法分析器知道何时应该停止并接受该串，也就是说当使用S&amp;rsquo;-&amp;gt;S进行规约的时候，就结束。&lt;/p&gt;
&lt;p&gt;　　(0)S’→S
　　(1)S→aS　　
　　(2)S→bS　　
　　(3)S→a&lt;/p&gt;
&lt;p&gt;　　构造该文法的LR(0)项目集规范族，I就是产生式，至于I0 I1就是往下递增就可以了。没什么特别的意思。：&lt;/p&gt;
&lt;p&gt;　　I0=CLOSURE({S&amp;rsquo; →•S})={S’ →•S, S→•aS, S→•bS, S→•a}&lt;/p&gt;
&lt;p&gt;　　//第一条是固定的，都是求S&amp;rsquo; →•S的闭包。而因为右侧的S又可以推导出后面三个，所以后面三个式子是属于该闭包的。在闭包的规则中可以看出，若A→α·Bβ属于CLOSURE(I)，此时S&amp;rsquo; →•S属于闭包，S相当于规则中的B,则每一形如B→·γ的项目也属于CLOSURE(I),此处相当于S-&amp;gt;后面的三个推导式。加上.就可以了&lt;/p&gt;
&lt;p&gt;　　I1=GO( I0 , a)=CLOSURE({S→a•S , S→a•})={S→a•S , S→a• , S→•aS, S→•bS, S→•a }&lt;/p&gt;
&lt;p&gt;　　//第二条你可能已经看出来了，其实就是把转换函数GO反过来用，在GO函数中，X为一文法符号，J＝{任何形如A→αX·β的项目| A→α·Xβ属于I}。也就是在I0中，找到右侧包含a的项目，然后将.右移一位来求他们的闭包函数，此处，I0中包含.a的项目为 S→•aS和 S→•a，.右移一位变成S→a•S , S→a•，求闭包函数的规则和上面那条是一样的，继续找推导式右边可以推导出来的式子就可以了，此处，右边同样是S可以推导出三个式子，前面加上.就可以了。&lt;/p&gt;
&lt;p&gt;　　I2=GO(I0 , b)=CLOSURE({S→b•S })={ S→b•S, S→•aS, S→•bS, S→•a }&lt;/p&gt;
&lt;p&gt;　　//第三条仿照第二条进行推导，先在I0中找有.b的，然后右移一位，然后推导式右侧的S继续用题目给出的推导，然后前面加上.&lt;/p&gt;
&lt;p&gt;　　I3=GO(I0 , S)=CLOSURE({S’ →S•})={ S’ →S•}&lt;/p&gt;
&lt;p&gt;　　//第四条因为右侧包含.S的只有一项。必须是.S。所以只有一个，右移后求闭包即可。因为S是右侧的第一位，所以不用再向下推导了，规则是：A→α·Bβ属于CLOSURE(I)，此处是S’ →S•，则B→·γ的项目也属于CLOSURE(I)，此处S相当于规则中的α，无B。。。。&lt;/p&gt;
&lt;p&gt;　　因为GO(I1, a)=CLOSURE({S→a•S , S→a•})=I1，&lt;/p&gt;
&lt;p&gt;　　//第五条同理，在I1中找有右侧有.a的项目，右移一位。进行求闭包，发现和I1求闭包的变量是一样的。所以结果必然也和I1是一样的。&lt;/p&gt;
&lt;p&gt;　　GO(I1, b)=CLOSURE(S→b•S)=I2.&lt;/p&gt;
&lt;p&gt;　　//第六条没有新的I产生。&lt;/p&gt;
&lt;p&gt;　　I4=GO(I1, S)=CLOSURE({S→aS•})={S→aS•}&lt;/p&gt;
&lt;p&gt;　　//这第七条在I1找右侧包含.S的项目，只有S→a•S，右移后求闭包，同第四条，无B，所以直接如此。&lt;/p&gt;
&lt;p&gt;　　GO(I2, a)= CLOSURE({S→a•S , S→a•})=I1&lt;/p&gt;
&lt;p&gt;　　GO(I2, b)=CLOSURE({S→b•S})=I2&lt;/p&gt;
&lt;p&gt;　　I5=GO(I2, S)=CLOSURE({S→bS•})={S→bS•}&lt;/p&gt;
&lt;p&gt;　　此时应该继续求GO(I3, a)，GO(I3, b)和，GO(I3, S)，但显然I3中没有.a,没有.b也没有.S，所以不用多此一举了，&lt;/p&gt;
&lt;p&gt;　　继续求GO(I4, a)，GO(I4, b)和，GO(I4, S)，显然同上，也没有。所以也不用求了，&lt;/p&gt;
&lt;p&gt;　　继续求GO(I5, a)，GO(I5, b)和，GO(I5, S),理由同上，没有任何必要了&lt;/p&gt;
&lt;p&gt;　　最终，项目集I0，I1，I2，I3，I4和I5构成了该文法的LR(0)项目集规范族。&lt;/p&gt;
&lt;p&gt;　　编译原理真是博大精深啊。就一个简单的三个推导式就得这么多步骤才构造了一个规范族，还要利用规范族来构造LR分析表，这。。手工果断不是事啊。今天看了几个小时才完全弄清楚LR(0)项目集规范族的构造。例题的步骤是我自己写的。这篇文章写了2个小时。。太费脑子了。。慢慢再写产生活前缀的DFA和LR分析表吧。&lt;/p&gt;
&lt;p&gt;　　参考：&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://metc.gdut.edu.cn/compile/nandian/n-7.htm&#34;&gt;http://metc.gdut.edu.cn/compile/nandian/n-7.htm&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>正规式-&gt;最小化DFA说明</title>
      <link>http://blog.leaver.me/2012/04/25/%E6%AD%A3%E8%A7%84%E5%BC%8F-%E6%9C%80%E5%B0%8F%E5%8C%96dfa%E8%AF%B4%E6%98%8E/</link>
      <pubDate>Wed, 25 Apr 2012 17:38:42 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/25/%E6%AD%A3%E8%A7%84%E5%BC%8F-%E6%9C%80%E5%B0%8F%E5%8C%96dfa%E8%AF%B4%E6%98%8E/</guid>
      <description>&lt;p&gt;　　今天早上去图书馆，去看编译原理，想把这部分搞清楚，看着龙书+国产的某一本不知什么的习题与解析，猜过程。。猜原理。。终于是看懂了。。
整体的步骤是三步：
一，先把正规式转换为NFA（非确定有穷自动机）,
二，在把NFA通过“子集构造法”转化为DFA，
三，在把DFA通过“分割法”进行最小化。&lt;/p&gt;
&lt;p&gt;　　　**一步很简单，就是反复运用下图的规则，**图1
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20920_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/6807123f3c419d9d4ae9c8bc7833f940ddd2cd83.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　这样就能转换到NFA了。
给出一个例题，来自Google book。本文主要根据这个例题来讲，图2
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20924_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1816f6c4b5eac34b7a8ee5a44400ea8ace103722.jpg&#34;&gt;&lt;/a&gt;
　　　&lt;strong&gt;二.子集构造法。&lt;/strong&gt;
同样的例题，把转换好的NFA确定化，图3
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20921_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/29683c76cbf62ad4420a384cdb4a6902818d49db.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　这个表是从NFA到DFA的时候必须要用到的。第一列第一行I的意思是从NFA的起始节点经过任意个ε所能到达的结点集合。Ia表示从该集合开始经过一个a所能到达的集合，经过一个a的意思是可以略过前后的ε。同样Ib也就是经过一个b，可以略过前后任意个ε。
至于第二行以及后面的I是怎么确定的。我参考了一些题目才明白，原来就是看上面的Ia和Ib哪个还没出现在I列，就拿下来进行运算，该列对应的Ia和Ib就是前面我说的那样推导。&lt;/p&gt;
&lt;p&gt;　　如果还不太明白，看图就是了。你会发现I中的几个项目都在Ia和Ib中出现了。而且是完全出现&lt;/p&gt;
&lt;p&gt;　　这步做完以后，为了画出最后的DFA，那么肯定得标出一些号来，比如1.2.3.。或者A。 B。c，我一般标的方法是先把I列全部标上1.2.3.递增。然后看1表示的集合和Ia和Ib中的哪个集合一样，就把那个集合也表示为1.继续向下做。最后会得到这样一个表格。图4
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20922_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/cfd89b33da236d53885bb7ff781a33633c15e072.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　至此，就可以表示出DFA了。就对照上面那个表，从0节点开始经过a到1.经过b到2，就这样画就行了。。&lt;/p&gt;
&lt;p&gt;　　最后的DFA如下图，图5
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20925_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/26ef020ce54f209ce93f988ab6af15e1daf0f131.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　双圈的表示终态，这个是怎么来的呢。去看看图4，会发现有些项之前有双圈标志，这个是因为在NFA图2中，9为终态，所以所有包含9的集合都被认为是终态集，改成1.2.3.。。方便画节点后就需要把这些点作为终态了。。&lt;/p&gt;
&lt;p&gt;　　　&lt;strong&gt;三.最小化，分割法。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;FA的最小化就是寻求最小状态DFA&lt;/p&gt;
&lt;p&gt;　　最小状态DFA的含义:
1.没有多余状态(死状态)2. 没有两个状态是互相等价（不可区别）
两个状态s和t等价的条件：
兼容性（一致性）条件——同是终态或同是非终态
传播性（蔓延性）条件——从s出发读入某个a和从t出发经过某个a并且经过某个b到达的状态等价。就是相同。&lt;/p&gt;
&lt;p&gt;　　DFA的最小化—例子，第一步都是固定的。分成终态和非终态&lt;/p&gt;
&lt;p&gt;１．将Ｍ的状态分为两个子集一个由终态k1=｛Ｃ，Ｄ，Ｅ，Ｆ｝组成，一个由非终态k2=｛Ｓ，Ａ，Ｂ｝组成，&lt;/p&gt;
&lt;p&gt;２．考察｛Ｓ，Ａ，Ｂ｝是否可分．&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20927_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/4bf93ce8a42fb3161b1d288da5697a5745effc23.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;因为Ａ经过a到达C属于k1.而S经过a到达A属于k2.B经过a到达A属于k2，所以K2继续划分为{S，B},{A},&lt;/p&gt;
&lt;p&gt;３．考察｛Ｓ，Ｂ｝是否可再分：&lt;/p&gt;
&lt;p&gt;B经过b到达D属于k1.S经过b到达B属于k2，所以S，B可以划分。划分为{S},{B}&lt;/p&gt;
&lt;p&gt;４．考察｛Ｃ，Ｄ，Ｅ，Ｆ｝是否可再分：
因为Ｃ，Ｄ，Ｅ，Ｆ经过a和b到达的状态都属于｛Ｃ，Ｄ，Ｅ，Ｆ｝=k1所以相同，所以不可再分：&lt;/p&gt;
&lt;p&gt;５．｛Ｃ，Ｄ，Ｅ，Ｆ｝以｛Ｄ｝来代替则，因为CDEF相同，你也可以用C来代替。无所谓的最小化的ＤＦＡ如图，：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20928_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/573e265f308413f9398a0f05b240403b07cff10f.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;真麻烦啊。。心里清楚，还得找些图来说明。。额。。基本上感觉自己讲清楚了。。。不清楚的地方。。请留言互相讨论。。谢谢。。&lt;/p&gt;
&lt;p&gt;参考：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.worldcat.org/title/bian-yi-yuan-li-xue-xi-fu-dao/oclc/302301738&#34;&gt;http://www.worldcat.org/title/bian-yi-yuan-li-xue-xi-fu-dao/oclc/302301738&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://metc.gdut.edu.cn/compile/cmpl3/3-3.htm&#34;&gt;http://metc.gdut.edu.cn/compile/cmpl3/3-3.htm&lt;/a&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
