导航:首页 > 源码编译 > 合工大编译原理实验词法分析

合工大编译原理实验词法分析

发布时间:2024-07-04 19:53:20

A. 编译原理这科里词法分析器的主要任务是什么单词常分为哪几类识别出的单词在编译程序中如何表示

1、识别出源程序中的各个单词符号,并转换成内部编码形式
2、删除无用的空白字符回车字符以及其他非实质性字符
3、删除注释
4、进行词法检查,报告所发现的错误。

B. 编译原理 词法分析

C语言词法分析器
#include<iostream>
#include<stdio.h>
#include<string>

using namespace std;

FILE *f; //定义一个文件变量
static int line = 1; //表示光标所在的行数
struct ID{ char *name; int count;}id[100];//用于存放ID号码
static int I = 0; //用于记录ID存放的数量
int Number[100]; //用于存放数字
static int P = 0; //用于记录存放数字的个数
int error[100] = {0}; //用于记录错误所在的行数
static int K = 0; //记录错误次数
void Error(); //记录错误
void loginID(char *); //注册ID号
void loginNumber(int &); //记录数字
void noteLine(char &); //记录光标所在的行数
void print(); //输出分析结果
int same(char *chr); //判断单词是否已经存在

void Error()
{ error[K++] = line; }

void loginID(char *chr) //注册ID号
{
int k = 0;
int h = 0;
for(int i = 0; i < I; i++)
{
if(!strcmp(chr,id.name)) //如果单词已经存在
{
id.count++;
k = 1;
}
}
if(k == 0) //该单词不存在
{
h = I + 1;
//I = h;
id[h].count++;
id[h].name = chr;
//strcpy(id[h].name ,chr);
}

}

void loginNumber(int &nu)
{ Number[P++] = nu; }

void noteLine(char &ch)
{
if ( ch == ' ' )
++line;
}

void print()//输出部分
{
//cout << "关键字以及变量:" << endl;
//for(int i = 0; i < 100; i++)
//cout << i <<" " << id.name << " " << id.count << endl;
cout << "数字:" << endl;
for(int i = 1; i <= P; i++)
cout << i << ": " << Number[i-1] << endl;
if(error[0] != 0)
{
cout << "出现的错误!" << endl;
for(int i = 1; i <= K; i++)
cout << "第" << i << "个错误: " << "第" << error[i-1] << "行" << endl;
}
else cout << "没有错误!" << endl;
}

//文件处理部分
void noblank( char &ch) //跳过空格,回车
{
noteLine(ch);
while(ch == ' ' || ch == ' ')
ch = fgetc(f);
}

void identifier(char name[],char &ch)//字母变量
{

int i;
for(i = 0; i < 20; i++)
name = '';
i = 0;
while (('0'<= ch && ch <= '9')||('a'<= ch&&ch <= 'z')||('A'<= ch&&ch <='Z'))
{
name = ch;
i++;
ch = fgetc(f);
}
loginID(name);
//for(int j = 0; j < i; j++)
//{cout << name[j];}
// cout << ' ';

}

int number(char &ch)//数字
{
int num=0;
while('0'<= ch && ch <= '9')
{
num = num* 10 + (ch-'0');
ch = fgetc(f);
}
if( ('a'<= ch&&ch <= 'z')||('A'<= ch&&ch <='Z'))
{
Error();
}
else if( ch == '.')
{;}
loginNumber(num); //记录数字
return num;
}

