LR(1)项目集规范簇的构造

 首先我们知道LR(0)的项目的形式是[A→α·β ]这样的.而在LR(1)中的项目形式是[A→α·β ,a ],其中A→α·β 为LR(0)项目,称为心,a为终结符或#,称为向前搜索符。对归约项目[A→α·,a],仅当前输入符号是a时,才能用A→α进行归约。一会将会看到具体的例子。 课本上给出的规则是:我将要对照着规则来说明,这里要强调一下,",‘在这里是分隔符。不是终结符。他是一个标志, 以S′→·S,#属于初始项目集中,把’#‘号作为向前搜索符,表示活前缀为γ(若γ是有关S产生式的某一右部)要归约成S时,必须面临输入符为’#‘号才行。因此对初始项目S′→·S,# 求闭包后再用转换函数逐步求出整个文法的LR(1)项目集族。具体构造步骤如下: (1) 构造LR(1)项目集的闭包函数。 a) I 的任何项目都属于CLOSURE(I) b) 若有项目[A→α·Bβ,a ]属于CLOSURE(I),B→γ是文法中的产生式,β∈V*,b∈FIRST(βa), 则[B→·γ,b]也属于CLOSURE(I)中。 c) 重复b)直到CLOSURE(I)不再增大为止。 (2) 转换函数的构造 LR(1)转换函数的构造与LR(0)的相似,GO(I,X)=CLOSURE(J) 其中I是LR(1)的项目集,X是文法符号: J={任何形如[A→αX·β,a]的项目 | [A→α·Xβ,a]∈I} 例如下列文法G′为: (0) S′→S (1) S→aAd (2) S→bAc (3) S→aec (4) S→bed (5) A→e 构造他的LR(1)项目集规范簇。 以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项目集为 { S′→·S,# S→·aAd,# S→·bAc,# S→·aec,# S→·bed,# } 然后使用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的项目集为: {S′→S·,# } 我们上一步是用的I1=GO(I0,S)来求得,我们求I2的时候使用GO(I0,a)来求,此时X就是a了。然后我们吧I0中符合的项目中的·后移一位得到J然后对J求闭包,就是I2了。此处J=S→a·Ad,# 和S→a·ec,# I2=GO(I0,a)=CLOSURE(S→a·Ad,# S→a·ec,#),然后又回到了求闭包了。 对于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中。。 最终I2的项目集为 { S→a·Ad,# S→a·ec,# A→·e,d } 到这里,关键点就说完了。只需要继续求GO(I0,b),然后求GO(I1,X),GO(I2,X)等等。X的确定前面已经说了,就是I1,I2的·后面的符号。就行了。。当然像此处的I1,·后面已经没付好了,所以GO(I1,X)就不用求了。。 这种东西还是要自己手动练习的。所以我给出最终的全部项目集规范簇,大家按照这个步骤来做一做。看看结果对不对吧。 I0: S′→·S,# S→·aAd,# S→·bAc,# S→·aec,# S→·bed,# I1: S′→S·,# I2: S→a·Ad,# S→a·ec,# A→·e,d I3: S→b·Ac,# S→b·ed,# A→·e,c I4: S→aA·d,# I5: S→ae·c,# A→e·,d I6: S→bA·c,# I7: S→be·d,# A→e·,c I8: S→aAd·,# I9: S→aec·,# I10:S→bAc·,# I11:S→bed·,# 构造的过程很繁琐。有点暴力计算的意思。不过,真正算起来步骤还是比较少的。

2012-06-02 · 1 min · bystander

比较HE和Think Aloud可用性测试

首先,HE和Think Aloud 都是两用可用性测试的方法,HE,也就是这个启发式评估可以在设计的早期阶段(比如草稿)就开始使用,并且不需要太多的其他步骤。而Think Aloud则更多建立在已经设计出来的原型系统上。需要更多的步骤。这两个各有利弊。互相协作。才能更好嘛,有些问题,HE可以发现,有些则只有Think Aloud可以发现。 1.Many Usability Aspects Identified in HE are Confirmed in Think-Aloud Usability Tests 许多可用性方面的问题可以在HE中识别。然后在Think Aloud测试中被确认。 2.When HE Predictions are not Confirmed by Think-Aloud Usability Tests 当HE预测了问题但是Think Aloud中,并没有发现。这种情况下。请相信Think Aloud测试。因为用户是王道。数据比预测更准确。 3.“False Alarms” vs. True Problems 假警告vs真问题,这个举个例子,在对话框中,有三个按钮。OK ,Apply和Cancel ,虽然HE规则预测了这个迷惑性。但是进行Think Aloud测试的时候,并没有这个问题,原因是用户就没想过这个事,他只按ok,但这并不能避免问题,或者说似乎这个问题并不是个问题,还有一种情况,比如HE规则中的文档帮助的问题,可能用户在测试的时候就没打开文档。这就需要HE来评估了。所以,这种情况下,还是应该好好分析一下HE给出的评估来改进系统。 4.Think-Aloud Usability Tests Can Show Things HEs Can’t Show Think Aloud测试可以展示HE没有发现的问题。 HE规则因为是建立在早期草稿原型上的。并不是真实情况,他只是在早期给出设计上的问题,他不能预测真实系统的问题,比如程序运行速度非常慢,以至于用户难以忍受。这就需要Think Aloud才能发现了。 基本上SSD4就讲了这么些东西了。四篇文章四点写到7点。。基本上算是写完了。工科男求安慰。。

