当前位置:文档之家› 编译原理-词法分析

编译原理-词法分析

编译原理-词法分析
编译原理-词法分析

《编译原理》实验

《编译原理》是国内外各高等院校计算机科学技术类专业,特别是计算机软件专业的一门重要专业课程。该课程系统地向学生介绍编译程序的结构、工作流程及编译程序各组成部分的设计原理和实现技术。由于该课程理论性和实践性都比较强,内容较为抽象复杂,涉及到大量的软件设计算法,因此,一直是一门比较难学的课程。为了使学生更好地理解和掌握编译技术的基本概念、基本原理和实现方法,实践环节非常重要,只有通过上机进行程序设计,才能使学生对比较抽象的教学内容产生具体的感性认识,增强学生综合分析问题、解决问题的能力,并对提高学生软件设计水平大有益处。

本实验内容可在《编译原理》课程教学的同时,安排学生进行相关的实验。实验平台可选择在MS-DOS或Windows操作系统环境,使用C/C++的任何版本作为开发工具。学生在做完试验后,应认真撰写实验报告,内容应包括实验名称、实验目的、实验要求、实验内容、测试或运行结果等。

实验一词法分析

2.实验要求

利用该词法分析器完成对源程序字符串的词法分析。输出形式是源程序的单词符号二元式的代码,并保存到文件中。

1.实验目的

对C语言的一个子集设计并实现一个简单的词法分析器,掌握利用状态转换图设计词法分析器的基本方法。

3.实验内容

(1) 假设该语言中的单词符号及种别编码如下表所示。

单词符号及种别编码

算符和界符= + -* / & <<=>>===!=&& || , : ; { } [ ] ( ) ID和NUM的正规定义式为:

ID→letter(letter | didit)*

NUM→digit digit*

letter→a | … | z | A | … | Z

digit→ 0 | … | 9

如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。空格由空白、制表符和换行符组成。

(3) 设计词法分析器的步骤:

①首先根据上面单词符号表及ID和NUM的正规定义式,构造出状态转换图;

②定义相关的变量和数据结构。关键字作为特殊标识符处理,把它们预先安排在一

张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查

到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串

数组,其描述如下:

char *KEY_WORDS[7]={″main″,″int″,″char″,″if″,″else″,″for″,″while″};

用以存放单词符号二元式的数据结构可如下定义:

#define MAXLENGTH 255 /* 一行允许的字符个数 */

union WORDCONTENT { /* 存放单词符号的内容 */

char T1[MAXLENGTH];/* 存放标识符及由两个(以上)字符组成的符号 */

int T2; /* 存放整型常数的拼数 */

char T3; /* 存放其他符号 */

};

typedef struct WORD { /* 单词符号二元式 */

int code; /* 存放种别编码 */

union WORDCONTENT value;

} WORD;

③按照编译程序一遍扫描的要求,把词法分析器Scaner作为一个独立的子程序来

设计,通过对Scaner的反复调用识别出所有的单词符号;

④当Scaner识别出一个单词符号时,则将该单词符号的二元式写入到输出文件中。

若Scaner无法识别出一个单词符号时,则调用错误处理程序PrintError,显示当

前扫描到的字符及其所在行、列位置,并跳过该字符重新开始识别单词符号。(4) 测试该设计词法分析器,可对下面的源程序进行词法分析:输出如下二元式代码序列: 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,})

实验二NFA的确定化

1.实验目的

设计并实现将NFA确定化为DFA的子集构造算法,从而更好地理解有限自动机之间的等价性,掌握词法分析器自动产生器的构造技术。该算法也是构造LR分析器的基础。

2.实验要求

设计并实现计算状态集合I的ε闭包的算法ε_Closure(I)和转换函数Move(I,a),并在此基础上实现子集构造算法Subset_Construction。利用该从NFA到DFA的转换程序Subset_Construction,任意输入一个NFA N=(S,Σ,δ,s0,F),输出一个接收同一语言的DFA M=(S’,Σ,δ’,s0’,F’)。

3.实验内容

(1)令I是NFA N的状态集S的一个子集,I的ε闭包的ε_Closure(I)构造规则如下:

(a)若s∈I,则s∈ε_Closure(I);

(b)若s∈ε_Closure(I)且δ(s, ε)=s’而s’?ε_Closure(I) ,则s’∈ε

_Closure(I)

根据上面的规则,下面给出了一个计算I的ε闭包的算法ε_Closure(I)。

SET S;

SETε_Closure(input)

SET *input;

{

S=input; /* 初始化 */

push(); /* 把输入状态集中的全部状态压入栈中 */

while(栈非空){

Nfa_state i;

pop(); /* 把栈顶元素弹出并送入i */

if(存在δ(i, ε)=j)

if(j不在S中) {

把i加到S中;

把j压入栈中;

}

}

return S; /* 返回ε_Closure(input)集合 */

}

完成上述算法的设计。

(2)令I是NFA N的状态集S的一个子集,a∈Σ, 转换函数Move(I,a)定义为:

Move(I,a)= ε_Closure(J)

其中,J={s’|s∈I且δ(s,a)=s’}

转换函数Move(I,a)的设计通过调用ε_Closure(input)实现,完成该函数的设计。

(3)从NFA N构造一个与其等价的DFA M的子集构造算法,就是要为DFA M构造状态转

换表Trans,表中的每个状态是NFA N状态的集合,DFA M将“并行”地模拟NFA N 面对输入符号串所有可能的移动。下面给出了子集构造算法Subset_Construction 的框架,请完成其设计过程。

