导航:首页 > 源码编译 > 编译原理词法分析

编译原理词法分析

发布时间:2022-01-27 07:32:42

‘壹’ 编译原理 词法分析器问题

NFA、DFA以及最简DFA如下图所示:

‘贰’ 编译原理 词法分析 要求输入一个源文件,或是text形式的,然后对该文件进行词法分析。要简单一点的。

#include <iostream>
#include <vector>
#include <string>
#include <fstream>

using namespace std;
/*用来存储目标文件名*/
string file_name;

/*提取文本文件中的信息。*/
string GetText();

/*获得一个单词符号,从位置i开始查找。
//并且有一个引用参数j,用来返回这个单词最后一个字符在str的位置。*/
string GetWord(string str,int i,int& j);

/*这个函数用来除去字符串中连续的空格和换行
//第一个参数为目标字符串,第二个参数为开始位置
//返回值为连续的空格和换行后的第一个有效字符在字符串的位置*/
int DeleteNull(string str,int i);

/*判断i当前所指的字符是否为一个分界符,是的话返回真,反之假*/
bool IsBoundary(string str,int i);

/*判断i当前所指的字符是否为一个运算符,是的话返回真,反之假*/
bool IsOperation(string str,int i);

/*此函数将一个pair数组输出到一个文件中*/
void OutFile(vector<pair<int,string> > v);

/*此函数接受一个字符串数组,对它进行词法分析,返回一个pair型数组*/
vector<pair<int,string> > analyst(vector<string> vec);

/*此函数判断传递的参数是否为关键字,是的话,返回真,反之返回假*/
bool IsKey(string str);

int main()
{
cout<<"*****************************\n";
cout<<"\n\nright: Archerzei\n\n\n";
cout<<"*****************************\n\n";
string com1=" ";
string com2="\n";
string fileline=GetText();
int begin=0,end=0;
vector<string> array;
do
{
begin=DeleteNull(fileline,begin);
string nowString;
nowString=GetWord(fileline,begin,end);
if(end==-1)
break;
if(nowString.compare(com1)&&nowString.compare(com2))
array.push_back(nowString);
begin=end+1;
}while(true);
vector<pair<int,string> > mid_result;
mid_result=analyst(array);
OutFile(mid_result);
cout<<"**********************************************************************\n";
cout<<"***程序已完成词法分析,分析结果已经存储在文件"<<file_name<<"中!!!***\n";
cout<<"**********************************************************************\n";
system("pause");
return 0;
}

/*提取文本文件中的信息*/
string GetText()
{
string file_name1;
cout<<"请输入源文件名(包括路径和后缀名):";
cin>>file_name1;
ifstream infile(file_name1.c_str(),ios::in);
if (!infile)
{
cerr<<"无法打开文件! "<<file_name1.c_str()<<" !!!"<<endl;
exit(-1);
}
cout<<endl;
char f[1000];
infile.getline(f,1000,EOF);
infile.close();
return f;
}

/*获得一个单词符号,从位置i开始查找。
//并且有一个引用参数j,用来返回这个单词最后一个字符在原字符串的位置。*/
string GetWord(string str,int i,int& j)
{
string no_use("(){} , ; \n+=*/-<>\"");
j=str.find_first_of(no_use,i);
if(j==-1)
return "";
if(i!=j)
j--;
return str.substr(i,j-i+1);
}

/*这个函数用来除去字符串中连续的空格和换行
//第一个参数为目标字符串,第二个参数为开始位置
//返回值为连续的空格和换行后的第一个有效字符在字符串的位置*/
int DeleteNull(string str,int i)
{
for(;;i++)
if(str[i]!=' '&&str[i]!='\n')
return i;
}

/*判断i当前所指的字符是否为一个分界符,是的话返回真,反之假*/
bool IsBoundary(string str,int i)
{
int t;
char arr[7]={',',';','{','}','(',')','\"'};
for (t=0;t<7;t++)
if(str[i]==arr[t])
return true;
return false;
}

/*判断i当前所指的字符是否为一个运算符,是的话返回真,反之假*/
bool IsOperation(string str,int i)
{
int t;
char arr[7]={'+','-','*','/','=','<','>'};
for (t=0;t<7;t++)
if(str[i]==arr[t])
return true;
return false;
}

