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

编译原理实验词法分析语法分析

编译原理实验词法分析语法分析
编译原理实验词法分析语法分析

本代码只供学习参考:

词法分析源代码:

#include

#include

#include

using namespace std;

string key[8]={"do","end","for","if","printf","scanf","then","while"}; string optr[4]={"+","-","*","/"};

string separator[6]={",",";","{","}","(",")"};

char ch;

//判断是否为保留字

bool IsKey(string ss) {

int i;

for(i=0;i<8;i++)

if(!strcmp(key[i].c_str(),ss.c_str()))

return true;

return false;

}

//字母判断函数

bool IsLetter(char c) {

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

return true;

return false;

}

//数字判断函数

bool IsDigit(char c) {

if(c>='0'&&c<='9')

return true;

return false;

}

//运算符判断函数

bool IsOptr(string ss) {

int i;

for(i=0;i<4;i++)

if(!strcmp(optr[i].c_str(),ss.c_str()))

return true ;

return false;

}

//分界符判断函数

bool IsSeparator(string ss) {

int i;

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

if(!strcmp(separator[i].c_str(),ss.c_str()))

return true;

return false;

}

void analyse(ifstream &in) {

string st="";

char ch;

int line=1,row=0;

while((in.get(ch))) {

st="";

if((ch==' ')||(ch=='\t')){} //空格,tab健

else

if(ch=='\n') {line++;row=0; } //换行行数加一处理

else

if(IsLetter(ch)) //关键字、标识符的处理

{

row++;

while(IsLetter(ch)||IsDigit(ch))

{

st+=ch;

in.get(ch);

}

in.seekg(-1,ios::cur);//文件指针(光标)后退一个字节

if(IsKey(st)) //判断是否为关键字查询关键字表;

cout<

else //否则为标示符

cout<

}

else

if(IsDigit(ch)) //无符号整数处理

{

row++;

while(IsDigit(ch))

{st+=ch;

ch=in.get();

}

in.seekg(-1,ios::cur);

cout<

// break;

}

else

{st="";

st+=ch;

if(IsOptr(st)) //运算符处理

{

row++;

cout<

}

else

if(IsSeparator(st))//分隔符处理

{ row++;

cout<

}

else{

switch(ch){row++;

case'=' : {row++;cout<<"="<<"\t("<<"="<<","<<"6"<<")"<<'\t'<<"\t关系运算符"<<'\t'<<"("<

case'>' :{row++;ch=in.get();

if(ch=='=')

cout<<">="<<'\t'<<"("<<">="<<","<<"6"<<")"<<'\t'<<"\t关系运算符"<<'\t'<<"("<

else {cout<<">"<<"\t("<<">"<<","<<"6"<<")"<<'\t'<<"\t关系运算符"<<'\t'<<"("<

in.seekg(-1,ios::cur);}

} break;

case'<' :{row++;ch=in.get();

if(ch=='=')cout<<"<="<<'\t'<<"("<<"="<<","<<"6"<<")"<<"\t关系运算符"<<'\t'<<"("<

else if(ch=='>') cout<<"<>"<<'\t'<<"("<<"<>"<<","<<"6"<<")"<<'\t'<<"\t关系运算符"<<'\t'<<"("<

else{cout<<"<"<<"\t("<<"<"<<","<<"6"<<")"<<"\t"<<"\t关系运算符"<<'\t'<<"("<

in.seekg(-1,ios::cur);}

}break;

default :{row++; cout<

"<<'\t'<<"("<

}

}}

}

}

int main()

{

ifstream in;

in.open("test.txt",ios::in);

cout<<"关键字-》1 标识符-》2 常数-》3 运算符-》4 分隔符-》5"<

if(in.is_open())

{

analyse(in);

in.close();

system("pause");

}

else

cout<<"文件操作出错"<

}

语法分析实验源代码LL

#include

using namespace std;

const int MaxLen=20; //初始化栈的长度

const int Length=20;//初始化数组长度

char Vn[5]={'E','G','T','S','F'};//非终结符数组

char Vt[8]={'i','(',')','+','-','*','/','#'};//终结符数组

char ch,X;//ch读当前字符,X获取栈顶元素

char strToken[Length];//存储规约表达式

struct LL//ll(1)分析表的构造字初始化

{

char*c;

};

LL E[8]={"TG","TG","error","error","error","error","error","error"};

LL G[8]={"error","error","null","+TG","-TG","error","error","null"};

LL T[8]={"FS","FS","error","error","error","error","error","error"};

LL S[8]={"error","error","null","null","null","*FS","/FS","null"};

LL F[8]={"i","(E)","error","error","error","error","error","error"};

class stack//栈的构造及初始化

{

public:

stack();//初始化

bool empty() const;//是否为空

bool full() const;//是否已满

bool get_top(char &c)const;//取栈顶元素

bool push(const char c);//入栈

bool pop();//删除栈顶元素

void out();//输出栈中元素

~stack(){}//析构

private:

int count;//栈长度

char data[MaxLen];//栈中元素

};

stack::stack()

{

count=0;

}

bool stack::empty() const

{

if(count==0)

return true;

return false;

}

bool stack::full() const

{

if(count==MaxLen)

return true;

return false;

}

bool stack::get_top(char &c)const

{

if(empty())

return false;

else

{

c=data[count-1];

return true;

}

}

bool stack::push(const char c)

{

if(full())

return false;

data[count++]=c;

return true;

}

bool stack::pop()

{

if(empty())

return false;

count--;

return true;

}

void stack::out()

{

for(int i=0;i

cout<

cout<<'\t';

}

int length(char *c)

{

int l=0;

for(int i=0;c[i]!='\0';i++)

l++;

return l;

}

void print(int i,char*c)//剩余输入串的输出{

for(int j=i;j

cout<

cout<<'\t';

}

void run()

{

bool flag=true;//循环条件

int step=0,point=0;//步骤、指针

int len;//长度

cout<<"输入规约的字符串:"<

cin>>strToken;

ch=strToken[point++];//读取第一个字符

stack s;

s.push('#');//栈中数据初始化

s.push('E');

s.get_top(X);//取栈顶元素

cout<<"步骤\t"<<"分析栈\t"<<"剩余输入串\t\t"<<"所用产生式\t"<<"动作"<

cout<

s.out();

print(point-1,strToken);

cout<<'\t'<<"初始化"<

while(flag)

{

if((X==Vt[0])||(X==Vt[1])||(X==Vt[2])||(X==Vt[3])||(X==Vt[4])||(X==Vt[5])||(X==Vt[6])) //判断是否为终结符(不包括#)

{

if(X==ch)//终结符,识别,进行下一字符规约

{

s.pop();

s.get_top(X);

ch=strToken[point++];

cout<

s.out();

print(point-1,strToken);

cout<<'\t'<<"GETNEXT(I)"<

}

else

{

flag=false;

}

}

else if(X=='#')//规约结束

{

if(X==ch)

{

cout<

s.out();

print(point-1,strToken);

cout<"<

s.pop();

flag=false;

}

else

{

flag=false;

}

}

else if(X==Vn[0]) //非终结符E

{

for(int i=0;i<8;i++)//查分析表

if(ch==Vt[i])

{

if(strcmp(E[i].c,"error")==0)//出错

{

flag=false;

}

else{ //对形如X->X1X2的产生式进行入栈操作s.pop();

len=length(E[i].c)-1;

for(int j=len;j>=0;j--)

s.push(E[i].c[j]);

cout<

s.out();

print(point-1,strToken);

cout<"<

for(int j=len;j>=0;j--)

cout<

cout<<")"<

s.get_top(X);

}

}

}

else if(X==Vn[1]) //同上,处理G

{

for(int i=0;i<8;i++)

if(ch==Vt[i])

{

if(strcmp(G[i].c,"null")==0)

{

s.pop();

cout<

s.out();

print(point-1,strToken);

cout<"<<"ε"<<'\t'<<"POP"<

s.get_top(X);

}

else if(strcmp(G[i].c,"error")==0)

{

flag=false;

}

else{

s.pop();

len=length(G[i].c)-1;

for(int j=len;j>=0;j--)

s.push(G[i].c[j]);

cout<

s.out();

print(point-1,strToken);

cout<"<

for(int j=len;j>=0;j--)

cout<

cout<<")"<

s.get_top(X);

}

}

}

else if(X==Vn[2]) //同上处理T

{

for(int i=0;i<8;i++)

if(ch==Vt[i])

{

if(strcmp(T[i].c,"error")==0)

{

flag=false;

}

else{

s.pop();

len=length(T[i].c)-1;

for(int j=len;j>=0;j--)

s.push(T[i].c[j]);

cout<

s.out();

print(point-1,strToken);

cout<"<

for(int j=len;j>=0;j--)

cout<

cout<<")"<

s.get_top(X);

}

}

}

else if(X==Vn[3])//同上处理S

{

for(int i=0;i<8;i++)

if(ch==Vt[i])

{

if(strcmp(S[i].c,"null")==0)

{

s.pop();

cout<

s.out();

print(point-1,strToken);

cout<"<<"ε"<<'\t'<<"POP"<

s.get_top(X);

}

else if(strcmp(S[i].c,"error")==0)

{

flag=false;

}

else{

s.pop();

len=length(S[i].c)-1;

for(int j=len;j>=0;j--)

s.push(S[i].c[j]);

cout<

s.out();

print(point-1,strToken);

cout<"<

for(int j=len;j>=0;j--)

cout<

cout<<")"<

s.get_top(X);

}

}

}

else if(X==Vn[4]) //同上处理F

{

for(int i=0;i<7;i++)

if(ch==Vt[i])

{

if(strcmp(F[i].c,"error")==0)

{

flag=false;

}

else{

s.pop();

len=length(F[i].c)-1;

for(int j=len;j>=0;j--)

s.push(F[i].c[j]);

cout<

s.out();

print(point-1,strToken);

cout<"<

for(int j=len;j>=0;j--)

cout<

cout<<")"<

s.get_top(X);

}

}

}

else //出错处理

{

flag= false;

}

}

}

int main()

{

cout<<"实验二"<

run();

system("pause");

return 0;

}

语法实验源代码LR

#include

using namespace std;

const int MaxLen=20; //初始化栈的长度

const int Length=20;//初始化数组长度

char ch,Y;//全局变量,ch用于读当前字符,Y用于获取栈顶元素char strToken[Length];//存储规约表达式

bool flag=true;//循环条件

int point=0,step=1;//步骤、指针

class stack//栈的构造及初始化

{

public:

stack();//初始化

bool empty() const;//是否为空

bool full() const;//是否已满

bool get_top(char &c)const;//取栈顶元素

bool push(const char c);//入栈

bool pop();

void out();//输出栈中元素

void out1();

~stack(){}//析构

private:

int count;//栈长度

char data[MaxLen];//栈中元素

};

stack l,r;//l代表符号栈,r代表状态栈

stack::stack()

{

count=0;

}

bool stack::empty() const

{

if(count==0)

return true;

return false;

}

bool stack::full() const

{

if(count==MaxLen)

return true;

return false;

}

bool stack::get_top(char &c)const

{

if(empty())

return false;

else

{

c=data[count-1];

return true;

}

}

bool stack::push(const char c)

{

if(full())

return false;

data[count++]=c;

return true;

}

bool stack::pop()

{

if(empty())

return false;

count--;

return true;

}

void stack::out()

{

for(int i=0;i

cout<

cout<<'\t';

}

void stack::out1()

{

for(int i=0;i

cout<

cout<<'\t';

}

void print(int i,char*c)//剩余输入串的输出

{

for(int j=i;j

cout<

cout<<'\t';

}

void Goto(int i,char c)//状态转换函数,对应于表中GOTO {

if(i==0)

{

if(c=='E')

{

r.push(1);

cout<<",GOTO(0,E)=1入栈"<

}

else if(c=='T')

{

r.push(2);

cout<<",GOTO(0,T)=2入栈"<

}

else if(c=='F')

{

r.push(3);

cout<<",GOTO(0,F)=3入栈"<

}

else

flag=false;

}

else if(i==4)

{

if(c=='E')

{

r.push(8);

cout<<",GOTO(4,E)=8入栈"<

}

else if(c=='T')

{

r.push(2);

cout<<",GOTO(4,T)=2入栈"<

}

else if(c=='F')

{

r.push(3);

cout<<",GOTO(4,F)=3入栈"<

}

else

flag=false;

}

else if(i==6)

{

if(c=='T')

{

r.push(9);

cout<<",GOTO(6,T)=9入栈"<

}

else if(c=='F')

{

r.push(3);

cout<<",GOTO(6,F)=3入栈"<

}

else

flag=false;

}

else if(i==7)

{

if(c=='F')

{

r.push(10);

cout<<",GOTO(7,F)=10入栈"<

}

else

flag=false;

}

else

flag=false;

}

void Action0()//状态0时

{

if(ch=='i')//下一个操作符为i ,移进

{

cout<

r.out1();

l.out();

print(point-1,strToken);

cout<<"ACTION[0,i]=S5,状态5入栈"<

r.push(5);

l.push(ch);

ch=strToken[point++];

}

else if(ch=='(')//下一个操作符为( ,移进

{

cout<

r.out1();

l.out();

print(point-1,strToken);

cout<<"ACTION[0,(]=S4,状态4入栈"<

r.push(4);

l.push(ch);

ch=strToken[point++];

}

else

flag=false;

}

void Action1()//状态1

{

if(ch=='+')//下一个操作符为i ,移进

{

cout<

r.out1();

l.out();

print(point-1,strToken);

cout<<"ACTION[1,+]=S6,状态6入栈"<

r.push(6);

l.push(ch);

ch=strToken[point++];

}

else if(ch=='#')//分析成功

{

flag=false;

cout<

r.out1();

l.out();

print(point-1,strToken);

cout<<"Acc:分析成功"<

}

else

flag=false;

}

void Action2() //状态2

{

if(ch=='*')//下一个操作符为* ,移进

{

cout<

r.out1();

l.out();

print(point-1,strToken);

cout<<"ACTION[2,*]=S7,状态7入栈"<

r.push(7);

l.push(ch);

ch=strToken[point++];

}

else if((ch=='+')||(ch==')')||(ch=='#'))//下一个操作符为+,),#规约{

cout<

r.out1();

l.out();

l.pop();

l.push('E');

print(point-1,strToken);

cout<<"r2: E→T归约";

r.pop();

r.get_top(Y);

Goto(int(Y),'E');

}

else

flag=false;

}

void Action3()//状态3

{

if((ch=='+')||(ch=='*')||(ch==')')||(ch=='#'))//下一个操作符为+,*,),#规约{

cout<

r.out1();

l.out();

l.pop();

l.push('T');

print(point-1,strToken);

cout<<"r4: T→F归约";

r.pop();

r.get_top(Y);

Goto(int(Y),'T');

}

else

flag=false;

}

void Action4_6_7(int x)//状态4,6,7

{

if(ch=='i')//下一个操作符为i ,移进

{

cout<

r.out1();

l.out();

print(point-1,strToken);

cout<<"ACTION[";

cout<

r.push(5);

l.push(ch);

ch=strToken[point++];

}

else if(ch=='(')//下一个操作符为(,移进

{

cout<

r.out1();

l.out();

print(point-1,strToken);

cout<<"ACTION[";

cout<

r.push(4);

l.push(ch);

ch=strToken[point++];

}

else

flag=false;

}

void Action5()//状态5

{

if((ch=='+')||(ch=='*')||(ch==')')||(ch=='#'))//下一个操作符为+,*,),#规约{

cout<

r.out1();

l.out();

l.pop();

l.push('F');

print(point-1,strToken);

cout<<"r6: F→i归约";

r.pop();

r.get_top(Y);

Goto(int(Y),'F');

}

else

flag=false;

}

void Action8()//状态8

{

if(ch=='+')//下一个操作符为+ ,移进

{

cout<

r.out1();

l.out();

print(point-1,strToken);

cout<<"ACTION[8,+]=S6,状态6入栈"<

r.push(6);

l.push(ch);

ch=strToken[point++];

}

else if(ch==')')//下一个操作符为),移进

{

cout<

r.out1();

l.out();

print(point-1,strToken);

cout<<"ACTION[8,)]=S11,状态11入栈"<

r.push(11);

ch=strToken[point++];

}

else

flag=false;

}

void Action9()//状态9

{

if(ch=='*')//下一个操作符为* ,移进

{

cout<

r.out1();

l.out();

print(point-1,strToken);

cout<<"ACTION[9,*]=S7,状态7入栈"<

r.push(7);

l.push(ch);

ch=strToken[point++];

}

else if((ch=='+')||(ch==')')||(ch=='#'))//下一个操作符为+,,),#规约

{

cout<

r.out1();

l.out();

l.pop();

l.pop();

l.pop();

l.push('E');

print(point-1,strToken);

cout<<"r1: E→E+T归约";

r.pop();

r.pop();

r.pop();

r.get_top(Y);

Goto(int(Y),'E');

}

else

flag=false;

}

void Action10()//状态10

{

if((ch=='+')||(ch=='*')||(ch==')')||(ch=='#'))//下一个操作符为+,*,),#规约{

cout<

l.out();

l.pop();

l.pop();

l.pop();

l.push('T');

print(point-1,strToken);

cout<<"r3: T→T*F归约";

r.pop();

r.pop();

r.pop();

r.get_top(Y);

Goto(int(Y),'T');

}

else

flag=false;

}

void Action11()//状态11

{

if((ch=='+')||(ch=='*')||(ch==')')||(ch=='#'))//下一个操作符为+,*,),#规约

{

cout<

r.out1();

l.out();

l.pop();

l.pop();

l.pop();

l.push('F');

print(point-1,strToken);

cout<<"r5: F→(E)归约";

r.pop();

r.pop();

r.pop();

r.get_top(Y);

Goto(int(Y),'F');

}

else

flag=false;

}

void run()//规约

{

cout<<"请输入要规约的字符串:"<

cin>>strToken;

cout<<"步骤\t"<<"状态栈\t"<<"符号栈\t"<<"输入串\t\t"<<"动作说明"<

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

编译原理语法分析实验报告 - 班级:XXX 学号:XXX 姓名:XXX 年月日 1、摘要: 用递归子程序法实现对pascal的子集程序设计语言的分析程序 2、实验目的: 通过完成语法分析程序,了解语法分析的过程和作用 3、任务概述 实验要求:对源程序的内码流进行分析,如为文法定义的句子输出”是”否则输出”否”,根据需要处理说明语句填写写相应的符号表供以后代码生成时使用 4、实验依据的原理 递归子程序法是一种自顶向下的语法分析方法,它要求文法是LL(1)文法。通过对文法中每个非终结符编写一个递归过程,每个过程的功能是识别由该非终结符推出的串,当某非终结符的产生式有多个候选式时,程序能够按LL(1)形式唯一地确定选择某个候选式进行推导,最终识别输入串是否与文法匹配。 递归子程序法的缺点是:对文法要求高,必须满足LL(1)文法,当然在某些语言中个别产生式的推导当不满足LL(1)而满足LL(2)时,也可以采用多向前扫描一个符号的办法;它的另一个缺点是由于递归调用多,所以速度慢占用空间多,尽管这样,它还是许多高级语言,例如PASCAL,C等编译系统常常采用的语法分析方法。

为适合递归子程序法,对实验一词法分析中的文法改写成无左递归和无左共因子的,,,如下: <程序>?<程序首部><分程序>。 <程序首部>?PROGRAM标识符; <分程序>?<常量说明部分><变量说明部分><过程说明部分> <复合语句> <常量说明部分>?CONST<常量定义><常量定义后缀>;|ε <常量定义>?标识符=无符号整数 <常量定义后缀>?,<常量定义><常量定义后缀> |ε <变量说明部分>?VAR<变量定义><变量定义后缀> |ε <变量定义>?标识符<标识符后缀>:<类型>; <标识符后缀>?,标识符<标识符后缀> |ε <变量定义后缀>?<变量定义><变量定义后缀> |ε <类型>?INTEGER | LONG <过程说明部分>?<过程首部><分程序>;<过程说明部分后缀>|ε <过程首部>?PROCEDURE标识符<参数部分>; <参数部分>?(标识符: <类型>)|ε <过程说明部分后缀>?<过程首部><分程序>;<过程说明部分后缀>|ε <语句>?<赋值或调用语句>|<条件语句>|<当型循环语句>|<读语句> |<写语句>|<复合语句>|ε <赋值或调用语句>?标识符<后缀> <后缀>?:=<表达式>|(<表达式>)|ε <条件语句>?IF<条件>THEN<语句> <当型循环语句>?WHILE<条件>DO <语句> <读语句>?READ(标识符<标识符后缀>)

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

编译技术 班级网络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(熟悉词法分析的基本原理,词法分析的过程以及词法分析中要注意的问题。 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]);

编译原理-编写递归下降语法分析器

学号107 成绩 编译原理上机报告 名称:编写递归下降语法分析器 学院:信息与控制工程学院 专业:计算机科学与技术 班级:计算机1401班 姓名:叶达成 2016年10月31日

一、上机目的 通过设计、编制、调试一个递归下降语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,掌握常用的语法分析方法。通过本实验,应达到以下目标: 1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。 2、掌握词法分析的实现方法。 3、上机调试编出的词法分析程序。 二、基本原理和上机步骤 递归下降分析程序实现思想简单易懂。程序结构和语法产生式有直接的对应关系。因为每个过程表示一个非终结符号的处理,添加语义加工工作比较方便。 递归下降分析程序的实现思想是:识别程序由一组子程序组成。每个子程序对应于一个非终结符号。 每一个子程序的功能是:选择正确的右部,扫描完相应的字。在右部中有非终结符号时,调用该非终结符号对应的子程序来完成。 自上向下分析过程中,如果带回溯,则分析过程是穷举所有可能的推导,看是否能推导出待检查的符号串。分析速度慢。而无回溯的自上向下分析技术,当选择某非终结符的产生时,可根据输入串的当前符号以及各产生式右部首符号而进行,效率高,且不易出错。 无回溯的自上向下分析技术可用的先决条件是:无左递归和无回溯。 无左递归:既没有直接左递归,也没有间接左递归。 无回溯:对于任一非终结符号U的产生式右部x1|x2|…|x n,其对应的字的首终结符号两两不相交。 如果一个文法不含回路(形如P?+ P的推导),也不含以ε为右部的产生式,那么可以通过执行消除文法左递归的算法消除文法的一切左递归(改写后的文法可能含有以ε为右部的产生式)。 三、上机结果 测试数据: (1)输入一以#结束的符号串(包括+—*/()i#):在此位置输入符号串例如:i+i*i# (2)输出结果:i+i*i#为合法符号串 (3)输入一符号串如i+i*#,要求输出为“非法的符号串”。 程序清单: #include #include char str[50]; int index=0; void E(); //E->TX; void X(); //X->+TX | e void T(); //T->FY void Y(); //Y->*FY | e void F(); //F->(E) | i int main() /*递归分析*/ { int len; int m;

编译原理词法分析和语法分析报告 代码(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语言版)

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

编译原理实验 (词法语法分析报告 附源代码

编译原理实验报告 ******************************************************************************* ******************************************************************************* PL0语言功能简单、结构清晰、可读性强,而又具备了一般高级程序设计语言的必须部分,因而PL0语言的编译程序能充分体现一个高级语言编译程序实现的基本方法和技术。PL/0语言文法的EBNF表示如下: <程序>::=<分程序>. <分程序> ::=[<常量说明>][<变量说明>][<过程说明>]<语句> <常量说明> ::=CONST<常量定义>{,<常量定义>}; <常量定义> ::=<标识符>=<无符号整数> <无符号整数> ::= <数字>{<数字>} <变量说明> ::=VAR <标识符>{, <标识符>}; <标识符> ::=<字母>{<字母>|<数字>} <过程说明> ::=<过程首部><分程序>{; <过程说明> }; <过程首部> ::=PROCEDURE <标识符>; <语句> ::=<赋值语句>|<条件语句>|<当循环语句>|<过程调用语句> |<复合语句>|<读语句><写语句>|<空> <赋值语句> ::=<标识符>:=<表达式> <复合语句> ::=BEGIN <语句> {;<语句> }END <条件语句> ::= <表达式> <关系运算符> <表达式> |ODD<表达式> <表达式> ::= [+|-]<项>{<加法运算符> <项>} <项> ::= <因子>{<乘法运算符> <因子>} <因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’ <加法运算符> ::= +|- <乘法运算符> ::= *|/ <关系运算符> ::= =|#|<|<=|>|>= <条件语句> ::= IF <条件> THEN <语句> <过程调用语句> ::= CALL 标识符 <当循环语句> ::= WHILE <条件> DO <语句> <读语句> ::= READ‘(’<标识符>{,<标识符>}‘)’ <写语句> ::= WRITE‘(’<表达式>{,<表达式>}‘)’ <字母> ::= a|b|…|X|Y|Z <数字> ::= 0|1|…|8|9 【预处理】 对于一个pl0文法首先应该进行一定的预处理,提取左公因式,消除左递归(直接或间接),接着就可以根据所得的文法进行编写代码。 【实验一】词法分析 【实验目的】给出PL/0文法规,要求编写PL/0语言的词法分析程序。 【实验容】已给PL/0语言文法,输出单词(关键字、专用符号以及其它标记)。

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

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

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

编译原理课程设计(词法分析,语法分析,语义分析,代码生成)

编译原理课程设计(词法分析,语法分析,语义分析,代码 生成) #include #include #include #include #include #include using namespace std; /************************************************/ struct token// token { int code;// int num;// token *next; }; token *token_head,*token_tail;//token struct str// string { int num;// string word;// str *next; }; str *string_head,*string_tail;//string struct ivan// {

char left;// string right;// int len;// }; ivan css[20];// 20 struct pank// action { char sr;// int state;// }; pank action[46][18];//action int go_to[46][11];// go_to struct ike// { ike *pre; int num;// int word;// ike *next; }; ike *stack_head,*stack_tail;// struct L// { int k; string op;// string op1;// string op2;// string result;// L *next;// L *Ltrue;//true L *Lfalse;//false };

编译原理-语法分析-算符优先文法分析器

编译原理实验报告 实验名称:编写语法分析分析器实验类型: 指导教师: 专业班级: 学号: 电子邮件: 实验地点: 实验成绩:

一、实验目的 通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。 1、选择最有代表性的语法分析方法,如LL(1) 语法分析程序、算符优先分析程序和LR分析分析程序,至少选一题。 2、选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。 二、实验过程 编写算符优先分析器。要求: (a)根据算符优先分析算法,编写一个分析对象的语法分析程序。读者可根据自己的能力选择以下三项(由易到难)之一作为分析算法中的输入: Ⅰ:通过构造算符优先关系表,设计编制并调试一个算法优先分析程序Ⅱ:输入FIRSTVT,LASTVT集合,由程序自动生成该文法的算符优先关系矩阵。 Ⅲ:输入已知文法,由程序自动生成该文法的算符优先关系矩阵。(b)程序具有通用性,即所编制的语法分析程序能够使用于不同文法以及各种输入单词串,并能判断该文法是否为算符文法和算符优先文法。 (c)有运行实例。对于输入的一个文法和一个单词串,所编制的语法分析程序应能正确地判断,此单词串是否为该文法的句子,并要求输出分析过程。 三、实验结果 算符优先分析器: 测试数据:E->E+T|T T->T*F|F F->(E)|i 实验结果:(输入串为i+i*i+i)

四、讨论与分析 自下而上分析技术-算符优先分析法: 算符文法:一个上下无关文法G,如果没有且没有P→..QR...(P ,Q ,R属于非终结符),则G是一个算符文法。 FIRSTVT集构造 1、若有产生式P →a...或P →Qa...,则a∈FIRSTVT(P)。 2、若有产生式P→...,则FIRSTVT(R)包含在FIRSTVT(P)中。由优先性低于的定义和firstVT集合的定义可以得出:若存在某个产生式:…P…,则对所有:b∈firstVT(P)都有:a≦b。 构造优先关系表: 1、如果每个非终结符的FIRSTVT和LASTVT集均已知,则可构造优先关系表。 2、若产生式右部有...aP...的形式,则对于每个b∈FIRSTVT(P)都有

编译原理实验词法分析语法分析

本代码只供学习参考: 词法分析源代码: #include #include #include using namespace std; string key[8]={"do","end","for","if","printf","scanf","then","while"}; string optr[4]={"+","-","*","/"}; string separator[6]={",",";","{","}","(",")"}; char ch; //判断是否为保留字 bool IsKey(string ss) { int i; for(i=0;i<8;i++) if(!strcmp(key[i].c_str(),ss.c_str())) return true; return false; } //字母判断函数 bool IsLetter(char c) { if(((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z'))) return true; return false; } //数字判断函数 bool IsDigit(char c) { if(c>='0'&&c<='9') return true; return false; } //运算符判断函数 bool IsOptr(string ss) { int i; for(i=0;i<4;i++) if(!strcmp(optr[i].c_str(),ss.c_str())) return true ; return false; } //分界符判断函数 bool IsSeparator(string ss) { int i; for(i=0;i<6;i++) if(!strcmp(separator[i].c_str(),ss.c_str()))

编译原理实验报告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.利用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’;

编译原理 语法分析器 (java完美运行版)

实验二语法分析器 一、实验目的 通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。有利于提高学生的专业素质,为培养适应社会多方面需要的能力。 二、实验内容 ◆根据某一文法编制调试LL (1 )分析程序,以便对任意输入的符号串 进行分析。 ◆构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分 析程序。 ◆分析法的功能是利用LL(1)控制程序根据显示栈栈顶内容、向前看符号 以及LL(1)分析表,对输入符号串自上而下的分析过程。 三、LL(1)分析法实验设计思想及算法 ◆模块结构: (1)定义部分:定义常量、变量、数据结构。 (2)初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等); (3)控制部分:从键盘输入一个表达式符号串; (4)利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。

四、实验要求 1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。 2、如果遇到错误的表达式,应输出错误提示信息。 3、对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG (2)G->+TG|—TG (3)G->ε (4)T->FS (5)S->*FS|/FS (6)S->ε (7)F->(E) (8)F->i 输出的格式如下:

五、实验源程序 LL1.java import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.sql.*; import java.util.Vector; public class LL1 extends JFrame implements ActionListener { /** * */ private static final long serialVersionUID = 1L; JTextField tf1; JTextField tf2; JLabel l; JButton b0; JPanel p1,p2,p3; JTextArea t1,t2,t3; JButton b1,b2,b3;

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

词法分析器实验报告 一、实验目的 选择一种编程语言实现简单的词法分析程序,设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 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 ”,}; (2)3、2 扫描子程序的算法思想: 首先设置3个变量:①token 用来存放构成单词符号的字符串;②sum 用来整型单词;③syn 用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。

昆明理工大学 编译原理 实验二 语法分析器

昆明理工大学信息工程与自动化学院学生实验报告 (2011 —2012 学年第 1 学期) 课程名称:编译原理开课实验室: 445 2011年 12 月 19日年级、专业、 班 计科093 学号200910405310 姓名孙浩川成绩 实验项目名称语法分析器指导教师严馨 教 师评语 该同学是否了解实验原理: A.了解□ B.基本了解□ C.不了解□ 该同学的实验能力: A.强□ B.中等□ C.差□ 该同学的实验是否达到要求: A.达到□ B.基本达到□ C.未达到□ 实验报告是否规范: A.规范□ B.基本规范□ C.不规范□ 实验过程是否详细记录: A.详细□ B.一般□ C.没有□ 教师签名: 年月日 一、实验目的及内容 实验目的:编制一个语法分析程序,实现对词法分析程序所提供的单词序列进行语法检 查和结构分析。 实验内容:在上机(一)词法分析的基础上,采用递归子程序法或其他适合的语法分析方法,实现其语法分析程序。要求编译后能检查出语法错误。 已知待分析的C语言子集的语法,用EBNF表示如下: <程序>→main()<语句块> <语句块> →‘{’<语句串>‘}’ <语句串> → <语句> {; <语句> }; <语句> → <赋值语句> |<条件语句>|<循环语句> <赋值语句>→ID=<表达式>

<条件语句>→if‘(‘条件’)’<语句块> <循环语句>→while’(‘<条件>’)‘<语句块> <条件> → <表达式><关系运算符> <表达式> <表达式> →<项>{+<项>|-<项>} <项> → <因子> {* <因子> |/ <因子>} <因子> →ID|NUM| ‘(’<表达式>‘)’ <关系运算符> →<|<=|>|>=|==|!= 二、实验原理及基本技术路线图(方框原理图或程序流程图)

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

《编译原理》 课程设计 院系信息科学与技术学院 专业软件工程 年级 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语言的一个子集,故字符集如下:

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

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

实验一:词法分析程序 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)

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

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

实验一、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、词法分析系统流程设计

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