有关数据结构:

States[] 是一个M的数组,每个状态有两个域,set域存放N的状态集合,

flg域为一标识。

Trans[] 是M的转移矩阵(输入字母表Σ元素个数×最大状态数),

Trans[i][a]=下一状态。

i M的当前状态号

a 输入符号,a∈Σ

Nstates[] M的下一新状态号

S 定义M的一个状态的N的状态集

初始化:

States[0].set=ε_Closure({N的初态})

States[0].flg=FALSE

Nstates=1

i=0

S=Ф

Trans初始化为无状态’-’

while(States[i]的flg为FALSE){

States[i].flg=TRUE;

for(每个输入符号a∈Σ){

S=ε_Closure(Move(States[i].set,a));

if(S非空)

if(States中没有set域等于 S的状态){

States[Nstates].set=S;

States[Nstates].flg=FALSE;

Trans[i][a]= Nstates++;

}

else

Trans[i][a]= States中一个set域为S的下标;

}

}

此算法的输出M主要由Trans矩阵描述,其中省略了每个状态是否为终态的描述,应加以完善。

(4)测试用例

NFA N的初态为12,DFA M的初态为ε_Closure({12})。

整个转换过程可用下表来概括。

DFA M的状态转换图如下。

实验三非递归预测分析

1.实验目的

设计一个非递归预测分析器,实现对表达式语言的分析,理解自上而下语法分析方法的基本思想,掌握设计非递归预测分析器的基本方法。

2.实验要求

建立文法及其LL(1)分析表表示的数据结构,设计并实现相应的预测分析器,对源程序经词法分析后生成的二元式代码流进行预测分析,如果输入串是文法定义的句子则输出“是”,否则输出“否”。

3.实验内容

(1)文法描述及其LL(1)分析表

表达式语言(XL)的语法规则如下:

1.程序→表达式;

2. |表达式;程序

3.表达式→表达式 + 项

4. |项

5.项→项 * 因式

6. |因式

7.因式→ num_or_id

8. |(表达式)

将该语言的文法转换为如下的LL(1)文法:

1prgm → expr;prgm’ 8 term → factor term’

2prgm’→ prgm 9 term’→ *factor term’

3prgm’→ε 10 term’→ε

4expr → term expr’ 11 factor → (expr)

5expr →ε 12 f actor → num

6expr’→ +term expr’ 13 system_goal → prgm

7expr’→ε

该LL(1)文法的LL(1)分析表如下:

对文法中每个文法符号指定一个常数值,符号编码表如下:

文法的产生式可用数组Yy_pushtab[]存放。数组的第一个下标是产生式号,第一个产生式的序号为0;每列按逆序存放该产生式右部各符号的常数值,并以0结束。对于该表达式语言XL的LL(1)分析表,可用数组Yy_d[]存放。第一个下标是非终结符数值,

第二个下标是终结符数值,数组元素的值为:0(表示接受),1(表示产生式号),-1(表示语法错)。

数组Yy_pushtab[]的具体内容及表示如下:

数组Yy_d[]的具体内容及表示如下:

0 1 2 3 4 5 6

# ; + * () Num

prgm’ 257

expr 258

expr’ 260

factor 261

term’ 262

system_goal 263

(3)预测分析器总控程序结构

预测分析器总控程序使用上面的两个表Yy_pushtab、Yy_d和一个分析栈(元素类型为int),其结构如下:

初始化;/* 把开始符号的常数值压入分析站,输入指向第一个输入符号 */ while(分析栈非空) {

if(栈顶常数表示一个终结符)

if(该常数与输入符号的常数不等)

报语法错;

else {

把一个数从栈顶弹出;

advance读下一输入符号;

}

else { /* 栈顶的常数表示一个非终结符 */

what_to_do=Yy_d[栈顶常数][当前输入符号的常数];

if(what_to_do= = -1)

报语法错;

else {

把栈顶元素弹出栈;

把Yy_pushtab[what_to_do]中列出的全部常数压入分析栈;

}

}

}

请实现该程序。在程序中添加输出栈内容的功能,以便和手工模拟分析过程作比

较。

(4)用预测分析器和手工模拟两种方式对文法的句子1+2;进行分析。综合分析过程可用下表表示。

实验四LR分析

1.实验目的

设计一个LR分析器,实现对表达式语言的分析,加深对LR语法分析方法的基本思想的理解,掌握LR分析器设计与实现的基本方法。

2.实验要求

建立文法及其LR分析表表示的数据结构,设计并实现一个LALR(1)的分析器,对源程序经词法分析后生成的二元式代码流进行分析,如果输入串是文法定义的句子则输出“是”,否则输出“否”。

3.实验内容

(1)文法描述及其LALR(1)分析表

描述表达式语言的文法G如下:

0.S → E

1. E → E+T

2. E → T

3.T → T*F

4.T → F

5. F → (E)

6. F → ID

该文法的LALR(1)分析表如下:

(2)LR分析器总控程序框架如下:

push(0);

advance();

while(Action[tos][sym]!=accept)

if(Action[tos][sym]= =’-’)

error();

else

if (Action[tos][sym]= =SN) {

push(N);

advance();

}