2012-05-29 · 1 min · bystander

Think-Aloud 可用性测试介绍

中文是指出声思考:出声思考。可用性测试中常用也很有用的一个数据收集方法,来改善产品。要求被测试者把在测试过程中即时的把自己的想法大声说出来。比如,你说我不知道干什么,这个好像有点问题,等等。然后有人来记录。 SSD4给出的具体步骤翻译添加解释如下: Define the study’s framework, 定义该测试报告的框架。比如系统准备解决什么问题,适合什么类型的用户,希望评估首次使用还是其他什么,希望最终的目标是什么,比如希望90%的用户可以初次顺利使用。 Choose what to observe, 选择打算观察测试者的什么行为,比如用户如何打开,先干了什么 Prepare for the think-aloud usability test, 为测试做准备,比如模拟真实情景,写个流程。开个会,招募实验人员。 Introduce the participants to the observation procedure, 给实验人员介绍步骤。抚慰一下他们的情绪。告诉他们目的,并且希望他们think aloud。 Conduct the observation, 进行观察 Analyze the observation, 分析观察结果 。 Find possible redesigns, 找到可能需要进行重新设计的地方 Write a report. 写个总结报告出来。完成 这不也就这样嘛。

2012-05-29 · 1 min · bystander

UAR报告的简单说明

UAR报告由以下几个部分构成。就这个例子简单说一下。 Example UAR — Time Zone ListBox Is Not Good //标题 UAR Identifier //问题编号,从1开始,每个问题都这样的格式来说明,就构成了UAR报告 HE18—Problem //后面这个problem表示有问题,也可以是Good,表示这部分很好。没问题。 Succinct description: //简短的描述 Time Zone pull-down ListBox provides too much irrelevant information. Evidence for the aspect: //违反了哪条规则,共有十条规则。 Heuristic: Aesthetics and minimalist design **Interface aspect: ** The pull-down ListBox has 50 lines of information—in very small font. There are many competing items of information to visually search, the vast majority of which are irrelevant to any one user’s particular task of finding a single desired time zone [![](/images/ "uar")](http://seqcc.icarnegie.com/content/SSD/SSD4/3.1/normal/pg-creatng-evaltng-interfaces/pg-crt-eval-list-combo/pg-he-clean-beauty/Ex5.png)In addition, the information is structured as follows:The string "[GMT " begins each line (which means Greenwich Mean Time). If the time zone is behind GMT, then a "-" indicates this fact, which is followed by the number of hours and minutes the time zone is behind GMT. If the time zone is ahead of GMT, a "+" is used instead. Finally, some words follow the GMT offset, which are either city or country names, or the names of regions.  The presentation of this structured information violates the aesthetics and minimalist design heuristic because the structure is not preserved visually from item to item. For example, the words are not always lined up vertically; see the entries for: ...

2012-05-29 · 3 min · bystander

10条可用性准则(Heuristics)

