文档库 最新最全的文档下载
当前位置:文档库 › 编译原理-词法语法分析实验报告

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

编译原理

词法分析

一、实验目的

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

二、实验要求

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.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)……

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

#include

#include

char prog[80],token[8],ch;

int syn,p,m,n,sum;

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

scaner();

void scanner_example (FILE *fp);

main()

{

FILE *fp;

fp=fopen("D:\\1.txt","r");//打开文件

scanner_example (fp);

scaner();

}

void scanner_example (FILE *fp)

{

do

{

ch=fgetc (fp);

prog[p++]=ch;

}while (ch!='#');

p=0;

do{

scaner();

switch(syn)

{case 11:printf("( %-10d%5d )\n",sum,syn);

break;

case -1:printf("you have input a wrong string\n");

default: printf("( %-10s%5d )\n",token,syn);

break;

}

}while(syn!=0);

}

scaner()

{ sum=0;

for(m=0;m<8;m++)token[m++]=NULL;

ch=prog[p++];

m=0;

while((ch==' ')||(ch=='\n'))ch=prog[p++];

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

{ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) {token[m++]=ch;

ch=prog[p++];

}

p--;

syn=10;

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

if(strcmp(token,rwtab[n])==0)

{ syn=n+1;

break;

}

}

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

{ while((ch>='0')&&(ch<='9'))

{ sum=sum*10+ch-'0';

ch=prog[p++];

}

p--;

syn=11;

}

else switch(ch)

{ case '<':token[m++]=ch;

ch=prog[p++];

if(ch=='=')

{ syn=22;

token[m++]=ch;

}

else

{ syn=20;

p--;

}

break;

case '>':token[m++]=ch;

ch=prog[p++];

if(ch=='=')

{ syn=24;

token[m++]=ch;

}

else

{ syn=23;

p--;

}

break;

case '+': token[m++]=ch;

ch=prog[p++];

if(ch=='+')

{ syn=17;

token[m++]=ch;

}

else

{ syn=13;

p--;

}

break;

case '-':token[m++]=ch;

ch=prog[p++];

if(ch=='-')

{ syn=29;

token[m++]=ch;

}

else

{ syn=14;

p--;

}

break;

case '!':ch=prog[p++];

if(ch=='=')

{ syn=21;

token[m++]=ch;

}

else

{ syn=31;

p--;

}

break;

case '=':token[m++]=ch;

ch=prog[p++];

if(ch=='=')

{ syn=25;

token[m++]=ch;

}

else

{ syn=18;

p--;

}

break;

case '*': syn=15;

token[m++]=ch;

break;

case '/': syn=16;

token[m++]=ch;

break;

case '(': syn=27;

token[m++]=ch;

break;

case ')': syn=28;

token[m++]=ch;

break;

case '{': syn=5;

token[m++]=ch;

break;

case '}': syn=6;

token[m++]=ch;

break;

case ';': syn=26;

token[m++]=ch;

break;

case '\"': syn=30;

token[m++]=ch;

break;

case '#': syn=0;

token[m++]=ch;

break;

case ':':syn=17;

token[m++]=ch;

break;

default: syn=-1;

break;

}

token[m++]='\0';

}

四、结果分析:

输入begin x:=9: if x>9 then x:=2*x+1/3; end # 后经词法分析输出如下序列:(begin 1)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图所示:

五、总结:

词法分析的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。通过本试验的完成,更加加深了对词法分析原理的理解。

语法分析

一、实验目的

编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

二、实验要求

利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

2.1 待分析的简单语言的语法

用扩充的BNF表示如下:

1<程序>::=begin<语句串>end

2<语句串>::=<语句>{;<语句>}

3<赋值语句>::=ID:=<表达式>

4<表达式>::=<项>{+<项> | -<项>}

