编译原理实验教(学)案

合集下载

编译原理实验教案

编译原理实验教案

编译原理实验教案计算机专业教研室季玉茹实验一:词法分析程序设计实验目的1.巩固对词法分析的基本功能和原理的认识。

2.能够应用自动机的知识进行词法分析。

3.理解并处理词法分析中的异常和错误。

实验要求1.掌握词法分析的基本功能,并将其实现。

2.词法分析程序应具有较好的可扩展性,应清晰明确。

3.除对相关问题的全面考虑外,还需对局部作一些优化考虑(如符号表)。

3.明确词法分析的基本功能和原理。

4.在词法分析中哪些地方体现自动机意识。

5.词法分析的异常和错误处理。

6.编写并运行该题目程序代码,具有该题目的参考答案。

7.深刻理解题目内涵,能够清晰描述问题,掌握该题目涉及的知识点,指导学生实验时需要注意的问题。

实验原理参考教材第2章2.3节和下图算法,可以做Pascal语言的词法分析程序;单词的种类分为五种:1.Pascal常用保留字:AND,ARRAY,BEGIN,CASE,CONST,DIV,DO,DOWNTO,ELSE,END,FILE,FOR,GOTO,FUNCTION,IF,IN,LABEL,MOD,NOT,OF,OR,PACKEN,PROCEDURE,PROG RAM,RECORD,REPEAR,SET,THEN,TO,TYPE,UNTIL,V AR,WHILE,WITH2.标识符:[字母]{字母|数字}另外标识符里包括:标准常量:false,ture标准类型:integer,boolen,real,char,text标准文件:input,output标准过程:read,readln,write,writeln3.运算符:+,-,*,/,DIV,MOD,OR,AND,NOT,<,<=,=,>=,>,<>,:=4.界符:“,”,“.”,“、”,“(”,“)”,“:”,“;”5.常数:如10,25,100,14.25实验内容对一段类高级语言代码进行词法分析,并输出词法分析的结果。

编译原理_教学设计方案

编译原理_教学设计方案

一、课程概述编译原理是计算机科学中的一个核心课程,主要研究如何将高级语言程序转换为机器语言或中间代码的过程。

本课程旨在使学生掌握编译器的基本原理和设计方法,培养学生分析和解决问题的能力。

二、教学目标1. 知识目标:- 理解编译器的基本概念、工作原理和设计方法。

- 掌握词法分析、语法分析、语义分析、代码生成和优化等编译器核心组件的工作原理。

- 了解编译器在软件工程中的重要作用。

2. 能力目标:- 能够分析和设计简单的编译器。

- 能够运用编译原理知识解决实际问题。

- 培养学生的编程能力和算法设计能力。

3. 素质目标:- 培养学生的逻辑思维能力和严谨的学术态度。

- 增强学生的团队合作意识和沟通能力。

三、教学内容1. 引言:编译器的概念、发展历史和作用。

2. 词法分析:正规表达式、有限自动机、词法分析器设计。

3. 语法分析:上下文无关文法、递归下降分析、LL(1)分析、LR分析。

4. 语义分析:类型检查、作用域分析、语义规则。

5. 中间代码生成:三地址码、四元式、逆波兰表示法。

6. 代码优化:数据流分析、代码优化策略。

7. 目标代码生成:机器代码、汇编语言、目标代码生成技术。

8. 编译器构造工具:编译器生成器、代码优化工具。

四、教学方法1. 讲授法:系统讲解编译原理的基本概念、原理和方法。

2. 案例分析法:通过分析经典的编译器案例,加深对理论知识的理解。

3. 实验法:设计实验,让学生动手实现编译器的基本组件。

4. 讨论法:组织课堂讨论,激发学生的学习兴趣,培养学生的批判性思维。

5. 项目法:设计编译器开发项目,让学生综合运用所学知识。

五、教学过程1. 导入:介绍编译原理的重要性,激发学生的学习兴趣。

2. 讲解:系统讲解编译原理的基本概念和原理。

3. 案例分析:分析经典的编译器案例,帮助学生理解理论知识。

4. 实验:设计实验,让学生动手实现编译器的基本组件。

5. 讨论:组织课堂讨论,解决学生在学习过程中遇到的问题。

编译原理实验教程课程设计

编译原理实验教程课程设计

