当前位置:首页 » 编程软件 » 编译原理一个晚上学完

编译原理一个晚上学完

发布时间: 2022-07-05 23:58:50

1. 操作系统,汇编语言,编译原理,这三门课程学习步骤是什么 以及原因,求详细解释,非常感谢。

汇编语言、编译原理、操作系统吧

1.首先编译原理肯定要在汇编之后学的,你不会汇编编什么译
2.汇编语言肯定讲的是实模式的内容,学完了实模式对计算机内程序有个基本概念了,研究保护模式的时候就要涉及到操作系统了
3.至于编译原理我没学过,姑且认为应该也是实模式的内容吧,所以放到操作系统之前学习

2. 编译原理学了有什么用

对大多数人来说,学过编译原理,应该可以知道对于很多代码的优化,编译器其实可以做好,不需要自己写代码的时候杞人忧天。在通用、局部的优化上,甚至编译器往往做得比程序员好。

大概率会意识到编译原理背后的故事,也许会沉迷在某个方向,也许还会乐于看一些奇妙的parser构建方式。

大概还可能会去学习类型系统,发现形式化的故事似乎在很多方面都有对应的版本,而后,他们也许会尝试走向研究,去挑战目前都没有好好解决的代码优化问题,也许会走向应用,用起LLVM,在上面加个target,支持一些新硬件,做个新语言的前端等。

编译原理是计算机专业的一门重要专业课,旨在介绍编译程序构造的一般原理和基本方法。内容包括语言和文法、词法分析、语法分析、语法制导翻译、中间代码生成、存储管理、代码优化和目标代码生成。 编译原理是计算机专业设置的一门重要的专业课程。

编译原理课程是计算机相关专业学生的必修课程和高等学校培养计算机专业人才的基础及核心课程,同时也是计算机专业课程中最难及最挑战学习能力的课程之一。编译原理课程内容主要是原理性质,高度抽象。

编译可以分为五个基本步骤:词法分析、语法分析、语义分析及中间代码的生成、优化、目标代码的生成。这是每个编译器都必须的基本步骤和流程, 从源头输入高级语言源程序输出目标语言代码。

1、词法分析

词法分析器是通过词法分析程序对构成源程序的字符串从左到右的扫描, 逐个字符地读, 识别出每个单词符号, 识别出的符号一般以二元式形式输出, 即包含符号种类的编码和该符号的值。

词法分析器一般以函数的形式存在, 供语法分析器调用。当然也可以一个独立的词法分析器程序存在。完成词法分析任务的程序称为词法分析程序或词法分析器或扫描器。

2、语法分析

语法分析是编译过程的第二个阶段。这阶段的任务是在词法分析的基础上将识别出的单词符号序列组合成各类语法短语, 如“语句”, “表达式”等.语法分析程序的主要步骤是判断源程序语句是否符合定义的语法规则, 在语法结构上是否正确。

而一个语法规则又称为文法, 乔姆斯基将文法根据施加不同的限制分为0型、1型、2型、3型文法, 0型文法又称短语文法, 1型称为上下文有关文法, 2型称为上下文无关文法, 3型文法称为正规文法, 限制条件依次递增。

3、语义分析

词法分析注重的是每个单词是否合法, 以及这个单词属于语言中的哪些部分。语法分析的上下文无关文法注重的是输入语句是否可以依据文法匹配产生式。

那么, 语义分析就是要了解各个语法单位之间的关系是否合法。实际应用中就是对结构上正确的源程序进行上下文有关性质的审查, 进行类型审查等。

4、中间代码生成与优化

在进行了语法分析和语义分析阶段的工作之后, 有的编译程序将源程序变成一种内部表示形式, 这种内部表示形式叫做中间语言或中间表示或中间代码。

所谓“中间代码”是一种结构简单、含义明确的记号系统, 这种记号系统复杂性介于源程序语言和机器语言之间, 容易将它翻译成目标代码。另外, 还可以在中间代码一级进行与机器无关的优化。

