词法分析程序实现

词法分析程序实现
词法分析程序实现

实验一词法分析程序实现

一、实验目的与要求

通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。

二、实验内容

选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。

输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。

输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。

三、实现方法与环境

1、首先设计识别各类单词的状态转换图。

描述无符号常数的确定、最小化状态转换图如图1所示。其中编号0,1,2, (6)

表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。

图1 文法G[<无符号数>]的状态转换图

其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。

在一个程序设计语言中,一般都含有若干类单词符号,为此可首先为每类单词建立一张状态转换图,然后将这些状态转换图合并成一张统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。

四则运算算术符号的识别很简单,直接在状态图的0状态分别引出相应标记的矢线至一个新的终态即可。根据自己的习惯,也可以将其转换为状态矩阵形式。

2、词法分析程序编写

根据描述语言中各类单词的文法状态转换图或状态矩阵,利用某种语言(C语言或JAVA 语言)直接编写词法分析程序。

3、词法分析程序测试

用于测试扫描器的实例源文件中应有词法正确的,也应有错误的字符串,对于输入的测试用例的源程序文件,以对照的形式将扫描器的分析结果信息在输出文件中表示出来。

四、源程序

#include

using namespace std; //使用标准命名空间

#define M 101 //定义可输入的字符个数

#define UNSIGNEDNUMBER 1 //无符号数

#define PLUS 2 //加号

#define SUBTRACT 3 //减号

#define MULTIPLY 4 //乘号

#define DIVIDE 5 //除号

#define LEFTBRACKET 6 //左括号

#define RIGHTBRACKET 7 //右括号

#define INEFFICACIOUSLABEL 8 //无效字符串

char pause;

class AccidenceAnalysis //定义词法分析类

{

private:

char testStr[M],*p; //私有数据

public:

AccidenceAnalysis(); //构造函数

~AccidenceAnalysis(); //析构函数

void InputStr(); //输入函数

void Output(int a,char *p1,char *p2); //输出函数

int IsAcceptantCharacter(char *p); //判断输入字符是否属于字符集

int IsOperator(char *p); //判断字符是否是字符集[+,-,*,/,(,)]中的字符

int IsUnsignedNum(char *p); //判断字符是否是0--9的整数

void AbnormityExamine(char a[]); //异常检测函数

void IdentifyOperator(char *p); //识别字符集[+,-,*,/,(,)]中的字符

void AssortIdentify(); //对输入字符分类识别

void static StartAccidenceAnalysis(); //开始分析函数

void static StartSystem();

};

AccidenceAnalysis::AccidenceAnalysis()//构造函数

{

int i;

for(i=0;i

testStr[i]='\0';

p=&testStr[0]; //指针P指向字符数组首元素

}

AccidenceAnalysis::~AccidenceAnalysis()//析构函数

{

}

void AccidenceAnalysis::InputStr()//输入函数

{

cout<<"\t输入待分析单词["<

char ch;

int i=0;

while((ch=cin.get())!='\n')

{

testStr[i]=ch;

i++;

}

}

void AccidenceAnalysis::Output(int a,char *p1,char *p2)//输出函数

{

cout<<"\t类别码:"<

while(p1<=p2)

{

cout<<*p1;

p1++;

}

cout<

}

int AccidenceAnalysis::IsOperator(char *p)//判断字符是否是字符集[+,-,*,/,(,)]中的字

{

char ch=*p;

if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')')

return 1;

else

return 0;

}

int AccidenceAnalysis::IsUnsignedNum(char *p)//是否是1——9的数字

{

char ch=*p;

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

return 1;

else

return 0;

}

int AccidenceAnalysis::IsAcceptantCharacter(char *p)//判断字符是否是字符集中的字

{

char ch=*p;

if(IsOperator(p)||IsUnsignedNum(p)||ch=='E'||ch=='.')

return 1;

else return 0;

}

void AccidenceAnalysis::IdentifyOperator(char *p)//对字符[+,-,*,/,(,)]分类识别

{

char ch=*p;

switch(ch)

{

case '+':

Output(PLUS,p,p);break;

case '-':

Output(SUBTRACT,p,p);break;

case '*':

Output(MULTIPLY,p,p);break;

case '/':

Output(DIVIDE,p,p);break;

case '(':

Output(LEFTBRACKET,p,p);break;

case ')':

Output(RIGHTBRACKET,p,p);break;

default:

break;

}

}

void AccidenceAnalysis::AssortIdentify()//对字符分类识别

