编译原理实验词法分析实验报告

编译技术实验报告

实验题目:词法分析

学院:信息学院

专业:计算机科学与技术

学号:

姓名:

一、实验目的

(1)理解词法分析的功能;

(2)理解词法分析的实现方法;

二、实验内容

PL0的文法如下

‘< >’为非终结符。

‘::=’ 该符号的左部由右部定义,可读作“定义为”。

‘|’ 表示‘或’,为左部可由多个右部定义。

‘{ }’ 表示花括号内的语法成分可以重复。在不加上下界时

可重复0到任意次数,有上下界时可重复次数的限制。

‘[ ]’ 表示方括号内的成分为任选项。

‘( )’ 表示圆括号内的成分优先。

上述符号为“元符号”,文法用上述符号作为文法符号时需

要用引号‘’括起。

〈程序〉∷=〈分程序〉.

〈分程序〉∷= [〈变量说明部分〉][〈过程说明部分〉]〈语句〉〈变量说明部分〉∷=VAR〈标识符〉{,〈标识符〉}:INTEGER;

〈无符号整数〉∷=〈数字〉{〈数字〉}

〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}

〈过程说明部分〉∷=〈过程首部〉〈分程序〉{;〈过程说明部分〉};

〈过程首部〉∷=PROCEDURE〈标识符〉;

〈语句〉∷=〈赋值语句〉|〈条件语句〉|〈过程调用语句〉|〈读语句〉|〈写语句〉|〈复合语句〉|〈空〉

〈赋值语句〉∷=〈标识符〉∶=〈表达式〉

〈复合语句〉∷=BEGIN〈语句〉{;〈语句〉}END

〈条件〉∷=〈表达式〉〈关系运算符〉〈表达式〉

〈表达式〉∷=〈项〉{〈加法运算符〉〈项〉}

〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}

〈因子〉∷=〈标识符〉|〈无符号整数〉|'('〈表达式〉')'

〈加法运算符〉∷=+|-

〈乘法运算符〉∷=*

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

〈条件语句〉∷=IF〈条件〉THEN〈语句〉

〈字母〉∷=a|b|…|X|Y|Z

〈数字〉∷=0|1|2|…|8|9

实现PL0的词法分析

三、实验分析与设计

PL0词法分析程序是一个独立的过程,其功能是为语法语义分析提供单词,把输入的字符串形式的源程序分割成一个个单词符号传递给语法语义分析。

其主要方法步骤为从源程序扫描下一个字符,忽略空格、换行、TAB和注释并识别单词,再将不同类别的单词归类输出。

四、实验的实现

#include

#include

#include

#include

#include

#define norw 11 //norw-1个关键字#define al 20 //最长的关键字的长度#define ID norw

#define INT norw+1

#define COMMA norw+2

#define ENDF norw+3

#define COLON norw+4

#define SEMIC norw+5

#define ADD norw+6

#define MINUS norw+7

#define MULTI norw+8

#define EVALU norw+9

#define LE norw+10

#define NE norw+11

#define LT norw+12

#define EQ norw+13

#define GE norw+14

#define GT norw+15

#define FLOAT norw+16

char TOKEN[20]; //字符数组用来依次存放单词词文的各个字符

extern int lookup(char *); //以TOKEN字符串查保留字表

extern void report_error(char); //报告程序中的词法错误bool isalpha(char); //判断接收字符是否为字母

bool isalnum(char); //判断接收字符是否为字母或者数字

bool isdigit(char); //判断接收字符是否为数字

bool isannotation(char); //判断接收字符是否为注释

extern char letter(char c); //用来将大写字母转化成小写字母FILE* fin;

FILE* fout;

void scanner()