SSD4第二单元其实就讲了这么一点东西,包括一点VB的控件常识 可用性测试(Usability testing),是一项通过用户的使用来评估产品的技术,由于它反应了用户的真实使用经验,所以可以视为一种不可或缺的可用性检验过程[1]。也就是说,可用性测试是指让用户使用产品(服务)的设计原型或者成品,通过观察,记录和分析用户的行为和感受,以改善产品(服务)可用性的一系列方法。它适用于产品(服务)前期设计开发,中期改进和后期维护完善的各个阶段,是用户中心设计的思想的重要体现。 10条可用性准则(Heuristics) These are ten general principles for user interface design. They are called “heuristics” because they are more in the nature of rules of thumb than specific usability guidelines. 1.Visibility of system status——系统状态的可见性 The system should always keep users informed about what is going on, through appropriate feedback within reasonable time. 系统应该始终在合理的时间以适当的反馈信息让用户知道系统正在做什么。 2.Match between system and the real world——系统和现实世界之间的吻合 The system should speak the users’ language, with words, phrases and concepts familiar to the user, rather than system-oriented terms. Follow real-world conventions, making information appear in a natural and logical order. 系统应该用用户熟悉的词,短语和概念来说用户的语言,而不是用面向系统的术语。遵循现实世界中的惯例,让信息以自然的合乎逻辑的次序展现在用户面前。 3.User control and freedom——用户控制和自由 Users often choose system functions by mistake and will need a clearly marked “emergency exit” to leave the unwanted state without having to go through an extended dialogue. Support undo and redo. 用户经常错误地选择系统功能,所以在不需要查看由于误操作而延伸出来地对话的情况下有一个明显地标志为“紧急退出”的操作来离开不想要的状态。另外,系统需要支持“撤销操作”和“重做”的功能。 4.Consistency and standards——一致性和标准 Users should not have to wonder whether different words, situations, or actions mean the same thing. Follow platform conventions. ...

2012-05-29 · 2 min · bystander

快速排序算法

#include using namespace std; //化分区间,找到最后元素的排序位置。并返回分隔的点(即最后一数据排序的位置)。 //划分的区间是[nBegin, nEnd). pData是保存数据的指针 int Partition(int* pData, int nBeging, int nEnd) { int i = nBeging - 1; //分隔符号,最后nD保存在这里 --nEnd; int nD = pData[nEnd]; //比较的数据。 int nTemp; // 交换用的临时数据 //遍历数据比较,找到nD的位置,这里注意,比较结果是, //i的左边是小于等于nD的,i的右边是大于nD的 for (int j = nBeging; j < nEnd; ++j) { if (pData[j] <= nD) //如果数据比要比较的小,则在该数据的左边,与i+1交换 { ++i; //小于nD的数据多一个,所以要加1,i的左边数据都比nD小 nTemp = pData[i]; //交换数据 pData[i] = pData[j]; pData[j] = nTemp; } } //最后不要忘了吧nD和i+1交换,因为这里就是nD的位置咯。 ++i; pData[nEnd] = pData[i]; pData[i] = nD; return i; //返回nD的位置,就是分割的位置。 } //排序的递归调用。 int QuickSortRecursion(int* pData, int nBeging, int nEnd) { if (nBeging >= nEnd -1) //如果区域不存在或只有一个数据则不递归排序 { return 1; } //这里因为分割的时候,分割点处的数据就是排序中他的位置。 //也就是说他的左边的数据都小于等于他,他右边的数据都大于他。 //所以他不在递归调用的数据中。 int i = Partition(pData, nBeging, nEnd); //找到分割点 QuickSortRecursion(pData, nBeging, i); //递归左边的排序 QuickSortRecursion(pData, i + 1, nEnd); //递归右边的排序 return 1; } //快速排序 int QuickSort(int* pData, int nLen) { //递归调用,快速排序。 QuickSortRecursion(pData, 0, nLen); return 1; } int main() { int nData[10] = {5,9,3,2,1,6,20,45,88,75}; //测试数据 QuickSort(nData, 10); //调用快速排序 for (int i = 0; i < 10; ++i) //输出结果 { cout<

2012-05-19 · 1 min · bystander