5、目标代码的生成

根据优化后的中间代码, 可生成有效的目标代码。而通常编译器将其翻译为汇编代码, 此时还需要将汇编代码经汇编器汇编为目标机器的机器语言。

6、出错处理

编译的各个阶段都有可能发现源码中的错误, 尤其是语法分析阶段可能会发现大量的错误, 因此编译器需要做出错处理, 报告错误类型及错误位置等信息。

3. 刚学完编译原理,想看看在编译层面c++是怎么实现的,有什么好的书籍...

C++ Primer Plus
C++ Primer

4. 学习编译原理和操作系统对编程能力有什么作用

学习编译原理和操作系统对编程能力对编程能力的作用在于:

1、学好了编译原理,才可能编写出高效,稳健,占用内存少的程序。

2、学习操作系统对windows相关的编程很有帮助。如果是对操作系统关系不大的C/C++/c#,java之类的编程,关系不大。

编译原理是计算机专业的一门重要专业课,旨在介绍编译程序构造的一般原理和基本方法。内容包括语言和文法、词法分析、语法分析、语法制导翻译、中间代码生成、存储管理、代码优化和目标代码生成。 编译原理是计算机专业设置的一门重要的专业课程。虽然只有少数人从事编译方面的工作,但是这门课在理论、技术、方法上都对学生提供了系统而有效的训练,有利于提高软件人员的素质和能力。

操作系统(Operating System,简称OS)是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在“裸机”上的最基本的系统软件,任何其他软件都必须在操作系统的支持下才能运行。

5. 学完编译原理能干什么

试着写写编译器吧,会有收获的~~~

6. 学完了c语言,是否有必要学Java

看完这个,你可能会有自己的一点想法了
应届生学C好还是学JAVA好,做什么更挣钱
老师:
你好。
我是一名09界刚毕业工作不久的java菜鸟级程序员。本人对java水平可以混口饭了,现在可以在工作中开发一般的小项目,都是B/S的。 本人基础很烂,基本上:算法 、数据结构、计算机组成原理、操作系统、编译原理可以说从来没有学过。目前我工作的环境是:开发b/s 架构的项目,不考虑性能,实际上实现需求就可以了。我可以跟客户打交道,可以自己分析需求,可以自己跟其他人合作一些10万以下的小项目。基本上都是对数据库的增删改查。来来去去都是那些表非常无聊。
虽然工作不久,但是目前已经感觉到在这样下去,顶多只是熟悉一下业务而言。就本身编程水平基本上没多少提高。因为公司追求效益,只要写出来的东西能用就完事,没时间考虑代码,而且java没有指针,也不用的算法,工作中的设计模式也就常用的几个。剩下的几乎没什么可以提高的了( 项目管理学了一些,已经其他 )。
目前非常希望转C方面发展,我C语言可以认为0水平。但是由于有了java功底。虽然已经体会到语言只不过是解决方案的工具而已。但是就算我在java里面花再多时间感觉自己只是在浪费青春,我绝不是小看java,因为我也是用这门语言的,java没有内存管理,用java或者类似的语言,我永远只看到上层的东西。我希望自己成为一名技术非常强悍的程序员。可以写出一些经典的开源工具。因为以前大学都是逃课,睡觉,打游戏。所以基础很差,实际上我相当于一个0基础的高中生学了半年java的人。目前自己每天在学数据结构。但是不知道路在哪里。我想换一份 C 的工作,不知道从哪里开始学。我选C有几个原因的:C的工作环境可以迫使你使用算法,然后进一步的慢慢深入,可以接触操作系统,然后慢慢使自己进入高层次的开发。因为C涉及面广,所以迫使自己学得到很多东西。进而提升自己水平而已。与其说选C语言,不如所选C语言所涉及的范围而已!因为在java环境,不可能到达我理想高度!
大环境很浮躁,这是我切身的体会。但是我有耐心和毅力。我第一步的想法是 先转到涉及算法的环境。实在不行,只要开发上用到C就行了。 因为我对C的工作环境不了解,可能理解上有误,希望你指点一下。如果像我这种水平的人,想要找到C的工作,大概怎么起步。 我说一下自己的java起步 当初我是这样的: 1、学习java 语法(j2se)。
2、用java 做一个 俄罗斯游戏。 3、学习 jsp 做一个MVC的留言板, 学习 流行框架(SSH), 做一个 管理系统。
就这样 我就找到 JAVA EE 应用开发的工作了。当时进公司不用适应期就直接上项目了。