{//词法分析的主体程序,对输入的文本文件进行词法分析

char ch;

int i,c;

int error=0; //记录文件中词法错误的个数

ch=fgetc(fin); //从输入文件中读取一个字符

while(ch!=EOF)

{//当从输入文件接收的字符不是文件结束符时,执行循环if(isalpha(ch))

{//如果从输入文件接收的第一个字符是字母

ch=letter(ch);

TOKEN[0]=ch;

ch=fgetc(fin);i=1;

while(isalnum(ch))

{ ch=letter(ch);

TOKEN[i]=ch;i++;

ch=fgetc(fin);

}

TOKEN[i]='\0';

c=lookup(TOKEN); //查保留字表

if(c==0) {fprintf(fout,"(%d,%s)\n", ID,TOKEN);} //输出标识符

else fprintf(fout,"(%d,%s)\n", c,TOKEN); //输出接收单词为保留字

}

if(isdigit(ch)) //如果从输入文件

接收的第一个字符是数字

{

int cdot=0; //统计小数点个数

TOKEN[0]=ch;

ch=fgetc(fin);i=1;

while(isdigit(ch)||ch=='.')

{//从第二个接收字符开始,当是数字或者是小数点时,执

行循环

if(ch=='.')

cdot++;

TOKEN[i]=ch;i++;

ch=fgetc(fin);//重复接收字符,直到接收到非数字

if(cdot>=2)

{

error++;

TOKEN[i]='\0';

printf("%s is error\n", TOKEN);

break;

}

}

if(isalpha(ch)) //如果第二个字符是字母

{

while(isalpha(ch)) //接收完所有的字母,跳出循环

{

TOKEN[i]=ch;i++;

ch=fgetc(fin);

}

TOKEN[i]='\0';

error++;

printf("%s is error\n", TOKEN);

}

else if(cdot==0) //当接收的字符为整型单词时

{

fseek(fin,-1,1);

TOKEN[i]='\0';

int a,temp=0,c;

for(c=0;c

{

a=TOKEN[c] - '0';

if(c!=0)

{

temp=temp*10;

temp=temp+a;

}

else

{

temp=a;

}

}

fprintf(fout,"(%d,%d)\n", INT, temp); //输出接收单词为整数

}

else if(cdot==1)

{

fseek(fin,-1,1);

TOKEN[i]='\0';

int a,part1=0,jc,b=0; //b用来确定小

数点所在的位置

float c=0.1,part2=0.0;

while(TOKEN[b]!='.')

{

b=b+1;

}

for(jc=0;jc

{

a=TOKEN[jc] - '0';

if(jc!=0)

{

part1=part1*10;

part1=part1+a;

}

else

{

part1=a;

}

}

for(jc=b+1;jc

{

a=TOKEN[jc]-'0';

part2=a*c+part2;

c=c*0.1;

}

fprintf(fout,"(%d,%f)\n", FLOAT, part1+part2); //输出接收单词为小数

}else if(cdot==2)

{

fseek(fin,-1,1);

}

}

else //如果从输入文件接收的第一个字符既不

是字母又不是数字

switch(ch)

{//将所接收到的符号字符进行分类,采取一符一类

case':':ch=fgetc(fin);

if(ch=='=') fprintf(fout,"(%d,:=)\n", EVALU);

//输出接收符号为赋值号

else

{ch=fgetc(fin);

fseek(fin,-1,1); //文

件接收字符回推一个字符

fprintf(fout,"(%d,':')\n", COLON);

//输出冒号

}

break;

case',':fprintf(fout,"(%d,',')\n", COMMA); break;

//输出逗号

case'.':fprintf(fout,"(%d,'.')\n", ENDF);break; //输出句号

case';':fprintf(fout,"(%d,'.')\n", SEMIC);break; //输出分号

case'+':fprintf(fout,"(%d,'+')\n", ADD);break; //输出加号

case'-':fprintf(fout,"(%d,'-')\n", MINUS);break; //输出减号

case'*':fprintf(fout,"(%d,'*')\n", MULTI);break; //输出乘号

case'<':ch=fgetc(fin);

if(ch=='=')fprintf(fout,"(%d,'<=')\n", LE);

//输出小于或等于号

else if(ch=='>')fprintf(fout,"(%d,'<>')\n", NE);

//输出不等于号

else

{

fseek(fin,-1,1);

fprintf(fout,"(%d,'<')\n", LT);;

//输出小于号

}

break;

case'=':fprintf(fout,"(%d,'=')\n", EQ);break; //输出等于号

case'>':ch=fgetc(fin);

if(ch=='=')fprintf(fout,"(%d,'>=')\n", GE);

//输出大于或等于号

else

{

fseek(fin,-1,1);

fprintf(fout,"(%d,'>')\n", GT);

//输出大于号

}

break;

case' ':break;

case'\n':break;

case'\t':break;

case'/':ch=fgetc(fin);//检查是否为单行注释

if(ch=='/'){

while(ch!='\n'){

ch=fgetc(fin);

}

}

else {

fseek(fin,-1,1);

printf("/ is error\n");

error++;

}

break;

case'{':

while(1){

ch=fgetc(fin);

if(ch=='}') break;

if(ch==EOF) {

fseek(fin,-1,1);

printf("{ is error\n");

error++;

break;

}

}

break;

default:printf("%c is error\n", ch); //接收非上述字符程序报告词法错误

error++;break;

}

ch=fgetc(fin); //继续从文件中读取下一个单词,直到文件结束

}//while循环结束

printf("共发现%d 个词法错误!",error);

return;

}

int lookup(char *token)

{

int j;

char word[norw][al];

strcpy(&(word[1][0]), "begin" );

strcpy(&(word[2][0]), "end");

strcpy(&(word[3][0]), "var");

strcpy(&(word[4][0]), "integer");

strcpy(&(word[5][0]), "while");

strcpy(&(word[6][0]), "do");

strcpy(&(word[7][0]), "if");

strcpy(&(word[8][0]), "then");

strcpy(&(word[9][0]), "procedure");

strcpy(&(word[10][0]), "else");

for(j=1;j<=norw-1;j++)if(strcmp(token,word[j])==0) return j; //以TOKEN字符串查保留字表,若查到返回保留字类别码

return 0; //TOKEN不是保留字,返回0

}

bool isalpha(char c)

{ //判断接收字符是否为字母

if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))return 1;

else return 0;

}

bool isalnum(char c)

{//判断接收字符是否为字母或者数字

if((c>='a'&&c<='z')||(c>='A'&&c<='Z')||(c>='0'&&c<='9'))ret urn 1;

else return 0;

}

bool isdigit(char c)

{//判断接收字符是否为数字

if(c>='0'&&c<='9')return 1;

else return 0;

}

char letter(char c) //将大写字母转换成小写字母,即不区分大小写

{

if(c>='A'&&c<='Z')

{

c=c+32;

}

return c;

}

int main()

{

char filename[20];

printf("请输入文件名:");

scanf("%s",filename);

if((fin=fopen(filename,"r"))==NULL) //打开要读取的文本文件{

printf("不能打开文件.\n");

exit(0);

}

printf("请输入保存分析结果的文件名:"); scanf("%s",filename);

if((fout=fopen(filename,"w"))==NULL) {

printf("不能打开文件.\n");

exit(0);

}

scanner(); //调用词法分析程序

//getchar();getchar();

fclose(fin);

fclose(fout);

return 0;

}