5<项>::=<因子>{*<因子> | /<因子>

6<因子>::=ID | NUM | (<表达式>)

2.2 实验要求说明

输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“ok”,否则输出“error”。

例如:

输入begin a:=9; x:=2*3; b:=a+x end #

输出ok!

输入x:=a+b*c end #

输出error

2.3 语法分析程序的酸法思想

(1)主程序示意图如图2-1所示。

(2)递归下降分析程序示意图如图2-2所示。 (3)语句串分析过程示意图如图2-3所示。

图2-3 语句串分析示意图

图2-2 递归下降分析程序示意图

(4)statement 语句分析程序流程如图2-4、2-5、2-6、2-7所示。

图2-4 statement 语句分析函数示意图 图2-5 expression 表达式分析函数示意图

图2-7 factor 分析过程示意图

三、语法分析程序的C 语言程序源代码:

#include "stdio.h" #include "string.h"

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

char *rwtab[6]={"begin","if","then","while","do","end"}; int syn,p,m,n,sum; int kk;

factor(); //递归下降分析 expression(); yucu(); term();

statement(); //语句串分析

parser();

scaner();

void scanner_example (FILE *fp);

main()

{

p=kk=0;

FILE *fp;

fp=fopen("D:\\1.txt","r");//打开文件

scanner_example (fp);

scaner();

parser();

}

void scanner_example (FILE *fp)

{

do

{

ch=fgetc (fp);

prog[p++]=ch;

}while (ch!='#');

p=0;

}

parser() //1

{

if(syn==1)

{

scaner(); /*读下一个单词符号*/

yucu(); //2 /*调用yucu()函数;*/

if (syn==6) //end

{ scaner();

if ((syn==0)&&(kk==0))

printf("ok!\n");

}

else

{

if(kk!=1) printf("the string haven't got a 'end'!\n");

kk=1;

}

}

else

{

printf("haven't got a 'begin'!\n");

kk=1;

return;

} //1

yucu() //2 --段分析

{

statement(); //3 /*调用函数statement();*/

while(syn==26) //;

{

scaner(); /*读下一个单词符号*/

if(syn!=6) //end

statement(); /*调用函数statement();*/

}

return;

} //2

statement() //3 --句子分析

{

if(syn==10) //letter

{

scaner(); /*读下一个单词符号*/

if(syn==18) //:=

{

scaner(); /*读下一个单词符号*/

expression(); /*调用函数expression();*/ }

else

{

printf("the sing ':=' is wrong!\n");

kk=1;

}

}

else

{

printf("wrong sentence!\n");

kk=1;

}

return;

} //3

expression() //4 句子内部运算

{

term();

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

{

scaner(); /*读下一个单词符号*/

term(); /*调用函数term();*/

return;

} //4

term() //5

{

factor();

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

{

scaner(); /*读下一个单词符号*/

factor(); /*调用函数factor(); */ }

return;

} //5

factor()

{

if((syn==10)||(syn==11)) //(letter|digit)

scaner();

else if(syn==27)

{

scaner(); /*读下一个单词符号*/

expression(); /*调用函数expression();*///........//

if(syn==28)

scaner(); /*读下一个单词符号*/

else

{

printf("the error on '('\n");

kk=1;

}

}

else

{

printf("the expression error!\n");

kk=1;

}

return;

} //5

scaner() //6 词法分析

{

sum=0;

for(m=0;m<8;m++)token[m++]=NULL;

m=0;

ch=prog[p++];

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

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

{

while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) {

token[m++]=ch;

ch=prog[p++];

}

p--;

syn=10;

token[m++]='\0';

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

if(strcmp(token,rwtab[n])==0)

{

syn=n+1;

break;

}

}

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

{

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

{

sum=sum*10+ch-'0';

ch=prog[p++];

}

p--;

syn=11;

}

else switch(ch)

{

case '<':m=0;

ch=prog[p++];

if(ch=='>')

{

syn=21;

}

else if(ch=='=')

{

syn=22;

}

else

{

syn=20;

p--;

}

break;

case '>':m=0;

ch=prog[p++];

if(ch=='=')

{

syn=24;

}

else

{

syn=23;

p--;

}

break;

case ':':m=0;

ch=prog[p++];

if(ch=='=')

{

syn=18;

}

else

{

syn=17;

p--;

}

break;

case '+': syn=13; break;

case '-': syn=14; break;

case '*': syn=15;break;

case '/': syn=16;break;

case '(': syn=27;break;

case ')': syn=28;break;

case '=': syn=25;break;

case ';': syn=26;break;

case '#': syn=0;break;

case 'if': syn=2;break;

case 'then': syn=3;break;

case 'wile': syn=4;break;

case 'do': syn=5;break;

case 'end': syn=6;break;

case ':=': syn=18;break;

case '<>': syn=21;break;

case '<=': syn=22;break;

case '>=': syn=24;break;

default: syn=-1;break; }

} //6

四、结果分析:在d:1.txt中输入begin a:=9; x:=2*3; b:=a+x end # 后输出ok!如图4-1

所示:

图4-1

输入x:=a+b*c end # 后输出haven’t got a ‘begin’如图4-2所示:

输入begin x:=(a+b)*c # 输出the sting haven’t got a ‘end’!

图4-2

五、总结:

通过本次试验,了解了语法分析的运行过程,主程序大致流程为:“置初值”→调用scaner 函数读下一个单词符号→调用IrParse→结束。递归下降分析的大致流程为:“先判断是否为begin”→不是则“出错处理”,若是则“调用scaner函数”→调用语句串分析函数→“判断是否为end”→不是则“出错处理”,若是则调用scaner函数→“判断syn=0&&kk=0是否成立”成立则说明分析成功打印出来。不成立则“出错处理”。

计算机编译原理实验报告

编译原理实验报告 实验一词法分析设计 一、实验功能: 1、对输入的IXt文件内的内容进行词法分析: 2、由文件流输入IesiJxi中的内容,对文件中的各类字符进行词法分析 3、打印出分析后的结果;

二、程序结构描述:(源代码见附录) 1、分别利用k[],siu,s2[],s3[]构造关键字表,分界符表,算术运算符表和关系运算符表。 2、bool isletter(){}用来判断其是否为字母,是则返回IrUe,否则返回false; bool isdigit(){)用来判断其是否为数字,是则返回IrUe,否则返回false; bool iscalcu(){)用来判断是否为算术运算符,是则返回IrUe,否则返回false; bool reserve(string a∣∣){)用来判断某字符是否在上述四个表中,是则返向InIe,否则返回false; void concat(){)用来连接字符串; void getn(){)用来读取字符; void getb(){)用来对空格进行处理; void retract(){}某些必要的退格处理; int analysis(){}对一个单词的单词种别进行具体判断; 在主函数中用switch决定输出。

3| file.txt -记事本 文件(F)编辑⑹格式(O)查看(V) W(H) if i = O then i ++; a <= 3b%); 富F:\cpp\词法分析器.exe Process exited after 2.503 seconds with return 信按任意键继续∙.∙ 四、实验总结 词法分析器一眼看上去很复杂,但深入的去做就会发现并没有一开始想象的那么困难。 对于一个字符的种别和类型可以用b∞l 函数来判断,对于关键字和标示符的识别(尤其是 3b)则费了一番功夫,最后对于常数的小数点问题处理更是麻烦。另外,这个实验要设定好 时候退格,否则将会导致字符漏读甚至造成字符重复读取。 我认为,这个实验在程序实现上大体不算困难,但在细节的处理上则需要好好地下功夫 去想,否则最后的程序很可能会出现看上去没有问题,但实际上漏洞百出的状况。 将学过的知识应用到实际中并不简单,只有自己不断尝试将知识转化成程序才能避免眼 高手低,对于知识的理解也必将更加深刻。 单词 *******分析结果如下美 二元序列 类型 then + + 3b <6,i> <4,=> 〈5.0) <6,i> <3,++> <6,a> <4,<=> Error Error <2,>> <2,;> 关标天常关OW ⅛: 天ErEr 八芬 键识系匿识术识系rorr 字 符运字符运符 运r O B-Tnvp 1%E,E--? 符符 算算 位置 <1,1> <1,2> <1,3〉 <1,4〉 <1,5> <1,6〉 <1,7〉 <2,1> <2,2〉 《2,3》 <2,4) <2,5〉 value 0