编译原理实验教程课程设计背景编译原理是计算机科学专业的一门重要课程,它研究如何将高级语言翻译成低级语言,以便计算机执行。

编译器是实现这一过程的关键工具。

然而,对于很多学生来说,编译原理的理论知识学习起来比较抽象,难以掌握。

因此,本文旨在为编译原理的学习提供一些实验教程的设计思路。

实验一:词法分析器词法分析器是编译器的第一个模块,它的作用是将输入的字符流转化为一个个单词符号。

本实验的目的是设计并实现一个简单的词法分析器,实现以下功能:1.识别输入的程序中所包含的各个单词符号。

2.输出所有单词符号及其对应的单词类型。

3.当遇到不合法单词符号时,给出相应的错误提示。

具体实现可以采用有限自动机的思想,使用正则表达式或者手写代码,实现对于不同的单词类型的识别,并对于不合法单词进行识别和报错处理。

实验二:语法分析器语法分析器是编译器的第二个模块,它的作用是将词法分析器输出的单词序列转换成语法树或者语法分析表,以便后续进行语义分析和目标代码生成。

本实验的目的是设计并实现一个简单的语法分析器,实现以下功能:1.识别输入的程序是否符合所设计的文法规则。

2.输出语法树或语法分析表。

具体实现可以采用自上而下的递归下降分析法或自下而上的移进-规约分析法,实现对于不同的句型的识别,并生成语法树或语法分析表。

实验三:语义分析器语义分析器是编译器的第三个模块,它的作用是对语法分析器输出的语法树或语法分析表进行语义分析,并生成中间代码。

本实验的目的是设计并实现一个简单的语义分析器,实现以下功能:1.对语法树或语法分析表进行遍历,识别语法错误和语义错误,给出相应的错误提示。

2.生成中间代码。

具体实现可以采用语义规则和符号表的检查方式,识别语法错误和语义错误,并在生成中间代码时,根据中间代码语言的规则进行实现。

实验四:目标代码生成器目标代码生成器是编译器的第四个模块,它的作用是将中间代码转换成机器语言,以便计算机执行。

本实验的目的是设计并实现一个简单的目标代码生成器,实现以下功能:1.将中间代码转换成机器语言。

编译原理-课程教学设计方案

编译原理-课程教学设计方案

《编译原理》课程教学设计方案适用专业:计算机科学技术编制人:系部主任:审核人:编制日期:2014年4院15日目录一、《编译原理》课程整体教学设计方案 (1)(一)基本信息 (1)(二)课程设计 (1)(三)考核方案设计 (4)(四)教学组织形式 (5)(五)教学材料 (5)二、课程单元教学方案设计 (6)(一)教学内容1 (6)1、教案头 (6)2、教学过程设计 (6)(二)教学内容2 (7)1、教案头 (7)2、教学过程设计 (8)(三)教学内容3 (10)1、教案头 (10)2、教学过程设计 (10)《编译原理》课程教学设计方案一、《编译原理》课程整体教学设计方案(一)基本信息课程名称:编译原理学时:72学时课程类型:专业技能课学分:3学分所属系部:计算机科学系授课对象:二年级学生先修课程:《数据结构》、《离散数学》后续课程:《JAVA程序设计》课程团队负责人及成员:孔玉静(二)课程设计1、课程目标设计(1)能力目标:培养学生掌握构造编译程序的基本原理与设计方法,为培养计算机语言与大型应用程序的开发人才打下良好的基础。

(2)知识目标:通过本课程学习,使学生掌握编译程序的一般构造原理,包括语言基础知识、词法分析程序设计原理和构造方法。

各种语法分析技术和中间代码生成符号表的构造、代码优化、并行编译技术常识及运行时存储空间的组织等基本方法和主要实现技术。

2、课程教学内容设计3、能力训练项目设计4、教学进度表设计5、教学方法与教学手段设计课堂教学:多媒体教学进行教学,使学生能够很快掌握课程的主要知识和解决问题的方法。

辅导和答疑:以习题课对课程中的重要概念和典型问题的解决方法进行总结和深入讨论,巩固和加深课堂内学到的知识。

采用电子邮件方式直接与教师联系进行答疑。

自学与练习:除读懂教科书中所讲内容外,还需大量做题。

其目的是要通过做题弄懂、加深对概念的理解,提高解决问题的能力。