五、运行的结果

编译原理语法分析实验报告

编译原理语法分析实验报告 编译原理语法分析实验报告 引言 编译原理是计算机科学中的重要课程,它研究的是如何将高级语言转化为机器 语言的过程。语法分析是编译过程中的一个关键步骤,它负责将输入的源代码 转化为抽象语法树,为后续的语义分析和代码生成提供便利。本实验旨在通过 实践,加深对语法分析的理解,并掌握常见的语法分析算法。 实验环境 本次实验使用的是Python编程语言,因为Python具有简洁的语法和强大的库 支持,非常适合用于编译原理的实验。 实验步骤 1. 词法分析 在进行语法分析之前,需要先进行词法分析,将源代码划分为一个个的词法单元。词法分析器的实现可以使用正则表达式或有限自动机等方式。在本实验中,我们选择使用正则表达式来进行词法分析。 2. 文法定义 在进行语法分析之前,需要先定义源代码的文法。文法是一种形式化的表示, 它描述了源代码中各个语法成分之间的关系。常见的文法表示方法有巴科斯范 式(BNF)和扩展巴科斯范式(EBNF)。在本实验中,我们选择使用BNF来表 示文法。 3. 自顶向下语法分析 自顶向下语法分析是一种基于产生式的语法分析方法,它从文法的起始符号开

始,逐步展开产生式,直到生成目标字符串。自顶向下语法分析的关键是选择合适的产生式进行展开。在本实验中,我们选择使用递归下降分析法进行自顶向下语法分析。 4. 自底向上语法分析 自底向上语法分析是一种基于移进-归约的语法分析方法,它从输入串的左端开始,逐步将输入符号移入分析栈,并根据产生式进行归约。自底向上语法分析的关键是选择合适的归约规则。在本实验中,我们选择使用LR(1)分析法进行自底向上语法分析。 实验结果 经过实验,我们成功实现了自顶向下和自底向上两种语法分析算法,并对比了它们的优缺点。 自顶向下语法分析的优点是易于理解和实现,可以直接根据产生式进行展开,但缺点是对左递归和回溯的处理比较困难,而且效率较低。 自底向上语法分析的优点是可以处理任意文法,对左递归和回溯的处理较为方便,而且效率较高,但缺点是实现相对复杂,需要构建分析表和使用分析栈。结论 通过本次实验,我们深入理解了编译原理中的语法分析过程,并掌握了自顶向下和自底向上两种常见的语法分析算法。语法分析是编译过程中的重要环节,它为后续的语义分析和代码生成提供了基础。掌握语法分析算法对于编译原理的学习和实践具有重要意义。

编译原理实验报告++词法分析器实验报告

编译原理实验报告 词法分析器制作与应用 设计思想 (1)程序主体结构部分: 说明部分 %% 规则部分 %% 辅助程序部分 (2)主体结构的说明 在这里说明部分告诉我们使用的LETTER,DIGIT, IDENT(标识符,通常定义为字母开头的字母数字串)和STR(字符串常量,通常定义为双引号括起来的一串字符)是什么意思.这部分也可以包含一些初始化代码.例如用#include来使用标准的头文件和前向说明(forward ,references).这些代码应该再标记"%{"和"%}"之间;规则部分>可以包括任何你想用来分析的代码;我们这里包括了忽略所有注释中字符的功能,传送ID名称和字符串常量内容到主调函数和main函数的功能. (3)实现原理 程序中先判断这个句语句中每个单元为关键字、常数、运算符、界符,对与不同的单词符号给出不同编码形式的编码,用以区分之。 PL/0语言的EBNF表示 <常量定义>::=<标识符>=<无符号整数>; <标识符>::=<字母>={<字母>|<数字>}; <加法运算符>::=+|- <乘法运算符>::=*|/ <关系运算符>::==|#|<|<=|>|>= <字母>::=a|b|…|X|Y|Z <数字>::=0|1|2|…|8|9 三:设计过程 1.关键字:void,main,if,then,break,int,Char,float,include,for,while,printfscanf 并为小写。 2."+”;”-”;”*”;”/”;”:=“;”:”;”<“;”<=“;”>“;”>=“;”<>“;”=“;”(“;”)”;”;”;”#”为运算符。 3.其他标记如字符串,表示以字母开头的标识符。 4.空格符跳过。 5.各符号对应种别码 关键字分别对应1-13 运算符分别对应401-418,501-513。 字符串对应100 常量对应200 结束符# 四:举例说明 目标:实现对常量的判别 代码:

编译原理词法分析实验报告

一、目的(本次实验所涉及并要求掌握的知识点) 通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。 编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示) 二、实验内容与设计思想(设计思路、主要数据结构、主要代码结构、主要代码段分析等) 程序输入/输出示例: 如源程序为C语言。输入如下一段: main() { int a,b; a = 10; b = a + 20; } 要求输出如右图。