我当初是在没有老师( 老师重来不把一个年年补考,每次都垫底的学生当人看),同学鄙视(最后一个学期每个人都找工作,打游戏。而我每天都在疯狂的学习 一直到毕业前夕 ),没有人管的情况下过来的。靠google, , 买经典教材,网络视频,Q群 的情况下,终于用一张合同在毕业前证明了自己的能力! 这段辛酸的经历给了我很多东西,特别是自制力、自学能力、毅力。

现在我已经打算辞职回家,再次进入疯狂的学习状态,虽然现在每天下班回来也在学习。但是每天4个小时远远比不上 原先每天12个小时的自学效率。而且自学可以连续学半年,现在每天还要工作,非常不合适。
我希望用半年 至少补上 大学的 数据结构,基本算法,计算机组成原理,操作系统、 同时复习数学知识( 主要是 离散数学、线性代数 )这些基础。 如果半年内时间紧的 Linux、汇编和编译原理可否先暂时缓缓。

工作意向:优先 游戏编程, 然后其他的用C的也可以( 曾经非常想考虑 C的嵌入式,但是发现涉及知识有点广,而且工具也不便宜 )其实我非常希望向网络发展,只是不知道代价多大( TCP/IP 和其它网络知识不懂,这个要多久,1个月内可以达到工作要求可以接受 )。

然而C的路子怎么走呢?
原先这样思考的 : 1 C语法 2、用一个小游戏( 俄罗斯方块、或者是 五指棋 )来巩固前面C语言基本知识。 掌握这些后我不知道干嘛了。
第三步:????( MFC? 不学它行不行,如果工作普遍需要我非常乐意学 )

目前本人的水平基本(资质普通)就这样了。你看通过半年 每天12个小时的高强度的学习,怎么才可以到达目前 找到 使用 C语言 开发 的工作。 希望您指点一下。最好可以列出来几条路子 , 比如 游戏编程的、网络的、然后其它的。
非常感谢你看完我的邮件, 静候佳音。
2009-10-12

专家回答:

这位同学你好,从这封信看得出来你的心情还是很急迫的,你这种心情我完全能够理解。我把问题分几点说,尽量说细一点,希望能对你有所帮助。

首先,你说你是09年毕业的大学生,那么算下来,你应该上班才几个月而已,就这一点,你能在新的单位几个月时间就把工作拿上手,首先恭喜你,这说明你是真的很有实力,当年我转行游戏编程,用了差不多两年才真正想清楚程序设计的真意,我觉得你比我强。呵呵。

你说Java基本上都是做B/S数据库,觉得没有意思,其实这个我也很理解,不过,我觉得你可能不是很了解实际情况。这里我需要给你讲清楚,其实不仅仅是Java程序员,只要到企业中做应用开发,或多或少都和数据库沾点边。当年我用VC还写报表系统呢,你能说这不是数据库?

其实有个问题可能大家都没有关注到,至少,我到学生大本营半年,发现大家都没有讨论过。那就是,做什么最赚钱?无可否认,软件可以实现各方面应用,不过,就我的观察,在现实生活中,有两种软件最赚钱,一种是数据库,一种就是嵌入式底层的东东,嗯,随着互联网的发展,目前做网络程序也很赚钱。