为此,安排一定的实验上机学时。

《编译原理》实验教学大纲

《编译原理》实验教学大纲

《编译原理》实验教学大纲一、实验目的和任务编译原理是计算机科学与技术专业的一门重要课程,它主要研究的是将高级语言程序翻译成机器语言程序的方法和技术。

通过本实验课程的学习,旨在使学生掌握编译原理的基本原理和方法,培养学生对编译器结构与构造技术的专门知识和技能,为学生今后进行编译器设计与实现打下基础。

二、实验设备和工具1.计算机和相关硬件设备2. 编程语言的开发环境,如C/C++或Java三、实验内容1.实验一:词法分析器设计与实现a)实验目的:学习词法分析器的原理和设计方法,掌握正则表达式、DFA和NFA的转换方法。

b)实验任务:i.设计并实现一个词法分析器的原型,能够正确地识别出给定的程序中的词法单元。

ii. 使用给定的正则表达式设计并实现识别给定程序中的关键字、标识符、常量等的词法分析器。

2.实验二:语法分析器设计与实现a)实验目的:学习语法分析器的原理和设计方法,掌握上下文无关文法和LR分析表的构造方法。

b)实验任务:i.学习并理解上下文无关文法和LR分析表的构造方法。

ii. 设计并实现一个简单的递归下降语法分析器。

3.实验三:语义分析器设计与实现a)实验目的:学习语义分析器的原理和设计方法,掌握语义动作的定义和处理方法。

b)实验任务:i.学习并理解语义分析器的原理和设计方法。

ii. 设计并实现一个简单的语义分析器,能够对给定的程序进行语义分析和语义动作的处理。

4.实验四:中间代码生成器设计与实现a)实验目的:学习中间代码生成器的原理和设计方法,掌握中间代码的生成和优化方法。

b)实验任务:i.学习并理解中间代码生成器的原理和设计方法。

ii. 设计并实现一个简单的中间代码生成器,能够将给定的程序翻译成中间代码。

5.实验五:目标代码生成器设计与实现a)实验目的:学习目标代码生成器的原理和设计方法,掌握目标代码的生成和优化方法。

b)实验任务:i.学习并理解目标代码生成器的原理和设计方法。

ii. 设计并实现一个简单的目标代码生成器,能够将中间代码翻译成目标代码。

编译原理实验教案

编译原理实验教案

编译原理实验教案1.1 背景介绍1.1.1 编译原理是计算机科学中的一个重要分支,研究如何将高级编程语言转换为机器语言。

1.1.2 编译器作为编程语言和计算机硬件之间的桥梁,对于软件开发至关重要。

1.1.3 通过实验学习编译原理,可以加深对编译过程的理解,提高实际编程能力。

二、知识点讲解2.1 编译器的基本组成部分2.1.1 词法分析器:将字符串分解为词法单元。

2.1.2 语法分析器:根据语言的语法规则,将词法单元组合成抽象语法树。

2.1.3 语义分析器:检查抽象语法树的语义正确性,如类型检查等。

2.1.4 中间代码器:将抽象语法树转换为中间代码表示。

2.1.5 代码优化器:对中间代码进行优化,提高代码执行效率。

2.1.6 目标代码器:将优化后的中间代码转换为目标机器代码。

三、教学内容3.1 词法分析实验3.1.1 实现一个简单的词法分析器,能够识别变量名、关键字、常量等。

3.1.2 练习使用正则表达式处理字符串,实现词法单元的提取。

3.1.3 分析词法分析过程中可能遇到的问题,如标识符与关键字的冲突等。

3.2 语法分析实验3.2.1 学习常用的语法分析算法,如LL(1)、LR(1)等。

3.2.2 实现一个简单的语法分析器,能够对简单的算术表达式进行解析。

3.2.3 通过构造预测分析表,解决标识符与关键字冲突的问题。

3.3 语义分析实验3.3.1 学习基本的语义分析方法,如静态语义分析、动态语义分析等。

3.3.2 实现一个简单的类型检查器,能够检查变量类型的正确性。

3.3.3 分析并解决常见语义错误,如类型不匹配、未定义变量等。

四、教学目标4.1 理解编译器的基本工作原理和各个组件的功能。

4.2 掌握基本的词法分析、语法分析和语义分析方法。