LR(0)和SLR分析表的构造

 上篇文章中,我已经说到了,LR(0)分析表是LR(0)分析器的重要组成部分,它是总控程序分析动作的依据,他是由LR(0)项目集规范族来进行构造的。他的结构主要有两个部分ACTION 和GOTO 先看看指导原则,可以直接跳过,看例题的时候可以返回来对照参考。 假设已构造出LR(0)项目集规范族为:C={I0,I1, … , In},其中Ik为项目集的名字,k为状态名,令包含S′→·S项目的集合Ik的下标k为分析器的初始状态。那么分析表的ACTION表和GOTO表构造步骤为: ① 若项目A→α·aβ属于Ik且转换函数GO(Ik,a)= Ij,当a为终结符时则置ACTION[k,a]为Sj。 ② 若项目A→α· 属于Ik,则对任何终结符a 和’#‘号置ACTION[k,a]和ACTION[k,#]为"rj",j为在文法G′中某产生式A→α的序号。 ③ 若GO(Ik,A)=Ij,则置GOTO[k,A]为"j",其中A为非终结符。 ④ 若项目S′→S·属于Ik,则置ACTION[k,#]为"acc",表示接受。 ⑤ 凡不能用上述方法填入的分析表的元素,均应填上"报错标志"。为了表的清晰我们仅用空白表示错误标志。 上篇文章的例题是这样的:LR(0)项目集规范簇也已经算出来了,共有6个I,从I0-I5,最终构造的LR(0)的分析表共7行,包括标题行,也就是ACTION和GOTO,然后是状态行,状态行和ACTION的交处分割成三列,分别是终结符号,和#终结符。也就是分割多少列取决于终结符的数目,GOTO列是非终结符,分割多少列也取决于非终结符的数目。,然后就是具体的6个状态了,画出表的结构后,如下,先不用管表的内容怎么写。 然后对照构造原则来填写表,这时你会发现要一个个从那么多的GO函数和I项目组中找对应的式子实在太难了,看不清楚,这时候,我们用GO函数把LR(0)项目集规范族连成一个识别该文法所产生的活前缀的DFA,有点像流程图了,首先把各个I项目画出来,然后需要把他们的关系表示出来,关系由GO函数确定,比如I5=GO(I2, S),则在I2和I5之间画一个箭头,由I2指向I5,线上写上S,由括号里的第二个值确定,此题构造的DFA如下图,很简单吧。 然后我们正式开始吧。第一条指导规则说到, 若项目A→α·aβ属于Ik且转换函数GO(Ik,a)= Ij,当a为终结符时则置ACTION[k,a]为Sj,我们先考察对于I0,发现S->·aS属于I0,且GO(I0,a)=I1,所有我们ACTION[0,a]置为S1.同理S->·bS属于I0,GO(I0,b)=I2,所以ACTION[0,b]置为S2。 再来看第二条规则,若项目A→α· 属于Ik,则对任何终结符a 和’#‘号置ACTION[k,a]和ACTION[k,#]为"rj",j为在文法G′中某产生式A→α的序号,也就是说这里的j可不是I项目的标号,而是增广文法 (0)S’→S (1)S→aS (2)S→bS (3)S→a 的标号,从0-3啦。我们考察I1,发现S→·aS属于I1,且GO(I1,a)=I1,所以应该置1和a的交的格子为S1,但是此时运用第二条规则会发现S->a·也属于I1,则又应该置ACTION[1,a]为=r3,ACTION[1,#]为r3,这样就发生了冲突。这是因为大多数文法不能满足LR(0)文法的条件,对于此冲突,我们不能确定看到S->a的时候是规约还是移进,有些文法是可以直接构造的,为此,此处不能够早LR(0)分析表了,我们构造经过改进后得到了一种新的SLR(1)文法,并没有什么太大差别,主要就是解决冲突。 解决冲突的指导原则如下: * 假设一个LR(0)项目集规范族中有如下项目集合: {X → α.bβ,A → γ.,B → δ.} 即存在移进-归约冲突和归约-归约冲突 * 如果FOLLOW(A)∩ FOLLOW(B)∩ {b} =ф,则可以如下来解决冲突(假设当前符号是 a ): 1、若 a = b,则移进 2、若 a∈ FOLLOW(A),则用产生式 A → γ归约 3、若 a∈ FOLLOW(B),则用产生式 B → δ归约 4、否则,报错 此处的冲突发生时,当前符号是a,并且此时项目集中无B推导式,且指导规则中的b在此处其实是S->.aS中的a,所以计算Follow(S)∩ {a} ,发现为空,所以可以解决冲突,因为此时,当前符号是a,此处规则中的b也是a,所以,移进,也就是置ACTION[1,a]为=S1,运用分析表的ACTION表和GOTO表构造步骤的第一步,而不是置为r3,所以冲突解决。 然后再看构造步骤中的第三步,若GO(Ik,A)=Ij,则置GOTO[k,A]为"j",其中A为非终结符。此题中,只有S为非终结符,看DFA中的I0,发现GO(I0,S)=I3,所以置GOTO[0,S]为3,ok 第四个步骤,若项目S′→S·属于Ik,则置ACTION[k,#]为"acc",很简单,DFA中,I3符合,所以置ACTION[3,#]为"acc"。到此解释完了 反复运用,直到填完表。 完成后的表如图一所示。太复杂了。脑子烧糊了都,下篇有机会的话介绍如何使用来进行分析。其实剩下的部分不怎么难了。应该可以看得懂了 参考: http://metc.gdut.edu.cn/compile/nandian/n-7.htm http://jpkc.hdu.edu.cn/computer/byyl/online/4-3.htm

2012-05-13 · 1 min · bystander