/*此函数将一个个字符串数组输出到一个文件中*/
void OutFile(vector<pair<int,string> > v)
{
cout<<"请输入目标文件名(包括路径和后缀名):";
cin>>file_name;
ofstream outfile(file_name.c_str(),ios::out);
if (!outfile)
{
cerr<<"无法打开文件! "<<file_name.c_str()<<" !!!"<<endl;
exit(-1);
}
cout<<endl;
int i;
cout<<"*****************************\n";
cout<<"\n\nright: Archerzei\n\n\n";
cout<<"*****************************\n\n";
for(i=0;i<v.size();i++)
outfile<<"<"<<v[i].first<<" , \""<<v[i].second<<"\">"<<endl;
outfile<<"\n\n*********************************\n";
outfile.close();
return;
}

/*此函数接受一个字符串数组,对它进行词法分析,返回一个pair型数组*/
vector<pair<int,string> > analyst(vector<string> vec)
{
vector<pair<int,string> > temp;
int i;
for(i=0;i<vec.size();i++)
{
if(vec[i].size()==1)
{
if((vec[i]==">"||vec[i]=="<"||vec[i]=="!")&&vec[i+1]=="=")
{
string jk=vec[i];
jk.append(vec[++i],0,1);
pair<int,string> pp(4,jk);
temp.push_back(pp);
continue;
}
if((vec[i]=="+"&&vec[i+1]=="+")||(vec[i]=="-"&&vec[i+1]=="-"))
{
string jk=vec[i];
jk.append(vec[++i],0,1);
pair<int,string> pp(4,jk);
temp.push_back(pp);
continue;
}
if(IsBoundary(vec[i],0))
{
pair<int,string> pp(5,vec[i]);
temp.push_back(pp);
}
else if(IsOperation(vec[i],0))
{
pair<int,string> pp(4,vec[i]);
temp.push_back(pp);
}
else if(vec[i][0]<='9'&&vec[i][0]>='0')
{
pair<int,string> pp(3,vec[i]);
temp.push_back(pp);
}
else
{
pair<int,string> pp(2,vec[i]);
temp.push_back(pp);
}
}
else if(vec[i][0]<='9'&&vec[i][0]>='0')
{
pair<int,string> pp(3,vec[i]);
temp.push_back(pp);
}
else if(IsKey(vec[i]))
{
pair<int,string> pp(1,vec[i]);
temp.push_back(pp);
}
else
{
pair<int,string> pp(2,vec[i]);
temp.push_back(pp);
}
}
return temp;
}

/*此函数判断传递的参数是否为关键字,是的话,返回真,反之返回假*/
bool IsKey(string str)
{
string p[16]={"char","double","int","long","double","float","for","while","do","break","continue","switch","short","case","return","if"};
vector<string> ppp(p,p+16);
int u;
for(u=0;u<ppp.size();u++)
if(!str.compare(ppp[u]))
return true;
return false;
}
/*finished*/

已经验收过了,在VC6.0上运行没有问题。程序很容易看懂的,报告的话自己写写就可以了。要是有分就好了…………哈哈!!!

‘叁’ 编译原理的词法分析器的原理......

将文件读入内存中 然后从首字符开始分析,匹配规则一般是采用自动机,以语句 int a = 12;为例 首先从字符i开始 每次取一个单词 即从一个非空白字符开始 到下一个空白字符出现为止 为一个单词 先 看看 该单词是不是关键字 如看看是不是if 是不是int 都不是的话 则将其当做 字符标记 依此类推