要求: 识别保留字:if、int、for、while、do、return、break、continue; 单词种别码为1。 其他的都识别为标识符;单词种别码为2。 常数为无符号整形数;单词种别码为3。 运算符包括:+、-、*、/、=、、<、=、<=、!= ; 单词种别码为4。 分隔符包括:,、;、{、}、(、);单词种别码为5。 三、实验使用环境(本次实验所使用的平台和相关软件) 平台:WindowsXP SP3 软件:MyElicpse 四、实验步骤和调试过程(实验步骤、测试数据设计、测试结果分析)1)定义常量及变量:

private JTextArea ta1; private JTextArea ta2; private JButton jb=new JButton("词法分析"); private JButton jb1=new JButton("清空文本区"); private JLabel jl1=new JLabel("输入源代码:"); private JLabel jl2=new JLabel("分析结果:"); static int m=0; //标识字符位置标记 static String str1 = new String(); String blz[]={"int","return","break","while","for","do","continue","if","else"}; 2)主要实现的函数: public void actionPerformed(ActionEvent e) { if(e.getSource()==jb1) { int a=JOptionPane.showConfirmDialog(null, "确定清空吗?","提示! ",JOptionPane.YES_NO_OPTION); if( a==JOptionPane.YES_OPTION) { ta1.setText(""); ta2.setText(""); } } if(e.getSource()==jb) { String a=ta1.getText(); //把输入的软代码赋值给字符串变量a char[] b=new char[a.length()]; //把a中的字符一个一个放入字符数组b中 for(int i=0;i

词法分析实验原理_编译原理实验报告范文分析

词法分析实验原理_编译原理实验报告范文分析 1.实验目的根据Sample语言或者自定义的某种语言,设计该语言的 编译前端。包括词法分析,语法分析、语义分析及中间代码生成部分。 2.实验内容及要求 (1)词法分析器 输入源程序,输出对应的token表,符号表和词法错误信息。按规则 拼单词,并转换成二元形式;滤掉空白符,跳过注释、换行符及一些无用 的符号;进行行列计数,用于指出出错的行列号,并复制出错部分;列表 打印源程序;发现并定位词法错误; (2)语法分析器 输入token串,通过语法分析,寻找其中的语法错误。要求能实现Sample语言或自定义语言中几种最常见的、基本的语法单位的分析:算 术表达式、布尔表达式、赋值语句、if语句、for语句、while语句、dowhile语句等。 (3)语义分析和中间代码生成 输入token串,进行语义分析,修改符号表,寻找其中的语义错误, 并生成中间代码。要求能实现Sample语言或自定义语言中几种最常见的、基本的语法单位的分析:算术表达式、布尔表达式、赋值语句、if语句、for语句、while语句、dowhile语句等。 实验要求:功能相对完善,有输入、输出描述,有测试数据,并介绍 不足。 3.实验方案设计

3.1编译系统原理介绍 编译器逐行扫描高级语言程序源程序,编译的过程如下: (1).词法分析 识别关键字、字面量、标识符(变量名、数据名)、运算符、注释行(给人看的,一般不处理)、特殊符号(续行、语句结束、数组)等六类 符号,分别归类等待处理。 (2).语法分析 一个语句看作一串记号(Token)流,由语法分析器进行处理。按照 语言的文法检查判定是否是合乎语法的句子。 如果是合法句子就以内部格式保存,否则报错。直至检查完整个程序。 (3).语义分析 语义分析器对各句子的语法做检查:运算符两边类型是否相兼容;该 做哪些类型转换(例如,实数向整数赋值要"取整");控制转移是否到不 该去的地方;是否有重名或者使语义含糊的记号,等等。如果有错误,则 转出错处理,否则可以生成执行代码。 .中间代码生成中间代码是向目标码过渡的一种编码,其形式尽可能 和机器的汇编语言相似,以便下一步的代码生成。 但中间码不涉及具体机器的操作码和地址码。 采用中间码的好处是可以在中间码上做优化。 .优化

编译原理实验词法分析实验报告

编译技术实验报告 实验题目:词法分析 学院:信息学院 专业:计算机科学与技术学号: 姓名:

一、实验目的 (1)理解词法分析的功能; (2)理解词法分析的实现方法; 二、实验内容 PL0的文法如下 ‘< >’为非终结符。 ‘::=’ 该符号的左部由右部定义,可读作“定义为”。 ‘|’ 表示‘或’,为左部可由多个右部定义。 ‘{ }’ 表示花括号内的语法成分可以重复。在不加上下界时可重复0到任意次 数,有上下界时可重复次数的限制。 ‘[ ]’ 表示方括号内的成分为任选项。 ‘( )’ 表示圆括号内的成分优先。 上述符号为“元符号”,文法用上述符号作为文法符号时需要用引号‘’括起。 〈程序〉∷=〈分程序〉. 〈分程序〉∷= [〈变量说明部分〉][〈过程说明部分〉]〈语句〉 〈变量说明部分〉∷=V AR〈标识符〉{,〈标识符〉}:INTEGER; 〈无符号整数〉∷=〈数字〉{〈数字〉} 〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉} 〈过程说明部分〉∷=〈过程首部〉〈分程序〉{;〈过程说明部分〉}; 〈过程首部〉∷=PROCEDURE〈标识符〉; 〈语句〉∷=〈赋值语句〉|〈条件语句〉|〈过程调用语句〉|〈读语句〉|〈写语句〉|〈复合语句〉|〈空〉 〈赋值语句〉∷=〈标识符〉∶=〈表达式〉 〈复合语句〉∷=BEGIN〈语句〉{;〈语句〉}END 〈条件〉∷=〈表达式〉〈关系运算符〉〈表达式〉 〈表达式〉∷=〈项〉{〈加法运算符〉〈项〉} 〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉} 〈因子〉∷=〈标识符〉|〈无符号整数〉|'('〈表达式〉')' 〈加法运算符〉∷=+|- 〈乘法运算符〉∷=* 〈关系运算符〉∷=<>|=|<|<=|>|>= 〈条件语句〉∷=IF〈条件〉THEN〈语句〉 〈字母〉∷=a|b|…|X|Y|Z 〈数字〉∷=0|1|2|…|8|9 实现PL0的词法分析