void test(char &ch)//符号
{
char str[2]={'0/'};
if(ch == '*')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '.')
{ str[0] = ch; ch = fgetc(f);}
if(ch == ',')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '"')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '/')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '%')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '^')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '-')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '{')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '}')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '[')
{ str[0] = ch; ch = fgetc(f);}
if(ch == ']')
{ str[0] = ch; ch = fgetc(f);}
if(ch == ';')
{str[0] = ch; ch = fgetc(f);}
if(ch == ':')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '?')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '(')
{ str[0] = ch; ch = fgetc(f);}
if(ch == ')')
{str[0] = ch; ch = fgetc(f);}
if(ch =='+')
{

str[0] = ch;
if((ch = fgetc(f)) == '+' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}

//cout << str[0]<< endl;
}
if(ch == '-')
{

str[0] = ch;
if((ch = fgetc(f)) == '-' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}

//cout << str[0]<< endl;
}
if(ch == '&')
{

str[0] = ch;
if((ch = fgetc(f)) == '&' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}

//cout << str[0]<< endl;
}
if(ch == '|')
{

str[0] = ch;
if((ch = fgetc(f)) == '|' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}

//cout << str[0]<< endl;
}
if(ch == '!')
{

str[0] = ch;
if((ch = fgetc(f)) == '=' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}

//cout << str[0]<< endl;
}
if(ch == '=')
{

str[0] = ch;
if((ch = fgetc(f)) == '=' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}

}
if(ch == '>')
{

str[0] = ch;
if((ch = fgetc(f)) == '=' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
else
if(ch == '>' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}

}
if(ch == '<')
{
str[0] = ch;
if((ch = fgetc(f)) == '=' )
{
str[1] = ch;
ch = fgetc(f);
}
else
if(ch == '<' )
{
str[1] = ch;
ch = fgetc(f);
}

}

}

int main()
{
char ch;
char name[30];
for(int i = 0; i < 30; i++)
name = '/0';
f = fopen("c.txt","r"); //打开指定输入文件
if (f == NULL)
cout<<"文件不存在!"<<endl;
ch = fgetc(f);
while(!feof(f))
{
noblank( ch ); //跳过回车,空格
if( ( ch >= 'a' && ch <= 'z' )||( ch >= 'A' && ch <= 'Z' ))
{ identifier(name,ch); } //处理字母
else if( ch >= '0'&& ch <= '9')
{ number(ch); } //处理数字
else
{ test(ch); } //处理符号
}
print(); //打印词法分析结果
fclose(f); //关闭文件
system("pause");
return 0;
}

C. 求编译原理的名词解释题

词法分析(Lexical analysis或Scanning)和词法分析程序(Lexical analyzer或Scanner)
词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。词法分析程序实现这个任务。词法分析程序可以使用lex等工具自动生成。

语法分析(Syntax analysis或Parsing)和语法分析程序(Parser)
语法分析是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.

语义分析(Syntax analysis)
语义分析是编译过程的一个逻辑阶段. 语义分析的任务是对结构上正确的源程序进行上下文有关性质的审查, 进行类型审查.例如一个C程序片断:
int arr[2],b;
b = arr * 10;
源程序的结构是正确的.
语义分析将审查类型并报告错误:不能在表达式中使用一个数组变量,赋值语句的右端和左端的类型不匹配.

Lex
一个词法分析程序的自动生成工具。它输入描述构词规则的一系列正规式,然后构建有穷自动机和这个有穷自动机的一个驱动程序,进而生成一个词法分析程序.

Yacc
一个语法分析程序的自动生成工具。它接受语言的文法,构造一个LALR(1)分析程序.因为它采用语法制导翻译的思想,还可以接受用C语言描述的语义动作,从而构造一个编译程序. Yacc 是 Yet another compiler compiler的缩写.[回页首]

源语言(Source language)和源程序(Source program)
被编译程序翻译的程序称为源程序,书写该程序的语言称为源语言.[回页首]

目标语言(Object language or Target language)和目标程序(Object program or Target program)
编译程序翻译源程序而得到的结果程序称为目标程序, 书写该程序的语言称为目标语言.[回页首]