{

cout<<"\t单词分析结果显示:\n"<

while(*p!='\0')

{

if(IsOperator(p))

{

IdentifyOperator(p++);

continue;

}

else if(IsUnsignedNum(p)||*p=='.')

{

char *p1=p;

if(IsUnsignedNum(p))

{

while(IsUnsignedNum(p))

p++;

if(*p=='\0')

{

Output(UNSIGNEDNUMBER,p1,--p);

p++;

continue;

}

else if(*p=='E')

{

p++;

if(IsUnsignedNum(p))

{

while(IsUnsignedNum(p))

p++;

Output(UNSIGNEDNUMBER,p1,--p);

p++;

continue;

}

else if(*p=='+'||*p=='-')

{

p++;

while(IsUnsignedNum(p))

p++;

Output(UNSIGNEDNUMBER,p1,--p);

p++;

continue;

}

else

{

Output(INEFFICACIOUSLABEL,p1,--p);

p++;

continue;

}

}

else if(*p=='.')

{

p++;

while(IsUnsignedNum(p))

p++;

if(*p=='\0')

{

Output(UNSIGNEDNUMBER,p1,--p);

p++;

continue;

else if(*p=='E')

{

p++;

if(IsUnsignedNum(p))

{

while(IsUnsignedNum(p))

p++;

Output(UNSIGNEDNUMBER,p1,--p);

p++;

continue;

}

else if(*p=='+'||*p=='-')

{

p++;

if(IsUnsignedNum(p))

{

while(IsUnsignedNum(p))

p++;

Output(UNSIGNEDNUMBER,p1,--p);

p++;

continue;

}

else

{

Output(INEFFICACIOUSLABEL,p1,--p);

p++;

continue;

}

}

else

{

Output(INEFFICACIOUSLABEL,p1,--p);

p++;

continue;

}

}

else

{

Output(UNSIGNEDNUMBER,p1,--p);

p++;

continue;

}

}

{

Output(UNSIGNEDNUMBER,p1,--p);

p++;

continue;

}

}

if(*p=='.')

{

p++;

if(IsUnsignedNum(p))

{

p++;

while(IsUnsignedNum(p))

p++;

if(*p=='\0')

{

Output(UNSIGNEDNUMBER,p1,--p);

p++;

continue;

}

else if(*p=='E')

{

p++;

if(IsUnsignedNum(p))

{

while(IsUnsignedNum(p))

p++;

Output(UNSIGNEDNUMBER,p1,--p);

p++;

continue;

}

else if(*p=='+'||*p=='-')

{

p++;

while(IsUnsignedNum(p))

p++;

Output(UNSIGNEDNUMBER,p1,--p);

p++;

continue;

}

}

else

{

Output(UNSIGNEDNUMBER,p1,--p);

p++;

continue;

}

}

else

{

Output(INEFFICACIOUSLABEL,p1,--p);

p++;

continue;

}

}

}

else if(*p=='E')

{

Output(INEFFICACIOUSLABEL,p,p);

p++;

continue;

}

}

}

void AccidenceAnalysis::StartAccidenceAnalysis()//开始分析函数

{

AccidenceAnalysis accidenceanalysis;

accidenceanalysis.InputStr();

accidenceanalysis.AssortIdentify();

}

int main()

{

AccidenceAnalysis::StartAccidenceAnalysis();

return 0;

}

五、实验感想

通过此次实验,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,根据识别语言单词的状态转换图,使用某种高级语言直接编写此法分析程序。另外,也让我重新熟悉了C++语言的相关内容,加深了对C++语言的用途的理解。

实验二语法分析程序实现

一、实验目的与要求

通过设计、编制、调试典型的SLR(1)语法分析程序,实现对实验一所得词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。

二、实验内容

选择对各种常见高级程序设计语言都较为通用的语法结构无符号数的算术四则运算作为分析对象,给出其文法描述(注意应与所采用的语法分析方法比较贴近),设计并实现一个完整的语法分析程序。

输入:由实验一输出的单词类别串,如1,3,1。

输出:对于所输入的源程序,如果输入符号串是给定文法定义的合法句子,则输出“RIGHT”,并且给出每一步归约的过程;如果不是句子,即输入串有错误,则输出“ERROR”,并且显示已经归约出的各个文法符号,以及必要的出错说明信息。

三、实现方法与环境

1、首先根据算术四则运算的语法定义,构造SLR(1)分析表。

无符号数的算术四则运算的语法可表示为:

E->E+T| E-T|T

T->T*F| T/F|F

F->(E)|i

2、语法分析程序编写

设置输入缓冲区、状态栈、符号栈,并根据SLR(1)分析表利用某种语言(C语言或JAVA语言)直接编写移进、归约、接受子程序,编写语法分析程序。

3、语法分析程序测试

用于测试的实例源文件中应有语法正确的,也应有语法错误的符号串,以对照的形式将分析结果信息在输出文件中表示出来。

四、实验程序

#include

#include

#include

#include

using namespace std ;

struct code_val

{

char code;

};

const char *p[]=

{ //产生式

"E'→E","E→E+T","E→E-T","E→T","T→T*F","T→T/F","T→F","F→(E)","F→i" };

const char TNT[ ]="+-*/()i#ETF"; //LR分析表列的字符

const int M[ ][11]={

{0,0,0,0,5,0,4,0,1,2,3},

{7,6,0,0,0,0,0,17},

{-3,-3,10,12,0,-3,0,-3},

{-6,-6,-6,-6,0,-6,0,-6},

{-8,-8,-8,-8,0,-8,0,-8},

{0,0,0,0,5,0,4,0,14,2,3},

{0,0,0,0,5,0,4,0,0,8,3},

{0,0,0,0,5,0,4,0,0,9,3},

{-2,-2,10,12,0,-2,0,-2},

{-1,-1,10,12,0,-1,0,-1},

{0,0,0,0,0,0,4,0,0,0,11},

{-4,-4,-4,-4,0,-4,0,-4},

{0,0,0,0,0,0,0,4,0,0,13},

{-5,-5,-5,-5,0,-5,0,-5},

{7,6,0,0,0,15,0,0},

{-7,-7,-7,-7,0,-7,0,-7}

};

int col(char); //列定位函数原型

void main()

{

int state[50]={0}; //状态栈初值

int top=0; //栈顶指针初值

ifstream cin("E:\lex_r.txt");

struct code_val t; //结构变量,存放单词。

cin>>t.code;

do{ //读一单词

int action;

action=M[state[top]][col(t.code)];

if(action>0 && action!=17)

{ //移进

state[++top]=action;

cin>>t.code;

}

else if(action < 0)

{ //归约

top=top-(strlen(p[-action])-3); //"→"为汉字,占 2字节故减3

state[top+1]=M[state[top]][col(p[-action][0])]; //产生式左部符号 top=top+1;

}

else if(action==17)

{

cout<<"Acc";break;}

else{cout<<"err";break;

}

}while(1);

}

int col(char c) //将字符+* ()i#ETF分别转换为数字012345678

{

for(int i=0;i<(int)strlen(TNT);i++)

if(c==TNT[i])return i;

cout<<"Err in col char>"<

exit(0); //终止程序运行

}

四、实验感想

SLR(1)文法有效地消除了规约和移进之间的冲突,在程序中设了两个堆栈,一个状态栈,一个符号栈。根据LR分析表构造了一个ACTION和GOTO矩阵,再用循环的方式把堆栈中的内容显示出来。

实验三语义分析程序实现

一、实验目的与要求

通过设计、编制、调试一个简单的语义处理分析程序,实现对实验一和实验二所得单词和语句的语义信息简单处里,进一步掌握语义处理的内容和简单方法。

二、实验内容

对实验一进行扩展,对识别的无符号数进行计值,并将输出形式改为(类别码,值)的二元式形式。

对实验二进行扩展,在语法分析的基础上,增加语义操作来实现语法制导翻译。对于给定文法中的每一产生式,编写相应的语义子程序。在语法分析过程中,每当用一产生式进行推导或归约时,语法分析程序除执行相应的语法分析动作之外,还要调用相应的语义子程序,计算并输出算术表达式的值。

将实验一与实验二的程序合并,以能对完整的输入源文件进行词法分析生成中间文件,然后进行语法制导翻译,输出最终翻译结果。

输入:由无符号数和+,—,*,/, ( , ) 构成的算术表达式。

输出:如果输入单词串是合法的无符号数的算术四则运算,输出运算结果,并且给出每一步的分析过程;如果不是无符号数的算术四则运算,输出“非法四则运算表达式”。

三、基本实验题目

对实验一中每个无符号数识别状态插入计值处理,最终获得无符号数的取值。

对实验二进行扩展,在归约(分析表中的归约动作已经反应了运算优先级)处理子程序中加入计值处理,接受子程序中加入输出算数表达式值的处理。

四、实验程序

#include

#include

#include

#include

using namespace std;

#define EndState -1

char ACTION[16][8]=

{

{'s','e','e','e','e','s','e','e'},{'e','s','s','e','e','e','e','a'},{'e','r

','r','s','s','e','r','r'},

{'e','r','r','r','r','e','r','r'},{'s','e','e','e','e','s','e','e'},{'e','r ','r','r','r','e','r','r'},

{'s','e','e','e','e','s','e','e'},{'s','e','e','e','e','s','e','e'},{'s','e ','e','e','e','s','e','e'},

{'s','e','e','e','e','s','e','e'},{'e','s','s','e','e','e','s','e'},{'e','r ','r','s','s','e','r','r'},

{'e','r','r','s','s','e','r','r'},{'e','r','r','r','r','e','r','r'},{'e','r ','r','r','r','e','r','r'},

{'e','r','r','r','r','e','r','r'}

};

int GOTO[16][11]=

{

{5,0,0,0,0,4,0,0,1,2,3},{0,6,7,0,0,0,0,0,0,0,0},{0,2,2,8,9,0,2,2,0,0,0}, {0,5,5,5,5,0,5,5,0,0,0},{5,0,0,0,0,4,0,0,10,2,3},{0,8,8,8,8,0,8,8,0,0,0}, {5,0,0,0,0,4,0,0,0,11,3},{5,0,0,0,0,4,0,0,0,12,3},{5,0,0,0,0,4,0,0,0,0,13}, {5,0,0,0,0,4,0,0,0,0,14},{0,6,7,0,0,0,15,0,0,0,0},{0,1,1,8,9,0,1,1,0,0,0}, {0,3,3,8,9,0,3,3,0,0,0},{0,4,4,4,4,0,4,4,0,0,0},{0,6,6,6,6,0,6,6,0,0,0}, {0,7,7,7,7,0,7,7,0,0,0,}

};

int Stimulation[16][8]=

{

{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,2,2,0,0,0,2,2},{0,5,5,5,5,0,5,5}, {0,0,0,0,0,0,0,0},{0,8,8,8,8,0,8,8},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,1,1,0,0,0,1,1}, {0,3,3,0,0,0,3,3},{0,4,4,4,4,0,4,4},{0,6,6,6,6,0,6,6},{0,7,7,7,7,0,7,7} };

class AccidenceAnnalysis

{

private:

char temp[20];

char *ptr;

int Class;

int CurrentState;

char test[20];

float FCON;

int w;

int n;

int p;

int e;

int d;

public:

int EXCUTE(int,char);

void Push_temp(char);

编译原理课程设计-词法语法分析器

编译原理课程设计Course Design of Compiling (课程代码3273526) 半期题目:词法和语法分析器 实验学期:大三第二学期 学生班级:2014级软件四班 学生学号:2014112218 学生姓名:何华均 任课教师:丁光耀 信息科学与技术学院 2017.6

课程设计1-C语言词法分析器 1.题目 C语言词法分析 2.内容 选一个能正常运行的c语言程序,以该程序出现的字符作为单词符号集,不用处理c语言的所有单词符号。 将解析到的单词符号对应的二元组输出到文件中保存 可以将扫描缓冲区与输入缓冲区合成一个缓冲区,一次性输入源程序后就可以进行预处理了 3.设计目的 掌握词法分析算法,设计、编制并调试一个词法分析程序,加深对词法分析原理的理解 4.设计环境(电脑语言环境) 语言环境:C语言 CPU:i7HQ6700 内存:8G 5.概要设计(单词符号表,状态转换图) 5.1词法分析器的结构 词法分析程序的功能:

输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 词法分析程序可以单独为一个程序;也可以作为整个编译程序的一个子程序,当需要一个单词时,就调用此法分析子程序返回一个单词. 为便于程序实现,假设每个单词间都有界符或运算符或空格隔开,并引入下面的全局变量及子程序: 1) ch 存放最新读进的源程序字符 2) strToken 存放构成单词符号的字符串 3) Buffer 字符缓冲区 4)struct keyType 存放保留字的符号和种别 5.2待分析的简单词法 (1)保留字 break、case、char、const、int、do、while… (2)运算符和界符 = 、+、-、* 、/、%、,、;、(、)、?、# 5.3各种单词符号对应的种别码