编译原理实验报告

编译原理实验报告 编译原理实验报告 一、实验目的 1. 了解编译器的基本原理和工作过程; 2. 掌握编译器设计和实现的基本方法和技巧; 3. 通过设计和实现一个简单的编译器,加深对编程语言和计算机系统的理解和认识。 二、实验原理 编译器是将高级语言程序翻译成机器语言程序的一种软件工具。它由编译程序、汇编程序、链接程序等几个阶段组成。本次实验主要涉及到的是编译程序的设计和实现。 编译程序的基本原理是将高级语言程序转换为中间代码,再将中间代码转换为目标代码。整个过程可以分为词法分析、语法分析、语义分析、代码生成和代码优化几个阶段。 三、实验内容 本次实验的设计目标是实现一个简单的四则运算表达式的编译器。 1. 词法分析 根据规定的语法规则,编写正则表达式将输入的字符串进行词法分析,将输入的四则运算表达式划分成若干个单词(Token),例如:运算符、操作数等。

2. 语法分析 根据定义的语法规则,编写语法分析程序,将词法分析得到的Token序列还原成语法结构,构建抽象语法树(AST)。 3. 语义分析 对AST进行遍历,进行语义分析,判断表达式是否符合语法 规则,检查语义错误并给出相应的提示。 4. 代码生成 根据AST生成目标代码,目标代码可以是汇编代码或者机器码。 四、实验过程和结果 1. 首先,根据输入的表达式,进行词法分析。根据所定义的正则表达式,将输入的字符串划分成Token序列。例如:输入 表达式“2+3”,经过词法分析得到的Token序列为["2", "+", "3"]。 2. 然后,根据语法规则,进行语法分析。根据输入的Token 序列,构建抽象语法树。 3. 接着,对抽象语法树进行语义分析。检查表达式是否符合语法规则,给出相应的提示。 4. 最后,根据抽象语法树生成目标代码。根据目标代码的要求,生成汇编代码或者机器码。 五、实验总结

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