编译原理实验报告

编译原理实验报告 一、实验目的 编译原理是计算机科学中的重要课程,旨在让学生了解编译器 的基本工作原理以及相关技术。本次实验旨在通过设计和实现一 个简单的编译器,来进一步加深对编译原理的理解,并掌握实际 应用的能力。 二、实验环境 本次实验使用了Java编程语言及相关工具。在开始实验前,我 们需要安装Java JDK并配置好运行环境。 三、实验内容及步骤 1. 词法分析 词法分析是编译器的第一步,它将源代码分割成一系列词法单元。我们首先实现一个词法分析器,它能够将输入的源代码按照 语法规则进行切割,并识别出关键字、标识符、数字、运算符等。

2. 语法分析 语法分析是编译器的第二步,它将词法分析得到的词法单元序列转化为语法树。我们使用自顶向下的LL(1)语法分析算法,根据文法规则递归地构建语法树。 3. 语义分析 语义分析是编译器的第三步,它对语法树进行检查和转换。我们主要进行类型检查、语法错误检查等。如果源代码存在语义错误,编译器应该能够提供相应的错误提示。 4. 代码生成 代码生成是编译器的最后一步,它将经过词法分析、语法分析和语义分析的源代码翻译为目标代码。在本次实验中,我们将目标代码生成为Java字节码。 5. 测试与优化

完成以上步骤后,我们需要对编译器进行测试,并进行优化。 通过多个测试用例的执行,我们可以验证编译器的正确性和性能。 四、实验心得 通过完成这个编译器的实验,我收获了很多。首先,我对编译 原理的知识有了更深入的理解。在实验过程中,我深入学习了词 法分析、语法分析、语义分析和代码生成等关键技术,对编译器 的工作原理有了更系统的了解。 其次,我提高了编程能力。实现一个完整的编译器需要处理复 杂的数据结构和算法,这对我的编程能力是一个很好的挑战。通 过实验,我学会了合理地组织代码,优化算法,并注意到细节对 程序性能的影响。 最后,我锻炼了解决问题的能力。在实验过程中,我遇到了很 多困难和挑战,但我不断地调试和改进代码,最终成功地实现了 编译器。这次实验使我明白了解决问题的关键在于坚持和勇于尝试。

编译原理 词法分析器 实验报告

词法分析器实验报告 实验目的: 设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。 功能描述: 该程序要实现的是一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error!”,然后跳过错误部分继续进行) 设计思想: 设计该词法分析器的过程中虽然没有实际将所有的状态转移表建立出来,但是所用的思想是根据状态转移表实现对单词的识别。首先构造一个保留字表,然后,每输入一个字符就检测应该进入什么状态,并将该字符连接到d串后继续输入,如此循环,最后根据所在的接受状态以及保留字表识别单词。

①标识符及保留字: ②number: ③关系操作符: digit digit digit E digit other other letter or

④ ⑤算术运算符: (<=, 2) * (<>, 2) (<,2) (>=, 2) (>, 2) (:=,2)

使用环境: Windows xp下的visual c++6.0 程序测试: input1 : int a,b; a=b+2; input2: while(a>=0) do 7x=x+6.7E+23; end; input3: begin: x:=9 if x>0 then x:=x+1; while a:=0 do b:=2*x/3,c:=a; end;

output1: 3,int 3,a 5,, 3,b 5,; 3,a 2,= 3,b 2,+ 4,2 5,; output2: 1,while 5,( 3,a 2,>= 4,0 5,) 1,do error line 3 2,= 3,x 2,+ 4,6.7E+23 5,; 1,end 5,; output3: 1,begin error line 1 3,x 2,:= 4,9 1,if 3,x 2,> 4,0 1,then 3,x 2,:= 3,x 2,+ 4,1 5,; 1,while 3,a 2,:= 4,0 1,do 3,b 2,:= 4,2 2,* 3,x 2,/ 4,3 5,, 3,c 2,:= 3,a 5,; 1,end 5,; 测试结果与预期结果一致源程序代码: #include #include void main()

编译原理实验报告 词法分析

编译原理实验一·词法分析

