编译原理简单优先
⑴ 把编程学好需要掌握哪几方面重点
1、扎实的基础 数据结构、离散数学、编译原理,这些是所有计算机科学的基础,如果不掌握它们,很难写出高水平的程序。程序人人都会写,但当你发现写到一定程度很难再提高的时候,就应该想想是不是要回过头来学学这些最基本的理论。不要一开始就去学OOP,即使你再精通OOP,遇到一些基本算法的时候可能也会束手无策。因此多读一些计算机基础理论方面的书籍是非常有必要的。 2、丰富的想象力 不要拘泥于固定的思维方式,遇到问题的时候要多想几种解决问题的方案,试试别人从没想过的方法。丰富的想象力是建立在丰富的知识的基础上,除计算机以外,多涉猎其他的学科,比如天文、物理、数学等等。开阔的思维对程序员来说很重要。 3、最简单的是最好的 这也许是所有科学都遵循的一条准则,复杂的质能转换原理在爱因斯坦眼里不过是一个简单得不能再简单的公式:E=mc2。简单的方法更容易被人理解,更容易实现,也更容易维护。遇到问题时要优先考虑最简单的方案,只有简单方案不能满足要求时再考虑复杂的方案。 4、不钻牛角尖 当你遇到障碍的时候,不妨暂时远离电脑,看看窗外的风景,听听轻音乐,和朋友聊聊天。当我遇到难题的时候会去玩游戏,当负责游戏的那部分大脑细胞极度亢奋的时候,负责编程的那部分大脑细胞就得到了充分的休息。当重新开始工作的时候,我会发现那些难题现在竟然可以迎刃而解。
⑵ 数控编程的技巧
数控编程的技巧
引导语:对于数控编程的技巧,大家知道的有多少呢?下面是我为大家精心整理出的一些关于数控编程技巧的资料,希望能够帮助到大家!
1 具有扎实的基础知识
数控机床加工受控于程序指令,加工的全过程都是按程序指令自动进行的。数控机床加工程序不仅要包括零件的工艺过程,而且还要包括切削用量,走刀路线,刀具尺寸以及机床的运动过程。我们要想熟练的掌握数控编程,首先必须了解数控机床的组成及工作原理,对数控机床的性能、特点、运动方式、刀具系统、切削规范以及工件的装夹方法都要非常熟悉。其次要具有扎实的数学基础,例如在手工编程中要遇到一些复杂形状零件的基点的计算,可根据零件图样给定的尺寸,运用代数、三角函数、几何或解析几何的有关知识,直接求出数值。再次,数据结构、离散数学、计算机高级语言,编译原理,这些是计算机科学的基础,如果不掌握它们,很难写出高水平的程序。程序人人都会写,但当你发现写到一定程度很难提高的时候,就应该回过头来学学这些最基本的理论。同时,金属切削与刀具也是我们必须要掌握的基础知识,在实习的过程中,用相同的加工程序加工出来的零件表面粗糙度却有较大的差别,这主要是刀具的角度刃磨不合理,刀具的刃磨在数控加工中显得尤为重要。
2 丰富的想象力
不要拘泥于固定的思维方式,遇到问题时要多想几种解决问题的方案,试试别人从未想到的方法,丰富的想象力是建立在丰富的知识基础上,除计算机之外,多涉猎其它的学科,比如天文、地理、数学等等。开阔的思维对程序员来说很重要。
3 最简单的是最好的
这也许是所有科学都遵循的一条准则,简单的方法更容易被人理解,更容易实现,更容易维护。遇到问题时优先考虑最简单的方案,只有简单方案不能满足时再考虑复杂的方案。例如简单的外圆加工,我们就可以直接利用G01来实现,没必要用G71来加工。再例如在数控铣削加工中,如果要实现零件的粗精加工,可以将刀具的运动轨迹编制成子程序,通过改变刀具半径补偿值和调用子程序来加工。
4 不钻牛角尖
当你遇到障碍时,不妨暂时远离电脑,看看窗外的风景,听听轻音乐,和朋友聊聊天。当我编程遇到障碍的时候,我会暂时看会报纸或者杂志,让负责编程的那部分大脑细胞得到充分的休息。当重新开始工作的时候,我会发现那些难题会迎刃而解。
5 对答案的渴求
人类自然科学的.发展史就是一个渴求得到答案的过程,即使只能得到答案的一小部分也值得我们去付出。只要你坚定信念,一定能找到答案,你才会付出精力去探索,即使最后没有得到答案,在过程中你也会学到很多东西。例如刚开始学习用宏程序加工椭圆,程序怎么也不运行,第二天重新仔细看了一遍,原来在三角函数的角度外面忘记加一个中括号。虽然我第一天没有把程序编制成功,但是我在这个过程中至少对变量的使用、控制语句加深了理解。当然在三角函数的角度上一定要加中括号这一点,使我牢记心中。
6 多与别人交流
三人行必有我师,也许和别人一次不经意的谈话中,就可以迸发出灵感的火花。多读读别人的程序,看看别人对问题的看法,会对你有很大启发。例如下图的加工实例,我就从别人的程序中学到了很好的编程思想和非常有用的见解,写出来大家共享。
上面编写的普通程序综合运用了子程序的嵌套、旋转坐标系。每次加工完一个孔,然后将坐标系绕工件原点旋转18°,程序非常简洁。这又进一步拓宽了我的编程思路,向更高方向的发展迈进了一步。
7 良好的编程风格
注意养成良好的习惯,如程序中要使用程序段号、字与字之间要有空格、多写注释语句等,使程序清晰,便于阅读和修改。大家都知道如何排除代码中的错误,却往往忽视了对注释的排错。注释是程序的一个重要的组成部分,它可以使你的代码更容易理解,而如果代码已经清楚地表达了你的思想,就不必再加注释了,如果注释和代码不一致,那就更加糟糕。指令代码的格式严格按照语法来书写,变量的命名规则要始终一致。
总之,随着科学技术的飞速发展,数控机床由于具有优越的加工特点,在机械制造业中的应用越来越广泛,为了充分发挥数控机床的作用,我们需要在编程中掌握一定的技巧,编制出合理、高效的加工程序,保证加工出符合图纸要求的合格工件,同时能使数控机床的功能得到合理的应用与充分的发挥,使数控车床能安全、可靠、高效地工作。本文总结的一些具体结论适用于FANUC0i数控机床,但是它表现的编程思想具有普遍意义。要编制合理高效的加工程序,必须要熟悉所使用机床的程序语言并能加以灵活运用,了解机床的主要参数,深入分析零件的结构特点、材料特性及加工工艺等。
;⑶ 编译原理笔记9:语法分析树、语法树、二义性的消除
语法分析树和语法树不是一种东西 。习惯上,我们把前者叫做“具体语法树”,其能够体现推导的过程;后者叫做“抽象语法树”,其不体现过程,只关心最后的结果。
语法分析树是语言推导过程的图形化表示方法。这种表示方法反映了语言的实质以及语言的推导过程。
定义:对于 CFG G 的句型,分析树被定义为具有下述性质的一棵树:
推导,有最左推导和最右推导,这两种推导方式在推导过程中的分析树可能不同,但因最终得到的句子是相同的,所以最终的分析树是一样的。
分析树能反映句型的推导过程,也能反映句型的结构。然而实际上,我们往往不关心推导的过程,而只关心推导的结果。因此,我们要对 分析树 进行改造,得到 语法树 。语法树中全是终结符,没有非终结符。而且语法树中没有括号
定义:
说白了,语法树这玩意,就一句话: 叶子全是操作数,内部全是操作符 ,树里没有非终结符也不能有括号。
语法树要表达的东西,是操作符(运算)作用于操作数(运算对象)
举俩例子吧:
【例】: -(id+id) 的语法树:
【例】:-id+id 的语法树:
显然,我们从上面这两个语法树中,直接就能观察出来它们的运算顺序。
【例】:句型 if C then s1 else s2
二义性问题:一个句子可能对应多于一棵语法树。
【例】: 设文法 G: E → E+E | E*E | (E) | -E | id
则,句子 id+id*id、id+id+id 可能的分析树有:
在该例中,虽然 id+id+id 的 “+” 的结合性无论左右都不会影响结果。但万一,万一“+”的含义变成了“减法”,那么左结合和右结合就会引起很大的问题了。
我们在这里讲的“二义性”的“义”并非语义——我们现在在学习的内容是“语法分析器”,尚未到需要研究语言背后含义的阶段。
我们现在讲的“二义性”指的是一个句子对应多种分析树。
二义性的体现,是文法对同一句子有不止一棵分析树。这种问题由【句子产生过程中的某些推导有多于一种选择】引起。悬空 else 问题就可以很好地体现这种【超过一种选择】带来的二义性问题,示例如下。
看下面这么个例子。。
(其实,我感觉这个其实比较像是“说话大喘气”带来的理解歧义问题。。。)上面的产生式中并没体现出来该咋算分一块,所以两种完全不同的句子结构都是合法的。
二义性问题是有救的,大概有以下这三种办法:
这些办法的核心,其实都是将优先级和结合性说明白。
核心:把优先级和结合性说明白
既然要说明白,那就不能让一个非终结符可以直接在当次推导中能推出会带来优先级和结合性歧义的东西。(对分析树的一个内部节点,不会有出现在其下面的分支是相同的非终结符的情况。如果有得选,那就有得歧义了。没得选才能确定地一路走到黑)
改写为非二义文法的二义文法大概有下面这几个特点:
改写的关键步骤:
【例】改写下面的二义文法为非二义文法。图右侧是要达成的优先级和结合性
改写的核心其实就两句话:
所以能够得到非终结符与运算的对应关系(因为不同的运算有不同的优先级,我们想要引入多个优先级就要引入多个新的非终结符。这样每个非终结符就可以负责一个优先级的运算符号,也就是说新的非终结符是与运算有关系的了。因此这里搞出来了“对应关系”四个字)如下:
优先级由低到高分别是 +、 、-,而距离开始符号越近,优先级越低。因此在这里的排序也可以+ -顺序。每个符号对应一层的非终结符。根据所需要的结合性,则可确定是左递归还是右递归,以确定新的产生式长什么样子
【例】:规定优先级和结合性,写出改写的非二义文法
我们已经掌握了一种叫做【改写】的工具,能让我们消除二义性。接下来我们就要用这个工具来尝试搞搞悬空 else 问题!
悬空 else 问题出现的原因是 then 数量多于 else,让 else 有多个可以结合的 then。在二义文法中,由于选哪两个 then、else 配对都可以,故会引起出现二义的情况。在这里,我们规定 else 右结合,即与左边最靠近的 then 结合。
为改写此文法,可以将 S 分为完全匹配(MS)和不完全匹配(UMS)两类。在 MS 中体现 then、else 个数相等即匹配且右结合;在UMS 中 then、else 不匹配,体现 else 右结合。
【例】:用改写后的文法写一个条件语句
经过检查,无法再根据文法写出其他分析树,故已经消除了二义性
虽然二义文法会导致二义性,但是其并非一无是处。其有两个显着的优点:
在 Yacc 中,我们可以直接指定优先级、结合性而无需自己重写文法。
left 表示左结合,right 表示右结合。越往下的算符优先级越高。
嗯就这么简单。。。
我们其实可以把语言本身定义成没有优先级和结合性的。。然后所有的优先、结合都交由括号进行控制,哪个先算就加括号。把一个过程的结束用明确的标志标记出来。
比如在 Ada 中:
在 Pascal 中,给表达式加括号:
⑷ 编译原理什么是素短语
编译原理中,素短语是至少含义一个终结符,并且自身不包含任何更小素短语的一种短语。
素短语是一种特殊的短语,它是一个递归的定义,至少含有一个终结符,并且除它自身之外不再含任何更小的素短语,所谓最左素短语就是处于句型最左边的素短语的短语。
一个算符优先文法G的任何句型的最左素短语是满足以下条件的最左子串NaNb…NcNdN(N是非终结符,a,b,c,d是终结符)。例如:句型T+T*F+id,T*F是最左素短语,id是素短语。
(4)编译原理简单优先扩展阅读:
通过语法树可以得知素短语:
1、每个句型对应一棵语法树
2、每棵语法树的叶子结点从左到右排列构成一个句型
3、每棵语法树的子树的叶子结点从左到右排列构成一个短语
4、每棵语法树的简单子树(只有父子两层结点)的叶子结点从左到右排列构成一个简单(直接)短语。
5、素短语是至少包含一个终结符的短语,但它不能包含其它素短语。