一、目的(本次实验所涉及并要求掌握的知识点) 通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。 编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“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

编译原理实验报告(手打)

《编译原理》实验报告 班级:计C104 姓名:李云霄 学号:108490

实验一词法分析程序实现 一、实验目的与要求 通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。 二、实验内容 选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。 输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。 输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。 三、实现方法与环境 1、首先设计识别各类单词的状态转换图。 描述无符号常数的确定、最小化状态转换图如图1所示。其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。 图1 文法G[<无符号数>]的状态转换图 其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。 在一个程序设计语言中,一般都含有若干类单词符号,为此可首先为每类单词建立一张状态转换图,然后将这些状态转换图合并成一张统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。 四则运算算术符号的识别很简单,直接在状态图的0状态分别引出相应标记的矢

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

词法分析实验原理_编译原理实验报告范文分析 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. 测试与优化

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

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

编译原理语法分析实验报告 编译原理实验报告 二、语法分析 (一) 实验题目 编写程序,实现对词法分析程序所提供的单词序列进行语法检查和 结构分析。 (二) 实验内容和要求 1. 要求程序至少能分析的语言的内容有: 1) 变量说明语句 2) 赋值语句 3) 条件转移语句 4) 表达式(算术表达式和逻辑表达式) 5) 循环语句 6) 过程调用语句 2. 此外要处理:包括依据文法对句子进行分析;出错处理;输出结果的构造。 3. 输入输出的格式: 输入:单词文件(词法分析的结果) 输出:语法成分列表或语法树(都用文件表示),错误文件(对 于不合文法的句子)。 4. 实现方法:可以采用递归下降分析法,LL(1)分析法,算符优先法或LR分析法的任何一种,也可以针对不同的句子采用不同的分析方法。 (三) 实验分析与设计过程

1. 待分析的C语言子集的语法: 该语法为一个缩减了的C语言文法,估计是整个C语言所有文 法的60%(各种关键字的定义都和词法分析中的一样),具体的 文法如下: 语法: 100: program -> declaration_list 101: declaration_list -> declaration_list declaration | declaration 102: declaration -> var_declaration|fun_declaration 103: var_declaration -> type_specifier ID;|type_specifier ID[NUM]; 104: type_specifier -> int|void|float|char|long|double| 105: fun_declaration -> type_specifier ID (params)|compound_stmt 106: params -> params_list|void 107: param_list ->param_list,param|param 108: param -> type-spectifier ID|type_specifier ID[] 109: compound_stmt -> {local_declarations statement_list} 110: local_declarations -> local_declarations var_declaration|empty 111: statement_list -> statement_list statement|empty 11 编译原理实验报告 112: statement -> epresion_stmt|compound_stmt |selection_stmt|iteration_stmt|return_stmt 113: expression_stmt -> expression;|; 114: selection_stmt -> if{expression)statement |if(expression)statement else statement