4.3 能够独立设计和实现简单的编译器组件,解决实际编程中的问题。

五、教学难点与重点5.1 编译器的设计与实现涉及多个方面的知识,如语言学、逻辑学、计算机科学等。

编译原理实验教案

编译原理实验教案

一、实验目的与要求1. 实验目的(1) 理解编译原理的基本概念和流程。

(2) 掌握常用的编译方法和技术。

(3) 熟练使用编译器开发工具。

2. 实验要求(1) 熟悉计算机专业基础知识。

(2) 掌握C/C++编程语言。

(3) 了解基本的编译原理。

二、实验环境1. 硬件环境(1) 计算机一台。

(2) 编译器开发工具(如GCC、Clang等)。

2. 软件环境(1) 操作系统(如Windows、Linux等)。

(2) 文本编辑器或集成开发环境(如Visual Studio、Eclipse等)。

三、实验内容1. 实验一:词法分析(1) 实现一个简单的词法分析器,识别出关键字、标识符、常量等。

(2) 分析输入的程序,输出词法分析结果。

2. 实验二:语法分析(1) 实现一个简单的语法分析器,根据给定的语法规则分析输入的程序。

(2) 分析输入的程序,输出语法分析树。

3. 实验三:语义分析(1) 实现一个简单的语义分析器,检查程序中的语义错误。

(2) 分析输入的程序,输出语义分析结果。

4. 实验四:中间代码(1) 实现一个简单的中间代码器,将转换为中间代码表示。

(2) 对输入的程序进行转换,输出中间代码。

5. 实验五:目标代码(1) 实现一个简单的目标代码器,将中间代码转换为目标代码。

(2) 对输入的中间代码进行转换,输出目标代码。

四、实验步骤与方法1. 实验一:词法分析(1) 编写词法分析器的代码。

(2) 测试并调试词法分析器。

2. 实验二:语法分析(1) 编写语法分析器的代码。

(2) 测试并调试语法分析器。

3. 实验三:语义分析(1) 编写语义分析器的代码。

(2) 测试并调试语义分析器。

4. 实验四:中间代码(1) 编写中间代码器的代码。

(2) 测试并调试中间代码器。

5. 实验五:目标代码(1) 编写目标代码器的代码。

(2) 测试并调试目标代码器。

五、实验注意事项1. 按照实验要求编写代码,注意代码规范和可读性。

编译原理实验教案

编译原理实验教案

实验教学进度表实验一 C语言子集编译程序一、实验目的用C语言对一个C语言的子集编制一个一遍扫描的编译程序,以加深对编译原理的理解,掌握编译程序的实现方法和技术。

1.设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

2.编制一个递归下降分析程序,并对C语言的简单子集进行分析。

3.通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换中间代码的语义翻译方法。

二、实验要求、内容及学时词法分析部分:2学时(一)待分析的C语言子集的词法:1.关键字main if else int return void while所有关键字都是小写。

2.专用符号= + - * / < <= > >= == != ; : , { } [ ] ( )3.其他标记ID和NUM通过以下正规式定义其他标记:ID→letter(letter|digit)*NUM→digit(digit)*letter→a|…|z|A|…|Z digit→0|…|94.空格由空白、制表符和换行符组成空格一般用来分隔ID、NUM、专用符号和关键字,词法分析阶段空格通(二)词法分析程序的功能:输入:所给文法的源程序字符串。

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

其中,syn 为单词类别码。

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

sum 为整型常量。

具体实现时,可以将单词的二元组用结构进行处理。

例如:对源程序main(){int i=10;while(i) i=i-1;}的源文件,经词法分析后输出如下序列:(1,main) (26,() (27,)) (30,{) (2,int) (10,i) (21,=) (20,10) (34,;) (7,while) (26,() (10,i) (27,)) (10,i) (21,=) (10,i) (23,-) (20,1) (34,;) (31, })(三)词法分析程序主要算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验教学进度表实验一 C语言子集编译程序一、实验目的用C语言对一个C语言的子集编制一个一遍扫描的编译程序,以加深对编译原理的理解,掌握编译程序的实现方法和技术。

1.设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

2.编制一个递归下降分析程序,并对C语言的简单子集进行分析。

3.通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换中间代码的语义翻译方法。