一、实验目的 通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。同时增强编写和调试程序的能力。 二、实验内容及要求 对某特定语言A ,构造其词法规则。 该语言的单词符号包括: 保留字(见左下表)、标识符(字母大小写不敏感)、整型常数、界符及运算符(见右下表) 。 功能要求如下所示: ·按单词符号出现的顺序,返回二元组序列,并输出。 ·出现的标识符存放在标识符表,整型常数存放在常数表,并输出这两个表格。 ·如果出现词法错误,报出:错误类型,位置(行,列)。 ·处理段注释(/* */),行注释(//)。 ·有段注释时仍可以正确指出词法错误位置(行,列)。 三、实验过程 1、词法形式化描述 使用正则文法进行描述,则可以得到如下的正规式: 其中ID表示标识符,NUM表示整型常量,RES表示保留字,DEL表示界符,OPR表示运算符。 A→(ID | NUM | RES | DEL | OPR) * ID→letter(letter | didit)* NUM→digit digit* letter→a | …| z | A | …| Z digit→0 | …| 9 RES→program | begin | end | var | int | and | or | not | if | then | else | while | do DEL→( | ) | . | ; | , OPR→+ | * | := | > | < | = | >= | <= | <>

编译原理词法分析器实验报告

一、实验目的 设计一个简单的词法分析器,从而进一步加深对词法分析器工作原理的理解。 二、实验要求 1、该个词法分析器要求至少能够识别以下几类单词: (1)关键字:else if int return void while共6个,所有的关键字都是保留字,并且必须是小写; (2)标识符:识别与C语言词法规定相一致的标识符,通过下列正则表达式定义:ID = letter (letter | digit)*; (3)常数:NUM = digit digit*(.digit digit* |ε)(e(+ | - |ε) digit digit* |ε),letter = a|..|z|A|..|Z|,digit = 0|..|9,包括整数,如123等;小数,如123.45等;科学计数法表示的常数,如1.23e3,2.3e-9等; (4)专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */; 2、分析器的输入为由上述几类单词构成的程序,输出为该段程序的机内表示形式,即关键字、运算符、界限符变为其对应的机内符,常数使用二进制形式,标识符使用相应的标识符表指针表示。 3、词法分析器应当能够指出源程序中的词法错误,如不可识别的符号、错误的词法等。 三、实验环境 实验环境为win7系统、vs2005。 四、实验内容 1、词法分析程序的功能: 输入:所给文法的源程序字符串。 输出:二元组(syn,token)或(sum或fsum,对应二进制)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数; fsum为浮点型常数。 2、各种单词符号种别码如下表:

实验1__词法分析实验报告

软件学院 《编译原理》实验报告 题目: 词法、语法分析 专业:软件工程 班级:rB软件W101 学号: 学生姓名:田博 指导教师:陆筱霞 日期:

实验词法分析实验报告 一:实验目的 调 试并完成一个词法分析程序,加深对词法分析原理的理解。 二:实验要求 1、待分析的简单语言的词法 (1)关键字: begin if then while do end 所有关键字都是小写。 (2)运算符和界符::= + –* / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义: ID=letter(letter| digit)* NUM=digit digit * (4)空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。 2、各种单词符号对应的别码

3、词法分析程序的输入 所给文法的源程序字符串。输出:二元组(syn,token或sum)构成的序列。其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 三:代码 #include#include#includechar prog[80],token[8];char ch;int syn,p,m=0,n,row,sum=0;char *rwtab[6]={"begin","if","then","while","do","end"}; void scaner(){ for(n=0;n<8;n++) token[n]=NULL; ch=prog[p++]; while(ch==' ') { ch=prog[p]; p++; } if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) {

编译原理实验报告(词法分析器-语法分析器)

编 译 原 理 实 验 报 告 实验一 一、实验名称:词法分析器的设计 二、实验目的:1,词法分析器能够识别简单语言的单词符号 2,识别出并输出简单语言的基本字.标示符.无符号整数.运算符.和界符。 三、实验要求:给出一个简单语言单词符号的种别编码词法分析器 四、实验原理: 1、词法分析程序的算法思想 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 2、程序流程图 (1)主程序 输入要分析的语句

(2)扫描子程序 Token清空 Get() 当前字符=? 标示符常数表中查找结束Error()基本字用户标示符 输出二元式 结束 3 单词符号种别码助记符内码值 while 1 while - if 2 if - else 3 else - switch 4 switch - case 5 case - 标识符 6 id id在符号表中的 位置 常数7 num num在常数表中的 位置 + 8 + - - 9 - - * 10 * - <= 11 relop LE < 11 relop LT == 11 relop EQ

= 12 = - ; 13 ; - 五、实验内容: 1、实验分析 编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k(int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符。字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。 2 实验词法分析器源程序: #include #include #include int i,j,k; char c,s,a[20],token[20]={'0'}; int letter(char s){ if((s>=97)&&(s<=122)) return(1); else return(0); } int digit(char s){ if((s>=48)&&(s<=57)) return(1); else return(0); } void get(){ s=a[i]; i=i+1; } void retract(){ i=i-1; } int lookup(char token[20]){ if(strcmp(token,"while")==0) return(1); else if(strcmp(token,"if")==0) return(2); else if(strcmp(token,"else")==0) return(3); else if(strcmp(token,"switch")==0) return(4); else if(strcmp(token,"case")==0) return(5); else return(0); } void main() { printf("please input string :\n"); i=0;

词法分析实验报告

词法分析实验报告 词法分析是编译原理中的一个重要概念,它是编译器中的第一个阶段,也是最基础的一个阶段。词法分析器将输入的源代码转化为一系列的标记(Token),这些标记是语法分析器后续 分析的基本单元。 在本次实验中,我们使用C语言编写了一个简单的词法分析器。该词法分析器可以识别常见的C语言关键字(如if、while、for等)、运算符(如+、-、*、/等)、标识符、常量等,并将它们转化为相应的标记。 实验过程中,我们使用了C++编程语言来实现词法分析器。 在主函数中,我们首先读取输入的源代码文件,并将其逐个字符地进行扫描。扫描过程中,我们利用一些常见的正则表达式来匹配每个标记,并将其转化为相应的Token。在匹配完成后,我们将Token存储在一个Token序列中,以便后续的语法分 析器使用。 实验过程中,我们遇到了一些困难。一是字符匹配的问题,在处理运算符等特殊字符时,需要对转义字符进行特殊处理。二是标识符的识别问题,我们需要判断一个字符是否属于标识符中的某一部分,而不能将其单独当作一个标记。为了解决这个问题,我们采用了状态机的方法,维护一个标识符的状态,根据状态的变化来判断是否识别到了一个完整的标识符。 在实验结果中,我们成功地将源代码转化为了一系列的标记。这些标记可以用于后序的语法分析和语义分析等过程中。同时,

我们也发现了一些问题,如在处理注释时可能会出现误判等。针对这些问题,我们可以进一步改进词法分析器,提高其准确性和鲁棒性。 总的来说,通过本次实验,我们深入理解了词法分析的原理和过程,并成功地实现了一个简单的词法分析器。通过这个实验,我们对编译原理有了更深入的了解,并提高了自己的编程能力。

词法分析实验报告(实验一)

编译原理词法分析实验报告 软工082班 兰洁 200831104044 一、实验内容 二、实验目的 三、实验预期 四、程序规定 五、实验原理 ●程序流程图 ●判别浮点功能扩展流程图 ●状态转换图 六、程序代码与浮点判别功能扩展 七、测试用例 ●扩展功能测试用例; ●普通功能测试用例 八、输出结果 九、实验心得

一、实验内容: 词法分析: 1、识别简单语言的单词符号; 2、识别关键字、标识符、数字、运算符等。并扩展浮点识别功能。 二、实验目的 调试词法分析程序,加深对词法分析原理的理解,掌握编写简单词法分析程序的一般步骤。 三、实验预期结果: 经过调试源代码程序,程序能够成功运行编译,对输入的简单字符串,能够别关键字、标识符、数字、运算符等,并且给出单词符号的对应编码。 四、程序规定: 1、关键字:"function","if","then","while","do","endfunc"; 2、算术运算符:”+”,”-”,”*”,”/”,”=”; 3、关系运算符:"<" ">" "<=" ">=" "==" "!="; 4、界符:"(" ")" ";" "#"; 5、标识符规定以字母开头,字母均为小写; 6、空格和换行符跳过; 7、单词对应编码: 十、实验原理: 输入串--------------------〉词法分析程序————————〉单词符号串 输入:字符串以#结束。 输出:单词的二元组(syn,token/sum)

程序流程图 分析浮点数功能扩展部分流程图:

shuzi()函数

状态转换图 六、程序代码: 备注:红色字体部分为程序功能的功能扩展,使程序能够分析浮点数! 我把浮点数的syn设置为80!

编译原理实验报告2-词法分析程序的设计

实验2 词法分析程序的设计 一、实验目的 掌握计算机语言的词法分析程序的开发方法。 二、实验容 编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。 三、实验要求 1、根据以下的正规式,编制正规文法,画出状态图; 标识符<字母>(<字母>|<数字字符>)* 十进制整数0 | ((1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*) 八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)* 十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)* 运算符和界符+ - * / > < = ( ) ; 关键字if then else while do 2、根据状态图,设计词法分析函数int scan( ),完成以下功能: 1)从文本文件中读入测试源代码,根据状态转换图,分析出一个单词, 2)以二元式形式输出单词<单词种类,单词属性> 其中单词种类用整数表示: 0:标识符 1:十进制整数 2:八进制整数 3:十六进制整数 运算符和界符,关键字采用一字一符,不编码 其中单词属性表示如下: 标识符,整数由于采用一类一符,属性用单词表示 运算符和界符,关键字采用一字一符,属性为空 3、编写测试程序,反复调用函数scan( ),输出单词种别和属性。 四、实验环境 PC微机 DOS操作系统或Windows 操作系统 Turbo C 程序集成环境或Visual C++ 程序集成环境 五、实验步骤 1、根据正规式,画出状态转换图;