词法分析程序设计与实现

实验一词法分析程序设计与实现 一、实验目的及内容 调试并完成一个词法分析程序,加深对词法分析原理的理解。 二、实验原理(状态转换图) 1、C语言子集 (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为整型常数。 二、软件平台及工具 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++];

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

编译原理实验报告实验名称:实验一编写词法分析程序 实验类型:验证型实验 指导教师:何中胜 专业班级: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.实践部分

词法分析程序设计与实现

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

` 3、词法分析程序的功能 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 二、软件平台及工具 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]={egin,if,hen,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')) 文档Word ` {

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

编译技术 班级网络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:源程序文件结束而注释未结束。注释格式为:/* …… */ 四、保留字和特殊符号表

编译原理词法分析和语法分析报告 代码(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请注意,第"<

TEST语言 -语法分析,词法分析实验报告

编译原理实验报告 实验名称:分析调试语义分析程序 TEST抽象机模拟器完整程序 保证能用!!!!! 一、实验目的 通过分析调试TEST语言的语义分析和中间代码生成程序,加深对语法制导翻译思想的理解,掌握将语法分析所识别的语法范畴变换为中间代码的语义翻译方法。 二、实验设计 程序流程图

extern int TESTScan(FILE *fin,FILE *fout); FILE *fin,*fout; //用于指定输入输出文件的指针 int main() { char szFinName[300]; char szFoutName[300]; printf("请输入源程序文件名(包括路径):"); scanf("%s",szFinName); printf("请输入词法分析输出文件名(包括路径):"); scanf("%s",szFoutName); if( (fin = fopen(szFinName,"r")) == NULL) { printf("\n打开词法分析输入文件出错!\n"); return 0; } if( (fout = fopen(szFoutName,"w")) == NULL) { printf("\n创建词法分析输出文件出错!\n"); return 0; } int es = TESTScan(fin,fout); fclose(fin); fclose(fout); if(es > 0) printf("词法分析有错,编译停止!共有%d个错误!\n",es); else if(es == 0) { printf("词法分析成功!\n"); int es = 0;

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

编译原理词法分析程序设计实验报告 【实验目的】 1.了解词法分析的主要任务。 2.熟悉编译程序的编制。 【实验容】 根据某文法,构造一基本词法分析程序。找出该语言的关键字、标识符、整数以及其他一些特殊符号,给出单词的种类和值。 【实验要求】 1.构造一个小语言的文法 类C小语言文法(以EBNF表示) <程序>::=<分程序>{<分程序>} . <分程序>::=<标识符>’(’<变量说明部分>{,<变量说明部分>}’)’<函数体> <变量说明部分>::=int<标识符>{,<标识符>} <函数体>::=’{’[<变量说明部分>;]<语句序列>’}’ <语句序列>::=<语句序列>;<语句>|<语句> <语句>::=<赋值语句>|<条件语句>|<循环语句>|<函数调用语句> <赋值语句>::=<标识符>=<表达式> <表达式>::=[+|-]<项>{<加法运算符><项>} <项>::=<因子>{<乘法运算符><因子>} <因子>:=<标识符>|<无符号整数> <加法运算符>::= +|- <乘法运算符>::= *|/ <条件语句>::=if<条件>’{’<语句序列>’}’[else’{’<语句序列>’}’] <条件>::=<表达式><关系运算符><表达式> <关系运算符>::= ==|!=|>|<|>=|<= <循环语句>::=for’(’<表达式>;<条件>;<表达式>’)’ ’{’<语句序列>’}’

<函数调用语句>::=<标识符>’(’<标识符>{,<标识符>}|<空>’)’ <标识符>::=<字母>{<字母>|<数字>} <无符号整数>::=<数字>{<数字>} <字母>::=a|b|c|…|X|Y|Z <数字>::=0|1|2|…|8|9 单词分类情况 关键字:int if else for 标识符:以字母开头的字母和数字的组合 关系运算符: ==|!=|>|<|>=|<= 加法运算符:+|- 乘法运算符: *|/界符:,;{ } ( ) 2.设计单词的输出形式,单词的种类和值的表示方法 种别码单词值 如:1 int 3. 编写词法分析程序cffx.c 实现基本的词法分析器,能够分析关键字、标识符、数字、运算符(需要有“==”或“:=”之类需要超前搜索的运算符)以及其他一些符号。 // 编译原理词法分析程序.cpp #include #include #include typedef struct words { int id; char name[20]; char value[20]; }word; char integer[20]={'i','n','t'}; char iff[20]={'i','f'}; char elsee[20]={'e','l','s','e'}; char forr[20]={'f','o','r'}; int main() { char code[10000];

编译原理课程设计-词法分析器(附含源代码)

编译原理-词法分析器的设计 一.设计说明及设计要求 一般来说,编译程序的整个过程可以划分为五个阶段:词法分析、语法分析、中间代码生成、优化和目标代码生成。本课程设计即为词法分析阶段。词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。如保留字(关键字或基本字)、标志符、常数、算符和界符等等。 二.设计中相关关键字说明 1.基本字:也称关键字,如C语言中的 if , else , while , do ,for,case,break, return 等。 2.标志符:用来表示各种名字,如常量名、变量名和过程名等。 3.常数:各种类型的常数,如12,6.88,和“ABC” 等。 4.运算符:如 + ,- , * , / ,%, < , > ,<= , >= 等。5.界符,如逗点,冒号,分号,括号,# ,〈〈,〉〉等。 三、程序分析 词法分析是编译的第一个阶段,它的主要任务是从左到右逐个字符地对源 程序进行 扫描,产生一个个单词序列,用以语法分析。词法分析工作可以是独立的一遍,把字符流的源程序变为单词序列,输出在一个中间文件上,这个文件做为语法分析程序的输入而继续编译过程。然而,更一般的情况,常将

词法分析程序设计成一个子程序,每当语法分析程序需要一个单词时,则 调用该子程序。词法分析程序每得到一次调用,便从源程序文件中读入一 些字符,直到识别出一个单词,或说直到下一个单词的第一个字符为止。 四、模块设计 下面是程序的流程图 五、程序介绍 在程序当前目录里建立一个文本文档,取名为infile.txt,所有需要分析的程序都写在此文本文档里,程序的结尾必须以“@”标志符结束。程序结果输出在同一个目录下,文件名为outfile.txt,此文件为自动生成。本程序所输出的单词符号采用以下二元式表示:(单词种别,单词自身的值)如程序输出结果(57,"#")(33,"include")(52,"<")(33,"iostream") 等。 程序的功能:(1)能识别C语言中所有关键字(共32个)(单词种别分别为1 — 32 ,详情见程序代码相关部分,下同) (2)能识别C语言中自定义的标示符(单词种别为 33) (3)能识别C语言中的常数(单词种别为0) (4)能识别C语言中几乎所有运算符(单词种别分别为41 — 54) (5)能识别C语言中绝大多数界符(单词种别分别为 55 — 66)六、运行结果 输入文件infile.txt 运行结果(输出文件 outfile.txt)

单词的词法分析程序设计

单词的词法分析程序设计 1实验题目 对于给定的源程序(如C语言或Pascal等),要求从组成源程序的字符行中寻找出单词,并给出它们的种别和属性——输出二元组序列。以便提供给语法分析的时候使用。要求能识别所有的关键字,标志符等,并且能够对出先的一些词法规则的错误进行必要的处理。 2 实验内容和要求 1. 给出语言的词法规则描述 2. 要求识别标识符、关键字、整常数、字符常数、浮点常数等 3. 要求能识别单界符:+,-,÷,×,:等符号 4. 双界符:/*,:=,等 5. 要求完成一些相关的辅助任务。一个任务实滤掉源程序中的注释、空格、制表符、换行符;另一个任务是使编译器能够将发现的错误信息与源程序的出错位置联系起来,以及错误的类型等。 3 待分析的词法文件 文件名称为:C:\1.txt (分析结果见7:程序结果) 4实验分析与设计过程 实验分析与设计过程 1. 实验说明 分析语言的选择:由于对C语言比较熟悉,我选择分析的程序为C语言编写的程序。 2. 词法分析器的功能以及输出形式分析 1) 功能: i. 对于输入的C源程序,输出单词符号,把相应的源程序的字符串转 换成单词符号的序列。 ii. 保存符号表,为所有的标识符建立一个符号表,以便于在语法和语义分析的时候使用。 iii. 错误输出与提示

2) 结果输出形式: i. 对于token用二元组输出, ii. 符号表可以单独输出到文件中 iii. 错误输出到界面即可 3. 单词符号的表示 各种关键字(保留字、基本字),各种运算符、各种分界符,都用一个种别码来标识。例:关键字break、保留字asm、运算符”+”、在源程序中1,2,3表示。即所规定得到的中别码对应的词法描述为: 1为关键字2为标志符 3为常数4为运算符或界符 5 算法描述 由于这是一个用高级语言编写一个词法分析器,使之能识别输入串,并把分析结果(单词符号,标识符,关键字等等)输出.输入源程序,输入单词符号,本词法分析器可以辨别关键字,标识符,常数,运算符号和某些界符,运用了文件读入来获取源程序代码,再对该源程序代码进行词法分析,这就是词法分析器的基本功能.当词法分析器调用预处理子程序处理出一串输入字符放进扫描缓冲区之后,分析器就从此缓冲区中逐一识别单词符号.当缓冲区里的字符串被处理完之后,它又调用预处理子程序来处理新串. 编写的时候,使用了文件的输入和输出,以便于词法分析的通用型,同时在文件输出时,并保存在输出文件output文件中。 从左到右扫描程序,通过初始化:1为关键字;2为标志符; 3为常数;4为运算符或界符。 扫描过程如下: 1.指针扫描所打开的文件首,如果是字母开始处理字符关键字或者标识符2.为单字符运算、限界符,写入输出文件并将扫描文件指针回退一个字符; 3.为双字符运算、限界符,写输出文件; 4.读入的下一个字符为文件结束符; 5.只考虑是否为单字符运算、限界符,若是,写输出文件

编译器的词法分析器

一.实验目的 ●了解编译器的词法分析器的作用。其作用是源程序转化为便于编译程序其余部分进行处 理的内部格式。 ●了解词法分析器的任务。识别出源程序中的各个基本语法单位;删除无用的空白字符, 回车以及其他与输入介质相关的非实质性的字符,以及注释等。 一.实验说明 ●词法分析程序:词法分析程序完成的是编译第一阶段的工作。词法分析工作可以是独立 的一遍,把字符流的源程序变为单词序列,输出在一个中间文件上,这个文件做为语法分析程序的输入而继续编译过程。然而,更一般的情况,是将词法分析程序设计成一个子程序,每当语法分析程序需要一个单词时,则调用该子程序。词法分析程序每得到一次调用,便从源程序文件中读入一些字符,直到识别出一个单词,或说直到下一单词的第一个字符为止。 ●词法分析程序的主要功能是从字符流的源程序中识别单词,它要从左至右逐个字符地扫 描源程序,因此它还可完成其它一些任务。比如,滤掉源程序中的注释和空白(由空格,制表或回车换行字符引起的空白);又比如,为了使编译程序能将发现的错误信息与源程序的出错位置联系起来,词法分析程序负责记录新读入的字符行的行号,以便行号与出错信息相联;再有,在支持宏处理功能的源语言中,可以由词法分析程序完成其预处理等等。 ●以下是五种单词符号: - 保留字,关键字 - 标识符 - 常数(量) - 运算符 - 界符 ●词法分析程序所输出的单词符号常常采用以下二元式表示:(单词种别,单词自身的值)。 单词的种别是语法分析需要的信息,而单词自身的值则是编译其它阶段需要的信息。比如在PASCAL的语句const i=25, yes=1;中的单词25和1的种别都是常数,常数的值25和1对于代码生成来说,是必不可少的。有时,对某些单词来说,不仅仅需要它的值,还需要其它一些信息以便编译的进行。比如,对于标识符来说,还需要记载它的类别、层次还有其它属性,如果这些属性统统收集在符号表中,那么可以将单词的二元式表示设计成如下形式(标识符,指向该标识符所在符号表中位置的指针),如上述语句中

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

编译原理词法分析和语法分析报告+代码(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 词法分析程序的设计与开发

编译原理实验报告 一、实验目的 ? 深入理解有限自动机及其应用 ? 掌握词法分析程序的开发。 ? 掌握根据语言的词法规则构造识别其单词的有限自动机的方法 ? 深入理解词法分析程序自动生成原理 二、实验要求 ? 掌握各类单词的形式描述 ?用直接转向法实现有限自动机的代码编写。 ? 独立完成PL0语言的词法分析器。 ? 掌握词法分析程序自动生成工具LEX 的使用。 三、实验原理 词法分析是编译过程的第一阶段。它的任务就是对输入的字符串形式的源程序按顺序进行扫描,根据源程序的词法规则识别具有独立意义的单词(符号),并输出与其等价的Token 序列。 有限自动机是描述程序设计语言单词构成的工具,而状态转换图是有限自动机的比较直观的描述方法。我们使用确定的有限状态自动机,简记为DFA 。 PL/0的语言的词法分析器将要完成以下工作: (1) 跳过分隔符(如空格,回车,制表符); (2) 识别诸如begin ,end ,if ,while 等保留字; (3) 识别非保留字的一般标识符,此标识符值(字符序列)赋给全局量id ,而全局量sym 赋值为SYM_IDENTIFIER 。 (4) 识别数字序列,当前值赋给全局量NUM ,sym 则置为SYM_NUMBER ; (5) 识别:=,<=,>=之类的特殊符号,全局量sym 则分别被赋值为SYM_BECOMES ,SYM_LEQ ,SYM_GEQ 等。 课程名称: 编译原理 班级: 计算1614 实验成绩: 指导教师: 付永钢 姓名: 施心萍 实验项目名称: 实验一 词法分析程序设计与开发 学号: 201621121097 上机实践日期:

词法分析程序的设计与实现

实验一词法分析程序的设计与实现 一、实验内容 【实验目的和要求】 设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解。 【实验内容】 通过对PL/0词法分析程序(GETSYM)的分析,并在此基础上按照附录A中给出的PL/0语言的语法描述,编写一个PL/0语言的词法分析程序。此程序应具有如下功能:输入为字符串(待进行词法分析的源程序),输出为单词串,即由(单词、类别)所组成的二元组序列。 有一定检查错误的能力,例如发现2A这类不能作为单词的字符串。 【实验环境】 Windows PC机,任何语言。 【提交内容】 提交实验报告,报告内容如下: 目的要求、算法描述、程序结构、主要变量名说明、程序清单、调试情况、设计技巧、心得体会。 提交源程序和可执行文件。 【学时】 4课时。 二、实验说明 词法分析程序的任务就是扫描源程序,依据词法规则识别单词并报告构词错误信息。通常将单词分为5种类型。

1)基本字:也叫关键字、保留字,是程序设计语言用来表示特定语法含义的一种标识符,如if、begin等。 2)运算符:如+、-、*、/、:=、>、<等。 3)标识符:用户定义的变量名、常数名、函数名等。不同的高级程序设计语言对关键字是否可以作为普通标识符有不同的要求,有的语言允许程序员使用关键字作为普通标识符,有的程序设计语言则不允许程序员将关键字用着普通标识符(如C/C++、Pascal等都不允许)。在允许程序员将关键字用作普通标识符的程序设计语言的编译器中,编译器必须具备能够区分一个标识符到底是关键字还是普通标识符的功能。 4)常数:如23、6等。 5)界符:如“,”、“;”、“(”、“)”、“.”等。 注意事项 ●空格的作用仅仅是将一个个单词分割开来,源程序中的空格不具备别的语法意义,在语法分析及其后续阶段都没有任何作用,因此,词法分析的另一个工作是过滤空格。 ●注释对整个源程序的编译也没有任何语法意义,只是为了便于阅读和交流,因此,有的编译程序的词法分析程序也负责过滤注释。 ●输出的单词符号采用[单词类别,单词自身值]的二元组形式来表示。 ●为了使扫描程序尽可能的高效,在进行词法分析程序的设计和实现时还需十分注意扫描程序结构的实际细节问题。 ●用于间隔单词的空格和我们通常所说的键盘上的空格是不同的,这里的空格指的是所有能引起一个单词结束的字符,它们包括空格、制表或回车换行符。 ●a*(b+c)这样的没有空格间隔的情况时要正确地识别出所有的单词 ●123ab这样的字符串时,一般字符串的首字符必须为字母,不要将123识别为数字,将ab识别为标识符 转换图说明

PL0语言词法分析程序

PL/0语言词法分析程序 //这是我编译原理的一次作业,中间有许多不足之处希望大家指正 /*编写PL/0语言的词法分析程序 要求: 1、读入用PL/0语言编写的源程序,正确的进行词法分析,并输出二元式序列。 2、若源程序有词法错误,能够给出出错的准确位置。 3、词法代号如下 (+,+); (-,-); (*,*); (/,/); ((,(); (),)); (,,,); (;,;); (.,.); (#,#); (=,=); (>,>); (<,<); (:=,a); (>=,b); (<=,c); (数字,d); (标识符,e); 关键字代号: (begin,f);

(call,g); (const,h); (do,i); (end,j); (if,k); (odd,l); (procedure,m); (read,n); (then,o); (var,p); (while,q); (write,r); 4、等于运算符号为一个 = 测试程序: A.C ====================== CONST A=10; VAR B,C; PROCEDURE P; VAR D; PROCEDURE Q; VAR X; BEGIN READ(X); D:=X; WHILE X DO CALL P; END; BEGIN WRITE(D);

CALL Q; END; BEGIN CALL P; END. */ /*program name:chifufenxi*/ /*作者:小万 QQ:421404493*/ /*date:2004.10.11*/ #include #include #include #include #include #define N 256//每一行的字符数不能超过256个 char buffer[N]; //用作存放一行字符 char word[20]; //用作存放经过分析单词 char *kword[13]={"begin","call","const","do","end","if","odd","procedure","read","the n","var","while","write"}; char ktype[13]={'f','g','h','i','j','k','l','m','n','o','p','q','r'}; int len;//记录每一行的长度 int count=0;//用来记录行数 void write(char *wstr,char wc,FILE *wout)//将分析结果按照规则写入到文件 { fputc('(',wout); fputs(wstr,wout); fputc(',',wout);

编译原理课程设计报告C语言词法与语法分析器的实现

编译原理课程设计报告 课题名称:编译原理课程设计 C-语言词法与语法分析器的实现

C-词法与语法分析器的实现 1.课程设计目标 (1)题目实用性 C-语言拥有一个完整语言的基本属性,通过编写C-语言的词法分析和语法分析,对于理解编译原理的相关理论和知识有很大的作用。通过编写C-语言词法和语法分析程序,能够对编译原理的相关知识:正则表达式、有限自动机、语法分析等有一个比较清晰的了解和掌握。(2)C-语言的词法说明 ①语言的关键字: else if int return void while 所有的关键字都是保留字,并且必须是小写。 ②专用符号: + - * / < <= > >= == != = ; , ( ) [ ] { } /* */ ③其他标记是ID和NUM,通过下列正则表达式定义: ID = letter letter* NUM = digit digit* letter = a|..|z|A|..|Z digit = 0|..|9 注:ID表示标识符,NUM表示数字,letter表示一个字母,digit表示一个数字。 小写和大写字母是有区别的。 ④空格由空白、换行符和制表符组成。空格通常被忽略。 ⑤注释用通常的c语言符号/ * . . . * /围起来。注释可以放在任何空白出现的位置(即注释不能放在标记)上,且可以超过一行。注释不能嵌套。

(3)程序设计目标 能够对一个程序正确的进行词法及语法分析。 2.分析与设计 (1)设计思想 a.词法分析 词法分析的实现主要利用有穷自动机理论。有穷自动机可用作描述在输入串中识别模式的过程,因此也能用作构造扫描程序。通过有穷自动机理论能够容易的设计出词法分析器。b.语法分析 语法分析采用递归下降分析。递归下降法是语法分析中最易懂的一种方法。它的主要原理是,对每个非终结符按其产生式结构构造相应语法分析子程序,其中终结符产生匹配命令,而非终结符则产生过程调用命令。因为文法递归相应子程序也递归,所以称这种方法为递归子程序下降法或递归下降法。其中子程序的结构与产生式结构几乎是一致的。 (2)程序流程图 程序主流程图: 词法分析: 语法分析:

编译原理实验 词法分析&语法分析程序

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

实验一:词法分析程序 1、实验目的 从左至右逐个字符的对源程序进行扫描,产生一个个单词符号,把字符串形式的源程序改造成单词符号形式的中间程序。 2、实验内容 表C语言子集的单词符号及内码值 单词符号种别编码助记符内码值 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 LQ = 12 = -- ; 13 ; -- 输入源程序如下 if a==1 a=a+1; else a=a+2; 输出对应的单词符号形式的中间程序 3、实验过程 实验上机程序如下: #include "stdio.h" #include "string.h" int i,j,k; char s ,a[20],token[20]; int letter() { if((s>=97)&&(s<=122))return 1; else return 0; } int Digit() {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() { 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 you source program,end('#'):\n"); i=0; do { i=i+1; scanf("%c",&a[i]); }while(a[i]!='#'); i=1; memset(token,0,sizeof(char)*10); j=0; get(); while(s!='#') { if(s==' '||s==10||s==13) get(); else { switch(s)

词法分析设计实验报告(附代码)

实验一词法分析设计 实验学时:4 实验类型:综合 实验要求:必修 一、实验目的 通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。 二、实验内容 用VC++/VB/JAVA语言实现对C语言子集的源程序进行词法分析。通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。 以下是实现词法分析设计的主要工作: (1)从源程序文件中读入字符。 (2)统计行数和列数用于错误单词的定位。 (3)删除空格类字符,包括回车、制表符空格。 (4)按拼写单词,并用(内码,属性)二元式表示。(属性值——token的机内表示) (5)如果发现错误则报告出错 (6)根据需要是否填写标识符表供以后各阶段使用。 单词的基本分类: 关键字:由程序语言定义的具有固定意义的标识符。也称为保留字例如if、 for、while、printf ;单词种别码为1。 标识符:用以表示各种名字,如变量名、数组名、函数名; 常数:任何数值常数。如 125, 1,,; 运算符:+、-、*、/; 关系运算符: <、<=、= 、>、>=、<>; 分界符:;、,、(、)、[、]; 三、实验要求 1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。 2、将标识符填写的相应符号表须提供给编译程序的以后各阶段使用。 3、根据测试数据进行测试。测试实例应包括以下三个部分: 全部合法的输入。 各种组合的非法输入。

相关文档
最新文档