中间语言(中间表示)(Intermediate language(representation))
在进行了语法分析和语义分析阶段的工作之后,有的编译程序将源程序变成一种内部表示形式,这种内部表示形式叫做中间语言或中间表示或中间代码。所谓“中间代码”是一种结构简单、含义明确的记号系统,这种记号系统复杂性介于源程序语言和机器语言之间,容易将它翻译成目标代码。另外,还可以在中间代码一级进行与机器无关的优化。

[回页首]

文法(Grammars)
文法是用于描述语言的语法结构的形式规则。文法G定义为四元组(,,,)。其中为非终结符号(或语法实体,或变量)集;为终结符号集;为产生式(也称规则)的集合;产生式(规则)是形如或 a ::=b 的(a , b)有序对,其中(∪)且至少含有一个非终结符,而(∪)。,和是非空有穷集。称作识别符号或开始符号,它是一个非终结符,至少要在一条规则中作为左部出现。
一个文法的例子: G=(={A,R},={0,1} ,={A?0R,A?01,R?A1},=A) [回页首]
文法分类(A hierarchy of Grammars)
着名语言学家Noam Chomsky定义了四类文法和四种形式语言类,文法的四种类型分别是0型、1型、2型和3型。几类文法的差别在于对产生式施加不同的限制,分别是:
0型文法(短语结构文法)(phrase structure grammars):
设G=(,,,),如果它的每个产生式是这样一种结构: (∪) 且至少含有一个非终结符,而(∪),则G是一个0型文法。
1型文法(上下文有关文法)(context-sensitive grammars):
设G=(,,,)为一文法,若中的每一个产生式均满足|,仅仅 除外,则文法G是1型或上下文有关的。
2型文法(上下文无关文法)(context-free grammars):
设G=(,,,),若P中的每一个产生式满足:是一非终结符,(∪) 则此文法称为2型的或上下文无关的。
3型文法(正规文法)(regular grammars):
设G=(,,,),若中的每一个产生式的形式都是A→aB或A→a,其中A和B都是非终结,a是终结符,则G是3型文法或正规文法。
0型文法产生的语言称为0型语言。
1型文法产生的语言称为1型语言,也称作上下文有关语言。
2型文法产生的语言称为2型语言,也称作上下文无关语言。
3型文法产生的语言称为3型语言,也称作正规语言。

D. 编译原理的词法分析器的原理......

将文件读入内存中
然后从首字符开始分析,匹配规则一般是采用自动机,以语句
int
a
=
12;为例
首先从字符i开始
每次取一个单词
即从一个非空白字符开始
到下一个空白字符出现为止
为一个单词

看看
该单词是不是关键字
如看看是不是if
是不是int
都不是的话
则将其当做
字符标记
依此类推

E. 编译原理课程设计-词法分析器设计(C语言)

#include"stdio.h"/*定义I/O库所用的某些宏和变量*/

#include"string.h"/*定义字符串库函数*/

#include"conio.h"/*提供有关屏幕窗口操作函数*/

#include"ctype.h"/*分类函数*/

charprog[80]={''},

token[8];/*存放构成单词符号的字符串*/

charch;

intsyn,/*存放单词字符的种别码*/

n,

sum,/*存放整数型单词*/

m,p;/*p是缓冲区prog的指针,m是token的指针*/

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