词法分析实验报告

词法分析实验报告 一、实验目的和背景 词法分析是编译原理中的重要部分之一,其主要作用是将源程序中的字符序列转化为有意义的单词序列,以便于后续的处理和分析。为了更好地理解词法分析的实现原理以及掌握相关算法和工具,本次词法分析实验旨在通过手动编写正则表达式、确定有限自动机的状态转移函数和实现词法分析程序来实现词法分析。 二、实验内容 在本次实验中,我们需要完成以下任务: 1.手动编写正则表达式; 2.确定有限自动机的状态转移函数; 3.实现词法分析程序。

三、实验过程 1.手动编写正则表达式 对于给定的源程序,我们首先需要根据其语法规则手动编写正则表达式。例如,对于一个简单的算术表达式,其正则表达式可以如下所示: i. 数字(0-9):[0-9]+ ii. 加号(+):\+ iii. 减号(-):- iv. 乘号(*):\* v. 除号(/):/ vi. 左括号(():\(

vii. 右括号()):\) 2.确定有限自动机的状态转移函数 根据正则表达式,我们可以确定有限自动机的状态转移函数。例如,对于上述算术表达式的正则表达式,其有限自动机的状态转移函数如下所示: i. 初始状态(S):判断下一个字符,如果是数字则进入数字状态,如果是左括号则进入左括号状态; ii. 数字状态(D):继续判断下一个字符,如果是数字则保持在数字状态,如果是运算符则输出数字记号,返回初始状态,如果是右括号则输出数字记号,返回初始状态; iii. 左括号状态(L):输出左括号记号,返回初始状态; iv. 右括号状态(R):输出右括号记号,返回初始状态。