LR(0)项目集规范族的构造

 此文略长。我也没想到这写起来这么多,但对构造过程绝对清楚,一步步慢慢看吧。 LR的第一个L和LL的第一个L含义相同,即从左到右扫描句子 ,第二个R表示Right most最右推导。 在通常的描述中,后面还有一个括号里面的数字如,LR(0)、LR(1)这样,括号里面的数字表示用于决策所需的后续token分词数。 首先看一下LR分析器的模型图 可惜看出,LR分析器最关键的部分就是 LR分析表了,而LR分析表的构建是由已构造出的LR(0)项目集规范族来进行构造的。LR分析法貌似是不要求掌握的,而且这部分比我想象的还要复杂,今天看了好多。才勉强搞清楚这个项目集规范族的构造,但是用来锻炼思维确实不错啊。 项目集,那么字面上看就是项目的集合了,项目是什么呢。这个也确实不好说,书上是说在文法G中每个产生式的右部适当位置添加一个圆点构成LR(0)项目,举个例子吧。 比如对于 A->xyz 这条产生式可以构造的LR(0)项目就有4个 A->.xyz A->x.yz A->xy.z A->xyz. 这样很清楚了吧,就是用.分割。这个分割产生的四个项目在进行真正的语法分析的时候对应不同的操作,比如规约还是移位。这里不讨论。重点是项目集规范族的构造, 在知道了LR(0)项目后,可以来看看项目集规范族的定义, 对于构成识别一个文法活前缀的DFA项目集(状态)的全体我们称之为这个文法的LR(0)项目集规范族。至于什么是活前缀呢,定义如下 对于任一文法G[S],若S’经过任意次推导得到αAω,继续经过一次推导得到![]}/images/6b23dd171a1f672514a2dbb29175df032a1f63d4.gif)αβω,若γ是αβ的前缀,则称γ是G的一个活前缀。 现在知道了LR(0)项目,了解了活前缀,和项目集规范族的定义,还须引入LR(0)项目集的闭包函数CLOSURE和状态转换函数GO两个概念,先给出数学上的定义,如果你觉得麻烦可以跳过,后面会给出一道例题。 ① 闭包函数CLOSURE(I)的定义如下: a)I的项目均在CLOSURE(I)中。 b)若A→α·Bβ属于CLOSURE(I),则每一形如B→·γ的项目也属于CLOSURE(I)。 c)重复b)直到不出现新的项目为止。即CLOSURE(I)不再扩大。 ② 转换函数GO(I,X)的定义: GO(I,X)=CLOSURE(J) 其中:I为包含某一项目的状态,就是前面我们说的那四个了。,X为一文法符号,X∈(VN∪VT),J={任何形如A→αX·β的项目| A→α·Xβ属于I}。 这样就可以使用闭包函数和转换函数构造文法G′的LR(0)项目集规范族,其步骤如下: a)置项目S′→·S为初态集的核,然后对核求闭包,CLOSURE({S′→·S})得到初态的项目集。 b)对初态集或其它所构造的项目集应用转换函数GO(I,X)=CLOSURE(J),求出新状态J的项目集。 c)重复b)直到不出现新的项目为止。 开始拿个例题来说明,定义没例题看起来看难了。 例题:对于下列文法,S→aS|bS|a,构造该文法的LR(0)项目集规范族 思路就是利用闭包函数CLOSURE和转换函数GO来构造。通过计算函数CLOSURE和GO得到文法的LR(0)项目集规范族,而GO函数则把LR(0)项目集规范族连成一个识别该文法所产生的活前缀的DFA。DFA大家都知道,有穷自动机。 (1)将文法G(S)拓广为G(S’)也就是该文法的增广文法,目的是使语法分析器知道何时应该停止并接受该串,也就是说当使用S’->S进行规约的时候,就结束。 (0)S’→S (1)S→aS (2)S→bS (3)S→a 构造该文法的LR(0)项目集规范族,I就是产生式,至于I0 I1就是往下递增就可以了。没什么特别的意思。: I0=CLOSURE({S’ →•S})={S’ →•S, S→•aS, S→•bS, S→•a} //第一条是固定的,都是求S’ →•S的闭包。而因为右侧的S又可以推导出后面三个,所以后面三个式子是属于该闭包的。在闭包的规则中可以看出,若A→α·Bβ属于CLOSURE(I),此时S’ →•S属于闭包,S相当于规则中的B,则每一形如B→·γ的项目也属于CLOSURE(I),此处相当于S->后面的三个推导式。加上.就可以了 I1=GO( I0 , a)=CLOSURE({S→a•S , S→a•})={S→a•S , S→a• , S→•aS, S→•bS, S→•a } //第二条你可能已经看出来了,其实就是把转换函数GO反过来用,在GO函数中,X为一文法符号,J={任何形如A→αX·β的项目| A→α·Xβ属于I}。也就是在I0中,找到右侧包含a的项目,然后将.右移一位来求他们的闭包函数,此处,I0中包含.a的项目为 S→•aS和 S→•a,.右移一位变成S→a•S , S→a•,求闭包函数的规则和上面那条是一样的,继续找推导式右边可以推导出来的式子就可以了,此处,右边同样是S可以推导出三个式子,前面加上.就可以了。 I2=GO(I0 , b)=CLOSURE({S→b•S })={ S→b•S, S→•aS, S→•bS, S→•a } //第三条仿照第二条进行推导,先在I0中找有.b的,然后右移一位,然后推导式右侧的S继续用题目给出的推导,然后前面加上. I3=GO(I0 , S)=CLOSURE({S’ →S•})={ S’ →S•} //第四条因为右侧包含.S的只有一项。必须是.S。所以只有一个,右移后求闭包即可。因为S是右侧的第一位,所以不用再向下推导了,规则是:A→α·Bβ属于CLOSURE(I),此处是S’ →S•,则B→·γ的项目也属于CLOSURE(I),此处S相当于规则中的α,无B。。。。 因为GO(I1, a)=CLOSURE({S→a•S , S→a•})=I1, //第五条同理,在I1中找有右侧有.a的项目,右移一位。进行求闭包,发现和I1求闭包的变量是一样的。所以结果必然也和I1是一样的。 GO(I1, b)=CLOSURE(S→b•S)=I2. //第六条没有新的I产生。 I4=GO(I1, S)=CLOSURE({S→aS•})={S→aS•} //这第七条在I1找右侧包含.S的项目,只有S→a•S,右移后求闭包,同第四条,无B,所以直接如此。 GO(I2, a)= CLOSURE({S→a•S , S→a•})=I1 GO(I2, b)=CLOSURE({S→b•S})=I2 I5=GO(I2, S)=CLOSURE({S→bS•})={S→bS•} 此时应该继续求GO(I3, a),GO(I3, b)和,GO(I3, S),但显然I3中没有.a,没有.b也没有.S,所以不用多此一举了, 继续求GO(I4, a),GO(I4, b)和,GO(I4, S),显然同上,也没有。所以也不用求了, 继续求GO(I5, a),GO(I5, b)和,GO(I5, S),理由同上,没有任何必要了 最终,项目集I0,I1,I2,I3,I4和I5构成了该文法的LR(0)项目集规范族。 编译原理真是博大精深啊。就一个简单的三个推导式就得这么多步骤才构造了一个规范族,还要利用规范族来构造LR分析表,这。。手工果断不是事啊。今天看了几个小时才完全弄清楚LR(0)项目集规范族的构造。例题的步骤是我自己写的。这篇文章写了2个小时。。太费脑子了。。慢慢再写产生活前缀的DFA和LR分析表吧。 参考: http://metc.gdut.edu.cn/compile/nandian/n-7.htm