voidscaner(){

m=0;

sum=0;

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

token[n]='';

ch=prog[p++];

while(ch=='')

ch=prog[p++];

if(isalpha(ch))/*ch为字母字符*/{

while(isalpha(ch)||isdigit(ch))/*ch为字母字符或者数字字符*/{

token[m++]=ch;

ch=prog[p++];}

token[m++]='';

ch=prog[p--];

syn=10;

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

if(strcmp(token,rwtab[n])==0)/*字符串的比较*/{

syn=n+1;

break;}}

else

if(isdigit(ch))/*ch是数字字符*/{

while(isdigit(ch))/*ch是数字字符*/{

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

ch=prog[p++];}

ch=prog[p--];

syn=11;}

else

switch(ch){

case'<':m=0;token[m++]=ch;ch=prog[p++];

if(ch=='>'){

syn=21;

token[m++]=ch;}

elseif(ch=='='){

syn=22;

token[m++]=ch;}

else{

syn=20;

ch=prog[p--];}

break;

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

if(ch=='='){

syn=24;

token[m++]=ch;}

else{

syn=23;

ch=prog[p--];}

break;

case':':m=0;token[m++]=ch;ch=prog[p++];

if(ch=='='){

syn=18;

token[m++]=ch;}

else{

syn=17;

ch=prog[p--];}

break;

case'+':syn=13;token[0]=ch;break;

case'-':syn=14;token[0]=ch;break;

case'*':syn=15;token[0]=ch;break;

case'/':syn=16;token[0]=ch;break;

case'=':syn=25;token[0]=ch;break;

case';':syn=26;token[0]=ch;break;

case'(':syn=27;token[0]=ch;break;

case')':syn=28;token[0]=ch;break;

case'#':syn=0;token[0]=ch;break;

default:syn=-1;}}

main()

{

printf(" Thesignificanceofthefigures: "

"1.figures1to6saidKeyword "

"2. "

"3.figures13to28saidOperators ");

p=0;

printf(" pleaseinputstring: ");

do{

ch=getchar();

prog[p++]=ch;

}while(ch!='#');

p=0;

do{

scaner();

switch(syn){

case11:printf("(%d,%d) ",syn,sum);break;

case-1:printf(" ERROR; ");break;

default:printf("(%d,%s) ",syn,token);

}

}while(syn!=0);

getch();

}

程序测试结果

对源程序beginx:=9:ifx>9thenx:=2*x+1/3;end#的源文件,经过词法分析后输出如下图5-1所示:

具体的你在修改修改吧

F. 编译原理中的词法分析器的输入与输出是什么

编译原理中的词法分析器的输入是源程序,输出是识别的记号流。

词法分析器编制一个读单词的程序,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符和分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示)。

(6)合工大编译原理实验词法分析扩展阅读

词法分析器的作用:

1、与符号表进行交互,存储和读取符号表中的标识符的信息。

2、读入源程序的输入字符,将他们组成词素,生成并输出一个词法单元序列,每个词法单元序列对应一个于一个词素。

3、过滤掉程序中的注释和空白。

4、将编译器生成的错误消息与源程序的位置联系起。


G. 请问编译原理中什么叫完成词法分析,语法分析

以你说的SQL语句为例,词法分析是将语句中的单词流识别出来,比如create table Student 词法分析是分析出 这句的单词流是 “create” “table” “identifier”(前提是你给它们编号 比如用宏或者枚举),然后语法分析 是通过单词流 判断 非逻辑错误 比如 有不能识别的符号 create table后面不是标示符等等 语义分析是分析语句的逻辑关系 比如字段长度越界什么的如 vchar(2) 你赋值为“啊啊啊啊啊啊”这种错误的识别是语义分析阶段完成的 希望能帮到你

阅读全文

与合工大编译原理实验词法分析相关的资料

热点内容
怎么进入电脑板2b2t服务器 浏览:282
idea编译进度条 浏览:132
文件夹工具箱软件 浏览:686
最近为什么手机连不上索尼服务器 浏览:877
海康录像机怎么关视频加密 浏览:786
编程以后有可能被机器人代替吗 浏览:522
windows创建文件命令 浏览:986
linuxcopy文件内容 浏览:383
程序员帅哥秃顶 浏览:839
阿里云服务器开通流程 浏览:105
如何开云服务器 浏览:979
网站小说源码 浏览:301
php用什么ide 浏览:867
网上预约课程app哪个好 浏览:153
android兼容测试工具 浏览:97
云服务器不支持虚拟化怎么办 浏览:189
加密方式的演变 浏览:364
java常用算法pdf 浏览:735
服务器数据遇到异常什么原因 浏览:450
phpexif信息 浏览:544