精华内容
下载资源
问答
  • 编译原理实验手册

    2017-08-18 23:18:49
    编译原理实验手册 一、实验目的 编译原理是一门实践性很强的课程,但由于课时所限,只能在课堂上讲授一些通用的原理和方法。而为了真正学好这门课程,必须自己动手构造出一个编译器,才能对书里讲到的原理、方法和...

    编译原理实验手册

    一、实验目的

    编译原理是一门实践性很强的课程,但由于课时所限,只能在课堂上讲授一些通用的原理和方法。而为了真正学好这门课程,必须自己动手构造出一个编译器,才能对书里讲到的原理、方法和技术有较全面的体会,才能对学生以后的程序设计和解决实际问题的能力有所帮助。

    实际的编译程序是十分复杂的,有时由多达十几万条指令组成。为此,编译原理的实践教学,采用简化编译过程的办法,选择最关键的三个环节──词法分析、语法分析、语义分析和中间代码产生,每个环节作为一个实践课题,逐步深入,扩展功能,直至得到一个简单实用的编译器。本实验不涉及到优化。

    二、实验内容

    任何一个实用的高级语言,其语法都比较复杂,如选其作为源语言,很难实践全过程。故本试验将定义一个简化的语言──PASCAL语言的一个子集作为源语言,分三个课题、一步步地构造出它的编译程序。所有试验项目前后贯穿这一条主线进行。本实验共进行6周,每周3学时,共18学时。本实验主要包括以下三个课题:

    1.  词法分析:以源程序为输入,输出单词符号流;

    2.  语法分析:以源语言的文法为依据,调用词法分析器,使用递归下降分析法或算符优先分析法或LR(1)分析法,构造能识别源语言各种语法结构的语法分析器;

    3.  语义分析和中间代码产生:使用语法制导翻译技术,对源语言程序进行简单的翻译,输出四元式序列。

    在本节的第三部分给出了PASCAL语言两个子集的文法,对这些文法稍加变换,即可获得用于语法分析的LL(1)文法或LR(1)文法。学生可以直接选择一个作为编译器的源语言,也可以对这些文法进行改造,以获得能力更为强大的源语言。学生也可以自己设计源语言,来完成这些题目;唯一的要求是源语言必须包含三种基本的程序设计结构(顺序、选择、循环)和至少两种不同的数据类型。

    本实验要求:

    ·        所有的输入输出均采用文件形式。

    ·        独立完成。

    ·        语言不限,开发工具不限;但必须有可运行的程序和规范的注释。

    三、PASCAL语言子集的文法

    由于Pascal语言结构严谨,层次清晰,语法与C语言接近,也便于理解,因此本实验抽取Pascal语言的一个子集,稍加改造,作为源语言,姑且命名为LittleP。一个LittleP程序由一系列全局数据声明和一个主程序体组成。所有数据采用静态存储分配,没有I/O,只支持一种基本数据类型:无符号整数。

    1.  LittleP的文法:

     

    〈程序〉→〈程序首部〉〈程序体〉

    〈程序首部〉→ program〈程序名〉
      〈程序体〉→〈变量声明〉〈复合语句〉

     

    〈变量声明〉→var〈变量定义列表〉|〈空〉

    <变量定义列表> → 〈变量定义〉〈变量定义列表〉|〈变量定义〉

    〈变量定义〉→〈变量名列表〉: <类型>

    <变量名列表> → 〈变量名〉|〈变量名〉,〈变量名列表〉

    <类型> →  integer

     

    〈复合语句〉→begin〈语句块〉end

    〈语句块〉→〈语句〉|〈语句〉 〈语句块〉

    〈语句〉→〈赋值语句〉|〈条件语句〉|〈循环语句〉|〈复合语句〉|〈空〉

     

    〈赋值语句〉→〈左部〉:=〈右部〉

    〈左部〉→〈变量名〉

    〈右部〉→〈算术表达式〉

     

    〈条件语句〉→ if〈关系表达式〉then〈语句〉else〈语句〉

     

    〈循环语句〉→ while〈关系表达式〉do〈语句〉

     

    <关系表达式> →〈算术表达式〉〈关系运算符〉〈算术表达式〉

    <算术表达式> → 〈项〉| 〈算术表达式〉〈加运算符〉〈项〉

    <项> → 〈因子〉| 〈项〉〈乘运算符〉〈因子〉

    〈因子〉→〈变量名〉|(〈算术表达式〉) |〈整数〉

     

    〈程序名〉→〈标识符〉

    〈变量名〉→〈标识符〉

    〈标识符〉→〈字母〉|〈标识符〉〈字母〉|〈标识符〉〈数字〉

     

    〈整数〉→〈数字〉|〈整数〉〈数字〉

    〈关系运算符〉→ < | <= || >= | > | <>

    〈加运算符〉→ +| -  

    〈乘运算符〉→ *| /  

    〈字母〉→ a|b||x|y|z

    〈数字〉→ 1|2|3|4|5|6|7|8|9|0

     

    2.在此基础上加以扩充,可得功能较强的一个 LittleP 语言的超集:LittleP+。该语言引入了实数、一维数组和过程、函数的定义,参数传递采用传值方式。另外,加入了I/O支持,编译器提供两个系统函数:read()和write()。

     

    〈程序〉→〈程序首部〉〈程序体〉

    〈程序首部〉→ program〈程序名〉
      〈程序体〉→〈变量声明〉<分程序声明>〈复合语句〉

     

    〈变量声明〉→var〈变量定义列表〉|〈空〉

    <变量定义列表> → 〈变量定义〉〈变量定义列表〉|〈变量定义〉

    〈变量定义〉→〈变量名列表〉: <类型>

    <变量名列表> → 〈变量名〉|〈变量名〉,〈变量名列表〉

     

     <类型> → <基本类型>|<数组>

    <基本类型> → integer | real

    <数组> →array [〈下界〉..〈上界〉] of <基本类型>

    <下界> →<整数>

    <上界> →<整数>

     

    <分程序声明> → 〈分程序〉 〈分程序声明〉|〈空〉

    〈分程序〉→〈分程序首部〉〈变量声明〉〈复合语句〉

    〈分程序首部〉→ procedure〈过程名〉( <形参列表> );

    | function〈函数名〉( <形参列表> ) : <基本类型>

    <形参列表> → 〈形参定义〉 ,〈形参列表〉|〈形参定义〉|〈空〉

    〈形参定义〉→〈变量名列表〉: <基本类型>

     

    〈复合语句〉→begin〈语句块〉end

    〈语句块〉→〈语句〉|〈语句〉〈语句块〉

    〈语句〉→〈赋值语句〉|〈条件语句〉|〈循环语句〉

    |〈过程调用语句〉|〈复合语句〉|〈读写语句〉|〈空〉

     

    〈赋值语句〉→〈左部〉:=〈右部〉

    〈左部〉→〈变量名〉|〈变量名〉[ 算术表达式 ]

    〈右部〉→〈算术表达式〉

     

    〈条件语句〉→ if〈关系表达式〉then〈语句〉else〈语句〉

     

    〈循环语句〉→ while〈关系表达式〉do〈语句〉

     

    〈过程调用语句〉→〈过程名〉( <实参列表> )
                          
    |〈函数名〉( <实参列表> )

    <实参列表> → 〈算术表达式〉| 〈算术表达式〉,〈实参列表〉|〈空〉

     

    〈读写语句〉→ read ( <变量名列表> ) |write (<实参列表> )

     

    <关系表达式> →〈算术表达式〉〈关系运算符〉〈算术表达式〉

    <算术表达式> → 〈项〉| 〈算术表达式〉〈加运算符〉〈项〉

    <项> → 〈因子〉| 〈项〉〈乘运算符〉〈因子〉

    〈因子〉→〈变量名〉|(〈算术表达式〉)|〈函数名〉(<实参列表>)

               |〈变量名〉[ 算术表达式 ] |〈整数〉|〈实数〉

     

    〈程序名〉→〈标识符〉

    〈变量名〉→〈标识符〉

    〈过程名〉→〈标识符〉

    〈函数名〉→〈标识符〉

    〈标识符〉→〈字母〉|〈标识符〉〈字母〉|〈标识符〉〈数字〉

     

    〈整数〉→〈数字〉|〈整数〉〈数字〉

    〈实数〉→〈整数〉 . 〈整数〉

    〈关系运算符〉→ < | <= || >= | > | <>

    〈加运算符〉→ +| -  

    〈乘运算符〉→ *| div | mod  

    〈字母〉→ a|b||x|y|z|A|B||X|Y|Z

    〈数字〉→ 1|2|3|4|5|6|7|8|9|0

     

    3.对源程序语法的其他说明:

    a)  出现在{ }里的所有字符作为注释跳过。

    b)  各单词符号之间的空格可有可无,但关键字和标识符必须分隔开来。

    c)  过程没有返回值,只能出现在过程调用语句中;函数有且只有1个返回值,只能出现在算术表达式中或作为赋值语句的右部。函数返回值通过函数名带回,因此在函数体内必须给函数名赋值。

    d)  标识符的长度不得超过8个字符。

    e)  关键字保留,包括read和write。

    四、实验要求:

    每个课题完成后写出实验报告。实验报告应该包括:

    ·        程序设计时考虑的算法和主要的数据结构;

    ·        可执行的程序

    ·        至少2个测试用例,包括:

    §  至少1个合法的源程序及其运行结果;

    §  至少1个非法的源程序及其错误报告。

    展开全文
  • 编译原理实验报告(词法分析)编译原理实验报告(词法分析)
  • 编译原理心得体会编译原理心得体会国际学院 0802 杨良燕 200819100227《编译原理》课程学习心得《编译原理》是计算机专业的一门重要课程,正如教材第一章的引论所述,“编译程序是现代计算机系统的基本组成部分之一...

    编译原理心得体会

    编译原理心得体会

    国际学院 0802 杨良燕 200819100227

    《编译原理》课程学习心得

    《编译原理》是计算机专业的一门重要课程,正如教材

    第一章的引论所述,“编译程序是现代计算机系统的基本组成部分之一”。“一个编译程序就是一个语言翻译程序,语言翻译程序把一种语言(源语言)书写的程序翻译成另一种语言(目标语言)的等价程序”。

    通过这一学期的学习,我觉得编译原理是一门理论性很强的课程,从文法和语言的概念到LL(1)文法和LR(0)文法的分析,几乎都是对具体问题的抽象。因而,我们需要更多的时间来理解、掌握相关的知识,当然在这一过程中也存在很多问题,比如我们后期学习具体文法的分析方法时,对于文法的概念不够清晰,影响了上课的效率,知道老师再次给我们讲解了文法等基础的知识点,我们才慢慢掌握后面所学的LL(1)文法等,也发现了知识点之间的关联。此外,这门课程的课时被安排得很少,一周只有一次,这样很不利于我们对这门重要课程的理解和掌握。但是我觉得我们很幸运,因为老师在有限的课程中尽量将知识点以比较容易接受的方式给我们讲解,教我们用简单的方法理解记忆不同的知识,对于我们提出的问题,无论课上或是课外,老师一直是不厌其烦,甚至利用课余时间为我们讲解重要的难题。

    编译原理这门课程不仅仅在于其本身的理论价值,更在于为我们解决问题提供的思维方式和方法。从LL(1)到LR(0),问题不断被解决的同时,又有一个个新的问题提了出来。对计算机语言世界的知识积累,像滚雪球一样越滚越大。这个逐渐递进,逐渐解决问题的过程对我来说是收获很大的。整个过程好像踏着前人研究编译理论的路线,不断感觉他们遇到的问题,更重要的是他们解决问题的思路。编译原理的课程带给我的不只是如何去编译程序这样的理论知识,相信更重要的是一种如何“自动计算”的思路。通过对相关编译问题的具体分析,让我体会最深的是一种“自动计算”的思想,同时完成编译试验后,更是感到了一种“自动计算”的快乐。”然而我明白自己虽然对编译有了一定的了解,我懂得了文法的分析,学会了构造确定和非确定有限自动机,学会了LL(1)文法和LR(0)文法等,但是并没有完全掌握,对于这些知识点的实质性和其他方面,更是认识不深。作为一名学习计算机科学与技术的学生,我明白编译原理是软件工程的基础,课程的结束并不意味着学习的结束,只有通过以后的学习,才能更深入地了解编译原理。

    篇二:编译原理课程设计心得体会

    编译原理课程设计心得体会

    经过一个星期的编译原理课程设计,本人在刘贞老师的指导下,顺利完成该课程设计。通过该课程设计,收获颇多。

    一、对实验原理有更深的理解

    通过该课程设计,掌握了什么是编译程序,编译程序工作的基本过程及其各阶段的基本任务,熟悉了编译程序总流程框图,了解了编译程序的生成过程、构造工具及其相关的技术对课本上的知识有了更深的理解,课本上的知识师机械的,表面的。通过把该算法的内容,算法的执行顺序在计算机上实现,把原来以为很深奥的书本知识变的更为简单,对实验原理有更深的理解。

    二、对该理论在实践中的应用有深刻的理解

    通过把该算法的内容,算法的执行顺序在计算机上实现,知道和理解了该理论在计算机中是怎样执行的,对该理论在实践中的应用有深刻的理解。

    三、激发了学习的积极性

    通过该课程设计,全面系统的理解了编译原理程序构造的一般原理和基本实现方法。把死板的课本知识变得生动有趣,激发了学习的积极性。把学过的计算机编译原理的知识强化,能够把课堂上学的知识通过自己设计的程序表示出来,加深了对理论知识的理解。以前对与计算机操

    作系统的认识是模糊的,概念上的,现在通过自己动手做实验,从实践上认识了操作系统是如何处理命令的,如何协调计算机内部各个部件运行,对计算机编译原理的认识更加深刻。课程设计中程序比较复杂,在调试时应该仔细,在程序调试时,注意指针,将不必要的命令去除。

    在这次课程设计中,我就是按照实验指导的思想来完成。加深了理解文件系统的内部功能及内部实现,培养实践动手能力和程序开发能力的目的。

    四、理解了该知识点以及学科之间的融合渗透

    本次课程设计程序部分是用c语言编写的,把《计算机操作系统》,《编译原理》,《算法分析与设计》《c语言》四门学科联系起来,把各个学科之间的知识融合起来,把各门课程的知识联系起来,对计算机整体的认识更加深刻。使我加深了对《计算机操作系统》,《编译原理》,《算法分析与设计》《c语言》四门课程的认识。

    篇三:编译原理课程设计心得体会

    经过一个星期的编译原理课程设计,本人在刘贞老师的指导下,顺利完成该课程设计。通过该课程设计,收获颇多。

    一、对实验原理有更深的理解

    通过该课程设计,掌握了什么是编译程序,编译程序工作的基本过程及其各阶段的基本任务,熟悉了编译程序总流程框

    展开全文
  • 编译原理是一门抽象性比较高的课程,本实验报告有助于各位在实验中深入理解编译原理的基本运作
  • 编译原理 词法分析 一、 实验题目 3 二、 实验目的 3 三、 实验要求 4 四、 实验步骤 4 基本设计思路 4 流程框图 5 算法设计 6 函数相关说明 6 输入与输出 8 程序运行结果 9 五、 实验方案设计实现 9 六、 实验程序...
  • 编译原理实验报告

    千次阅读 2016-11-23 10:54:43
    20160119提交的编译原理实验报告,一共有三次提交。程序其实不完美。 最近分析RFC等系列文档需要涉及词法、语法、语义。于是整合一下,回顾一下。

    20160119提交的编译原理实验报告,一共有三次提交。程序其实不完美。

    最近分析RFC等系列文档需要涉及词法、语法、语义。于是整合一下,回顾一下。

    含义介绍:

    词法分析Lexical analysis或Scanning:根据代码文本区分单词类型 保留字(while  if  else ...),数据类型(整型,字符,浮点..),操作符(+ - * | & ...)  ,若有对应单词类型继续语法分析,否 则 词法异常

    语法分析Syntax analysis或Parsin:根据给定的语法,在词法分析器给的结果分析是否符合语法规则。LL分析法和LR分析法。符合继续语义分析,否则 语法异常

    语义分析semantic analysis:在语法分析的基础上,给出对应语法语句的语义规则,根据语义规则得到中间代码(eg.三地址码(类似汇编))


    编译实验(一)词法分析

    [实验内容]
    经过改造的PASCAL语言源程序作为词法分析对象,选取它的一个适当大小的子集,可以选取一类典型单词(改造部分必须完成)。
    基本要求:对源程序从左到右进行扫描,对组成源程序的字符串拼接成为词素;并把其转换成属性字输出,并管理符号表,在分析结束后将符号表顺序输出,处理词法错误(要给出错误的行号)。
    [语言的改造部分]
    (1)如果一个整数以“0X”开头,则按三十六进制数处理。此时后面可跟后跟0,1,…,9,A,B,…Z。词法分析时,应将三十六进制数转化为十进制整数。
    如0X1AG   要转化为1672
    注:PSACAL语言大小写不敏感
    (2)能处理注释,注释以--开头,以换行结束。
         例如: --sort by index
    (3)大于等于224的整数报越界错误;标识符长度大于32报错,标识符的有效长度为8。


    输入:WHILE (next<>NIL)  DO BEGIN x:=6; Y:=xy+z END;
    输出:
    <while>
    <(> 
    <id,next> 
    <<>
    <nil> 
    <)> 
    <do> 
    <begin> 
    <id, x>
    <:=> 
    <num, 6> 
    <;> 
    <id,y> 
    <:=> 
    <id, xy> 
    <+> 
    <id, z> 
    <end> 
    <;>
    部分代码小组成员的写的


    使用说明:


    (1)       运行.cpp文件,在当前目录生成Debug文件夹和如下文件: output.txt,.dsp,.ncb,.plg;
    (2)       新建input.txt,并将output.txt和input.txt移到Debug目录下;
    (3)       在input.txt中输入pascal语言,双击.exe可执行文件,在output.txt中则自动输出词法分析结果。

    #include<iostream>
    #include<string>
    #include<vector>
    using namespace std;  
    #define LENWords 36
    #define Max10Len 8
    #define Max36Len 4
    string words[]={"program","function","procedure","array","const","file","lable","packed","var","record","set","type","of",
    "case","do","downto","else","for","goto","if","repeat","then","to","until","while","with","forward","and","not","or",
    "in","div","mod","begin","end","nil"};/*36/82,"false","true","maxint","interger","real","char","string","boolean","text",
    "input","output","abs","arctan","chr","cos","eof","eoln","exp","odd","ord","pred","round","sin","sqr","sqrt","succ","trunc",
    "get","new","pack","page","put","read","readln","reset","rewrite","unpack","write","writeln","longint","int64","shortint",
    "single","double","ansistring","qword"*/
    long int line;
     int lenth;
     string xiaoshu;
    vector<string>worddd;
    void JiaRu_In(string ans)
    {
    	for(int i=0;i<worddd.size();i++)
    		if(worddd[i]==ans)return;
    		worddd.push_back(ans);
    		
    }
    bool IsLetter_ZiMu(char c)/*判断是否为字母*/
    {
       if(c>='a'&&c<='z'||c>='A'&&c<='Z')
    	   return true;
       return false;
    }
    bool IsDigit_ShuJi(char c)/*判断是否为数字*/
    {
    	if(c>='0'&&c<='9')
    		return true;
    	return false;
    }
    bool Is0X_ShiLIu(char c)/*判断数字是否为三十六进制*/
    {
    	if(c=='x'||c=='X')return true;
    	return false;
    } 
    long int jisuan(char (*c),long int sum)/*十进制值的计算函数*/
    {  
        if( IsDigit_ShuJi(*c))
    	{ 
    		do
    		{
    		if(lenth<Max10Len)
    		sum=sum*10+(*c)-'0'; 
    	   	lenth++;
    		} while(((*c)=getchar())>='0'&&(*c)<='9');
    	}
    	if((*c)=='.')
    	{
    	    lenth=0;
    		xiaoshu='.';
            while(((*c)=getchar())>='0'&&(*c)<='9')
    			xiaoshu+=(*c); 
    	}
    	return sum; 
    }
    long int exchange(char (*c))/*将36进制转换为10进制*/
    {
    	long int t=0;
    	while(((*c)=getchar())>='0'&&(*c)<='9'||IsLetter_ZiMu((*c)))
    	{ 
    		if(IsDigit_ShuJi((*c)))  t=t*36+(*c)-'0';
            else if((*c)>='a'&&(*c)<='z')  t=t*36+(*c)-'a'+10;
    		else  if((*c)>='A'&&(*c)<='Z')   t=t*36+(*c)-'A'+10; 
    		lenth++;
    	}
    	if(lenth>4)
    	{
    		t=1<<24;
    		t++;
    	}
    	return t;
    }  
    bool judge_digitscale(long int ansInt)/*判断数字是否越界*/
    {
        long int a;
    	a=1<<24;
    	if(ansInt>=a)
    		return false; 
    	return true;
    }
    void getWord(string*ans,char *c)
    {
       	 do
    	 { 
    		 if((*c)>='A'&&(*c)<='Z')(*c)=(*c)-'A'+'a';
    		 (*ans)+=(*c); 
    	 }
         while(((*c)=getchar())=='_'||IsDigit_ShuJi((*c))||IsLetter_ZiMu((*c)));
    }
    bool InTheWords(string*ans)
    { 
    	for(int i=0;i<LENWords;i++)
    		if(words[i]==(*ans))return true;
    		return false;
    }
    void AnalyFunc()
    { 
    	bool valid;
    	char c=getchar();
       for(;c!=EOF;)
       {
    	   for(valid=false;!valid;)
    	   {
    		   if(c==' '||c=='\t')c=getchar();
    		   else if(c=='\n')
    		   {
    			   line++;
    			   c=getchar();
    		   }
    			else valid=true;
    	   }
           string ans="";
           long int ansInt=0;
    	   xiaoshu='\0';
    	   lenth=0;
    	   switch(c)
    	   { 
    	      case '-': 
                      c=getchar();
    				  if(c=='-')
    				  {
    					  getline(cin,ans);
    					  line++;
    					  c=getchar();
    				  }
    				  else cout<<"<->"<<endl;
    				  valid=false;
    			      break;
    		  case '<':
    			      c=getchar();
    				  if(c=='='){cout<<"<<=>"; c=getchar();}
    				  else if(c=='>'){cout<<"<<>>"; c=getchar();}
    				  else if(c=='<'){cout<<"<<<>"; c=getchar();}
    			      else cout<<"<<>";
    			      valid=false; 
    				  cout<<endl;
    				  break; 
    		  case '>':
                      c=getchar();
    				  if(c=='='){cout<<"<>=>";  c=getchar();} 
    				  else if(c=='>'){ cout<<"<>>>"; c=getchar();}
    			      else cout<<"<>>";
    			      valid=false; 
    				  cout<<endl;
    				  break; 
    		  case ':':
                      c=getchar();
    				  if(c=='='){cout<<"<:=>";c=getchar();}
    			      else cout<<"<:>";
    			      valid=false; 
    				  cout<<endl;
    				  break; 
    	   }
    	   if(valid)
    	   {
    	      if(IsDigit_ShuJi(c))
    		  { 
    		     ansInt=c-'0';
    			 c=getchar();
    		     if(ansInt==0&&Is0X_ShiLIu(c))
    				 ansInt=exchange(&c);
    			 else  ansInt=jisuan(&c,ansInt);
    		     if(judge_digitscale(ansInt))
    			 {
    				 if(xiaoshu.size()==0)
    				 cout<<"<num,"<<ansInt<<">";
    				 else
    				 { 
    				   cout<<"<num,"<<ansInt<<xiaoshu<<">";
    				 }
    			 }
    		     else cout<<"error line"<<line<<":out of range";/*数字越界*/
    		  }
    		  else if(IsLetter_ZiMu(c)||c=='_')
    		  { 
    			  getWord(&ans,&c);
    			  if(InTheWords(&ans))
    				  cout<<"<"<<ans<<">";
    			  else if(ans.size()>32)  cout<<"error line"<<line<<":invalid identifier";/*标识符越界,输出无效的标识*/
    			  else 
    			  { 
    				       if(ans.size()>8)
    					   {
    				         ansInt=ans.size()-8; 
    				         ans.erase(8,ansInt);
    					   }
    				      JiaRu_In(ans);
    				      cout<<"<id,"<<ans<<">"; 
    			  }
    		  }
    		  else {cout<<"<"<<c<<">"; c=getchar();}/*_+_*_/_&_^_|_~_=_!_(_)_._'*/
             cout<<endl;
    	   }
       }
    }
    int main()
    { 
    	freopen("input.txt","r",stdin);
    	freopen("output.txt","w",stdout);
    	line=1;
    	AnalyFunc();
    	line=0;
    	for(line=0;line<LENWords;line++)
    	cout<<line<<" "<<words[line]<<endl;
    	for(int i=0;i<worddd.size();i++)
    		cout<<line+i<<" "<<worddd[i]<<endl;
    	return 0;
    }

     编译实验(二)语法分析  

    采用的是手工制造SLR(1)
    这个实验中的SLR(1)组员做的还有错误未订正,后面三个实验整合一起的错误比较少

    [实验内容 ]
      对所给语言文法的子集,构造SLR(1)分析表,编制语法分析程序,要求将错误信息输出到错误文件中,并输出分析句子的过程(显示栈的内容,采取的动作);
      实验报告必须包括采用的文法,设计的思路,SLR(1)分析表,以及测试报告(输入测试例子,输出结果)。
    [文法 ]
     S → program id ( id_lists );  compound_stmt .
    id_lists → id | id_lists , id
    compound_stmt →begin optional_stmts end
    optional_stmts →stmts | ε
    stmts → stmt | stmts; stmt
    stmt  → id := expr  |  compound_stmt | if bool then stmt |
       if bool then stmt else stmt | while bool  do stmt
    bool → expr < expr
    expr → expr + term  | term
    term →term * factor | factor
    factor →  id | num
    [样例程序(记号流版) ]
              program id ( id , id ) ;
        begin
     id:=num;
    if id<id then id:=id
                   else begin
    while id+id<id do id:=id+num;
    id:=id*num
    end
    end.
    使用说明:


    (1)运行.cpp文件,在当前目录生成Debug文件夹和如下文件: output.txt,.dsp,.ncb,.plg;
    (2)新建input.txt,并将output.txt和input.txt移到Debug目录下;
    (3)在input.txt中输入pascal语言,双击.exe可执行文件,在output.txt中则自动输出词法分析结果。

    #include<iostream>
    
    #include<vector> 
    
    #include<string>
    
    using namespace std;
    
    #define len 21
    
    #define Hang 45
    
    #define Lie 30
    
    int Cnt[len]={
    
    	1,8,1,3,3,1,0,1,3,3,1,4,6,4,3,3,1,3,1,1,1};
    
    string WenFa[len][2] = {
    
    	{"S'","->S"},
    
    	{"S","->program id(id_lists);compound_stmt."},
    
    	{"id_lists","-> id"},
    
    	{"id_lists","->id_lists,id"},
    
    	{"compound_stmt","->begin optional_stmts end"},
    
    	{"optional_stmts","->stmts"},
    
    	{"optional_stmts","->ε"},
    
    	{"stmts","->stmt"},
    
    	{"stmts","->stmts; stmt"},
    
    	{"stmt","->id := expr"},
    
    	{"stmt","->compound_stmt "},
    
    	{"stmt","->if bool then stmt "},
    
    	{"stmt","->if bool then stmt else stmt "},
    
    	{"stmt","->while bool  do stmt"},
    
    	{"bool","->expr < expr"},
    
    	{"expr","->expr + term "},
    
    	{"expr","->term"},
    
    	{"term","->term * factor"},
    
    	{"term","->factor"},
    
    	{"factor","->id"},
    
    	{"factor","->num"}
    
    };
    
    string Lie_index[Lie]=
    
    {
    
    	    "program",
    
    		"id",
    
    		"(",
    
    		")",
    
    		";",
    
    		",",
    
    		"begin",
    
    		"end",
    
    		":=",
    
    		"if",
    
    		"then",
    
    		"else",
    
    		"while",
    
    		"do",
    
    		"<",
    
    		"+",
    
    		"*",
    
    		"num",
    
    		".",
    
    		"$",
    
    		"S",
    
    		"id_lists",
    
    		"compound_stmt",
    
    		"optional_stmts",
    
    		"stmts",
    
    		"stmt",
    
    		"bool",
    
    		"expr",
    
    		"term",
    
    		"factor", 
    
    };
    
    int line = 1;
    
    struct cont
    
    {
    
    	bool move;
    
    	int to;
    
    	cont():move(true), to(-1){}
    
    	cont(bool tf, int t) :move(tf), to(t){}
    
    	/*规约:false,规约编号>0
    
    	*移入:true,移入状态>=0
    
    	接受:false,编号0
    
    	    true,-1出错*/
    
    };
    
    cont FenXi_table[Hang][Lie];
    
    bool IsLetter_ZiMu(char c)/*判断是否为字母*/
    
    {
    
    	if (c >= 'a'&&c <= 'z' || c >= 'A'&&c <= 'Z')
    
    		return true;
    
    	return false;
    
    }
    
    void getWord(string*ans, char *c)
    
    {
    
    	do
    
    	{
    
    		if ((*c) >= 'A' && (*c) <= 'Z')(*c) = (*c) - 'A' + 'a';
    
    		(*ans) += (*c);
    
    	} while (((*c) = getchar()) == '_' || IsLetter_ZiMu((*c)));
    
    }
    
    void reduce(vector<int >*sTate, vector<string>*Nsign, int index)
    
    {
    
    	for (int i = 0; i < Cnt[index]; i++)
    
    	{
    
    		sTate->pop_back();
    
    		Nsign->pop_back();
    
    	}
    
    }
    
    int findIndex(string ans)
    
    {
    
      for(int index=0;index<Lie;index++)
    
       if(Lie_index[index]==ans)return index;
    
      return Lie;
    
    }
    
    void ShuChu(vector<int >*sTate, vector<string >*Nsign, string str, bool succ)
    
    {
    
    	if (succ)
    
    	{
    
    		for (vector<int>::iterator iter = sTate->begin(); iter != sTate->end(); iter++)
    
    			cout << (*iter);
    
    		cout << " ";
    
    		for (vector< string >::iterator it = Nsign->begin(); it != Nsign->end(); it++)
    
    			cout << (*it) << " ";
    
    	}
    
    	else cout << line;
    
    	cout << str << endl;
    
    } 
    
    void wordAna(vector<int>*sTate, vector<string>*Nsign)
    
    {
    
    	bool succ = true;
    
    	bool YiJingYiRU = true;
    
    	bool flagw = false;//用于处理如果不是
    
    	string ans;
    
    	char c;
    
    	sTate->push_back(0);
    
    	Nsign->push_back("$"); 
    
    	c = getchar();
    
    	while (c != EOF&&succ)
    
    	{
    
    		for (bool fl=true;fl;)/*吸收空格退格换行*/
    
    		{
    
    			if (c == ' ' || c == '\t')c = getchar();
    
    			else
    
    			if (c == '\n')
    
    			{ 
    
    				line++;
    
    				c=getchar(); 
    
    			}
    
    			else fl = false;
    
    		}
    
    		/*输入词获取与处理*/ 
    
    		if (YiJingYiRU)
    
    		{ 
    
    			ans = "";
    
    		if (IsLetter_ZiMu(c))getWord(&ans, &c);
    
    		else if (c == ':')
    
    		{
    
    			c = getchar();
    
    			if (c == '=')
    
    			 ans = ":=";
    
    			else
    
    			{
    
    				succ = false; 
    
    				ShuChu(sTate, Nsign, " error: :=",succ);
    
    				return;
    
    			}
    
    			flagw = true;
    
    		}
    
    		else
    
    		{ 
    
    			ans = c;  
    
    			flagw = true;
    
    		}
    
    		} 
    
            /*分析表的输入action读取*/ 
    
            int li=findIndex(ans);
    
    		if(li>=Lie)
    
    		{
    
    			succ = false; 
    
    			ShuChu(sTate, Nsign, " error: input",succ);
    
    			return;
    
    		}
    
    		cont temp = FenXi_table[(*sTate)[sTate->size()-1]][li]; 
    
    		/*移入/规约/接受/出错*/
    
    		if (temp.move&&temp.to>=0)
    
    		{
    
    			YiJingYiRU = true;
    
    			ShuChu(sTate, Nsign, " 移入",succ);
    
    			sTate->push_back(temp.to);
    
    			Nsign->push_back(ans);
    
    			if (flagw)
    
    			{
    
    				c = getchar(); 
    
    				flagw = false;
    
    			}
    
    		}
    
    		else if (!temp.move&&temp.to > 0)
    
    		{ 
    
    			YiJingYiRU = false;
    
    			string str= WenFa[temp.to][0];
    
    			ShuChu(sTate, Nsign, " 根据" + str + WenFa[temp.to][1] + "归约", succ);
    
    			reduce(sTate,Nsign, temp.to);
    
                Nsign->push_back(str);
    
    			/*分析表的GOTO读取*/
    
    			 li = findIndex(str);
    
    			if (li >= Lie)
    
    			{
    
    				succ = false;
    
    				ShuChu(sTate, Nsign, " error:input", succ);
    
    				return;
    
    			} 
    
    			li = FenXi_table[(*sTate)[sTate->size() - 1]][li].to; 
    
    			if (li <0)
    
    			{
    
    				succ = false;
    
    				ShuChu(sTate, Nsign, " error:GOTO", succ);
    
    				return;
    
    			}
    
    			sTate->push_back(li);
    
    		}
    
    		else if (!temp.move&&temp.to == 0)
    
    		{
    
    			ShuChu(sTate, Nsign, " 接受",succ);
    
    			return;
    
    		} 
    
    		else
    
    		{
    
    			succ = false; 
    
    			ShuChu(sTate, Nsign, " error",succ);
    
    			return;
    
    		}
    
    	}
    
       
    
    }
    
    void initial_table()
    
    {
    
    //------------------------input  sn
    
     FenXi_table[0][0]=cont(true,2);
    
     FenXi_table[2][1]=cont(true,3);
    
     FenXi_table[3][2]=cont(true,4);
    
     FenXi_table[4][1]=cont(true,6);
    
     FenXi_table[5][3]=cont(true,7);
    
     FenXi_table[5][5]=cont(true,8);
    
     FenXi_table[7][4]=cont(true,9);
    
     FenXi_table[8][1]=cont(true,10);
    
     FenXi_table[9][6]=cont(true,13);
    
     FenXi_table[11][18]=cont(true,12);
    
     FenXi_table[13][1]=cont(true,17);
    
     FenXi_table[13][6]=cont(true,13);
    
     FenXi_table[13][9]=cont(true,19);
    
     FenXi_table[13][12]=cont(true,20);
    
     FenXi_table[14][7]=cont(true,21);
    
     FenXi_table[15][4]=cont(true,22);
    
     FenXi_table[17][8]=cont(true,23);
    
     FenXi_table[19][1]=cont(true,28);
    
     FenXi_table[19][17]=cont(true,29);
    
     FenXi_table[20][1]=cont(true,28);
    
     FenXi_table[20][17]=cont(true,29);
    
     FenXi_table[22][1]=cont(true,17);
    
     FenXi_table[22][6]=cont(true,13);
    
     FenXi_table[22][9]=cont(true,19);
    
     FenXi_table[22][12]=cont(true,30);
    
     FenXi_table[23][1] = cont(true, 28);
    
     FenXi_table[23][17]=cont(true,29);
    
     FenXi_table[24][10]=cont(true,32);
    
     FenXi_table[25][14]=cont(true,33);
    
     FenXi_table[25][15]=cont(true,34);
    
     FenXi_table[26][16]=cont(true,35);
    
     FenXi_table[30][13]=cont(true,36);
    
     FenXi_table[31][15]=cont(true,34);
    
     FenXi_table[32][1]=cont(true,17);
    
     FenXi_table[32][6]=cont(true,13);
    
     FenXi_table[32][9]=cont(true,19);
    
     FenXi_table[32][12]=cont(true,20);
    
     FenXi_table[33][1]=cont(true,28);
    
     FenXi_table[33][17]=cont(true,29);
    
     FenXi_table[34][1]=cont(true,28);
    
     FenXi_table[34][17]=cont(true,29);
    
     FenXi_table[35][1]=cont(true,28);
    
     FenXi_table[35][17]=cont(true,29);
    
     FenXi_table[36][1]=cont(true,17);
    
     FenXi_table[36][6]=cont(true,13);
    
     FenXi_table[36][9]=cont(true,19);
    
     FenXi_table[36][12]=cont(true,20);
    
     FenXi_table[37][11]=cont(true,42);
    
     FenXi_table[38][15]=cont(true,34);
    
     FenXi_table[39][16]=cont(true,35);
    
     FenXi_table[42][1]=cont(true,17);
    
     FenXi_table[42][6]=cont(true,13);
    
     FenXi_table[42][9]=cont(true,19);
    
     FenXi_table[42][12]=cont(true,20);
    
    //	*移入状态i,输入j,sn:FenXi_table[i][findIndex(j)]=cont(true,n);
    
    
    
     //------------------rn
    
     FenXi_table[6][3] = 
    
     FenXi_table[6][5] = cont(false,2 );
    
     FenXi_table[10][3] = 
    
     FenXi_table[10][5] = cont(false, 3);
    
     FenXi_table[12][19] = cont(false, 1);
    
     FenXi_table[13][7] = cont(false,6 );
    
     FenXi_table[15][7] = cont(false, 5);
    
     FenXi_table[16][4] = 
    
     FenXi_table[16][7] = cont(false, 7);
    
     FenXi_table[18][4] = 
    
     FenXi_table[18][7] = 
    
     FenXi_table[18][11] = cont(false,20);
    
     FenXi_table[21][18] = cont(false,4);
    
    
    
     FenXi_table[26][4] = 
    
     FenXi_table[26][7] = 
    
     FenXi_table[26][10] = 
    
     FenXi_table[26][11] = 
    
     FenXi_table[26][13] = 
    
     FenXi_table[26][14] = 
    
     FenXi_table[26][15] = cont(false, 16);
    
    
    
    
    
     FenXi_table[27][4] = 
    
     FenXi_table[27][7] = 
    
     FenXi_table[27][10] = 
    
     FenXi_table[27][11] = 
    
     FenXi_table[27][13] = 
    
     FenXi_table[27][14] = 
    
     FenXi_table[27][15] =
    
     FenXi_table[27][16] = cont(false,18 );
    
     FenXi_table[28][4] = 
    
     FenXi_table[28][7] = 
    
     FenXi_table[28][10] = 
    
     FenXi_table[28][11] = 
    
     FenXi_table[28][13] = 
    
     FenXi_table[28][14] = 
    
     FenXi_table[28][15] = 
    
     FenXi_table[28][16] = cont(false, 19);
    
     FenXi_table[29][4] = 
    
     FenXi_table[29][7] = 
    
     FenXi_table[29][10] = 
    
     FenXi_table[29][11] = 
    
     FenXi_table[29][13] =
    
     FenXi_table[29][14] = 
    
     FenXi_table[29][15] = 
    
     FenXi_table[29][16] = cont(false,20);
    
     FenXi_table[31][4] = 
    
     FenXi_table[31][7] =
    
     FenXi_table[31][11] = cont(false, 9);
    
     FenXi_table[37][4] =
    
     FenXi_table[37][7] = cont(false, 11);
    
     FenXi_table[38][10] =
    
     FenXi_table[38][13] = cont(false, 14);
    
     FenXi_table[39][4] =
    
     FenXi_table[39][7] =
    
     FenXi_table[39][10] =
    
     FenXi_table[39][11] =
    
     FenXi_table[39][13] =
    
     FenXi_table[39][14] =
    
     FenXi_table[39][15] = cont(false,15 );
    
     FenXi_table[40][4] =
    
     FenXi_table[40][7] =
    
     FenXi_table[40][10] =
    
     FenXi_table[40][11] =
    
     FenXi_table[40][13] =
    
     FenXi_table[40][14] =
    
     FenXi_table[40][15] =
    
     FenXi_table[40][16] = cont(false, 17);
    
     FenXi_table[41][4] =
    
     FenXi_table[41][7] =
    
     FenXi_table[41][11] = cont(false, 13);
    
     FenXi_table[43][4] =
    
     FenXi_table[43][7] =
    
     FenXi_table[43][11] = cont(false, 12);
    
     FenXi_table[44][4] =
    
    	 FenXi_table[44][7] = cont(false, 8);
    
     //规约状态i,输入j,rn:FenXi_table[i][findIndex(j)]=cont(false,n);false,规约编号>0
    
    
    
    
    
     //----------------GOTO n
    
     FenXi_table[0][20] = cont(true, 1);
    
     FenXi_table[4][21] = cont(true, 5); 
    
     FenXi_table[9][22] = cont(true, 11);
    
     FenXi_table[13][22] = cont(true, 18);
    
     FenXi_table[13][23] = cont(true, 14);
    
     FenXi_table[13][24] = cont(true, 15);
    
     FenXi_table[13][25] = cont(true, 16);
    
     FenXi_table[19][26] = cont(true, 24);
    
     FenXi_table[19][27] = cont(true, 25);
    
     FenXi_table[19][28] = cont(true, 26);
    
     FenXi_table[19][29] = cont(true, 27);
    
     FenXi_table[20][26] = cont(true, 30);
    
     FenXi_table[20][27] = cont(true, 25);
    
     FenXi_table[20][28] = cont(true, 26);
    
     FenXi_table[20][29] = cont(true, 27);
    
     FenXi_table[22][22] = cont(true, 18);
    
     FenXi_table[22][25] = cont(true, 44);
    
     FenXi_table[23][27] = cont(true, 31);
    
     FenXi_table[23][28] = cont(true, 26);
    
     FenXi_table[23][29] = cont(true, 27); 
    
     FenXi_table[32][22] = cont(true, 18);
    
     FenXi_table[32][25] = cont(true, 37);
    
    
    
     FenXi_table[33][27] = cont(true, 38);
    
     FenXi_table[33][28] = cont(true, 26);
    
     FenXi_table[33][29] = cont(true, 27);
    
    
    
     FenXi_table[34][28] = cont(true, 39); 
    
     FenXi_table[34][29] = cont(true, 27);
    
     FenXi_table[35][29] = cont(true, 40);
    
     FenXi_table[36][22] = cont(true, 18);
    
     FenXi_table[36][25] = cont(true, 41);
    
     FenXi_table[42][22] = cont(true, 18);
    
     FenXi_table[42][25] = cont(true, 43);
    
    //状态i,GOTOj,rn:FenXi_table[i][findIndex(j)]=cont(true,n);
    
    
    
    
    
    
    
    //--------------acc
    
    FenXi_table[1][19]=cont(false,0);
    
    //	接受状态i,输入j,acc:FenXi_table[i][findIndex(j)]=cont(false,0);false,编号0
    
    
    
    }
    
    int main()
    
    {
    
    	freopen("input.txt", "r", stdin);
    
    	freopen("output.txt", "w", stdout);
    
    	vector<int>sTate;
    
    	vector<string>Nsign; 
    
    	initial_table();
    
    	wordAna(&sTate, &Nsign); 
    
    	return 0;
    
    }

    编译实验(三)语义分析
    [实验内容 ]
      对所给语言文法的子集,给出SDD或SDT,编制语义分析程序,要求将错误信息输出到错误文件中,并输出输入程序对应的三地址码;
      实验报告必须包括采用的文法以及相应的SDD或SDT,设计的思路,SLR(1)分析表,以及测试报告(输入测试例子,输出结果),设计的体会。
    [文法 ]
     S → program id ( id_lists );  compound_stmt .
    id_lists → id | id_lists , id
    compound_stmt →begin optional_stmts end
    optional_stmts →stmts | ε
    stmts → stmt | stmts; stmt
    stmt  → id := expr  |  compound_stmt | if bool then stmt |
       if bool then stmt else stmt | while bool  do stmt
    bool → expr < expr
    expr → expr + term  | term
    term →term * factor | factor
    factor →  id | num
    使用说明:


    (1)       将semantics.h,wordAnalyze.h,source.cpp文件放到同一目录下,运行.cpp文件,在当前目录生成Debug文件夹和如下文件: input1.txt,output.txt,.dsp,.ncb,.plg;


    (2)       在Debug文件夹内新建input.txt和output.txt;


    (3)       在input.txt中输入pascal语言,双击.exe可执行文件,在output.txt中则自动输出词法分析结果,会自动生成一个input1.txt保存中间结果。


    [样例程序]
    program test(a,b);
       begin
    while x+y<x do
                             while x+y<x do y:=y+1;
    z:=z*7 
    end.$
    输出:
    LABLE0:
          t0=x+y
          if t0<x GOTO LABLE1
          GOTO LABLE2
    LABLE1:
    LABLE3:
          t1=x+y
          if t1<x GOTO LABLE4
          GOTO LABLE5
    LABLE4:
          t2=y+1
          y=t2
          GOTO LABLE3
    LABLE5:
          GOTO LABLE0
    LABLE2:
          t3=z*7
          z=t3
     
     //wordAnalyze.h
    #include<iostream>
    #include<string>
    #include<vector>
    using namespace std;
    #define LENWords 36
    #define Max10Len 8
    #define Max36Len 4
    string words[]={"program","function","procedure","array","const","file","lable","packed","var","record","set","type","of",
    "case","do","downto","else","for","goto","if","repeat","then","to","until","while","with","forward","and","not","or",
    "in","div","mod","begin","end","nil"};/*36/82,"false","true","maxint","interger","real","char","string","boolean","text",
    "input","output","abs","arctan","chr","cos","eof","eoln","exp","odd","ord","pred","round","sin","sqr","sqrt","succ","trunc",
    "get","new","pack","page","put","read","readln","reset","rewrite","unpack","write","writeln","longint","int64","shortint",
    "single","double","ansistring","qword"*/
     int lenth;
     int line1;
     string xiaoshu;
    vector<string>worddd;
    void JiaRu_In(string ans)
    {
    	for(int i=0;i<worddd.size();i++)
    		if(worddd[i]==ans)return;
    		worddd.push_back(ans);
    		
    }
    bool IsLetter_ZiMu(char c)/*判断是否为字母*/
    {
       if(c>='a'&&c<='z'||c>='A'&&c<='Z')
    	   return true;
       return false;
    }
    bool IsDigit_ShuJi(char c)/*判断是否为数字*/
    {
    	if(c>='0'&&c<='9')
    		return true;
    	return false;
    }
    bool Is0X_ShiLIu(char c)/*判断数字是否为三十六进制*/
    {
    	if(c=='x'||c=='X')return true;
    	return false;
    } 
    long int jisuan(char (*c),long int sum)/*十进制值的计算函数*/
    {  
        if( IsDigit_ShuJi(*c))
    	{ 
    		do
    		{
    		if(lenth<Max10Len)
    		sum=sum*10+(*c)-'0'; 
    	   	lenth++;
    		} while(((*c)=getchar())>='0'&&(*c)<='9');
    	}
    	if((*c)=='.')
    	{
    	    lenth=0;
    		xiaoshu='.';
            while(((*c)=getchar())>='0'&&(*c)<='9')
    			xiaoshu+=(*c); 
    	}
    	return sum; 
    }
    long int exchange(char (*c))/*将36进制转换为10进制*/
    {
    	long int t=0;
    	while(((*c)=getchar())>='0'&&(*c)<='9'||IsLetter_ZiMu((*c)))
    	{ 
    		if(IsDigit_ShuJi((*c)))  t=t*36+(*c)-'0';
            else if((*c)>='a'&&(*c)<='z')  t=t*36+(*c)-'a'+10;
    		else  if((*c)>='A'&&(*c)<='Z')   t=t*36+(*c)-'A'+10; 
    		lenth++;
    	}
    	if(lenth>4)
    	{
    		t=1<<24;
    		t++;
    	}
    	return t;
    }  
    bool judge_digitscale(long int ansInt)/*判断数字是否越界*/
    {
        long int a;
    	a=1<<24;
    	if(ansInt>=a)
    		return false; 
    	return true;
    }
    void getWord(string*ans,char *c)
    {
       	 do
    	 { 
    		 if((*c)>='A'&&(*c)<='Z')(*c)=(*c)-'A'+'a';
    		 (*ans)+=(*c); 
    	 }
         while(((*c)=getchar())=='_'||IsDigit_ShuJi((*c))||IsLetter_ZiMu((*c)));
    }
    bool InTheWords(string*ans)
    { 
    	for(int i=0;i<LENWords;i++)
    		if(words[i]==(*ans))return true;
    		return false;
    }
    void AnalyFunc()
    { 
    	bool valid;
    	char c=getchar();
       for(;c!=EOF;)
       {
    	   for(valid=false;!valid;)
    	   {
    		   if(c==' '||c=='\t')c=getchar();
    		   else if(c=='\n')
    		   {
    			   line1++;
    			   c=getchar();
    		   }
    			else valid=true;
    	   }
           string ans="";
           long int ansInt=0;
    	   xiaoshu='\0';
    	   lenth=0;
    	   switch(c)
    	   { 
    	      case '-': 
                      c=getchar();
    				  if(c=='-')
    				  {
    					  getline(cin,ans);
    					  line1++;
    					  c=getchar();
    				  }
    				  else cout<<"-"<<endl;
    				  valid=false;
    			      break;
    		  case '<':
    			      c=getchar();
    				  if(c=='='){cout<<"<="; c=getchar();}
    				  else if(c=='>'){cout<<"<>"; c=getchar();}
    				  else if(c=='<'){cout<<"<<"; c=getchar();}
    			      else cout<<"<";
    			      valid=false; 
    				  cout<<endl;
    				  break; 
    		  case '>':
                      c=getchar();
    				  if(c=='='){cout<<">=";  c=getchar();} 
    				  else if(c=='>'){ cout<<">>"; c=getchar();}
    			      else cout<<">";
    			      valid=false; 
    				  cout<<endl;
    				  break; 
    		  case ':':
                      c=getchar();
    				  if(c=='='){cout<<":=";c=getchar();}
    			      else cout<<":";
    			      valid=false; 
    				  cout<<endl;
    				  break; 
    	   }
    	   if(valid)
    	   {
    	      if(IsDigit_ShuJi(c))
    		  { 
    		     ansInt=c-'0';
    			 c=getchar();
    		     if(ansInt==0&&Is0X_ShiLIu(c))
    				 ansInt=exchange(&c);
    			 else  ansInt=jisuan(&c,ansInt);
    		     if(judge_digitscale(ansInt))
    			 {
    				 if(xiaoshu.size()==0)
    				 cout<<"num "<<ansInt;
    				 else
    				 { 
    				   cout<<"num "<<ansInt<<xiaoshu;
    				 }
    			 }
    		     else cout<<"error line"<<line1<<":out of range";/*数字越界*/
    		  }
    		  else if(IsLetter_ZiMu(c)||c=='_')
    		  { 
    			  getWord(&ans,&c);
    			  if(InTheWords(&ans))
    				  cout<<ans;
    			  else if(ans.size()>32)  cout<<"error line"<<line1<<":invalid identifier";/*标识符越界,输出无效的标识*/
    			  else 
    			  { 
    				       if(ans.size()>8)
    					   {
    				         ansInt=ans.size()-8; 
    				         ans.erase(8,ansInt);
    					   }
    				      JiaRu_In(ans);
    				      cout<<"id "<<ans; 
    			  }
    		  }
    		  else {cout<<c; c=getchar();}/*_+_*_/_&_^_|_~_=_!_(_)_._'*/
             cout<<endl;
    	   }
       }
    }
    void wordAnalyze()
    { 
    
      //FILE*f;
      //freopen_s(&f, "input.txt", "r", stdin);
      //freopen_s(&f, "input1.txt", "w", stdout);
    	freopen("input.txt","r",stdin);
    	freopen("input1.txt","w",stdout);
    	line1=0;
    	AnalyFunc(); 
    cout<<"$"<<endl;
    //fclose(f);
    }

     //semantics.h
    #include<iostream>
    #include<string>
    #include<vector>
    #include <sstream>
    using namespace std; 
    int lable=0;//label
    int id_num = 0;//t
    struct E
    {
    	string addr_place;
    	string code;
    	string lable_true;
    	string lable_false;
    	E() :addr_place(""), code(""), lable_true(""), lable_false(""){}  
    };
    string ToStr(int num)
    {
    	stringstream ss;
    	string temp;
    	ss << num;
    	ss >> temp;
    	return temp;
    } 
    void nowstr( vector<E>*expandNsign, string*itt,int li)
    { 
    	E value;
    	switch (li)
    	{
    	case 1://id
    		value.addr_place = (*itt);
    		break; 
    	case 9://if出口标志存储
    		value.lable_false = "LABLE" + ToStr(lable++);
    		break;
    	case 11://if else标志输出
    		cout << "      GOTO "+(*expandNsign)[(*expandNsign).size() - 4].lable_false+"\n"
    			<<(*expandNsign)[(*expandNsign).size() - 3].lable_false + ":" << endl;
    		break;
    	case 12://while循环标志输出
    		value.lable_false= "LABLE" + ToStr(lable++);
    		cout << value.lable_false << ":" << endl;
    		break;
    	case 17: //num
    		value.addr_place = (*itt); 
    		break;
    	}
    	expandNsign->push_back(value);
    }
    void outstr(vector<string>*Nsign, vector<E>*expandNsign,int WenFaindex)
    {
    	int
    		i = expandNsign->size();;
    	string str = "";
    	switch (WenFaindex)
    	{
    	case 20:
    	case 19:
    	case 18:
    	case 16:
    	case 10:
    	case 8:
    	case 7:
    	case 6:
    	case 5:
    	case 4:
    	case 3:
    	case 2:
    	case 1:
    	case 0:
    		(*expandNsign)[i - 1].code = "";
    		break;
    	case 17: //term->term*factor
    		str = "t" + ToStr(id_num++);
    		(*expandNsign)[i - 3].code = "      " +
    			str + "=" + (*expandNsign)[i - 3].addr_place+"*"+(*expandNsign)[i-1].addr_place+"\n";
    		(*expandNsign)[i - 3].addr_place = str;
    		break; 
    	case 15://expr->expr+term
    		str = "t" + ToStr(id_num++);
    		(*expandNsign)[i - 3].code = "      "+
    			str + "=" + (*expandNsign)[i - 3].addr_place + "+" + (*expandNsign)[i - 1].addr_place+"\n";
    		(*expandNsign)[i - 3].addr_place = str;
    	 
    		break;
    	case 14:  //bool->expr<expr
    		(*expandNsign)[i - 3].lable_true = "LABLE" + ToStr(lable++);
    		(*expandNsign)[i - 3].lable_false= "LABLE" + ToStr(lable++);
    		(*expandNsign)[i - 3].code = "      if "+ (*expandNsign)[i - 3].addr_place + "<" + (*expandNsign)[i - 1].addr_place+
    			" GOTO " + (*expandNsign)[i - 3].lable_true + "\n" 
    			+ "      GOTO " + (*expandNsign)[i - 3].lable_false+"\n"
    			+ (*expandNsign)[i - 3].lable_true+":\n";
    		break;
    	case 13: //stmt->while bool do stmt
    		(*expandNsign)[i - 4].code = "      GOTO " + (*expandNsign)[i - 4].lable_false + "\n"
    			+ (*expandNsign)[i - 3].lable_false + ":\n";
    		break;
    	case 12://stmt->if bool then stmt else stmt
    		(*expandNsign)[i - 6].code = (*expandNsign)[i - 6].lable_false + ":\n";
    	case 11://stmt->if bool them stmt
    		(*expandNsign)[i - 4].code = (*expandNsign)[i - 3].lable_false + ":\n"
    			+ (*expandNsign)[i - 4].lable_false + ":\n";
    		break;
    	case 9://stmt->id := expr
    		(*expandNsign)[i - 3].code = "      " + (*expandNsign)[i - 3].addr_place + "=" + (*expandNsign)[i - 1].addr_place + "\n";
    		break;   
    	}
    }
    
    
     //Source.cpp
    //#include<iostream>
    //#include<vector> 
    //#include<string>
    #include"wordAnalyze.h"
    #include"semantics.h"
    using namespace std;
    //#pragma warning(disable:4996)去掉vs的freopen_s警告
    #define len 21
    #define Hang 45
    #define Lie 30
    int Cnt[len] = {
    	1, 8, 1, 3, 3, 1, 0, 1, 3, 3, 1, 4, 6, 4, 3, 3, 1, 3, 1, 1, 1 };
    string WenFa[len][2] = {
    	{ "S'", "->S" },
    	{ "S", "->program id(id_lists);compound_stmt." },
    	{ "id_lists", "-> id" },
    	{ "id_lists", "->id_lists,id" },
    	{ "compound_stmt", "->begin optional_stmts end" },
    	{ "optional_stmts", "->stmts" },
    	{ "optional_stmts", "->ε" },
    	{ "stmts", "->stmt" },
    	{ "stmts", "->stmts; stmt" },
    	{ "stmt", "->id := expr" },
    	{ "stmt", "->compound_stmt " },
    	{ "stmt", "->if bool then stmt " },
    	{ "stmt", "->if bool then stmt else stmt " },
    	{ "stmt", "->while bool  do stmt" },
    	{ "bool", "->expr < expr" },
    	{ "expr", "->expr + term " },
    	{ "expr", "->term" },
    	{ "term", "->term * factor" },
    	{ "term", "->factor" },
    	{ "factor", "->id" },
    	{ "factor", "->num" }
    };
    string Lie_index[Lie] =
    {
    	"program",
    	"id",
    	"(",
    	")",
    	";",
    	",",
    	"begin",
    	"end",
    	":=",
    	"if",
    	"then",
    	"else",
    	"while",
    	"do",
    	"<",
    	"+",
    	"*",
    	"num",
    	".",
    	"$",
    	"S",
    	"id_lists",
    	"compound_stmt",
    	"optional_stmts",
    	"stmts",
    	"stmt",
    	"bool",
    	"expr",
    	"term",
    	"factor",
    };
    int line = 0;
    struct cont
    {
    	bool move;
    	int to;
    	cont() :move(true), to(-1){}
    	cont(bool tf, int t) :move(tf), to(t){}
    	/*规约:false,规约编号>0
    	*移入:true,移入状态>=0
    	接受:false,编号0
    	true,-1出错*/
    };
    cont FenXi_table[Hang][Lie];
    void reduce(vector<int >*sTate, vector<string>*Nsign, vector<E>*expandNsign, int index)
    {
    	for (int i = 0; i < Cnt[index]; i++)
    	{
    		sTate->pop_back();
    		Nsign->pop_back();
    		expandNsign->pop_back();
    	}
    }
    int findIndex(string ans)
    {
    	for (int index = 0; index<Lie; index++)
    		if (Lie_index[index] == ans)return index;
    	return Lie;
    }
    void ShuChu(vector<int >*sTate, vector<string >*Nsign, string str, bool succ)
    {
    	if (succ)
    	{
    		for (vector<int>::iterator iter = sTate->begin(); iter != sTate->end(); iter++)
    			cout << (*iter);
    		cout << " ";
    		for (vector< string >::iterator it = Nsign->begin(); it != Nsign->end(); it++)
    			cout << (*it) << " ";
    	}
    	else cout << line;
    	cout << str << endl;
    }
    void getfirst(string*ans, char*c)
    {
    	do
    	{
    		(*ans) += (*c);
    	} while (((*c) = getchar()) != ' ' && (*c) != '\n' && (*c) != '\t' && (*c) != EOF);
    }
    void wordAna(vector<int>*sTate, vector<string>*Nsign,vector<E>*expandNsign)
    {
    	bool succ = true;
    	bool YiJingYiRU = true;
    	string ans;
    	string itt;
    	char c;
    	sTate->push_back(0);
    	Nsign->push_back("$");
    	c = getchar();
    	while (c != EOF&&succ)
    	{
    		/*输入词获取与处理*/
    		if (YiJingYiRU)
    		{
    			YiJingYiRU = false;
    			ans = "";
    			getfirst(&ans, &c);
    			line++;
    			if (c != '\n'&&c != EOF)
    				getline(cin, itt);
    			if (c != EOF)
    				c = getchar();
    		}
    		/*分析表的输入action读取*/
    		int li = findIndex(ans);
    		if (li >= Lie)
    		{
    			succ = false;
    			ShuChu(sTate, Nsign, " error: input", succ);
    			return;
    		}
    		cont temp = FenXi_table[(*sTate)[sTate->size() - 1]][li];
    		/*移入/规约/接受/出错*/
    		if (temp.move&&temp.to >= 0)
    		{
    			//--------
    			nowstr( expandNsign, &itt, li);
    			//--------
    			YiJingYiRU = true;
    			//ShuChu(sTate, Nsign, " 移入", succ);
    			sTate->push_back(temp.to);
    			Nsign->push_back(ans);
    		}
    		else if (!temp.move&&temp.to > 0)
    		{
    			YiJingYiRU = false;
    			string str = WenFa[temp.to][0];
    
    			//--------
    			outstr(Nsign, expandNsign,  temp.to);
    			expandNsign->push_back(E());//简单的增加一个后面同时规约相同个数
    			//--------
    
    			//ShuChu(sTate, Nsign, " 根据" + str + WenFa[temp.to][1] + "归约", succ);
    			reduce(sTate, Nsign, expandNsign, temp.to);
    			Nsign->push_back(str);
    
    			//---
    			cout << (*expandNsign)[(*expandNsign).size() - 1].code;
    			//---
    
    
    			/*分析表的GOTO读取*/
    			li = findIndex(str);
    			if (li >= Lie)
    			{
    				succ = false;
    				ShuChu(sTate, Nsign, " error:input", succ);
    				return;
    			}
    			li = FenXi_table[(*sTate)[sTate->size() - 1]][li].to;
    			if (li <0)
    			{
    				succ = false;
    				ShuChu(sTate, Nsign, " error:GOTO-format", succ);
    				return;
    			}
    			sTate->push_back(li);
    		}
    		else if (!temp.move&&temp.to == 0)
    		{
    			//ShuChu(sTate, Nsign, " 接受", succ);
    			return;
    		}
    		else
    		{
    			succ = false;
    			ShuChu(sTate, Nsign, " error", succ);
    			return;
    		}
    	}
    
    }
    void initial_table()
    {
    	//------------------------input  sn
    	FenXi_table[0][0] = cont(true, 2);
    	FenXi_table[2][1] = cont(true, 3);
    	FenXi_table[3][2] = cont(true, 4);
    	FenXi_table[4][1] = cont(true, 6);
    	FenXi_table[5][3] = cont(true, 7);
    	FenXi_table[5][5] = cont(true, 8);
    	FenXi_table[7][4] = cont(true, 9);
    	FenXi_table[8][1] = cont(true, 10);
    	FenXi_table[9][6] = cont(true, 13);
    	FenXi_table[11][18] = cont(true, 12);
    	FenXi_table[13][1] = cont(true, 17);
    	FenXi_table[13][6] = cont(true, 13);
    	FenXi_table[13][9] = cont(true, 19);
    	FenXi_table[13][12] = cont(true, 20);
    	FenXi_table[14][7] = cont(true, 21);
    	FenXi_table[15][4] = cont(true, 22);
    	FenXi_table[17][8] = cont(true, 23);
    	FenXi_table[19][1] = cont(true, 28);
    	FenXi_table[19][17] = cont(true, 29);
    	FenXi_table[20][1] = cont(true, 28);
    	FenXi_table[20][17] = cont(true, 29);
    	FenXi_table[22][1] = cont(true, 17);
    	FenXi_table[22][6] = cont(true, 13);
    	FenXi_table[22][9] = cont(true, 19);
    	FenXi_table[22][12] = cont(true, 20);
    	FenXi_table[23][1] = cont(true, 28);
    	FenXi_table[23][17] = cont(true, 29);
    	FenXi_table[24][10] = cont(true, 32);
    	FenXi_table[25][14] = cont(true, 33);
    	FenXi_table[25][15] = cont(true, 34);
    	FenXi_table[26][16] = cont(true, 35);
    	FenXi_table[30][13] = cont(true, 36);
    	FenXi_table[31][15] = cont(true, 34);
    	FenXi_table[32][1] = cont(true, 17);
    	FenXi_table[32][6] = cont(true, 13);
    	FenXi_table[32][9] = cont(true, 19);
    	FenXi_table[32][12] = cont(true, 20);
    	FenXi_table[33][1] = cont(true, 28);
    	FenXi_table[33][17] = cont(true, 29);
    	FenXi_table[34][1] = cont(true, 28);
    	FenXi_table[34][17] = cont(true, 29);
    	FenXi_table[35][1] = cont(true, 28);
    	FenXi_table[35][17] = cont(true, 29);
    	FenXi_table[36][1] = cont(true, 17);
    	FenXi_table[36][6] = cont(true, 13);
    	FenXi_table[36][9] = cont(true, 19);
    	FenXi_table[36][12] = cont(true, 20);
    	FenXi_table[37][11] = cont(true, 42);
    	FenXi_table[38][15] = cont(true, 34);
    	FenXi_table[39][16] = cont(true, 35);
    	FenXi_table[42][1] = cont(true, 17);
    	FenXi_table[42][6] = cont(true, 13);
    	FenXi_table[42][9] = cont(true, 19);
    	FenXi_table[42][12] = cont(true, 20);
    	//	*移入状态i,输入j,sn:FenXi_table[i][findIndex(j)]=cont(true,n);
    
    	//------------------rn
    	FenXi_table[6][3] =
    		FenXi_table[6][5] = cont(false, 2);
    	FenXi_table[10][3] =
    		FenXi_table[10][5] = cont(false, 3);
    	FenXi_table[12][19] = cont(false, 1);
    	FenXi_table[13][7] = cont(false, 6);
    	FenXi_table[15][7] = cont(false, 5);
    	FenXi_table[16][4] =
    		FenXi_table[16][7] = cont(false, 7);
    	FenXi_table[18][4] =
    		FenXi_table[18][7] =
    		FenXi_table[18][11] = cont(false, 10);
    
    
    	FenXi_table[21][7] =
    	FenXi_table[21][11] =
    	FenXi_table[21][18] = cont(false, 4);
    
    	FenXi_table[26][4] =
    		FenXi_table[26][7] =
    		FenXi_table[26][10] =
    		FenXi_table[26][11] =
    		FenXi_table[26][13] =
    		FenXi_table[26][14] =
    		FenXi_table[26][15] = cont(false, 16);
    
    
    	FenXi_table[27][4] =
    		FenXi_table[27][7] =
    		FenXi_table[27][10] =
    		FenXi_table[27][11] =
    		FenXi_table[27][13] =
    		FenXi_table[27][14] =
    		FenXi_table[27][15] =
    		FenXi_table[27][16] = cont(false, 18);
    	FenXi_table[28][4] =
    		FenXi_table[28][7] =
    		FenXi_table[28][10] =
    		FenXi_table[28][11] =
    		FenXi_table[28][13] =
    		FenXi_table[28][14] =
    		FenXi_table[28][15] =
    		FenXi_table[28][16] = cont(false, 19);
    	FenXi_table[29][4] =
    		FenXi_table[29][7] =
    		FenXi_table[29][10] =
    		FenXi_table[29][11] =
    		FenXi_table[29][13] =
    		FenXi_table[29][14] =
    		FenXi_table[29][15] =
    		FenXi_table[29][16] = cont(false, 20);
    	FenXi_table[31][4] =
    		FenXi_table[31][7] =
    		FenXi_table[31][11] = cont(false, 9);
    	FenXi_table[37][4] =
    		FenXi_table[37][7] = cont(false, 11);
    	FenXi_table[38][10] =
    		FenXi_table[38][13] = cont(false, 14);
    	FenXi_table[39][4] =
    		FenXi_table[39][7] =
    		FenXi_table[39][10] =
    		FenXi_table[39][11] =
    		FenXi_table[39][13] =
    		FenXi_table[39][14] =
    		FenXi_table[39][15] = cont(false, 15);
    	FenXi_table[40][4] =
    		FenXi_table[40][7] =
    		FenXi_table[40][10] =
    		FenXi_table[40][11] =
    		FenXi_table[40][13] =
    		FenXi_table[40][14] =
    		FenXi_table[40][15] =
    		FenXi_table[40][16] = cont(false, 17);
    	FenXi_table[41][4] =
    		FenXi_table[41][7] =
    		FenXi_table[41][11] = cont(false, 13);
    	FenXi_table[43][4] =
    		FenXi_table[43][7] =
    		FenXi_table[43][11] = cont(false, 12);
    	FenXi_table[44][4] =
    		FenXi_table[44][7] = cont(false, 8);
    	//规约状态i,输入j,rn:FenXi_table[i][findIndex(j)]=cont(false,n);false,规约编号>0
    
    
    	//----------------GOTO n
    	FenXi_table[0][20] = cont(true, 1);
    	FenXi_table[4][21] = cont(true, 5);
    	FenXi_table[9][22] = cont(true, 11);
    	FenXi_table[13][22] = cont(true, 18);
    	FenXi_table[13][23] = cont(true, 14);
    	FenXi_table[13][24] = cont(true, 15);
    	FenXi_table[13][25] = cont(true, 16);
    	FenXi_table[19][26] = cont(true, 24);
    	FenXi_table[19][27] = cont(true, 25);
    	FenXi_table[19][28] = cont(true, 26);
    	FenXi_table[19][29] = cont(true, 27);
    	FenXi_table[20][26] = cont(true, 30);
    	FenXi_table[20][27] = cont(true, 25);
    	FenXi_table[20][28] = cont(true, 26);
    	FenXi_table[20][29] = cont(true, 27);
    	FenXi_table[22][22] = cont(true, 18);
    	FenXi_table[22][25] = cont(true, 44);
    	FenXi_table[23][27] = cont(true, 31);
    	FenXi_table[23][28] = cont(true, 26);
    	FenXi_table[23][29] = cont(true, 27);
    	FenXi_table[32][22] = cont(true, 18);
    	FenXi_table[32][25] = cont(true, 37);
    
    	FenXi_table[33][27] = cont(true, 38);
    	FenXi_table[33][28] = cont(true, 26);
    	FenXi_table[33][29] = cont(true, 27);
    
    	FenXi_table[34][28] = cont(true, 39);
    	FenXi_table[34][29] = cont(true, 27);
    	FenXi_table[35][29] = cont(true, 40);
    	FenXi_table[36][22] = cont(true, 18);
    	FenXi_table[36][25] = cont(true, 41);
    	FenXi_table[42][22] = cont(true, 18);
    	FenXi_table[42][25] = cont(true, 43);
    	//状态i,GOTOj,rn:FenXi_table[i][findIndex(j)]=cont(true,n);
    
    
    
    	//--------------acc
    	FenXi_table[1][19] = cont(false, 0);
    	//	接受状态i,输入j,acc:FenXi_table[i][findIndex(j)]=cont(false,0);false,编号0
    
    }
    void worda()
    {
    
    //	FILE*f;
    //	freopen_s(&f, "input1.txt", "r", stdin);
    //	freopen_s(&f, "output.txt", "w", stdout);
     
    	freopen("input1.txt","r",stdin);
    	freopen("output.txt","w",stdout);
    	vector<int>sTate;
    	vector<string>Nsign;
    	vector<E>expandNsign;
    	initial_table();
    	wordAna(&sTate, &Nsign,&expandNsign);
    //	fclose(f);
    }
    int main()
    {
    
    	wordAnalyze();
    	worda(); 
    	return 0;
    }




    LL 分析法和 LR 分析法
    展开全文
  • 一、实验目的通过设计、开发一个高级语言的词法分析程序,加深对课堂教学内容(包括正规文法、正规表达式、有限自动机、NFA到DFA的转换、DFA的最小化)的理解,提高词法分析方法的实践能力。二、实验要求(1)深入理解、...

    一、实验目的

    通过设计、开发一个高级语言的词法分析程序,加深对课堂教学内容(包括正规文法、正规表达式、有限自动机、NFA到DFA的转换、DFA的最小化)的理解,提高词法分析方法的实践能力。

    二、实验要求

    (1)深入理解、掌握有限自动机及其应用;

    (2)掌握根据语言的词法规则构造识别其单词的有限自动机的方法;

    (3)掌握NFA到DFA的等价变换方法、DFA最小化的方法;

    (4)掌握设计、编码、调试词法分析程序的技术与方法,具体实现S语言的词法分析程序。

    2.1 待分析的简单的词法

    (1)关键字:

    begin if then while do end 所有的关键字都是小写。

    (2)运算符和界符

    : : = + - * /

    <

    <=

    <>

    >

    >= = ; ( ) #

    (3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:

    ID = letter (letter |

    digit)*

    NUM = digit

    digit*

    (4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。

    2.2 各种单词符号对应的种别码

    表2.1 各种单词符号对应的种别码

    单词符号

    种别码

    单词符号

    种别码

    begin

    1

    17

    if

    2

    :

    =

    18

    then

    3

    <

    20

    while

    4

    <>

    21

    do

    5

    <=

    22

    end

    6

    >

    23

    letter

    (letter | digit)*

    10

    >=

    24

    digit

    digit*

    11

    =

    25

    +

    13

    ;

    26

    -

    14

    (

    27

    *

    15

    )

    28

    /

    16

    #

    0

    2.3 词法分析程序的功能

    输入:所给文法的源程序字符串。

    输出:二元组(syn,token或sum)构成的序列。

    其中:syn为单词种别码;

    token为存放的单词自身字符串;

    sum为整型常数。

    例如:对源程序

    begin x:=9: if x>9 then x:=2*x+1/3; end

    #的源文件,经过词法分析后输出如下序列:

    (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……

    三、词法分析程序的算法思想

    算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

    3.1 主程序示意图

    主程序示意图如图3-1所示。其中初始包括以下两个方面:

    (1)

    关键字表的初值。

    关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下:

    Char *rwtab[6] =

    {“begin”, “if”, “then”, “while”, “do”, “end”,};

    blog_64c505480100rj7a.html

    图3-1

    (2)程序中需要用到的主要变量为syn,token和sum

    3.2 扫描子程序的算法思想

    首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。

    blog_64c505480100rj7a.html

    图 3-2

    四、词法分析程序的C语言程序源代码

    #include

    #include

    #include

    char

    prog[100],ch,token[8];

    int

    p=0,syn,n,i;

    char

    *keyword[6]={"begin","then","if","while","do","end"};

    void

    scaner();

    void

    Irparse();

    void

    statement();

    void

    expression_r();

    void

    term();

    void

    factor();

    void

    main()

    {

    int select=-1;

    p=0;

    printf("please input sentence, end of '#' !\n");

    do

    {

    ch=getchar();

    prog[p++]=ch;

    }while(ch!='#');

    p=0;

    printf("请输入1 或 2 \n 1.词法分析\n 2.语法分析\n");

    scanf("%d",&select);

    if(select==1)

    {

    do

    {

    scaner();

    switch(syn)

    {

    case -1:printf("词法分析

    出错\n");break;

    default

    :printf("\n",syn,token);break;

    }

    }while(syn!=0);

    printf("词法分析

    成功\n");

    }

    else if(select==2)

    {

    scaner();

    if(syn==1)

    {Irparse();}//begin

    else

    {printf("语法分析出错! 请检查begin关键字\n");return;}

    if(syn==6)//end

    {

    scaner();

    if(syn==0)

    {

    printf("恭喜

    语法分析 成功\n");

    }

    else

    {printf("语法分析出错! 请检查是否缺少'#'\n");}

    }

    else{printf("语法分析出错! 请检查是否缺少'end'\n");}

    }

    getchar();

    }

    void

    scaner()

    {

    for(n=0;n<8;n++)

    {token[n]='\0';}

    n=0;

    ch=prog[p++];

    while(ch==' '){ch=prog[p++];}

    if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))

    {

    do{

    token[n++]=ch;

    ch=prog[p++];

    }while((ch>='a'&&ch<='z')||(ch>='a'&&ch<='z')||(ch>='0'&&ch<='9'));

    syn=10;

    for(n=0;n<6;n++)

    {if(strcmp(token,keyword[n])==0)

    {

    syn=n+1;

    }

    }

    p--;

    //return;

    }

    else

    if(ch>='0'&&ch<='9')

    {

    p--;

    do

    {

    token[n++]=prog[p++];

    ch=prog[p];

    }while(ch>='0'&&ch<='9');

    syn=11;

    return;

    }

    else

    {

    //ch=prog[p++];

    switch(ch)

    {

    case '+':syn=13;token[0]=ch;break;

    case '-':syn=14;token[0]=ch;break;

    case '*':syn=15;token[0]=ch;break;

    case '/':syn=16;token[0]=ch;break;

    case ':':syn=17;token[0]=ch;

    ch=prog[p++];

    if(ch=='='){token[1]=ch;syn++;}

    else p--;

    break;

    case '

    ch=prog[p++];

    if(ch=='>'){token[1]=ch;syn++;}

    else if(ch=='='){token[1]=ch;syn=syn+2;}

    else p--;

    break;

    case '>':syn=23;token[0]=ch;

    ch=prog[p++];

    if(ch=='='){token[1]=ch;syn++;}

    else p--;

    break;

    case '=':syn=25;token[0]=ch;break;

    case ';':syn=26;token[0]=ch;break;

    case '(':syn=27;token[0]=ch;break;

    case ')':syn=28;token[0]=ch;break;

    case '#':syn=0;token[0]=ch;break;

    default: printf("词法分析出错! 请检查是否输入非法字符\n");syn=-1;break;

    }

    //return;

    }

    }

    void

    Irparse()

    {

    scaner();

    statement();

    while(syn==26)//;

    {

    scaner();

    statement();

    }

    }

    void

    statement()

    {

    if(syn==10)

    {

    scaner();

    if(syn==18)

    {

    scaner();

    expression_r();

    }

    else

    {

    printf("语法分析出错! 请检查表达式是否正确\n");return;

    }

    }

    else

    {

    printf("语法分析出错! 请检查语句是否正确\n");return;

    }

    }

    void

    expression_r()

    {

    term();

    while(syn==13||syn==14)//+ -

    {

    scaner();

    term();

    }

    }

    void

    term()

    {

    factor();

    while(syn==15||syn==16)//* /

    {

    scaner();

    factor();

    }

    }

    void

    factor()

    {

    if(syn==10||syn==11)

    {

    scaner();

    }

    else if(syn==27)

    {

    scaner();

    expression_r();

    if(syn==28)

    {

    scaner();

    }

    else {printf("语法分析出错! 请检查是否缺少')'\n");return;}

    }

    else {printf("语法分析出错! 请检查是否输入非法字符\n");return;}

    }

    五、调试结果:

    1)开始的调试界面

    blog_64c505480100rj7a.html

    2)对程序begin x=4;if

    x>0 then x+3*x+1/2; end #的源文件,经过词法分析后如下图所示

    blog_64c505480100rj7a.html

    六、总结:

    通过编译原理的这次程序实验,在自已动手体验的情况下,更加透彻地理解了词法分析的过程,以及该算法。对于以后由模型向程序代码的转化能力上,有了很大的锻炼。以后我会更加专心的研究计算机知识,不断将现实中遇到的实际问题,向程序方面转变,做到灵活运用所学知识。

    展开全文
  • 2010编译原理实验报告

    2010-06-25 19:38:39
    词法分析实验、语法分析实验、语义分析及中间代码生成实验。每个实验的实验报告包括四个部分,例如词法分析: 1. 词法分析的功能、目的 2. 词法分析程序设计说明 3. 输入文件内容及输出文件内容...4. 词法分析实验体会
  • 编译原理实验一 词法分析 实验目的 (1)根据 PL/0 语言的文法规范,编写PL/0语言的词法分析程序;或者调研词法分析程序的自动生成工具LEX或FLEX,设计并实现一个能够输出单词序列的词法分析器。 (2)通过设计调试...
  • 编译原理实验六】语义分析

    千次阅读 2018-12-23 16:25:27
    语义分析器 内容 学习经典的语义分析器 (1)选择一个编译器,如:...TINY语言请参考《编译原理及实践》第6.5节;PL/0语言请参考相关实现文档。 (3)理解符号表的定义(栏目设置)与基于抽象语法树的类型检查/...
  • 编译原理实验一:DFA的编程实现

    千次阅读 2019-01-29 20:59:16
    初步认识编译器系统和目标机,体会系统编程,了解条件编译和增量编程。 实验任务 获取TINY语言编译器相关源代码。 了解TINY语言定义,可参见文档《TINY语言及其编译器实现》。第一次实验时对TINY语言有大致了解...
  • 通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
  • 编译原理实验一 词法分析设计

    千次阅读 2019-11-27 21:41:29
    通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设 计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的 理解,并能正确地、熟练地运用。 二、实验内容 用 VC++/VB/JAVA ...
  • 自上而下 语法分析实验 一、实验目的 (1)给出 PL/0 文法规范,要求编写 PL/0语言的语法分析程序。 (2)通过设计、编制、调试一个典型的自上而下语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和...
  • 实验要求 实验三 语法分析程序 (一)学习经典的语法分析器 一、实验目的 学习已有编译器的经典语法分析源...TINY语言请参考《编译原理及实践》第3.7节。对TINY语言要特别注意抽象语法树的定义与应用。 (3)测试语
  • 电子科技大学-编译原理实验

    千次阅读 2015-08-04 14:19:11
    通过设计词法分析器的实验,使同学们了解和掌握词法分析程序设计的原理及相应的程序设计方法,同时提高编程能力。 四、实验原理: 1.编译程序要求对高级语言编写的源程序进行分析和合成,生成目标程序。词法分析是...
  • 文章目录前言一、实验目的二、实验步骤1.删除注释2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文...
  • (3)实现原理 程序中先判断这个句语句中每个单元为关键字、常数、运算符、界符,对与不同的单词符号给出不同编码形式的编码,用以区分之。 PL/0语言的EBNF表示 <常量定义>::=<标识符>=<无符号整数>; <标识符>::...
  • 编译原理实验三 LR(1)分析法

    千次阅读 2019-11-27 21:44:10
    实验三 LR(1)分析法 构造 LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文 法识别的句子,了解 LR(K)分析方法是严格的从左向右扫描,和自底向上的 语法分析方法。 二、实验内容 对下列文法,用 ...
  • 编译原理实验二 LL(1)分析法

    千次阅读 2019-11-27 21:43:02
    使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方 法,训练学生掌握开发应用程序的基本方法。有利于提高学生的专业素质,为培 养适应社会多方面需要的能力。 二、实验内容  根据某一文法编制...
  • 编译原理实验报告(一)-词法分析程序》由会员分享,可在线阅读,更多相关《编译原理实验报告(一)-词法分析程序(11页珍藏版)》请在人人文库网上搜索。1、编译原理实验报告(一) 词法分析程序【目的要求】通过设计编制...
  • 编译原理上机实验系列(3) 一、预习准备 1.实验目的 掌握First和Follow集合求法,深入理解LL(1)文法分析过程。 2.实验要求 根据文法求出First和Follow集合 3.实验环境 Xcode 二、实验过程 1.实验步骤 (1)First集 ...
  • 编译原理-实验4

    2012-05-23 10:31:46
    编译原理实验6.2 目标代码生成-四元式,的目标代码及运行结果截图。还有个人的心得体会
  • 编译原理上机实验系列(2) 一、预习准备 1.实验目的 掌握First和Follow集合求法,深入理解LL(1)文法分析过程。 2.实验要求 根据文法求出First和Follow集合 3.实验环境 Xcode 二、实验过程 1.实验步骤 (1)First集 ...
  • 实验目的: 设计、编制和调试一个具体的词法分析程序,加深对词法分析的理解。 要求: (1)通过对PL/0词法分析程序(GETSYS)的分析,编制一个具有以下功能的词法分析程序: a,输入为字符串(或待进行词法分析的...
  • 写这篇文章的目的,是帮助大家了解到编译原理语法分析的模拟实现过程,因为我身边的一些同学,对这后两个实验没什么思路,所以就引发了写作此文的冲动。 -----------------------先上图------------------------...
  • 1.词法分析………………………………………. 2.语法分析………………………………………. 3.语义分析………………………………………. 4.心得体会……………………………………….
  • 实验报告一:PL0语言编译器分析一、实验目的 通过阅读与解析一个实际编译器(PL/0语言编译器)的源代码, 加深对编译阶段(包括词法分析、语法分析、语义分析、中间代码生成等)和编译系统软件结构的理解,并达到...
  • 《合肥工业大学编译原理实验报告(完整代码版)》由会员分享,可在线阅读,更多相关《合肥工业大学编译原理实验报告(完整代码版)(58页珍藏版)》请在人人文库网上搜索。1、计算机与信息学院编译原理实验报告专业班级...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,560
精华内容 2,624
关键字:

编译原理实验体会