二、实验要求、容及学时词法分析部分:2学时(一)待分析的C语言子集的词法:1.关键字main if else int return void while所有关键字都是小写。

2.专用符号= + - * / < <= > >= == != ; : , { } [ ] ( )3.其他标记ID和NUM通过以下正规式定义其他标记:ID→letter(letter|digit)*NUM→digit(digit)*letter→a|…|z|A|…|Z digit→0|…|94.空格由空白、制表符和换行符组成空格一般用来分隔ID、NUM、专用符号和关键字,词法分析阶段空格通(二)词法分析程序的功能:输入:所给文法的源程序字符串。

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

其中,syn 为单词类别码。

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

sum 为整型常量。

具体实现时,可以将单词的二元组用结构进行处理。

例如:对源程序main(){int i=10;while(i) i=i-1;}的源文件,经词法分析后输出如下序列:(1,main) (26,() (27,)) (30,{) (2,int) (10,i) (21,=) (20,10) (34,;) (7,while) (26,() (10,i) (27,)) (10,i) (21,=) (10,i) (23,-) (20,1) (34,;) (31, })(三)词法分析程序主要算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

:注:①关键字表初值关键字作为特殊标识符处理,把它们预先安排在一表格中(称为关键字),当扫描程序识别出标识符时,查关键字表。

如能查到匹配的单词,则该单词为关键字,否则为一般标识符。

关键字表可处理为一个字符串数组(实际为指向字符数组的指针数组),其描述如下:char *KEY_WORDS[8]={“main”,”int”,”char”,”if”,”else”,”for”,”while”};为分析方便,这里把main作关键字处理。

②程序中需要用到的主要变量:syn,token和sum。

2.扫描子程序(scaner)的算法思想首先设置三个变量:token用来存放构成单词符号的字符串;sum用来存放整型单词;syn用来存放单词的类别码。

扫描子程序主要部分N—S图语法分析部分:2学时(一)待分析的C语言子集的语法用扩充的BNF表示如下:1.<程序>→main()<语句块>2. <语句块>→’{‘<语句串>’}’3. <语句串>→<语句>{;<语句>};4. <语句>→<赋值语句>|<条件语句>|<循环语句>5. <赋值语句>→ID=<表达式>6. <条件语句>→if(<条件表达式>)<语句块>7. <循环语句>→while(<条件表达式>)<语句块>8. <条件表达式>→<表达式><关系运算符><表达式>9. <表达式>→<项>{+<项>|-<项>}10.<项>→<项>{*<因子>|/<因子>}11.<因子>→ID|NUM|(<表达式>)12.<关系运算符>→<|<=|>|>=|==|!=(二)语法分析程序的主要算法思想1.主程序结构示意图如下:2.递归下降分析程序结构示意图如下:4.语句串分析结构示意图如下:6.expression函数结构示意图如下:79语义分析部分:2学时(一)实验的输入和输出输入是语法分析提供的正确的单词串,输出是四元式序列。

例如,对于语句串i=2*3+4;if(i>10) {j=3;}while(j>0) k=1;输出的四元式序列如下:1:*, 2, 3, T12:+, T1, 4, T23:=, T2, , i4:j>, i, 10, 65:j, , , 76:=, 3, , j7:j>, j, 0, 98:j, , , 119:=, 1, , k10:j, , , 7(二)算法思想1.设置语义过程①int gen(op,arg1,arg2,result)该函数是将四元式(op,arg1,arg2,result)送到四元式表中。

②char *newtemp()该函数回送一个新的临时变量名,临时变量名产生的顺序为:T1,T2,……③int merg(p1,p2)该函数将以p1和p2为头指针的两条链合并为一,合并后的链表首为返回值。

④int bp(p,t)该函数的功能是把p所的每个四元式的第四区段都填为t。

2.主程序示意图如下:3.函数lrparse 在原来语法分析的基础上插入相应的语义动作。

将输入串翻译成四元式序列。

在实验中我们只对表达式、if 语句和while 语句进行翻译,其具体翻译程序见实例。

算符优先分析法部分:(选作)算符优先分析法特别有利于表达式的处理,宜于手工实现。

算符优先分析过程是自下而上的归约过程,但这种归约未必是严格的规归约。

因此,所谓算符优先分析法就是定义算符之间的某种优先关系,并借助这种关系寻找句型的最左素短语进行归约。