其实原因很简单,就是因为软件的盗版问题。我想看到我这篇文章的每个人,或多或少都用过盗版软件,包括我自己,呵呵,咱们中国人穷啊,动辄几百上千的软件费用,咱们买不起的,所以电脑城的光盘市场才这么火爆。

但是,这带来了另外一个问题,就是当有一天,我们自己成为软件开发者的时候,才发现,盗版导致我们自己的收入降低,无法维系生活。这时候,恐怕再来大声疾呼,杜绝盗版,已经晚了,你说是不?

其实我们可能对市场不敏感,反正每个月发薪水,收入基本上旱涝保收,但是公司的老总们对这个很敏感,软件卖不出钱,公司就亏本,亏多了,就垮掉了,最终程序员还是没有收入。

因此,公司里面做软件,一般都做上面的软件,即数据库应用,嵌入式应用,控制类应用,网络服务应用较多。因为这几种应用,不容易被盗版,能卖到钱。通用性的应用,比如操作系统,比如很多工具软件,比如PC游戏,其实很难卖钱的。

数据库应用,一般数据库本身是使用成熟的商用系统,如MySQL,SQL Server,Oracle等,我们小公司拿来,再根据具体应用需求,做二次定制开发,这是一大类市场,其实这个市场的真正名字叫做“企业数据应用定制市场”。由于是定制的,自然没有通用性,也就不会有盗版了。

控制类,嵌入式类,很多都和具体硬件设备相关,换个硬件平台就不通用了,大家知道,中国的东东,要防盗版,最好和硬件相关,只要绑定硬件,软件一般不好到,以前出的防病毒卡,汉卡什么的,其实利用的就是这个市场规律。

服务应用呢,就更好说了,由于主要程序逻辑都在服务器端,基于B/S的模型,客户端连个软件都没有,服务器的管理自然比卖出去的软件好管理,不容易盗版。因此,这类企业也活得长,比如各个网站,各种网游什么的。所以我一直觉得,以后云计算发展起来后,很多软件可能会把零售制改为租用制,比如photoshop,大家买套软件几千,但一般人就是处理一下自家照片,自然不划算,因此盗版很多,但以后假如软件公司把它做成服务器版,大家把照片上传,处理,最后再存回来,这个过程每次租金1毛钱,每个人都花得起的话,我看以后就没那么多盗版了。另外,服务器应用其实大多数也是数据库应用。

所以,我首先要说,不管你是不是换工作,以后你恐怕会一直遇到数据库类的应用,不管你喜欢不喜欢,但这是社会的现实,你必须承认。你说对吧?

在这个共识下,我们再来看,其实我们会发现,三大主流应用中,只有嵌入式不适合Java,其他的数据库和服务器应用,其实Java比C和C++方便得多,因此,我建议你就在Java这条路上走下去,不一定非要转C和C++。本来你的强项就是Java,而且这也是主流的可以卖钱的市场,为啥不坚持呢?

从另外一个角度说,我也认为你应该坚持,你毕竟毕业不到半年,对社会,对公司,对本职工作其实了解并不深入,你认为Java就那么几个设计模式,没有挑战性,这个我能理解,但是,我觉得你说的不全面。起码我做程序做了这么多年,到底有多少种设计模式,我也说不清楚,我相信很多人都说不清楚。需要具体应用具体分析。

我不是Java程序员,不过我觉得,如果要做一个合格的程序员,首先不应该是程序设计的大师,而应该是理解客户需求,并迅速拿出解决方案的专家,这个,不管用什么语言,不管在哪里工作,都是必须的,同时,这也需要很长时间的积累。

准确的讲,我认为,一个人不在一门语言,一种业务领域努力3年、5年乃至10年,是很难成为专家的。因此,我建议你完全没有必要这山望着那山高,轻易就决定跳槽,建议你就这个环境,先锻炼自己,我这里放句话,你可以试着验证一下,两三年以后,你再看Java语言和数据库开发,都还是会找到自己不会,值得学习和钻研的东西的。因为最起码,客户的需求是千变万化,永无止境的。