3.实现词法分析程序 根据以上的正则表达式和有限自动机的状态转移函数,我们可以编写一个简单的词法分析程序。该程序的主要流程如下所示: i. 读取源程序的字符序列; ii. 根据有限自动机的状态转移函数,逐个字符进行状态转移; iii. 如果当前状态为接受状态,则输出相应的记号; iv. 继续进行状态转移,直至读取完整个源程序。 四、实验结果 通过以上步骤,我们成功完成了对给定源程序的词法分析。在实验中,我们还可以尝试根据实际需求对正则表达式、有限自动机的状态转移函数进行优化,以提高程序的效率和准确性。

编译原理实验报告——词法分析器(内含源代码)

编译原理实验(一)——词法分析器

一.实验描述 运行环境:vc++2020 对某特定语言A ,构造其词法规那么。 该语言的单词符号包括: 1该程序能识别的单词符号及类别说明表

2状态转换图 3程序流程:

词法分析作成一个子程序,由另一个主程序挪用,每次挪用返回一个单词对应的二元组,输出标识符表、常数表由主程序来完成。 二.实验目的 通过动手实践,使学生对构造编译系统的大体理论、编译程序的大体结构有更为深切的明白得和把握;使学生把握编译程序设计的大体方式和步骤;能够设计实现编译系统的重要环节。同时增强编写和调试程序的能

力。 三.实验任务 编制程序实现要求的功能,并能完成对测试样例程序的分析。四.实验原理 char set[1000],str[500],strtaken[20];//set[]存储代码,strtaken[]存储当前字符char sign[50][10],constant[50][10];//存储标识符和常量 概念了一个Analyzer类 class Analyzer{ public: Analyzer(); //构造函数 ~Analyzer(); //析构函数 int IsLetter(char ch); //判定是不是是字母,是那么返回 1,不然返回 0。 int IsDigit(char ch); //判定是不是为数字,是那么返回 1,不然返回 0。 void GetChar(char *ch); //将下一个输入字符读到ch中。 void GetBC(char *ch); //检查ch中的字符是不是为空白, 假设是,那么挪用GetChar直至ch进入一个非空白字符。 void Concat(char *strTaken, char *ch); //将ch中的字符连接到strToken以后。 int Reserve(char *strTaken); //对strTaken中的字符串查找保留字表,假设是一个保留字返回它的数码,不然返回0。 void Retract(char *ch) ; //将搜索指针器回调一个字符位置,将ch置为空白字符。void input();//向寄存输入结果的字符数组输入一句语句。 void display();//输出一些程序终止字符显示样式 int analyzerSubFun();//词法分析器子程序,为了实现词法分析的要紧功能。 五.代码实现 // cifa.cpp : 概念操纵台应用程序的入口点。 // #include"stdafx.h"

(完整word版)编译原理词法分析程序实现实验报告

(完整word版)编译原理词法分析程序实现实验报告 实验一词法分析程序实现 一、实验内容 选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。 输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。 输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。 二、设计部分 因为需要选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来,而其中的关键则为无符号数的识别,它不仅包括了一般情况下的整数和小数,还有以E为底数的指数运算,其中关于词法分析的无符号数的识别过程流程图如下: GOTO 1:

(完整word版)编译原理词法分析程序实现实验报告 GOTO 2: 三、源程序代码部分 #include #include #include #define MAX 100 #define UNSIGNEDNUMBER 1 #define PLUS 2 #define SUBTRACT 3

#define MULTIPLY 4 #define DIVIDE 5 #define LEFTBRACKET 6 #define RIGHTBRACKET 7 #define INEFFICACIOUSLABEL 8 #define FINISH 111 int count=0; int Class; void StoreType(); int Type[100]; char Store[20]={'\0'}; void ShowStrFile();//已经将要识别的字符串存在文件a中 void Output(int a,char *p1,char *p2);//字符的输出过程 int Sign(char *p);//'+''-''*''/'整体识别过程 int UnsignedNum(char *p);//是否适合合法的正整数0~9 int LegalCharacter(char *p);//是否是合法的字符:Sign(p)||UnsignedNum(p)||'E'||'.' void DistinguishSign(char *p);//'+''-''*''/'具体识别过程 void TypyDistinguish();//字符的识别过程 void ShowType();//将类别码存储在Type[100]中,为语法分析做准备 void ShowStrFile()//已经将要识别的字符串存在文件a中 { FILE *fp_s; char ch; if((fp_s=fopen("a.txt","r"))==NULL)

编译原理词法分析实验报告

词法分析器实验报告 一、实验目的 选择一种编程语言实现简单的词法分析程序,设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 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 各种单词符号对应的种别码 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所示。其中初始包括以下两个方面: ⑴ 关键字表的初值。 关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下: Char *rwtab[6] = {“begin ”, “if ”, “then ”, “while ”, “do ”, “end ”,}; 图3-1 (2)程序中需要用到的主要变量为syn,token 和 sum 3.2 扫描子程序的算法思想: 首先设置3个变量:①token 用来存放构成单词符号的字符串;②sum 用来整型单词;③syn 用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。

相关主题
相关文档
最新文档