else if(Action[tos][sym]= =RN){ act(N);

pop(产生式N的右部的符号个数);

push(Goto[新tos][ 产生式N的左部符号]);

accept();

上述算法中的有关函数与符号的意义如下:

accept() 返回成功状态,LR分析器停止工作

act(N) 执行利用产生式N的归约的动作,通常为产生代码

advance() 丛输入流读下一单词到sym

error() 出错处理

pop(N) 从栈顶弹出N个符号(状态)

push(N) 把状态N压入状态栈

sym 当前输入的单词符号

tos 栈顶状态号

(3)存放LR分析表的数据结构

①实现方法一:用一个二维整数数组表示

数组元素为表示动作的整数。数组的行下标为状态号,列下标用来表示终结符与非终结符的整数表示。数组元素可作如下约定:

正整数:表示移进动作,如S6用数6表示;

负整数:表示归约动作,如R5用数-5表示;

0:表示接受,通常为按产生式0归约;

状态号也用整数表示;

用不可能是状态号的较大的整数表示错误转移。

请将上述LALR(1)分析表用这种表示方法,完成LR分析器的程序设计,并添加输出状态栈内容的功能。用上述表达式文法G的一个句子作为输入,进行测试。

②实现方法二:采用压缩表示法

动作Action表的每一行用一个数组表示,数组的第一个元素是本数组中存放的数偶个数,第二个元素到最后一个元素都以[终结符,动作]的数偶的形式存放。

再用一个以状态号为下标的下标数组,每个元素含一个指向数偶数组的指针。若数

组元素的值为NULL,则表示从此状态无转移弧发出。若分析表有几行相同,则只

需保存一行,其它元素则都指向存放这一行表的数组即可。转移Goto表也按同样

方式组织,只是这个行数组的数偶为[非终结符,下一状态号]。

每个行数组Yyan表示动作表Yy_action的一行,每个行数组Yygn表示转移表Yy_goto的一行。假定上述表达式文法G中终结符及非终结符的整数值为:终结符: # ID + * ( ) 非终结符: S E T F

整数值: 0 1 2 3 4 5 整数值: 0 1 2 3 Yy_action数组是以状态号为下标的下标数组,每个元素含有指向数组Yyan的指针;下标数组Yy_goto的每个元素含有指向数组Yygn的指针。

表达式文法G的LALR(1)分析表的具体压缩表示如下:

Yy_action

Yy_goto

以上分析表用C 语言程序描述如下:

/*

* Yy_action 表

*/

int Yya000[]={2,4,2,1,1};

int Yya001[]={4,5,-6,3,-6,2,-6,0,-6};

int Yya003[]={2,0,0,2,7};

int Yya004[]={4,5,-2,2,-2,0,-2,3,8};

int Yya005[]={4,5,-4,3,-4,2,-4,0,-4};

int Yya006[]={2,5,9,2,7};

int Yya009[]={4,5,-5,3,-5,2,-5,0,-5};

int Yya010[]={4,5,-1,2,-1,0,-1,3,8};

int Yya011[]={4,5,-3,3,-3,2,-3,0,-3};

int Yy_action[]=

{

Yya000, Yya001, Yya000, Yya003, Yya004, Yya005,

Yya006, Yya000, Yya000, Yya009, Yya010, Yya011

};

/*

* Yy_goto表

*/

int Yyg000[]={3,3,5,2,4,1,3};

int Yyg002[]={3,3,5,2,4,1,6};

int Yyg007[]={2,3,5,2,10};

int Yyg008[]={1,3,11};

int Yy_goto[]=

{

Yyg000, NULL, Yyg002, NULL, NULL, NULL,

NULL, Yyg007, Yyg008, NULL, NULL, NULL

};

/*

* 为了进行归约,使用一个Yy_lhs[]数组,其值为代表产生式左部符号的

* 整数,数组的下标为产生式号

*/

int Yy_lhs[7]=

{

/* 0 */ 0,

/* 1 */ 1,

/* 2 */ 1,

/* 3 */ 2,

/* 4 */ 2,

/* 5 */ 3,

/* 6 */ 3

};

/*

* Yy_reduce[]数组元素的值为产生式右部符号的个数,

* 以产生式号为数组的下标索引

*/

int Yy_reduce[]=

{

/* 0 */ 1,

/* 1 */ 3,

/* 2 */ 1,

/* 3 */ 3,

/* 4 */ 1,

/* 5 */ 3,

/* 6 */ 1

};

根据以上数组结构,构造函数Yy_next(),其功能是在给定状态和输入符号下,求出应采取的动作或转向的下一状态。

int Yy_next(table,cur_state,symbol)

int **table; /* 要查的表 */

int cur_state; /* 行号 */

int symbol; /* 列号 */

{

int *p=table[cur_state];

int i;

if(p)

for(i=(int)*p++ ; --i>0 ; p+=2)

if(symbol = = p[0])

return(p[1]);

return YYF; /* 出错指示 */

};

指针p指向Yyan数组或Yygn数组,由参数table的值而定。如果table指向Yy_action,则p指向Yyan数组;若table指向Yy_goto,则p指向Yygn数组据。

根据上述LALR(1)分析表压缩表示方法,完成LR分析器的程序设计,并添加输出状态栈内容的功能。用上述表达式文法G的一个句子作为输入,进行测试。

实验五语义分析和中间代码生成

1.实验目的

通过设计一个简单的语义分析和中间代码生成器,加深对语法制导翻译方法的理解,掌握将语法分析所识别的语法范畴变换为中间代码的语义翻译方法。

2.实验要求

采用递归下降语法制导翻译方法,构造语义分析和中间代码生成器,实现对算术表达式、赋值语句、条件语句、循环语句进行语义分析,生成四元式中间代码的序列。

3.实验内容

(1)待分析的语言为C语言的一个子集,其文法用扩充的BNF描述如下:程序→ main( ) 语句块

语名块→′{′语句串′}′

语句串→语句 { ;语句 } ;

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

赋值语句→ ID = 表达式

条件语句→ if (条件)语句块

循环语句→ while(条件)语句块

条件→表达式关系运算符表达式

表达式→项 { + 项 | - 项 }

项→因子 { * 因子 | / 因子 }

因子→ ID | NUM |(表达式)

关系运算符→ < | <= | > | >= | == | !=

上面语名块产生式中的{和}是终结符号,加引号以示区别。

(2)通过为上面文法中的每一个非终结符构造一个递归子程序,设计一个递归下降分析器。

(3)在条件、表达式、赋值语句、条件语句、循环语句的递归子程序中,加入语义分析和生成四元式的代码。

构造下面的语义过程:

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。

(4)实验的输入和输出

输入是语法分析提供的正确的单词串,输出是四元式序列。

例如,对于语句串

i = 2 * 3 + 4;

if ( i>8 ) j = 10;

while( j>0){

k = k + 1;

j = j - 1;

}

输出的四元式序列如下:

1.(*,2,3,T

1

2.(+,T1,4,T2)

3.(=,T2,,i)

4.(j>,i,8,6)

5. (j,,,7)

6.(=,10,,j)

7.(j>,j,0,9)

8.(j,,,14)

9.(+,k,1,T3)

10.(=,T3,,k)

11.(-,j,1,T4)

12.(=,T4,,j)

13.(j,,,7)

14.……

实验六基于DAG的基本块优化

1.实验目的

了解基本块的DAG表示及其应用,掌握局部优化的基本方法。

2.实验要求

设计一个转换程序,把由四元式序列表示的基本块转换为DAG,并在构造DAG的过程中,进行合并已知量、删除无用赋值及删除公共子表达式等局部优化处理。最后再从所得到的DAG出发,按原来生成DAG各个结点的顺序,重建四元式序列形式的基本块。

3.实验内容

(1)DAG的结点类型只考虑0型、1型和2型,如下表所示。

(2)由基本块构造DAG算法如下:

while(基本块中还有未处理过的四元式) {

取下一个四元式Q;

newleft=newright=0;

if(getnode(B)= =NULL){

makeleaf(B);

newleft=1;

}

switch(Q的类型){

case 0 : n= getnode(B);

insertidset(n,A);

break;

case 1: if(isconsnode(B)){

p=calcons(Q.op,B);

if(newleft= =1) /* getnode(B)是处理Q时新建结点 */

delnode(B);

if((n=getnode(p))= =NULL){

makeleaf(p);

n=getnode(p);

}

} else{

if((n=findnode(Q.op,B))= =NULL)

n=makenode(Q.op,B);

}

insertidset(n,A);

break;

case 2: if(getnode(C)= =NULL){

makeleaf(C);

newright=1;

}

if(isconsnode(B) && isconsnode(C)){

p=calcons(Q.op,B,C);

if(newleft= =1) /* getnode(B)是处理Q时新建结点 */

delnode(B);

if(newright= =1) /* getnode(C)是处理Q时新建结点 */

delnode(C);

if((n=getnode(p))= =NULL){

makeleaf(p);

n=getnode(p);

}

} else{

if((n=findnode(Q.op,B,C))= =NULL)

n=makenode(Q.op,B,C);

}

insertidset(n,A);

break;

}

}

上述算法中应设置如下的函数:

getnode(B) :返回B(可以是标记或附加信息)在当前DAG中对应的结点号。 makeleaf(B):构造标记为B的叶子结点。

isconsnode(B):检查B对应的结点是否为标记为常数的叶子结点。

calcons(Q.op,B):计算op B 的值(即合并已知量)。它的另一种调用形式是 calcons(Q.op,B,C),计算B op C 的值。

delnode(B):删除B(结点的标记)在当前DAG中对应的结点。

findnode(Q.op,B):在当前DAG中查找并返回这样的结点:标记为op,后继

为getnode(B)(即查找公共子表达式op B)。它的另一种调用

形式是findnode (Q.op,B,C) (即查找公共子表达式B op C)。 makenode(Q.op,B,C):构造并返回标记为op,左右后继分别为getnode(B)、

getnode(C)的内部结点。

insertidset(n,A):若getnode(A)=NULL,则把A附加到结点n;否则,若A

在getnode(A)的附加标识符集中,且getnode(A)无前驱或虽

有前驱但getnode(A) 附加标识符集中符号数大于1,则把A

从getnode(A)的附加标识符集中删除(即删除无用赋值)。

请实现上述基本块的DAG构造算法,并添加从所得DAG按原来生成DAG各个结点的顺序,重建四元式序列的功能。

(3)测试用例

用下面的基本块作为输入:

(1) T1 = A * B

(2) T2 = 3 / 2

(3) T3 = T1 ― T2

(4) X = T3

(5) C = 5

(6) T4 = A * B

(7) C = 2

(8) T5 = 18 + C

(9) T6 = T4 * T5

(10) Y = T6

基本块的DAG如下:

⑤T3,X

⑨T6,Y

③T1,T4 *

*

①②④T2⑧T5⑥⑦C

A B 1.5 20 5 2

按生成DAG各个结点的顺序,重建四元式序列如下:

(1) T1 = A * B

(2) T2 = 1.5

(3) T3 = T1 ― 1.5

(4) X = T3

(5) T4 = T1

(6) C = 2

(7) T5 = 20

(8) T6 = T1 * 20

(9) Y = T6

编译原理实验--词法分析器

编译原理实验--词法分析器 实验一词法分析器设计 【实验目的】 1(熟悉词法分析的基本原理,词法分析的过程以及词法分析中要注意的问题。 2(复习高级语言,进一步加强用高级语言来解决实际问题的能力。 3(通过完成词法分析程序,了解词法分析的过程。 【实验内容】 用C语言编写一个PL/0词法分析器,为语法语义分析提供单词,使之能把输入的字符 串形式的源程序分割成一个个单词符号传递给语法语义分析,并把分析结果(基本字, 运算符,标识符,常数以及界符)输出。 【实验流程图】

【实验步骤】 1(提取pl/0文件中基本字的源代码 while((ch=fgetc(stream))!='.') { int k=-1; char a[SIZE]; int s=0; while(ch>='a' && ch<='z'||ch>='A' && ch<='Z') { if(ch>='A' && ch<='Z') ch+=32; a[++k]=(char)ch; ch=fgetc(stream); } for(int m=0;m<=12&&k!=-1;m++) for(int n=0;n<=k;n++) {

if(a[n]==wsym[m][n]) ++s; else s=0; if(s==(strlen(wsym[m]))) {printf("%s\t",wsym[m]);m=14;n=k+1;} } 2(提取pl/0文件中标识符的源代码 while((ch=fgetc(stream))!='.') { int k=-1; char a[SIZE]=" "; int s=0; while(ch>='a' && ch<='z'||ch>='A' && ch<='Z') { if(ch>='A' && ch<='Z') ch+=32; a[++k]=(char)ch; ch=fgetc(stream); } for(int m=0;m<=12&&k!=-1;m++) for(int n=0;n<=k;n++) { if(a[n]==wsym[m][n]) ++s; else s=0; if(s==(strlen(wsym[m]))) {m=14;n=k+1;} } if(m==13) for(m=0;a[m]!=NULL;m++) printf("%c ",a[m]);

编译原理实验报告实验一编写词法分析程序

编译原理实验报告实验名称:实验一编写词法分析程序 实验类型:验证型实验 指导教师:何中胜 专业班级:13软件四 姓名:丁越 学号: 电子邮箱: 实验地点:秋白楼B720 实验成绩: 日期:2016年3 月18 日

一、实验目的 通过设计、调试词法分析程序,实现从源程序中分出各种单词的方法;熟悉词法分析 程序所用的工具自动机,进一步理解自动机理论。掌握文法转换成自动机的技术及有穷自动机实现的方法。确定词法分析器的输出形式及标识符与关键字的区分方法。加深对课堂教学的理解;提高词法分析方法的实践能力。通过本实验,应达到以下目标: 1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。 2、掌握词法分析的实现方法。 3、上机调试编出的词法分析程序。 二、实验过程 以编写PASCAL子集的词法分析程序为例 1.理论部分 (1)主程序设计考虑 主程序的说明部分为各种表格和变量安排空间。 数组 k为关键字表,每个数组元素存放一个关键字。采用定长的方式,较短的关键字 后面补空格。 P数组存放分界符。为了简单起见,分界符、算术运算符和关系运算符都放在 p表中 (编程时,还应建立算术运算符表和关系运算符表,并且各有类号),合并成一类。 id和ci数组分别存放标识符和常数。 instring数组为输入源程序的单词缓存。 outtoken记录为输出内部表示缓存。 还有一些为造表填表设置的变量。 主程序开始后,先以人工方式输入关键字,造 k表;再输入分界符等造p表。 主程序的工作部分设计成便于调试的循环结构。每个循环处理一个单词;接收键盘上 送来的一个单词;调用词法分析过程;输出每个单词的内部码。 ⑵词法分析过程考虑 将词法分析程序设计成独立一遍扫描源程序的结构。其流程图见图1-1。 图1-1 该过程取名为 lexical,它根据输入单词的第一个字符(有时还需读第二个字符),判断单词类,产生类号:以字符 k表示关键字;i表示标识符;c表示常数;p表示分界符;s表示运算符(编程时类号分别为 1,2,3,4,5)。 对于标识符和常数,需分别与标识符表和常数表中已登记的元素相比较,如表中已有 该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组id中,将常数 变为二进制形式存入数组中 ci中,并记录其在表中的位置。 lexical过程中嵌有两个小过程:一个名为getchar,其功能为从instring中按顺序取出一个字符,并将其指针pint加1;另一个名为error,当出现错误时,调用这个过程, 输出错误编号。 2.实践部分

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

编译技术 班级网络0802 学号3080610052姓名叶晨舟 指导老师朱玉全2011年 7 月 4 日

一、目的 编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。 二、任务及要求 基本要求: 1.词法分析器产生下述小语言的单词序列 这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表: 单词符号种别编码助记符内码值 DIM IF DO STOP END 标识符 常数(整)= + * ** , ( )1 2 3 4 5 6 7 8 9 10 11 12 13 14 $DIM $IF $DO $STOP $END $ID $INT $ASSIGN $PLUS $STAR $POWER $COMMA $LPAR $RPAR - - - - - - 内部字符串 标准二进形式 - - - - - - 对于这个小语言,有几点重要的限制: 首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。例如,下面的写法是绝对禁止的: IF(5)=x 其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。也就是说,对于关键字不专设对应的转换图。但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。 再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。例如,一个条件语句应写为

实验1-3-《编译原理》词法分析程序设计方案

实验1-3 《编译原理》S语言词法分析程序设计方案 一、实验目的 了解词法分析程序的两种设计方法之一:根据状态转换图直接编程的方式; 二、实验内容 1.根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。在此,词法分析程序作为单独的一遍,如下图所示。 具体任务有: (1)组织源程序的输入 (2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件 (3)删除注释、空格和无用符号 (4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。将错误信息输出到屏幕上。 (5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。 标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址 注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。 常量表结构:常量名,常量值 三、实验要求 1.能对任何S语言源程序进行分析 在运行词法分析程序时,应该用问答形式输入要被分析的S源语言程序的文件名,然后对该程序完成词法分析任务。 2.能检查并处理某些词法分析错误 词法分析程序能给出的错误信息包括:总的出错个数,每个错误所在的行号,错误的编号及错误信息。 本实验要求处理以下两种错误(编号分别为1,2): 1:非法字符:单词表中不存在的字符处理为非法字符,处理方式是删除该字符,给出错误信息,“某某字符非法”。 2:源程序文件结束而注释未结束。注释格式为:/* …… */ 四、保留字和特殊符号表

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

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

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

编译原理词法分析和语法分析报告+代码(C语言版)

词法分析 一、实验目的 设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 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 各种单词符号对应的种别码: 输入:所给文法的源程序字符串。 输出:二元组(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)关键字: begin if then while do end 所有的关键字都是小写。 (2)运算符和界符 : = + - * / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义: ID = letter (letter | digit)* NUM = digit digit* (4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。 各种单词符号对应的种别码: 表各种单词符号对应的种别码 词法分析程序的功能: 输入:所给文法的源程序字符串。 输出:二元组(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所示。其中初始包括以下两个方面: ⑴关键字表的初值。 关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下: Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,}; 图3-1 (2)程序中需要用到的主要变量为syn,token和sum 扫描子程序的算法思想: 首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn 用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。

编译原理词法分析和语法分析报告 代码(C语言版)

词法分析 三、词法分析程序的算法思想: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 3.1 主程序示意图: 扫描子程序主要部分流程图 其他

词法分析程序的C语言程序源代码: // 词法分析函数: void scan() // 数据传递: 形参fp接收指向文本文件头的文件指针; // 全局变量buffer与line对应保存源文件字符及其行号,char_num保存字符总数。 void scan() { char ch; int flag,j=0,i=-1; while(!feof(fp1)) { ch=fgetc(fp1); flag=judge(ch); printf("%c",ch);//显示打开的文件 if(flag==1||flag==2||flag==3) {i++;buffer[i]=ch;line[i]=row;} else if(flag==4) {i++;buffer[i]='?';line[i]=row;} else if(flag==5) {i++;buffer[i]='~';row++;} else if(flag==7) continue; else cout<<"\n请注意,第"<

编译原理C语言词法分析器

编译原理 C语言词法分析器 一、实验题目 编制并调试C词法分析程序。 a.txt源代码: ?main() { int sum=0 ,it=1;/* Variable declaration*/ if (sum==1) it++; else it=it+2; }? 设计其词法分析程序,能识别出所有的关键字、标识符、常数、运算符(包括复合运算符,如++)、界符;能过滤掉源程序中的注释、空格、制表符、换行符;并且能够对一些词法规则的错误进行必要的处理,如:标识符只能由字母、数字和下划线组成,且第一个字符必须为字母或下划线。实验要求:要给出所分析语言的词法说明,相应的状态转换图,单词的种别编码方案,词法分析程序的主要算法思想等。 二、实验目的 1、理解词法分析在编译程序中的作用; 2、掌握词法分析程序的实现方法和技术; 3、加深对有穷自动机模型的理解。 三、主要函数 四、设计 1.主函数void main ( )

2. 初始化函数void load ( ) 3. 保留字及标识符判断函数void char_search(char *word) 4. 整数类型判断函数void inta_search(char *word) 5. 浮点类型判断函数void intb_search(char *word)

6. 字符串常量判断函数void cc_search(char *word) 7. 字符常量判断函数void c_search(char *word) 同4、5函数图 8.主扫描函数void scan ( ) 五、关键代码 #include #include

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

编译原理实验报告

实验一 一、实验名称:词法分析器的设计 二、实验目的: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 #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; do{i=i+1; scanf("%c",&a[i]);

编译原理实验报告一 简单样本语言的词法分析器

理工大学信息工程与自动化学院学生实验报告 (2012 —2013学年第一学期) 一、实验目的及容 编译技术是理论与实践并重的课程,而其实验课要综合运用所学的多门课程的容,用来完成一个小型编译程序。从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。 调试并完成一个词法分析程序,加深对词法分析原理的理解。 二、实验原理及基本技术路线图(框原理图或程序流程图) 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为整型常数。 二、所用仪器、材料(设备名称、型号、规格等或使用软件)

1台PC以及VISUAL C++6.0软件。 三、实验法、步骤(或:程序代码或操作过程) (1)程序代码: #include #include #include char 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')) { m=0; while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) { token[m++]=ch; ch=prog[p++]; } token[m++]='\0'; p--; syn=10; for(n=0;n<6;n++)

编译原理词法分析和语法分析报告+代码(C语言版)

信息工程学院实验报告(2010 ~2011 学年度第一学期) 姓名:柳冠天 学号:2081908318 班级:083

词法分析 一、实验目的 设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 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 主程序示意图:

编译原理词法分析器语法分析课程设计报告书

《编译原理》 课程设计 院系信息科学与技术学院 专业软件工程 年级 2011级 学号 20112723 姓名林苾湲 西南交通大学信息科学与技术学院 2013年 12月

目录 课程设计1 词法分析器 (2) 1.1 设计题目 (2) 1.2 设计容 (2) 1.3 设计目的 (2) 1.4 设计环境 (2) 1.5 需求分析 (2) 1.6 概要设计 (2) 1.7 详细设计 (4) 1.8 编程调试 (5) 1.9 测试 (11) 1.10 结束语 (13) 课程设计2 赋值语句的解释程序设计 (14) 2.1 设计题目 (14) 2.2 设计容 (14) 2.3 设计目的 (14) 2.4 设计环境 (14) 2.5 需求分析 (15) 2.6 概要设计 (16) 2.7 详细设计 (16) 2.8 编程调试 (24) 2.9 测试 (24) 2.10 结束语 (25)

课程设计一词法分析器设计 一、设计题目 手工设计c语言的词法分析器(可以是c语言的子集)。 二、设计容 处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。 三、设计目的 了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。 四、设计环境 该课程设计包括的硬件和软件条件如下: 4.1.硬件 (1)Intel Core Duo CPU P8700 (2)存4G 4.2.软件 (1)Window 7 32位操作系统 (2)Microsoft Visual Studio c#开发平台 4.3.编程语言 C#语言 五、需求分析 5.1.源程序的预处理:源程序中,存在许多编辑用的符号,他们对程序逻辑功能无任何影响。例如:回车,换行,多余空白符,注释行等。在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。 5.2.单词符号的识别并判断单词的合法性:将每个单词符号进行不同类别的划分。单词符号可以划分成5中。 (1)标识符:用户自己定义的名字,常量名,变量名和过程名。 (2)常数:各种类型的常数。 (3) 保留字(关键字):如if、else、while、int、float等。 (4) 运算符:如+、-、*、<、>、=等。 (5)界符:如逗号、分号、括号等。 5.3.将所有合法的单词符号转化为便于计算机处理的二元组形式:(单词分类号,单词自身值);以图形化界面显示出来。 5.4.可选择性地将结果保存到文件中。 六、概要设计 6.1.数据类型 6.1.1.单词的分类:本词法分析器演示的是C语言的一个子集,故字符集如下:

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

编译原理实验报告 实验一 实验题目:词法分析 指导老师:任姚鹏 专业班级:计算机科学与技术系网络工程方向1002班姓名:xxxx

2013年 4月13日 实验类型__验证性__ 实验室_软件实验室三__ 一、实验项目的目的和任务: 了解和掌握词法分析的方法,编程实现给定源语言程序的词法分析器,并利用该分析器扫描源语言程序的字符串,按照给定的词法规则,识别出单词符号作为输出,发现其中的词法错误。 二、实验内容: 1.设计一个简单的程序设计语言(语言中有若干运算符和分界符;有若干关健字;若干标识符及若干常数) 2.确定编译中使用的表格、词法分析器的输出形式、标识符与关键字的区分方法。 3.把词法分析器设计成一个独立的过程。 三、实验要求: 1.从键盘上输入源程序; 2.处理各单词,计算个单词的值和类型; 3.输出个单词名、单词的值和类型。 四、实验代码 #include #include char file[1024]; int length=0; int index; char keywords[][10]={"auto","short","int","long","float", "double","char","struct","union","enum", "typedef","const","unsigned","signed","extern", "register","static","volatile","void","default", "if","else","switch","case","for", "do","while","goto","continue","break", "sizeof","return"}; char limits[]={'(',')','[',']','{','}',',',';'}; char operators[]={'+', '-', '*', '/', '%', '>','<','&','|','^', '~','!','='}; //13 int IsChar(char ch) //是否是字符 { if ( (ch>='a'&&ch<='z') || (ch>='A'&&ch<='Z')) return 1; return 0;}

编译原理词法分析器

一、实验目的 了解词法分析程序的两种设计方法:1.根据状态转换图直接编程的方式;2.利用DFA 编写通用的词法分析程序。 二、实验内容及要求 1.根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。在此,词法分析程序作为单独的一遍,如下图所示。 具体任务有: (1)组织源程序的输入 (2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件 (3)删除注释、空格和无用符号 (4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。将错误信息输出到屏幕上。 (5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。 标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址 注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。 常量表结构:常量名,常量值 2.编写DFA模拟程序 算法如下: DFA(S=S0,MOVE[][],F[],ALPHABET[]) /*S为状态,初值为DFA的初态,MOVE[][]为状态转换矩阵,F[] 为终态集,ALPHABET[] 为字母表,其中的字母顺序与MOVE[][] 中列标题的字母顺序一致。*/ { Char Wordbuffer[10]=“”//单词缓冲区置空 Nextchar=getchar();//读 i=0; while(nextchar!=NULL)//NULL代表此类单词 { if (nextcha r!∈ALPHABET[]){ERROR(“非法字符”),return(“非法字符”);} S=MOVE[S][nextchar] //下一状态 if(S=NULL)return(“不接受”);//下一状态为空,不能识别,单词错误 wordbuffer[i]=nextchar ;//保存单词符号 i++; nextchar=getchar(); } Wordbuffer[i]=‘\0’;

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

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

YY *p=0~9*p=0~9 NN 无符号数无符号数 P++P++ continuecontinue GOTO 2: GOTO 2 *p=Econtinue Y 无符号数 P++ continue 三、源程序代码部分 #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

编译原理实验报告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、根据正规式,画出状态转换图;

编译原理实验-词法分析器的设计与实现.docx

南华大学 计算机科学与技术学院实验报告 (2018~2019学年度第二学期) 课程名称编译原理 实验名称词法分析器的设计与 实现 姓名学号 专业班级 地点教师

1.实验目的及要求 实验目的 加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。 实验要求 1.对单词的构词规则有明确的定义; 2.编写的分析程序能够正确识别源程序中的单词符号; 3.识别出的单词以<种别码,值>的形式保存在符号表中,正确设计和维护 符号表; 4.对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误 提示,保证顺利完成整个源程序的词法分析; 2.实验步骤 1.词法分析规则 <标识符>::=<字母>|<标识符><字母>|<标识符><数字> <常数>::=<数字>|<数字序列><数字> <数字序列>::=<数字序列><数字>|<数字>|<.> <字母>::=a|b|c|……|x|y|z <数字>::=0|1|2|3|4|5|6|7|8|9 <运算符>::=<关系运算符>|<算术运算符>|<逻辑运算符>|<位运算符>|<赋值运算符> <算数运算符>::=+|-|*|/|...|-- <关系运算符>::=<|>|!=|>=|<=|== <逻辑运算符>::=&&| || |! <位运算符>::=&| | |! <赋值运算符>::==|+=|-=|/=|*= <分界符>::=,|;|(|)|{|}|:| // |/**/ <保留字>::=main|if|else|while|do|for|...|void

编译原理词法分析及语法分析

编译原理 实验报告 实验名称:词法分析及语法分析专业班级: 姓名: 学号: 完成日期:

实验一、sample语言的词法分析 一、实验目的 给出SAMPLE文法规范,要求编写SAMPLE语言的词法分析程序。 二、实验准备 了解sample语言单词的定义,选择任一种编程语言实现词法分析。 三、实验内容 给出SAMPLE语言文法,输出单词(关键字、专用符号以及其它标记)。 1、格式 输入:源程序文件。输出:关键字、专用符号以及其它标记。 2、实现原理 程序中先判断这个句语句中每个单元为关键字、常数、运算符、界符,对与不同的单词符号给出不同编码形式的编码,用以区分之。 3、实验方法 读懂Sample源代码,自己重点独立实现对常量的判别。 四、实验设计 1、设计SAMPLE语言的词法分析器 A、字符集定义 1. <字符集> → <字母>│<数字>│<单界符> 2. <字母> → A│B│…│Z│a│b│…│z 3. <数字> → 0│1│2│…│9 4. <单界符> → +│-│*│/│=│<│>│(│)│[│]│:│. │; │, │' B、单词集定义 5.<单词集> → <保留字>│<双界符>│<标识符>│<常数>│<单界符> 6.<保留字> → and│array│begin│bool│call│case│char│constant│dim│do│else │end│false│for│if│input│integer│not│of│or│output│procedure│program │read│real│repeat│set│stop│then│to│true│until│var│while│write 7.<双界符> → <>│<=│>=│:= │/*│*/│.. 8.<标识符> → <字母>│<标识符> <数字>│<标识符> <字母> 9.<常数> → <整数>│<布尔常数>│<字符常数> 10.<整数> → <数字>│<整数> <数字> 11.<布尔常数> → true│false 12.<字符常数> → ' 除 {'} 外的任意字符串 ' 2、词法分析系统流程设计

(完整版)《编译原理》词法分析程序设计方案

实验1-4 《编译原理》S语言词法分析程序设计方案 一、实验目的 了解词法分析程序的两种设计方法:1.根据状态转换图直接编程的方式;2.利用DFA 编写通用的词法分析程序。 二、实验内容 1.根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。在此,词法分析程序作为单独的一遍,如下图所示。 具体任务有: (1)组织源程序的输入 (2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件 (3)删除注释、空格和无用符号 (4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。将错误信息输出到屏幕上。 (5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。 标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址 注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。 常量表结构:常量名,常量值 2.编写DFA模拟程序 算法如下: DFA(S=S0,MOVE[][],F[],ALPHABET[]) /*S为状态,初值为DFA的初态,MOVE[][]为状态转换矩阵,F[] 为终态集,ALPHABET[] 为字母表,其中的字母顺序与MOVE[][] 中列标题的字母顺序一致。*/ { Char Wordbuffer[10]=“”//单词缓冲区置空 Nextchar=getchar();//读 i=0; while(nextchar!=NULL)//NULL代表此类单词 { if (nextcha r!∈ALPHABET[]){ERROR(“非法字符”),return(“非法字符”);} S=MOVE[S][nextchar] //下一状态 if(S=NULL)return(“不接受”);//下一状态为空,不能识别,单词错误 wordbuffer[i]=nextchar ;//保存单词符号 i++; nextchar=getchar(); } Wordbuffer[i]=‘\0’; If(S∈F)return(wordbuffer);//接受 Else return(“不接受”);

相关主题
文本预览
相关文档 最新文档