当然,话分两说,如果你真的喜欢C,很想做嵌入式应用,就是不想做Java,那也无可厚非,因为毕竟每个人都有选择的权利。

不过,我仍然不建议你辞职回家学习。我以前有句话,大学毕业,才是学习的开始,不过,这个大学毕业后的学习,和学校中的学习,有很大差别,突出的几点:没有老师,没有教材,都是自己主动学,针对自己的需求来学习,学技巧多,学原理少,并且一般都是干中学,而不是学完了再干,我总结就是“用以致学”,而不是“学以致用”,这是我总结的学习经验。

同时,毕业了,总不好意思再向家里面父母要钱,总得自己赚钱养活自己。你说是吧?你说辞职半年,专心学习,那你没有收入吃啥?还不是吃父母的?这样不是很好。

C语言没有那么神圣的,也没有太高的门槛的,不要想太复杂了。另外,指针,内存什么的,学习C语言确实能接触到,但是,我还是要说,C语言并不是因为有了指针和内存的直接访问,才牛叉,C语言是因为大量的程序员用它解决了很多具体应用,才牛叉的。请你注意不要学偏了,不要为学指针而学指针。指针就是指针,仅仅是个访问工具而已,不是用来显得很酷的,需要了才用它。

Java语言用个数组,其实也能模拟指针的大部分功能的。其实我作为C程序员,我们平时工作时对指针是很谨慎的,能不用都不用,尽量用引用来代替,为啥,因为危险,容易出错。

数据结构,计算机组成原理,算法语言,编译原理,嗯,还有个图论,这几门应该算最经典的计算机理论了,但是,也没那么神秘的,书店里面有,自己没事买几本回来看看就好了,生活是没有考试的,不需要你必须考够100分才能找到工作,了解,理解就好了,背书是背不出好程序员的。你说对吧?

其实这几门,不用C和C++语言,用Java语言一样可以学习的。嗯,编译原理可能够呛,需要理解一点C。

另外,我再给你透露一点点,其实真正实际应用中,我们对于上述基础知识用得很少,用得最多的,其实就是数据结构里面的队列了,其他,包括栈都很少用,C程序员也不是每天都从底层,从0做起的,还是有很多工具套用的。这和Java语言从框架开发是一个道理。

反而有一门课程建议你好好学,就是概率和统计学,这门知识是我现在应用最多的,很多时候,我们评估软件系统性能,瓶颈优化,都是在用这个学问。程序员做久了,可能大多数时候都是和这个在打交道,建议买本好好看。

总结一下吧,建议你目前暂时不要辞职,既然选择了Java和数据库应用开发,选择了B/S模型,你耐心做3年再看,也许3年后,你自己的想法就变了。

C可以学,你说的课程都可以学,不过,不要辞职专门学,先赚钱养活自己,再利用时间学习,你这么大的决心,每天晚上就不要看电视了,那你每天晚上,19:00~24:00,至少有5个小时来学习,利用好了,我敢说比你在大学里面效率高。

看书学习不是什么神秘,神圣的事情的,也不需要什么斋戒沐浴,念几天经才能学习,我觉得就和我们吃饭喝水一样,随时都可以学的,找几本书,就在床头放着,每天晚上看看,几个月也就看完了,又有多难嘛?

关键是,养成习惯。

你说对不?呵呵,先说到这里,有问题再问哈。

最后补充一点,如果学习C,并且有一定基础的话,等我书出来看看吧,里面的跨平台开发工程库,可以帮助你迅速掌握嵌入式底层的一些技巧。不过,要有基础哈,一点不会C看不明白的。

7. 编译原理究竟有没有用对编程的人