编译原理实验二LL(1)语法分析实验报告

专题3_LL(1)语法分析设计原理与实现 李若森 13281132 计科1301 一、理论传授 语法分析的设计方法和实现原理;LL(1) 分析表的构造;LL(1)分析过程;LL(1)分析器的构造。 二、目标任务 实验项目 实现LL(1)分析中控制程序(表驱动程序);完成以下描述算术表达式的 LL(1)文法的LL(1)分析程序。 G[E]: E→TE’ E’→ATE’|ε T→FT’ T’→MFT’|ε F→(E)|i A→+|- M→*|/ 设计说明 终结符号i为用户定义的简单变量,即标识符的定义。加减乘除即运算符。 设计要求 (1)输入串应是词法分析的输出二元式序列,即某算术表达式“专题 1”的输出结果, 输出为输入串是否为该文法定义的算术表达式的判断结果; (2)LL(1)分析程序应能发现输入串出错; (3)设计两个测试用例(尽可能完备,正确和出错),并给出测试结果。 任务分析 重点解决LL(1)表的构造和LL(1)分析器的实现。

三、实现过程 实现LL(1)分析器 a)将#号放在输入串S的尾部 b)S中字符顺序入栈 c)反复执行c),任何时候按栈顶Xm和输入ai依据分析表,执行下述三个动作之一。 构造LL(1)分析表 构造LL(1)分析表需要得到文法G[E]的FIRST集和FOLLOW集。 构造FIRST(α) 构造FOLLOW(A)

构造LL(1)分析表算法 根据上述算法可得G[E]的LL(1)分析表,如表3-1所示: 表3-1 LL(1)分析表 主要数据结构 pair: 用pair来存储单个二元组。该对照表由专题1定义。 map: 存储离散化后的终结符和非终结符。 vector[][]: 存储LL(1)分析表 函数定义 init: void init(); 功能: 初始化LL(1)分析表,关键字及识别码对照表,离散化(非)终结符 传入参数: (无) 传出参数: (无) 返回值: (无)

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

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

一、实验目的 通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。同时增强编写和调试程序的能力。 二、实验内容及要求 对某特定语言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→+ | * | := | > | < | = | >= | <= | <>

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

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

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

编译原理实验报告5-语法分析程序的设计()

实验5语法分析程序的设计(2)一、实验目的 通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析中算法优先分析方法。 二、实验内容 设计一个文法的算法优先分析程序,判断特定表达式的正确性。 三、实验要求 1、给出文法如下: G[E] E->T|E+T; T->F|T*F; F->i|(E); 2、计算机中表示上述优先关系,优先关系的机内存放方式有两种1)直接存放,2)为 优先关系建立优先函数,这里由学生自己选择一种方式; 1、给出算符优先分析算法如下: k:=1; S[k]:=‘#’; REPEAT 把下一个输入符号读进a中; IF S[k]∈V T THEN j:=k ELSE j:=k-1; WHILE S[j] a DO BEGIN REPEAT Q:=S[j]; IF S[j-1]∈V T THEN j:=j-1 ELSE j:=j-2 UNTIL S[j] Q 把S[j+1]…S[k]归约为某个N; k:=j+1;

S[k]:=N; END OF WHILE; IF S[j] a OR S[j] a THEN BEGIN k:=k+1;S[k]:=a END ELSE ERROR UNTIL a=‘#’ 1、 根据给出算法,利用适当的数据结构实现算符优先分析程序; 2、 利用算符优先分析程序完成下列功能: 1) 手工将测试的表达式写入文本文件,每个表达式写一行,用“;”表示结束; 2) 读入文本文件中的表达式; 3) 调用实验2中的词法分析程序搜索单词; 4) 把单词送入算法优先分析程序,判断表达式是否正确(是否是给出文法的语 言),若错误,应给出错误信息; 5) 完成上述功能,有余力的同学可以对正确的表达式计算出结果。 四、实验环境 PC 微机 DOS 操作系统或 Windows 操作系统 Turbo C 程序集成环境或 Visual C++ 程序集成环境 五、实验步骤 1、 分析文法中终结符号的优先关系; 2、 存放优先关系或构造优先函数; 3、利用算符优先分析的算法编写分析程序; 4、写测试程序,包括表达式的读入和结果的输出; 5、程序运行效果,测试数据可以参考下列给出的数据。 六、测试数据 输入数据: 编辑一个文本文文件expression.txt ,在文件中输入如下内容:

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