‘肆’ 编译原理的一个词法分析题(希望

#include "word.h"

void main(){
menu();
}

///列表生成工具
void makelist(char * text){
char ch[20][20];
int i=0;
int j,k;
while(1){
cin>>ch[i];
if(strcmp(ch[i],"enterend")==0)
break;
i++;
}
char xch[20];
for(k=0;k<i;k++)
{
for(j=0;j<i-1;j++)
{
if(strcmp(ch[j],ch[j+1])>0)
{strcpy(xch,ch[j]);strcpy(ch[j],ch[j+1]);strcpy(ch[j+1],xch);}
}
}
ofstream out(text);
for(k=0;k<i;k++)
{
out<<ch[k]<<endl;
}

}

//单词分离
void wordfind(char * text){
cout<<"请输入要分析的文件名:"<<endl;
cin>>text;
char buf;
int i=0;
int len=0;
char buff[2048];
ifstream fin(text);
//源文件的规则化
while(!fin.eof()){
buf=fin.get();
if(buf=='\n'||buf==';')
buf=' ';
buff[len]=buf;
len++;
}
char * buffer=new char[len];
strncpy(buffer,buff,len);
//单词提取
ofstream out(Words);
for(i=0;i<len-1;i++)
{
if((buffer[i]>='a'&&buffer[i]<='z')||(buffer[i]>='A'&&buffer[i]<='Z')||(buffer[i]>='0'&&buffer[i]<='9'))
{
out<<buffer[i];
}
else
{
if(buffer[i]!=' ')
{
if(buffer[i-1]!=' ')
out<<endl;
out<<buffer[i]<<endl;
}
else
{
if(buffer[i-1]!=' ')
out<<endl;
}

}
}
}

//单词判断
bool casein(char * text,char * words){
char word[10];
int k=0;
ifstream fin(text);
while(!fin.eof()){
fin>>word;
if(k=strcmp(word,words)==0)
return TRUE;
else
if(k>0)
return FALSE;
}
return FALSE;

}

//单词分组
int switchgroup(char * word){
if(casein(Word,word))
return 1;
if(casein(Char,word))
return 2;
if(word[0]==':')
return 3;
else
return 4;
}

//使用集 各参数的使用
void fanal(){
int kind;
int lastkind=0;
char word[10];
ifstream fin(Words);
while(!fin.eof()){
fin>>word;
kind=switchgroup(word);
if(kind==3)
{
fin>>word;
kind=switchgroup(word);
if(word[0]=='=')
{
print(kind,":=",lastkind);
}
}
else
{
print(kind,word,lastkind);
}
lastkind=kind;

}
}

//单词类型分析
int startwith(char * word){
if(word[0]>='0'&&word[0]<='9')
return NUMBER;
else
return CHAR;
}

//显示打印
void print(int k,char * word,int l){
if(k==1)
cout<<"类型是: 关键字 名字是: "<<word<<" 值是:"<<word<<endl;
if(k==2)
cout<<"类型是: 特殊符号 名字是: "<<word<<" 值是:"<<word<<endl;
if(k==4)
if(l==1)
cout<<"类型是: 变量 名字是: "<<word<<" 值是:"<<word<<endl;
if((l==2)&&startwith(word))
cout<<"类型是: 变量 名字是: "<<word<<" 值是:"<<word<<endl;
if((l==2)&&!startwith(word))
cout<<"类型是: 常量 名字是: "<<word<<" 值是:"<<word<<endl;
}

#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include <stdlib.h>
#define FALSE 0
#define TRUE 1
#define BUFSIZE 2048
#define CHAR 1
#define NUMBER 0

//函数声明
bool casein(char *);
void wordfind(char *);
void makelist(char *);
int switchgroup(char * );
void print(int,char *,int);
void menu();
void menu2();
int startwith(char *);

//全局变量定义
char Word[]="wordlist.txt";
char Char[]="charlist.txt";
char readfile[]="readfile.txt";
char Words[]="wordslist.txt";
charlist.txt的内容 可以随便加你要的符号
(
)
*
+
-
/
=
wordlist.txt 关键字表 也可以随便写 我写的是
else
end
if
read
repeat
then
until
write
以上都是一个词一行
还有readfile.txt 是被分析文件 自己写吧.你有诚意给我冲10QB 447322160 我写了4个小时

‘伍’ 编译原理词法分析器

用C++语言
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <conio.h>
#define NULL 0
FILE *fp;
char ch;
char *keyword[34]={"auto","break","case","char","const","continue","default","do","double",
"else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef", "printf",
"union","unsigned","void","volatile","while","main"};
char *operatornum[6]={"+","-","*","/","++","--"};
char *comparison[8]={"<","<=","=",">",">=","<>","==","!="};
char *interpunction[8]={",",";",":=",".","(",")","{","}"};
char *biaoshifu[6]={"%","$","^","&","_","#"};//特殊标识符
char *zhushifu[3]={"//","/*","*/"};//注释符
char *luoji[3]={"&&","||","!"};//逻辑运算符
//////////////////////////////////////////////////////////////////////////////////////////
bool search(char searchstr[],int wordtype)
{
int i;
switch (wordtype)
{
case 1:for(i=0;i<=33;i++)
{
if(strcmp(keyword[i],searchstr)==0)
return(true);

}
case 2:{
for(i=0;i<=5;i++)
{
if(strcmp(operatornum[i],searchstr)==0)
return(true);
}
break;
}
case 3: {
for(i=0;i<=7;i++)
{
if(strcmp(comparison[i],searchstr)==0)
return(true);
}
break;
}
case 4: for(i=0;i<=7;i++)
{
if(strcmp(interpunction[i],searchstr)==0)
return(true);
}

break;
case 5: for(i=0;i<=5;i++)
{
if(strcmp(biaoshifu[i],searchstr)==0)
return(true);
}break;
case 6: for(i=0;i<=2;i++)
{
if(strcmp(zhushifu[i],searchstr)==0)
return(true);
}break;
case 7: for(i=0;i<=2;i++)
{
if(strcmp(luoji[i],searchstr)==0)
return(true);
}break;
}
return(false);
}

///////////////////////////////////////////////////////////////////////////////////////////
char letterprocess (char ch)//字母处理函数
{
int i=-1;
char letter[20];
while (isalnum(ch)!=0)
{
letter[++i]=ch;
ch=fgetc(fp);
};
letter[i+1]='\0';
if (search(letter,1))
{
printf("<%s,关键字>\n",letter);
//strcat(letter,"\n");
//fputs('<' letter '>\n',outp);
}
else
{
printf("<%s,自定义变量>\n",letter);
//strcat(letter,"\n");
//fputs(letter,outp);
}
return(ch);
}
///////////////////////////////////////////////////////////////////////////////////////////
char numberprocess(char ch)//数字处理程序
{
int i=-1;
char num[20];
while (isdigit(ch)!=0)
{
num[++i]=ch;
ch=fgetc(fp);
}
if(isalpha(ch)!=0)
{
while(isspace(ch)==0)
{
num[++i]=ch;
ch=fgetc(fp);
}
num[i+1]='\0';
printf("错误!非法标识符:%s\n",num);
goto u;
}
num[i+1]='\0';
printf("<%s,数字>\n",num);
//strcat(num,"\n");
//fputs(num,outp);
u: return(ch);
}
//////////////////////////////////////////////////////////////////////////////////////////////
char otherprocess(char ch)
{
int i=-1;
char other[20];
if (isspace(ch)!=0)
{
ch=fgetc(fp);
goto u;
}
while ((isspace(ch)==0)&&(isalnum(ch)==0))
{
other[++i]=ch;
ch=fgetc(fp);
}
other[i+1]='\0';
if (search(other,2))
printf("<%s,算数运算符>\n",other);
else
if (search(other,3))
printf("<%s,关系运算符号>\n",other);
else
if (search(other,4))
printf("<%s,分隔符号>\n",other);
else
if (search(other,5))
printf("<%s,特殊标识符号>\n",other);
else
if (search(other,6))
printf("<%s,注释符号>\n",other);
else
if (search(other,7))
printf("<%s,逻辑运算符号>\n",other);
else
printf("错误!非法字符:%s\n",other);
u: return (ch);
}

/////////////////////////////////////////////////////////////////////////////////////////////
void main ()
{
char str,c;
printf("**********************************词法分析器************************************\n");
//outp=fopen("二元式表.txt","w");
if ((fp=fopen("源程序.txt","r"))==NULL)
printf("源程序无法打开!\n");
else
{
str =fgetc(fp);
while (str!=EOF)
{
if (isalpha(str)!=0)
str=letterprocess(str);
else
{
if (isdigit(str)!=0)
str=numberprocess(str);
else
str=otherprocess(str);
}

};
printf("词法分析结束,谢谢使用!\n");
printf("点任意键退出!\n");
}
c=getch();
}

‘陆’ 编译原理中词法分析和语法分析的任务分别是什么

在编译原理中,语法规则和词法规则不同之处在于:规则主要识别单词,而语法主要识别多个单词组成的句子。
词法分析和词法分析程序:
词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。词法分析程序实现这个任务。词法分析程序可以使用lex等工具自动生成。
语法分析(Syntax analysis或Parsing)和语法分析程序(Parser)
语法分析是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.
语义分析(Syntax analysis)
语义分析是编译过程的一个逻辑阶段. 语义分析的任务是对结构上正确的源程序进行上下文有关性质的审查, 进行类型审查.语义分析将审查类型并报告错误:不能在表达式中使用一个数组变量,赋值语句的右端和左端的类型不匹配.

‘柒’ 编译原理课程设计-词法分析器设计(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所示:

具体的你在修改修改吧

‘捌’ 怎样较容易理解编译原理中词法分析的原理即实现过程,最好配上图文解说

词法分析的本质是让计算机程序理解词法规则。例如,在我们平时用的语言里,“你”是指一个人,当“你们”出现的时候就是一个词是指多个人,这就是一种规则,但是是人能理解的规则,词法分析要用数学的表达方式让计算机理解,计算机的做法是对每个遇到的字先判断是不是“你”,如果不是,那么不符合这条规则;如果是,就要记下现在这个状态---即已经看到一个“你”字,然后判断下一个字是不是“们”,是则这条规则成立,也就是让计算机理解了这一个词,而不是单个的两个字。词法分析不是编译原理才有的,在搜索、数据挖掘等领域都用到。编译原理中的词法分析就是把源程序中的字符按顺序一个一个输入给计算机,计算机对每个字符按照所有规则进行判断,例如输入了一个“a”,要判断它是不是“and“的开头,是不是一个变量名,函数名,还是字符串等等,每个可能性都是一条规则决定的。根据规则的复杂性,可以用多种数学方法描述,比如基本的方法是状态机、正则表达式。

‘玖’ 编译原理词法分析程序

(一)Block子程序分析

procere enter(k: object1); //填写符号表
begin {enter object into table}
tx := tx + 1; //下标加1,tx的初始值为零,零下标不地址不填写标志符,用于查找失败使用
with table[tx] do //填入内容,保存标志符名和类型
begin name := id; kind := k;
case k of //根据类型判断是否正确
constant: begin if num > amax then //如果是常量,判断是否大于最大值,若是则报30号错
begin error(30); num :=0 end;
val := num //否则保存数值
end;
varible: begin level := lev; adr := dx; dx := dx + 1; //如果是变量,填写变量内部表示,LEVEl是变量的层次,adr为地址
end;
proc: level := lev //如果是过程,保存过程的层次
end
end
end {enter};

//查找符号表的位置
function position(id: alfa): integer;
var i: integer;
begin {find indentifier id in table} //从后向前查找
table[0].name := id; i := tx; //找到保存类型
while table[i].name <> id do i := i-1;
position := i //返回标志符在符号表中的位置
end {position};

procere block(lev,tx: integer; fsys: symset);
var dx: integer; {data allocation index} //数据分配索引
tx0: integer; {initial table index} //初始符号表索引
cx0: integer; {initial code index} //初始代码索引
procere enter(k: object1); //填写符号表,下次分析
begin {enter object into table}
tx := tx + 1;
with table[tx] do
begin name := id; kind := k;
case k of
constant: begin if num > amax then
begin error(30); num :=0 end;
val := num
end;
varible: begin level := lev; adr := dx; dx := dx + 1;
end;
proc: level := lev
end
end
end {enter};

function position(id: alfa): integer; //查找符号表,下次分析
var i: integer;
begin {find indentifier id in table}
table[0].name := id; i := tx;
while table[i].name <> id do i := i-1;
position := i
end {position};

procere constdeclaration; //常量声明
begin if sym = ident then //如果是标志符,读入一个TOKEN
begin getsym;
if sym in [eql, becomes] then //读入的是等号或符值号继续判断
begin if sym = becomes then error(1); //如果是“=”报1号错
getsym; //读入下一个TOKEN
if sym = number then //读入的是数字,填写符号表
begin enter(constant); getsym
end
else error(2) //如果不是数字,报2号错
end else error(3) //不是等号或符值号,报3号错
end else error(4) //如果不是标志符,报4号错
end {constdeclaration};

procere vardeclaration; //变量声明
begin if sym = ident then //读入的是标志符,填写符号表
begin enter(varible); getsym
end else error(4) //不是标志符,报4号错
end {vardeclaration};

procere listcode;
var i: integer;
begin {list code generated for this block}
for i := cx0 to cx-1 do
with code[i] do
writeln(i:5, mnemonic[f]:5, 1:3, a:5)
end {listcode};

procere statement(fsys: symset);
var i, cx1, cx2: integer;
procere expression(fsys: symset); //表达式分析
var addop: symbol;
procere term(fsys: symset); //项分析
var mulop: symbol;
procere factor(fsys: symset); //因子分析
var i: integer;
begin test(facbegsys, fsys, 24); //读入的是“(”,标志符或数字
while sym in facbegsys do
begin
if sym = ident then //是标志符,查表
begin i:= position(id);
if i = 0 then error(11) else //未找到,报11号错
with table[i] do //找到,读入标志符类型
case kind of
constant: gen(lit, 0, val); //写常量命令
varible: gen(lod, lev-level, adr);//写变量命令
proc: error(21) //过程名,报21号错
end;
getsym //读入下一个TOKEN
end else
if sym = number then //读入的是数字
begin if num > amax then //如果数字大于最大数,报30号错误
begin error(30); num := 0
end;
gen(lit, 0, num); getsym //调用数字命令,读入下一个TOKEN
end else
if sym = lparen then //读入的是“(”
begin getsym; expression([rparen]+fsys); //调用表达式分析函数
if sym = rparen then getsym else error(22) //如果“(”后无“)”,报22号错
end;
test(fsys, [lparen], 23)
end
end {factor};//因子分析结束

//项分析
begin {term} factor(fsys+[times, slash]); //调用因子分析程序
while sym in [times, slash] do //取得是乘、除号循环
begin mulop:=sym;getsym;factor(fsys+[times,slash]); //记录符号,调用因子分析
if mulop=times then gen(opr,0,4) else gen(opr,0,5) //写乘除指令
end
end {term};
begin {expression}
if sym in [plus, minus] then //如果是加减号
begin addop := sym; getsym; term(fsys+[plus,minus]); //记录符号,调用项分析程序
if addop = minus then gen(opr, 0,1) //写加减指令
end else term(fsys+[plus, minus]);
while sym in [plus, minus] do //如果是加减号循环
begin addop := sym; getsym; term(fsys+[plus,minus]);
if addop=plus then gen(opr,0,2) else gen(opr,0,3)
end
end {expression};

//条件过程
procere condition(fsys: symset);
var relop: symbol;
begin
if sym = oddsym then //如果是判奇符
begin getsym; expression(fsys); gen(opr, 0, 6) //取下一个TOKEN,调用expression,填指令
end else
begin expression([eql, neq, lss, gtr, leq, geq]+fsys);
if not(sym in [eql, neq, lss, leq, gtr, geq]) then //如果不是取到逻辑判断符号,出错.20
error(20) else
begin relop := sym; getsym; expression(fsys);
case relop of
eql: gen(opr, 0, 8); // =,相等
neq: gen(opr, 0, 9); // #,不相等
lss: gen(opr, 0, 10); // <,小于
geq: gen(opr, 0, 11); // ],大于等于
gtr: gen(opr, 0, 12); // >,大于
leq: gen(opr, 0, 13); // [,小于等于
end
end
end
end {condition};

begin {statement}
if sym = ident then //如果是标识符
begin i := position(id); //查找符号表
if i = 0 then error(11) else //未找到,标识符未定义,报11号错
if table[i].kind <> varible then //如果标识符不是变量,报12号错
begin {assignment to non-varible} error(12); i := 0
end;
getsym; if sym = becomes then getsym else error(13); //如果是变量读入下一个TOKEN,不是赋值号,报13好错;是则读入一个TOKEN
expression(fsys); //调用表达是过程
if i <> 0 then //写指令
with table[i] do gen(sto, lev-level, adr)
end else
if sym = callsym then //如果是过程调用保留字,读入下一个TOKEN
begin getsym;
if sym <> ident then error(14) else //不是标识符报14号错
begin i := position(id);
if i = 0 then error(11) else //是标识符,未定义,报13号错
with table[i] do // 已定义的标识符读入类型
if kind=proc then gen(cal, lev-level, adr) //是过程名写指令
else error(15); //不是过程名,报15号错
getsym
end
end else
if sym = ifsym then //如果是IF
begin getsym; condition([thensym, dosym]+fsys); //读入一个TOKEN,调用条件判断过程
if sym = thensym then getsym else error(16); //如果是THEN,读入一个TOKEN,不是,报16号错
cx1 := cx; gen(jpc, 0, 0); //写指令
statement(fsys); code[cx1].a := cx
end else
if sym = beginsym then //如果是BEGIN
begin getsym; statement([semicolon, endsym]+fsys); //读入一个TOKEN
while sym in [semicolon]+statbegsys do
begin
if sym = semicolon then getsym else error(10); //如果读入的是分号
statement([semicolon, endsym]+fsys)
end;
if sym = endsym then getsym else error(17) //如果是END 读入一个TOKEN,不是,报17号错
end else
if sym = whilesym then //如果是WHILE
begin cx1 := cx; getsym; condition([dosym]+fsys); //调用条件过程
cx2 := cx; gen(jpc, 0, 0); //写指令
if sym = dosym then getsym else error(18); //如果是DO读入下一个TOKEN,不是报18号错
statement(fsys); gen(jmp, 0, cx1); code[cx2].a := cx
end;
test(fsys, [], 19)
end {statement};

begin {block}
dx:=3;
tx0:=tx;
table[tx].adr:=cx;
gen(jmp,0,0);
if lev > levmax then error(32);
repeat
if sym = constsym then //如果是CONST
begin getsym; //读入TOKEN
repeat constdeclaration; //常量声明
while sym = comma do
begin getsym; constdeclaration
end;
if sym = semicolon then getsym else error(5) //如果是分号读入下一个TOKEN,不是报5号错
until sym <> ident //不是标志符常量声明结束
end;
if sym = varsym then 如果是VAR
begin getsym; 读入下一个TOKEN
repeat vardeclaration; //变量声明
while sym = comma do
begin getsym; vardeclaration
end;
if sym = semicolon then getsym else error(5) //如果是分号读入下一个TOKEN,不是报5号错
until sym <> ident; //不是标志符常量声明结束
end;
while sym = procsym do //过程声明
begin getsym;
if sym = ident then
begin enter(proc); getsym
end
else error(4); //不是标志符报4号错
if sym = semicolon then getsym else error(5); //如果是分号读入下一个TOKEN,不是报5号错
block(lev+1, tx, [semicolon]+fsys);
if sym = semicolon then //如果是分号,取下一个TOKEN,不是报5号错
begin getsym;test(statbegsys+[ident,procsym],fsys,6)
end
else error(5)
end;
test(statbegsys+[ident], declbegsys, 7)
until not(sym in declbegsys); //取到的不是const var proc结束
code[table[tx0].adr].a := cx;
with table[tx0] do
begin adr := cx; {start adr of code}
end;
cx0 := 0{cx}; gen(int, 0, dx);
statement([semicolon, endsym]+fsys);
gen(opr, 0, 0); {return}
test(fsys, [], 8);
listcode;
end {block};

‘拾’ 请问编译原理中什么叫完成词法分析,语法分析

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

阅读全文

与编译原理词法分析相关的资料

热点内容
android图片变灰 浏览:268
linuxvi下一个 浏览:975
安卓手机的应用锁怎么解 浏览:735
linux增加路径 浏览:849
sql身份证号最后四位加密 浏览:533
xp系统表格加密 浏览:856
光遇安卓军大衣什么时候上线 浏览:840
android应用商店图标 浏览:341
java计算圆的面积 浏览:643
应用编译优化recovery 浏览:577
域控命令n 浏览:258
php导出文件 浏览:15
谷歌地图网页版无法连接服务器地址 浏览:298
菜鸟工具在线编译python 浏览:858
栅格化命令有何作用 浏览:825
为什么压缩文件不能解压 浏览:311
足球app哪个软件好 浏览:96
产品经理逼疯程序员的一天 浏览:17
修改svn服务器ip地址 浏览:584
下列关于编译说法正确的是 浏览:246