我跟你说,编译原理太有用了。
我是做手机游戏的,现在做一个游戏引擎。既然是引擎,就需要提供抽象的东西给上层使用。这里,我引入了脚本系统。
这个脚本系统包括一堆我根据实际需求自行设计的指令集,包括基本的输入输出,四则运算,系统功能调用,函数声明,调用等等(其实你要是用过lua或者其他游戏脚本你就知道了。)整个结构包括指令集、编译器、虚拟机等部分。这样,引擎提供一些基础服务,比如绘图,计算位置等,脚本就可以非常简单控制游戏。甚至快速构建新游戏。你应该知道QUAKE引擎吧?
这里提供给你一个计算器的小程序,应用了EBNF理论,支持表达式,比如(2+3*6)*4+4,你自己体验一下它的简洁和强大。
/*
simple integer arithmetic calculator according to the EBNF
<exp> -> <term>{<addop><term>}
<addop>->+|-
<term>-><factor>{<mulop><factor>}
<mulop> -> *
<factor> -> ( <exp> )| Number
Input a line of text from stdin
Outputs "Error" or the result.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

char token;/*global token variable*/
/*function prototypes for recursive calls*/
int exp(void);
int term(void);
int factor(void);

void error(void)
{
fprintf(stderr,"Error\n");
exit(1);
}

void match(char expectedToken)
{
if(token==expectedToken)token=getchar();
else error();
}

main()
{
int result;
token = getchar();/*load token with first character for lookahead*/
result = exp();
if(token=='\n')/*check for end of line */
printf("Result = %d\n",result);
else error();/*extraneous cahrs on line*/
return 0;
}

int exp(void)
{
int temp = term();
while((token=='+')||(token=='-'))
switch(token)
{
case '+':
match('+');
temp+=term();
break;
case '-':
match('-');
temp-=term();
break;
}
return temp;
}

int term(void)
{
int temp = factor();
while (token=='*')
{
match('*');
temp*=factor();
}
return temp;
}

int factor(void)
{
int temp;
if(token=='('){
match('(');
temp = exp();
match(')');
}
else if(isdigit(token)){
ungetc(token,stdin);
scanf("%d",&temp);
token = getchar();
}
else error();
return temp;
}
其实编程学到一定程度总是没有方向了,总是在问学C/C++下一步怎么学啊,觉得掌握了该语言了云云,实际上,你缺少的就是这些软的东西,缺少的是理论。
编译原理不是单一的理论,它涵盖了一个niche,里面可以学到很多其他知识,比如正则表达式、BNF、EBNF、分析树、语法树还有很多运行时环境等知识
这些给你带来的是非常丰厚的回报。不说多了,学完运行时,你就会加深对C++语言本身的理解。
你要想有好的发展,还是学吧。

8. 有关编译原理

编译原理的"原理"其实跟C语言关系不太大,除非你是想亲手实践一个小型的编译器,对于数据结构,你明白基本的队列和栈基本就够了,如果还没全懂,不必怕看不懂编译原理.
编译原理比较难学,但是在学的过程中我觉得一定要明白每一种词法分析到底是在干什么,不要只为了编译原理的题而学,那样我觉得学起来会非常抽象.
至于书,我觉得还是使用清华大学的<编译原理>,张素琴,吕映芝那本.这本书也是编译原理的经典教材,虽然不是特别好懂,但我觉得这本书你"熟读千遍",肯定会有所收获.把前七章学完,"原理"部分就完毕了.
最好这门课找些视频教程学来会容易一些,否则真是要自己硬看的话还是有一定难度的...