(完整)编译原理实验报告(词法分析器语法分析器) 编辑整理: 尊敬的读者朋友们: 这里是精品文档编辑中心,本文档内容是由我和我的同事精心编辑整理后发布的,发布之前我们对文中内容进行仔细校对,但是难免会有疏漏的地方,但是任然希望((完整)编译原理实验报告(词法分析器语法分析器))的内容能够给您的工作和学习带来便利。同时也真诚的希望收到您的建议和反馈,这将是我们进步的源泉,前进的动力。 本文可编辑可修改,如果觉得对您有帮助请收藏以便随时查阅,最后祝您生活愉快业绩进步,以下为(完整)编译原理实验报告(词法分析器语法分析器)的全部内容。

编 译 原 理 实 验 报 告 实验一 一、实验名称:词法分析器的设计 二、实验目的:1,词法分析器能够识别简单语言的单词符号

2,识别出并输出简单语言的基本字.标示符.无符号整数。运算符.和界符。 三、实验要求:给出一个简单语言单词符号的种别编码词法分析器 四、实验原理: 1、词法分析程序的算法思想 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 2、程序流程图 (1)主程序 (2)扫描子程序 3 五、实验内容: 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 〈stdio.h〉 #include

词法分析实验报告

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

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

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

词法分析器实验报告 一、实验目的 选择一种编程语言实现简单的词法分析程序,设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 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所示。

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

编译原理实验报告 词法分析器制作与应用 设计思想 (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 结束符# 四:举例说明 目标:实现对常量的判别 代码:

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

编译原理实验报告 一.LL(1)文法分析 1.设计要求 (1)对输入文法,它能判断是否为LL(1)文法,若是,则转(2);否则报错并终止; (2)输入已知文法,由程序自动生成它的LL(1)分析表; (3)对于给定的输入串,应能判断识别该串是否为给定文法的句型。 2.分析 该程序可分为如下几步: (1)读入文法 (2)判断正误 (3)若无误,判断是否为LL(1)文法 (4)若是,构造分析表; (5)由总控算法判断输入符号串是否为该文法的句型。 3.流程图 开始 读入文法 有效? 是 是LL(1)文法? 是 判断句型报错 结束

4.源程序 /******************************************* 语法分析程序 作者:xxx 学号:xxx ********************************************/ #include #include #include /*******************************************/ int count=0; /*分解的产生式的个数*/ int number; /*所有终结符和非终结符的总数*/ char start; /*开始符号*/ char termin[50]; /*终结符号*/ char non_ter[50]; /*非终结符号*/ char v[50]; /*所有符号*/ char left[50]; /*左部*/ char right[50][50]; /*右部*/ char first[50][50],follow[50][50]; /*各产生式右部的FIRST和左部的FOLLOW集合*/ char first1[50][50]; /*所有单个符号的FIRST集合*/ char select[50][50]; /*各单个产生式的SELECT集合*/ char f[50],F[50]; /*记录各符号的FIRST和FOLLOW是否已求过*/ char empty[20]; /*记录可直接推出^的符号*/ char TEMP[50]; /*求FOLLOW时存放某一符号串的FIRST集合*/ int validity=1; /*表示输入文法是否有效*/ int ll=1; /*表示输入文法是否为LL(1)文法*/ int M[20][20]; /*分析表*/ char choose; /*用户输入时使用*/ char empt[20]; /*求_emp()时使用*/ char fo[20]; /*求FOLLOW集合时使用*/ /******************************************* 判断一个字符是否在指定字符串中 ********************************************/ int in(char c,char *p) { int i; if(strlen(p)==0)

相关文档
相关文档 最新文档