2012-05-12 · 1 min · bystander

《乌合之众》笔记下部

 看完了下部,本书绝对是群体心理学的经典。没有废话,180多页的小册子讲的非常非常好。 执政府和帝国的具体工作就是用新的名称把过去大多数的制度重新包装一遍,用新名词代替那些能够让群众想起不利形象的名称。因为新鲜能够防止这种联想。 统治者的艺术,就像律师的艺术,首先在于驾驭辞藻的学问。 推动各民族演化的主要因素,永远不是真理,而是谬误。 社会主义的谬误,群众从来不渴求真理,他们需要对他们有诱惑力的谬误,凡是能供应幻觉的,都是他们的主人,使他们幻灭的。都将成为牺牲品。 尽管存在着理性,文明的动力仍然是各种感情–譬如尊严,自我牺牲,宗教信仰,爱国主义以及对荣誉的爱 只要有一些生物聚集在一起,不管是人还是动物,都会本能的让自己处在一个头领的统治之下。 头脑敏锐,深谋远虑的人往往不能成为群体领袖,因为他们这种品质会让人犹疑不决,而那些有毛病的,兴奋的人则可能。 在群体的灵魂中,占上风的,不是对自由的追求,而是当奴才的欲望。 领袖的动员手段:断言,重复和感染。 传染的威力很大,不但能迫使个人接受某些意见,而且能让他接受一些感情模式。 名望是某个人,某本著作,或是某种观念对我们头脑的支配力。会麻痹我们的批判能力。让我们充满惊奇和敬畏。名望的特点就是阻止我们看到事物的本来面目。 用一时的意见影响群众的头脑不难,想让一种信念在其中长久扎根却极为不易。 一种信念开始衰亡的确切时刻很容易辨认-他的价值开始受到质疑。不过即使已经摇摇欲坠,根据他建立的制度依然会保持其力量,消失的十分缓慢 需要一种普遍信念来支持一个国家。实干家一心要让这种普遍接受的信仰变成现实,立法者一心想把他付诸实行,哲学家,艺术家和文人全都醉心于如何以各种不同的方式表现他。 今天的社会主义信念虽然有明显的破绽,但并没有阻止他赢得群众。他的力量的增长只能到他获得胜利,掌权的那一天为止。 报纸媒体不断把对联意见带给人们,由于受到对立意见的暗示作用的破坏,结果任何意见都难以普及,他们全都成了过眼烟云。一种意见还没来得及被足够多的人接受。就已经寿终正寝。 报业既然成了仅仅提供信息的部门,也就放弃了让人接受某种观念或学说的努力。 如果有什么事情能够推迟一种文明的毁灭的话,那就是极不稳定的群众意见,以及他们对一切普遍信仰的麻木不仁。 两类群体:异质性,街头,议会。同质性,派别,身份 杰出律师的主要用心在于,打动陪审团的感情,不需要太多论证,留心他们,得出自己的结论,确定那些人赞同,转向不赞同的人。 选民群体属于异质性群体,他们极少推理,没有批判精神,轻信,易怒而且头脑简单。 选民的心理和其他群体一样:既不更好,也不更差。 文明是少数智力超常的人的产物,他们构成了金字塔的顶点,随着金字塔各个层次加宽,智力越来越少,如果一个伟大的文明仅仅以人多势众自夸的低劣成员的选票。是无法让人放心的。 领袖的影响力只在很小的程度上是因为他们提出的论据,而在很大程度上来自他们的名望,一旦他们不知道什么原因威信扫地,他们的影响力也将随之消失。 在政治集会中,才华横溢者无任何作用。伟大的民众领袖头脑的狭隘令人瞠目 演讲者演说的成功与否很大程度上也取决于自己的名望。 由法律专家制定的法律是最好的法律,因为他是个人的产物,只有当一系列修正案把他们变成集体努力的产物的时候,才可能产生灾难性的后果。 表面自由的增加,必然伴随着真正自由的减少。 各国被一种谬见所蒙蔽,就是认为保障自由与平等的最好办法就是制定法律,结果使人变成奴才。 人们似乎热爱自由,其实只是痛恨主子 -托克维尔。