9. 学完编译原理这门课,用c语言或者c++语言,编一个预测分析的程序,对预测分析也至少测试三个句子(含错误

我写好的.
scan.h

/*
* scan.h
* ccompiler
*
* Created by on 09-10-12.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/

#ifndef _SCAN_H_
#define _SCAN_H_

#include <string>
#include <fstream>
using namespace std;

typedef enum
{
ENDFILE,ERROR,
ELSE,IF,INT,RETURN,VOID,WHILE,
ID,NUM,
ASSIGN,EQ,LT,GT,LE,GE,NE,ADD,SUB,MUL,DIV,SEMI,LPAREN,RPAREN,LZK,RZK,LDK,RDK,COMMA
}
TokenType;

class Scan
{
private:
string tokenStr;
string linebuffer;
ifstream * in;
int linepos;
int lineno;
bool EOF_Flag;
bool traceScan;
void printToken(TokenType tt,const string &tok);
public:
Scan(ifstream * in)
{
this->in=in;
linepos=0;
linebuffer="";
lineno=0;
EOF_Flag=false
traceScan=true;
}
char getNextChar();

void ungetNextChar();

TokenType reservedLookup(string &s);

void setTraceScan(bool f);

bool getTraceScan();

TokenType getToken();

string getTokenStr();

};
#endif

scan.cpp

/*
* scan.cpp
* ccompiler
*
* Created by on 09-10-12.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/

#include <string>
#include <fstream>
#include <iostream>
using namespace std;

#include "scan.h"

typedef enum

StateType;

static struct
{
string str;
TokenType tok;
} reservedWords[6]
=,,,,,};

char Scan::getNextChar()
{
if(linepos>=linebuffer.size())
{
if(getline(*in,linebuffer))
{
linebuffer+="\n";
lineno++;
linepos=0;
return linebuffer[linepos++];
}
else
{
EOF_Flag=true;
return EOF;
}
}
else
return linebuffer[linepos++];
}

void Scan::ungetNextChar()
{
if(!EOF_Flag) linepos--;
}

TokenType Scan::reservedLookup(string &s)
{
for(int i=0;i<6;i++)
if(s==reservedWords[i].str)
return reservedWords[i].tok;
return ID;
}

void Scan::setTraceScan(bool f)
{
traceScan=f;
}

bool Scan::getTraceScan()
{
return traceScan;
}

TokenType Scan::getToken()
{
tokenStr="";
TokenType currentToken;
StateType state=START;

while(state!=DONE)
{
bool save=false;
char c=getNextChar();
switch (state) {
case START:
if(c>='0'&&c<='9'){
state=INNUM;
save=true;
}
else if((c>='a'&&c<='z')||(c>='A'&&c<='Z')){
state=INID;
save=true;
}
else if(c==' '||c=='\t'||c=='\n')
{
state=START;
}
else if(c=='/'){
state=SLASH;
}
else if(c=='='){
state=TEMPE;
}
else if(c=='>')
state=TEMPG;
else if(c=='<')
state=TEMPL;
else if(c=='!')
state=INNOTEQ;
else
{
state=DONE;
switch (c) {
case EOF:
currentToken=ENDFILE;
break;
case '+':
currentToken=ADD;
break;
case '-':
currentToken=SUB;
break;
case '*':
currentToken=MUL;
break;
case '(':
currentToken=LPAREN;
break;
case ')':
currentToken=RPAREN;
break;
case '[':
currentToken=LZK;
break;
case ']':
currentToken=RZK;
break;
case '{':
currentToken=LDK;
break;
case '}':
currentToken=RDK;
break;
case ';':
currentToken=SEMI;
break;
case ',':
currentToken=COMMA;
break;
default:
currentToken=ERROR;
break;
}
}
break;
case INNUM:
if(c<'0'||c>'9')
{
ungetNextChar();
state=DONE;
currentToken=NUM;
}
else
save=true;
break;
case INID:
if(!((c>='a'&&c<='z')||(c>='A'&&c<='Z')))
{
ungetNextChar();
state=DONE;
currentToken=ID;
}
else
save=true;
break;
case SLASH:
if (c!='*')
{
state=DONE;
currentToken=DIV;
}
else
state=INCOMMENT1;
break;
case INCOMMENT1:
if (c!='*')
state=INCOMMENT1;
else if(c==EOF){
state=DONE;
currentToken=ENDFILE;
}
else
state=INCOMMENT2;
break;
case INCOMMENT2:
if (c=='*') {
state=INCOMMENT2;
}else if(c=='/'){
state=START;
}else if(c==EOF){
state=DONE;
currentToken=ENDFILE;
}else {
state=INCOMMENT1;
}
break;
case TEMPE:
if (c=='=') {
state=DONE;
currentToken=EQ;
}else{
state=DONE;
ungetNextChar();
currentToken=ASSIGN;
}
break;
case TEMPG:
if (c=='=') {
state=DONE;
currentToken=GE;
}else{
state=DONE;
ungetNextChar();
currentToken=GT;
}
break;
case TEMPL:
if (c=='=') {
state=DONE;
currentToken=LE;
}else{
state=DONE;
ungetNextChar();
currentToken=LT;
}
break;
case INNOTEQ:
if (c=='=') {
state=DONE;
currentToken=NE;
}else {
state=DONE;
ungetNextChar();
currentToken=ERROR;
}
break;

default:
cerr<<"Scanner Bug: state= "<<state<<endl;
state=DONE;
currentToken=ERROR;
break;
}
if(save){
string newChar(1,c);
tokenStr+=newChar;
}
if (state==DONE&¤tToken==ID)
currentToken=reservedLookup(tokenStr);
}
if (traceScan) {
cout<<"Scan at line "<<lineno<<" token: ";
printToken(currentToken, tokenStr);
cout<<endl;
}
return currentToken;
}

string Scan::getTokenStr()
{
return tokenStr;
}

void Scan::printToken(TokenType tt,const string &tok)
{
string type;
switch (tt) {
case ENDFILE:
type="EOF";
break;
case ERROR:
type="ERROR";
break;
case ELSE:
case IF:
case INT:
case RETURN:
case VOID:
case WHILE:
type="reserved word";
break;
case ID:
type="ID";
break;
case NUM:
type="NUM";
break;
case ASSIGN:
type="=";
break;
case EQ:
type="==";
break;
case LT:
type="<";
break;
case GT:
type=">";
break;
case LE:
type="<=";
break;
case GE:
type=">=";
break;
case NE:
type="!=";
break;
case ADD:
type="+";
break;
case SUB:
type="-";
break;
case MUL:
type="*";
break;
case DIV:
type="/";
break;
case SEMI:
type=";";
break;
case LPAREN:
type="(";
break;
case RPAREN:
type=")";
break;
case LZK:
type="[";
break;
case RZK:
type="]";
break;
case LDK:
type="{";
case RDK:
type="}";
break;
case COMMA:
type=",";
break;
default:
break;
}
cout << type<<": "<<tok;
}

main.cpp

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#include "scan.h"

int main (int argc, char * const argv[]) {
string fileName="/Users/huanglongyin/scan_in.txt";
//cout<< "File name: ";
//cin>>fileName;
ifstream in(fileName.c_str());
if(!in){
cerr<<"Error occurs when openning file "<<fileName<<endl;
return -1;
}
Scan scan(&in);
while(scan.getToken()!=ENDFILE);
return 0;
}

热点内容
手机f加密 发布:2024-05-19 03:28:47 浏览:225
用什么密码写日记 发布:2024-05-19 03:27:57 浏览:303
数据库access2003 发布:2024-05-19 02:49:39 浏览:620
碧蓝航线pc挂机脚本 发布:2024-05-19 02:30:03 浏览:589
脚本fir 发布:2024-05-19 02:28:57 浏览:261
阿里云独享服务器 发布:2024-05-19 02:23:54 浏览:253
织梦源码ga 发布:2024-05-19 02:23:20 浏览:571
java文件名后缀 发布:2024-05-19 02:14:39 浏览:956
快手点榜脚本 发布:2024-05-19 02:08:44 浏览:163
pythonforinkeys 发布:2024-05-19 01:55:44 浏览:793