算符优先分析法通常有两种:优先矩阵法和优先函数法。

前者是提供一算符优先关系表,后者提供两个优先函数(入栈优先函数f 和比较优先函数g ),优先函数法比优先矩阵法节约存储空间,所以较为普遍。

下面介绍使用优先函数法的分析过程。

分析过程:先在算符栈置“$”,然后开始顺序扫描表达式。

若读来的单词符号是操作数,则直接进操作数栈,然后继续下一个单词符号。

分析过程从头开始,并重复进行;若读来的单词符号是运算符2θ,则将当前处于运算符栈顶的运算符1θ的入栈优先函数f 与2θ的比较优先函数g 进行比较。

1.若12()()f g θθ≤,则2θ进算符栈,并继续顺序往下扫描,分析过程重复进行。

2.若12()()f g θθ>,则产生对操作数栈顶的若干项进行1θ运算的中间代码,并从运算符栈顶移去1θ,且从操作数栈顶移去相应若干项,然后把执行1θ运算的结果压入操作数栈。

接着以运算符栈新的项与2θ进行上述比较。

3.重复步骤1,2,直到“$”和“$”配对为止。

三、实验环境DOS 或Windows 操作系统 TURBO C 2.0或Visual C++ 四、实验参考(参考代码)#ifndef _GLOBALS_H #define _GLOBALS_H#include<stdio.h>#include<stdlib.h>#include<string.h>#define _SYN_MAIN 1 #define _SYN_INT 2 #define _SYN_CHAR 3 #define _SYN_IF 4 #define _SYN_ELSE 5 #define _SYN_FOR 6 #define _SYN_WHILE 7#define _SYN_ID 10 #define _SYN_NUM 20#define _SYN_ASSIGN 21 #define _SYN_PLUS 22 #define _SYN_MINUS 23 #define _SYN_TIMES 24 #define _SYN_DIVIDE 25 #define _SYN_LPAREN 26 #define _SYN_RPAREN 27 #define _SYN_LEFTBRACKET1 28 #define _SYN_RIGHTBRACKET1 29 #define _SYN_LEFTBRACKET2 30 #define _SYN_RIGHTBRACKET2 31#define _SYN_COMMA 32#define _SYN_COLON 33#define _SYN_SEMICOLON 34#define _SYN_LG 35#define _SYN_LT 36#define _SYN_ME 37#define _SYN_LE 38#define _SYN_EQ 39#define _SYN_NE 40#define _SYN_END 1000#define _SYN_ERROR -1#define MAXLENGTH 255#ifndef _SEMANTEM_H#define _SEMANTEM_H/*四元组的结构*/typedef struct QUAD{char op[MAXLENGTH]; /*操作符*/char argv1[MAXLENGTH]; /*第一个操作数*/char argv2[MAXLENGTH]; /*第二个操作数*/char result[MAXLENGTH]; /*运算结果*/}QUATERNION;void lrparse(void); /*语法语义分析主函数*/#endifunion WORDCONTENT{char T1[MAXLENGTH];int T2;char T3;};typedef struct WORD{int syn;union WORDCONTENT value;}WORD;#ifndef _SCAN_H#define _SCAN_H#define _TAB_LEGNTH 4#define _KEY_WORD_END "waiting for you expanding"void Scaner(void);#endifQUATERNION *pQuad;int nSuffix,nNXQ,ntc,nfc;extern WORD uWord;extern int gnColumn,gnRow;FILE *fw;char *strFileName;char *strSource;char *Expression(void);char *Term(void);char *Factor(void);void Statement_Block(int *nChain);/*FILE *Source;*/FILE *fw;char *strSource;void Do_Tag(char *strSource);void Do_Digit(char *strSource);void Do_EndOfTag(char *strSource); void Do_EndOfDigit(char *strSource); void Do_EndOfEqual(char *strSource);void Do_EndOfPlus(char *strSource);void Do_EndOfSubtraction(char *strSource); void Do_EndOfMultiply(char *strSource);void Do_EndOfDivide(char *strSource);void Do_EndOfLParen(char *strSource);void Do_EndOfRParen(char *strSource);void Do_EndOfLeftBracket1(char *strSource); void Do_EndOfRightBracket1(char *strSource); void Do_EndOfLeftBracket2(char *strSource); void Do_EndOfRightBracket2(char *strSource); void Do_EndOfColon(char *strSource);void Do_EndOfComma(char *strSource);void Do_EndOfSemicolon(char *strSource);void Do_EndOfMore(char *strSource);void Do_EndOfLess(char *strSource);void Do_EndOfEnd(char *strSource);void PrintWord(WORD uWord);void ApartWord(char *strSource);void PrintError(int nColumn,int nRow,char chInput);void Scaner(void);int gnColumn,gnRow,gnLocate,gnLocateStart; WORD uWord;char*KEY_WORDS[20]={"main","int","char","if","el se","for","while","void",_KEY_WORD_END};int IsDigit(char chInput)//判断扫描的字符是否数字{if(chInput<='9'&&chInput>='0') return 1;else return 0;}int IsChar(char chInput)//判断扫描的字符是否字母{if((chInput<='z'&&chInput>='a')||(chInput <='Z'&&chInput>='A'))return 1;else return 0;}void Do_Start(char *strSource)//开始识别一个单词{gnLocateStart=gnLocate;switch(strSource[gnLocate]){case '+': Do_EndOfPlus(strSource); break;case '-': Do_EndOfSubtraction(strSource);break;case '*': Do_EndOfMultiply(strSource); break;case '/': Do_EndOfDivide(strSource);break;case '(': Do_EndOfLParen(strSource);break;case ')': Do_EndOfRParen(strSource);break;case '[': Do_EndOfLeftBracket1(strSource);break;case ']': Do_EndOfRightBracket1(strSource);break;case '{': Do_EndOfLeftBracket2(strSource);break;case '}': Do_EndOfRightBracket2(strSource);break;case ':': Do_EndOfColon(strSource);break;case ',': Do_EndOfComma(strSource);break;case ';': Do_EndOfSemicolon(strSource);break;case '>': Do_EndOfMore(strSource); break;case '<': Do_EndOfLess(strSource); break;case '=': Do_EndOfEqual(strSource); break;case '\0': Do_EndOfEnd(strSource); break;default:if(IsChar(strSource[gnLocate])){Do_Tag(strSource);}elseif(IsDigit(strSource[gnLocate])){uWord.value.T2=strSource[gnLocate]-'0';Do_Digit(strSource);}else{if(strSource[gnLocate]!=' ' &&strSource[gnLocate]!='\t'&&strSource[gnLocate]!='\n'&&strSource[gnLocate]!='\r'){PrintError(gnColumn,gnRow,strSource[gnLoc ate]);}if(strSource[gnLocate]=='\n'||strSource[gnLocate]=='\r'){gnColumn++;gnRow=1;}elseif(strSource[gnLocate]=='\t'){gnColumn+=_TAB_LEGNTH;}elsegnRow++;gnLocate++;Do_Start(strSource);}break;}return;}void Do_Tag(char *strSource)//识别标识符的中间状态{gnLocate++;gnRow++;if(IsChar(strSource[gnLocate])||IsDigit(s trSource[gnLocate])){Do_Tag(strSource);}elseDo_EndOfTag(strSource);return;}void Do_Digit(char *strSource)//识别整数的中间状态{gnLocate++;gnRow++;if(IsDigit(strSource[gnLocate])){uWord.value.T2=uWord.value.T2*10+strSourc e[gnLocate]-'0';Do_Digit(strSource);}else Do_EndOfDigit(strSource);return;}void Do_EndOfTag(char *strSource)//识别标识符的最后状态{int nLoop;uWord.syn=_SYN_ID;strncpy(uWord.value.T1,strSource+gnLocate Start,gnLocate-gnLocateStart);uWord.value.T1[gnLocate-gnLocateStart]='\0';nLoop=0;while(strcmp(KEY_WORDS[nLoop],_KEY_WORD_E ND)){if(!strcmp(KEY_WORDS[nLoop],uWord.value.T 1)){uWord.syn=nLoop+1;}nLoop++;}return;}void Do_EndOfDigit(char *strSource)//识别数的最后状态{uWord.syn=_SYN_NUM;return;}void Do_EndOfEqual(char *strSource)//识别==的最后状态,它的开始状态在Do_Start中已处理,//运算符没有中间状态,因为最多由两个符号组成,//而数和标识符可以由多个终结符组成。

相关文档
最新文档