2012-05-11 · 1 min · bystander

四种I/O控制方式

 基本上原文照搬过来吧。主要是原文排版太乱。不利于传播。 随着计算机技术的发展,I/O控制方式也在不断地发展。I/O控制的发展经历了以下四个阶段: 一.程序I/O控制方式 在早期的计算机系统中,由于无中断机构,处理机对I/O设备的控制,采取程序I/O方式(Programmed I/O方式)。在程序I/O方式中,由于CPU的高速性和I/O设备的低速性,致使CPU 的绝大部分时间都处于等待I/O设备完成数据I/O的循环测试中,造成对CPU的极大浪费。在该方式中,CPU之所以要不断地测试I/O设备的状态,就是因为在CPU中无中断机构,使 I/O设备无法向CPU报告它已完成了一个字符的输入操作。如下图所示: 图1.![]}/images/c83bce26670bc565b0fb2eaa4984e5b7575b618a.jpg) 程序I/O方式又称忙–等待方式,即在处理机向设备控制器发出一条I/O指令启动输入设备、输出数据时,要同时把状态寄存器中的忙/闲标志busy置为1,然后便不断地循环测试busy。当busy=1时,表示输入机尚未输完一个字(符),处理机应继续对busy进行测试;直至busy=0,表明输入机已将输入数据送入控制器的数据寄存器中,于是处理机将数据寄存器中的数据取出,送入内存指定单元中,接着,再启动去读下一个数据,并置busy=1。 △ 此方式造成对CPU的极大浪费。 二.中断驱动I/O控制方式 在现代计算机系统中,对I/O设备的控制,广泛采用中断驱动(Interrupt—Driven)方式。在I/O设备输入每个数据的过程中,由于无须CPU干预,因而可使CPU与I/O设备并行工作。仅当输完一个数据时,才需CPU花费极短的时间去做些中断处理。可见,这样可使CPU和I/O设备都处于忙碌状态,从而提高了整个系统的资源利用率及吞吐量。如下图所示: 图2 当某进程要启动某个I/O设备工作时,便由CPU向相应的设备控制器发出一条I/O命令,然后立即返回继续执行原来的任务。设备控制器便按照该命令的要求去控制I/O设备。此时,CPU与I/O设备并行操作。 例如,从终端输入一个字符的时间约为 100ms , 而将字符送入终端缓冲区的时间小于 0.1ms 。 若采用程序 I/O 方式, CPU 约有 99.9ms 的 时间处于忙 — 等待中。 采用中断驱动方式后, CPU 可利用这 99.9 ms 的时间去做其它事情,而仅用 0.1 ms 的时间来处理由控制器发来的中 断请求 。 可见,中断驱动方式可以成百倍地提高 CPU 的利用率。△ 中断驱动方式可以成百倍地提高CPU的利用率。 三.直接存储器访问DMA控制方式 –>DMA控制方式的引入 虽然中断驱动I/O比程序I/O方式更有效,但它是以字(节)为单位进行I/O的,若将这种方式用于块设备的I/O,显然将会是极其低效的。为了进一步减少CPU对I/O的干预,而引入了直接存储器访问(Direct Memory Access)方式。如下图: 图3![]}/images/ee3e0c3ca8d998d2a84488f01d3ca4d6e642f217.jpg) 此方式的特点是: 数据传输的基本单位是数据块;所传输的数据是从设备直接送入内存的,或者相反;整块数据的传送是在控制器的控制下完成的; 可见,DMA方式较之中断驱动方式,又是成百倍地减少了CPU对I/O的干预,进一步提高了CPU与I/O设备的并行操作程度。 –>DMA控制器的组成 DMA控制器由三部分组成,如下图: 图4![]}/images/bbb47eca5cb44fe7cf36bea37349cf6b728e99b5.jpg) 主机与DMA控制器的接口;DMA控制器与块设备的接口;I/O控制逻辑; 为了实现控制器与主机之间成块数据的直接交换,必须在DMA控制器中设四类寄存器,如上图 命令/状态寄存器;内存地址寄存器MAR;数据寄存器DR;数据计数器DC; –>DMA工作过程 DMA的工作过程如下图: 图5 四.I/O通道控制方式 –>I/O通道控制方式的引入 I/O通道方式是DMA方式的发展,它可进一步减少CPU的干预,即把对一个数据块的读(或写)为单位的干预,减少为对一组数据块的读(或写)及有关的控制和管理为单位的干预。同时,又可实现CPU、通道和I/O设备三者的并行工作,从而更有效的提高了整个系统的资源利用率。 –>通道程序 通道是通过执行通道程序,并与设备控制器来共同实现对I/O设备的控制的。通道程序是由一系列的通道指令(或称通道命令)所构成。通道指令与一般的机器指令不同,在它的每条指令中包含下列诸信息: 操作码—-它规定了指令所执行的操作;内存地址;计数—-表明本条指令所要读(或写)数据的字节数;通道程序结束位P;记录结束标志位R 有几种I/O控制方式?各有何特点? 答:I/O控制方式有四种:程序直接控制方式、中断控制方式、DMA方式和通道控制方式。 (1) 程序直接控制方式:优点是控制简单,不需要多少硬件支持。但CPU和外设只能串行工作,且CPU的大部分时间处于循环测试状态,使CPU的利用率大大降低,因此该方式只适用于那些CPU执行速度较慢且外设较少的系统。 (2) 中断处理方式:优点是能实现CPU与外设间的并行操作,CPU的利用率较程序直接控制方式大大提高。由于在一次数据传送过程中CPU通常以字节为单位进行干预,中断次数较多而耗去大量的CPU时间。 (3) DMA方式:与中断方式相比,DMA方式是在一批数据传送完成后中断CPU,从而大大减少CPU进行中断处理的次数,且DMA方式下的数据传送实在DMA控制下完成的。但DMA方式仍有一定的局限,如对外设的管理和某些操作仍由CPU控制,多个DMA控制器的使用也不经济。 (4) 通道控制方式:CPU只需发出I/O指令,通道完成相应的I/O操作,并在操作结束时向CPU发出中断信号;同时一个通道还能控制多台外设。但是通道价格较高,从经济角度出发不宜过多使用。 参考: http://oa.gdut.edu.cn/os/multimedia/oscai/chapter5/pages/ch52.htm

2012-05-07 · 1 min · bystander