c语言的词法分析
⑴ 一个c语言词法分析题目
//给你课程设计的词法部分呵呵
#include <iostream>
#include <fstream>
#include <stack>
#include <map>
#include <string>
using namespace std;
#define zhengshu 1 //int
#define IF 2 //if
#define ELSE 3 //else
#define shishu 4 //float
#define PRINT 5 //print
#define ID 6 //identify
#define CONSTANT 7 //constant
#define op_fu 8 //=
#define op_add 9 //+
#define op_mul 10 //*
#define op_2star 11 //**
#define div_fenhao 12 //;
#define syl_ls 13 //(
#define syl_rs 14 //)
#define syl_lb 15 //{
#define syl_rb 16 //}
#define sbl_lm 17 //[
#define sbl_rm 18 //]
#define op_sub 19 //-
#define op_div 20 // /
#define div_douhao 21 //,
#define rop_yu 22 //&&
#define op_or 23 //||
#define rop_fei 24 //!
#define rop_equal 25 //==
#define rop_dayu 26 //>
#define rop_xiaoyu 27 //<
#define rop_buxiaoyu 28 //>=
#define rop_budayu 29 //<=
#define rop_uneql 30 //!=
#define TEMP 31
#define NULL 0
#define JMP 32
#define GOTO 33 //goto标识
/*****************************重要数据结构的声明开始*************************/
struct delos
{
int code,value;
}*result; //结果
//变量表
struct analyse
{
int state;
char sign;
};
struct list
{
int value;
list *next;
};
//条件语句的LR(1)分析表,110表示接受,999表示出错
int table[38][20]={
/*0*/{3,999,999,999,999,999,999,999,999,999,999,999,4,999,1,2,999,999,999,999},
/*1*/{999,999,999,999,999,999,999,999,999,999,999,999,999,110,999,999,999,999,999,999},
/*2*/{74,999,999,999,999,999,999,999,999,999,999,999,74,74,999,999,999,999,5,999},
/*3*/{999,6,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999},
/*4*/{999,999,999,999,7,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999},
/*5*/{999,999,999,999,999,999,999,999,999,999,999,999,999,61,999,999,999,999,999,999},
/*6*/{999,12,999,999,999,999,999,9,999,999,999,11,13,999,999,999,8,10,999,999},
/*7*/{999,12,999,999,999,999,999,999,999,999,999,11,13,999,999,999,999,14,999,999},
/*8*/{999,999,15,999,999,16,17,999,999,999,999,999,999,999,999,999,999,999,999,999},
/*9*/{999,12,999,999,999,999,999,9,999,999,999,11,13,999,999,999,18,10,999,999},
/*10*/{999,999,999,999,999,999,999,999,19,20,21,999,999,999,999,999,999,999,999,999},
/*11*/{999,12,999,999,999,999,999,999,999,999,999,11,13,999,999,999,999,22,999,999},
/*12*/{999,12,999,999,999,999,999,999,999,999,999,11,13,999,999,999,999,23,999,999},
/*13*/{999,999,73,73,999,73,73,999,73,73,73,999,999,73,999,999,999,999,999,999},
/*14*/{999,999,999,64,999,999,999,999,999,20,21,999,999,64,999,999,999,999,999,999},
/*15*/{74,999,999,999,999,999,999,999,999,999,999,999,74,74,999,999,999,999,24,999},
/*16*/{74,999,999,999,999,999,999,999,999,999,999,999,74,74,999,999,999,999,999,25},
/*17*/{74,999,999,999,999,999,999,999,999,999,999,999,74,74,999,999,999,999,999,26},
/*18*/{999,999,67,999,999,67,67,999,999,999,999,999,999,999,999,999,999,999,999,999},
/*19*/{999,12,999,999,999,999,999,999,999,999,999,11,13,999,999,999,999,27,999,999},
/*20*/{999,12,999,999,999,999,999,999,999,999,999,11,13,999,999,999,999,28,999,999},
/*21*/{999,12,999,999,999,999,999,999,999,999,999,11,13,999,999,999,999,29,999,999},
/*22*/{999,999,71,71,999,71,71,999,71,71,71,999,999,71,999,999,999,999,999,999},
/*23*/{999,999,30,999,999,999,999,999,999,20,21,999,999,999,999,999,999,999,999,999},
/*24*/{3,999,999,999,999,999,999,999,999,999,999,999,4,999,999,31,999,999,999,999},
/*25*/{999,12,999,999,999,999,999,9,999,999,999,11,13,999,999,999,32,10,999,999},
/*26*/{999,12,999,999,999,999,999,9,999,999,999,11,13,999,999,999,33,10,999,999},
/*27*/{999,999,68,999,999,68,68,999,999,20,21,999,999,999,999,999,999,999,999,999},
/*28*/{999,999,69,69,999,69,69,999,69,69,21,999,999,69,999,999,999,999,999,999},
/*29*/{999,999,70,70,999,70,70,999,70,70,70,999,999,70,999,999,999,999,999,999},
/*30*/{999,999,72,72,999,72,72,999,72,72,72,999,999,72,999,999,999,999,999,999},
/*31*/{999,999,999,75,999,999,999,999,999,999,999,999,999,63,999,999,999,999,999,34},
/*32*/{999,999,65,999,999,65,65,999,999,999,999,999,999,999,999,999,999,999,999,999},
/*33*/{999,999,66,999,999,16,66,999,999,999,999,999,999,999,999,999,999,999,999,999},
/*34*/{999,999,999,35,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999},
/*35*/{74,999,999,999,999,999,999,999,999,999,999,999,74,74,999,999,999,999,36,999},
/*36*/{3,999,999,999,999,999,999,999,999,999,999,999,4,999,999,37,999,999,999,999},
/*37*/{999,999,999,62,999,999,999,999,999,999,999,999,999,62,999,999,999,999,999,999}
};
/*****************************重要数据结构的声明结束*************************/
/*********************************全局变量声明开始**************************/
int place=1;
int nextpos=1;
stack<list *> stknext;
stack<list *> stktrue;
stack<list *> stkfalse;
stack<int> stkpos;
stack<delos> stktemp;//常量,变量,临时变量
delos temp;
delos gen[50][4];//生成的三地址
string str[31]={"","int","if","else","float","print","标识符","常数",
"=","+","*","**",";","(",")",
"{","}","[","]","-","/",",","&&","||","!",
"==",">","<",">=","<=","!="};
//变量
string *var;
int varlen=0,nowvar=1;
//常量
float *myconst;
int constlen=0,nowconst=1;
int resultlen=0,nowresult=0;
/*********************************全局变量声明结束**************************/
void renewresult()
{
delos *p3=result;
int i;
resultlen+=10;
result=new delos[resultlen];
for(i=0;i<resultlen;i++)
{ result[i].code=p3[i].code;
result[i].value=p3[i].value;
}
delete[] p3;
}
void renewvar()
{
string *p1=var;
int i;
varlen+=10;
var=new string[varlen];
for(i=0;i<nowvar;i++)
var[i]=p1[i];
delete[] p1;
}
void renewconst()
{
float *p2=myconst;
int i;
constlen+=10;
myconst=new float[constlen];
for(i=0;i<nowconst;i++)
myconst[i]=p2[i];
delete[] p2;
}
bool isletter(char c) //判别是否字母
{
if(c>64&&c<91||c>96&&c<123)
return true;
return false;
}
bool isdigital(char c) //判别是否数字
{ if(c>47&&c<58)
return true;
return false;
}
int reserve(char c[],int i)
{
string s(c,0,i);
for(int j=1;j<7;j++)
if(s==str[j])
return j;
return 0;
}
void insertresult(int code,int value)
{ if(nowresult>resultlen)
renewresult();
result[nowresult].code=code;
result[nowresult++].value=value;
}
void insertid(char c[],int i)
{ string s(c,0,i);
insertresult(ID,nowvar);
if(nowvar>varlen)
renewvar();
var[nowvar++]=s;
}
//插入常数,为浮点型
void insertconst(char c[],int i)
{ int d=0,j;
float a=0,b=1;
while(c[d]!='.'&&d<i)
d++;
for(j=d-1;j>=0;j--)
{ a=a+(c[j]-48)*b;
b=b*10;
}
b=10;
for(j=d+1;j<i;j++)
{a=a+(c[j]-48)/b;
b=b*10;
}
insertresult(CONSTANT,nowconst);
if(nowconst>constlen)
renewconst();
myconst[nowconst++]=a;
}
/**********************************词法分析函数开始***********************/
void wordanalyse()
{
char strtoken[10];
int i=0,code;
char ch;
ifstream myfile;
myfile.open("sourcefile.txt");
if(!myfile)
{ cout<<"Can not open input file !"<<endl;
return;
}
while(!myfile.eof())
{ i=0;
for(ch=myfile.get();ch==' '||ch==13||ch==10;ch=myfile.get())
;
if(isletter(ch))
{while(isletter(ch)||isdigital(ch))
{strtoken[i++]=ch;
ch=myfile.get();
}
myfile.seekg(-1,ios::cur);
code=reserve(strtoken,i);
if(code==0)
insertid(strtoken,i);
else
{insertresult(code,0);
}
}
else if(isdigital(ch))
{while(isdigital(ch)||ch=='.')
{strtoken[i++]=ch;
ch=myfile.get();
}
myfile.seekg(-1,ios::cur);
insertconst(strtoken,i);
}
else if(ch=='=')
{ ch=myfile.get();
if(ch=='=')
insertresult(rop_equal,0);
else
{insertresult(op_fu,0);
myfile.seekg(-1,ios::cur);
}
}
else if(ch=='+')
{insertresult(op_add,0);
}
else if(ch=='*')
{ ch=myfile.get();
if(ch=='*')
insertresult(op_2star,0);
else
{insertresult(op_mul,0);
myfile.seekg(-1,ios::cur);
}
}
else if(ch==';')
{ insertresult(div_fenhao,0);
}
else if(ch=='(')
{insertresult(syl_ls,0);
}
else if(ch==')')
{insertresult(syl_rs,0);
}
else if(ch=='{')
{ insertresult(syl_lb,0);
}
else if(ch=='}')
{ insertresult(syl_rb,0);
}
else if(ch=='[')
{ insertresult(sbl_lm,0);
}
else if(ch==']')
{ insertresult(sbl_rm,0);
}
else if(ch=='-')
{ insertresult(op_sub,0);
}
else if(ch=='/')
{ insertresult(op_div,0);
}
else if(ch==',')
{ insertresult(div_douhao,0);
}
else if(ch=='&')
{ ch=myfile.get();
if(ch=='&')
insertresult(rop_yu,0);
else
{
myfile.seekg(-1,ios::cur);
myfile.get(strtoken,10);
cout<<"ERROR :"<<strtoken<<endl;
}
}
else if(ch=='|')
{ ch=myfile.get();
if(ch=='|')
insertresult(op_or,0);
else
{
myfile.seekg(-1,ios::cur);
myfile.get(strtoken,10);
cout<<"ERROR :"<<strtoken<<endl;
}
}
else if(ch=='!')
{ ch=myfile.get();
if(ch=='=')
insertresult(rop_uneql,0);
else
{insertresult(rop_fei,0);
myfile.seekg(-1,ios::cur);
}
}
else if(ch=='>')
{ ch=myfile.get();
if(ch=='=')
insertresult(rop_buxiaoyu,0);
else
{insertresult(rop_dayu,0);
myfile.seekg(-1,ios::cur);
}
}
else if(ch=='<')
{ ch=myfile.get();
if(ch=='=')
insertresult(rop_budayu,0);
else
{insertresult(rop_xiaoyu,0);
myfile.seekg(-1,ios::cur);
}
}
else
{if(ch!=-1)
{myfile.seekg(-1,ios::cur);
myfile.get(strtoken,10);
cout<<"ERROR :"<<strtoken<<endl;
myfile.seekg(1,ios::cur);
}
}
}
myfile.close();
cout<<"词法分析成功啦!!"<<endl;
}
/**********************************词法分析函数结束***********************/
⑵ c语言的词法分析器
任务1:识别小型语言所有单词的词法分析程序设计
源程序设计语言
G[<程序>]
<程序>→<变量说明><BEGIN>
<语句表>
<END>.
<变量说明>→VAR<变量表>:<类型>;|<空>
<变量表>→<变量表>,<变量>|<变量>
<类型>→INTEGER
<语句表>→<语句>
|
<语句>;<语句表>
<语句>→<赋值语句>|<条件语句>|<WHILE语句>|<复合语句>
<赋值语句>→<变量>:=<算术表达式>
<条件语句>→IF<关系表达式>THEN<语句>ELSE<语句>
<WHILE语句>→WHILE<关系表达式>DO<语句>
<复合语句>→BEGIN<语句表>END
<算术表达式>→<项>|<算术表达式>+<项>|<算术表达式>-<项>
<项>→<因式>|<项>*<因式>|<项>/<因式>
<因式>→<变量>|<整数>|(<算术表达式>)
<关系表达式>→<算术表达式><关系符><算术表达式>
<变量>→<标识符>
<标识符>→<标识符><字母>|<标识符><数字>|<字母>
<整数>→0|<非零数字><泛整数>
<泛整数>→<数字>|<数字><泛整数>|ε
<关系符>→<|<=|==|>|>=|<>
<字母>
→A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
<非零数字>→1|2|3|4|5|6|7|8|9
<数字>→<非零数字>|0
<空>→
要求和提示:
词法分析阶段,可以打开任意位置和名称的源文件进行词法分析,可以进行非法字符和数字后边跟字母的错误判断,如果没有错误则提示“词法分析正确完成!”,并且可以选择输出token.txt(token文件)string.txt(符号表)两个文件;
1.词法分析程序的主要任务如下:
①
组织源程序的输入,识别出源程序中的各个基本语法单位(也称为单词或语法符号),按规则转换成二元式的形式;
②
删除无用的空白字符、回车符、及其它非实质性符号;
③
删除注解行;
④
为后面的语法和语义分析提供二元式链表;
单词
编码
单词
编码
标识符
1
<
15
正整数
2
<=
16
BEGIN
3
>
17
END
4
>=
18
IF
5
<>
19
THEN
6
==
20
ELSE
7
;
21
WHILE
8
.
22
DO
9
:=
23
INTEGER
10
,
24
+
11
(
25
-
12
)
26
*
13
/
14
1)
对标识符的长度控制在8个字符(包括8个)以内,超过的做截断处理;
2)
数字不大于65535,否则报错;
3)
能跳过源程序中的空白格:两个单词之间的任何空格,制表符,回车,换行都是白空格,除了用来分隔单词以外,没有意义;
4)
能跳过注释:
a)
接连出现的/*到下一次接连出现的*/之间的任何文字都是注释(多行);
b)
从某行接连出现的//到该行的结尾的任何文字都是注释(单行)。
3.怎样编写词法分析程序:
1)
预处理:把源文件一个字符一个字符的读入词法分析程序设置的输入字符结构体数组中(输入缓冲区),读入过程要删除注释,删除多余的白空格;
2)
从源程序字符数组中获得单词,
编码为二元式.:
二元式采用结构体数组存储,
把单词类型和词元记录下来。
分解单词的方法:
1)
Case多路转换语句根据单词的特点直接编写;
2)
通过描述单词的正规文法得到相应的有穷自动机,通过case多路转换语句完成有穷自动机的处理流程。
3.编写词法分析程序要注意的问题:
1)
检查词法是否有错误
检查是否有非法字符:如
@,
&,
!
检查标志符和数字是否满足限制条件
检查注释符号是否配对
2)
符分隔单词
能够区分两个单词的符号为界符
有些界符不是单词:如白空格
有些界符仅仅用来分隔:如;
有些界符本身还是源程序不可缺少的单词,如(,
),
+,
/,
等等
有些界符包含两个字符:如<>,
>=等等
3)
输出词法错误
如果有错误,需要报告词法错误的原因。并且要能够越过错误,分解下一个单词,直到源程序结束。
4)
输出的二元式流保存在二元式结构体数组中。
⑶ 求c语言词法分析程序
以前学c语言的时候写的,但是没有经过很好的设计,程序结构比较乱。运行没有问题。也可以处理包含的头文件。
/*************************************************
c语言分析程序
*************************************************/
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
char *key[]={"auto","bool","break","case","char","complex","const","continue","default","restrict","do","double","else","enum","extern","float","for","goto","if","imaginary","inline","int","long","register","return","stort","signed","sizeof","static","struct","switch","tyepdef","union","unsigned","void","volatile","while"};
char *limit[]={"#","(",")","[","]","'","\"",";",":","{","}","\\",","};
char *ysf[]={"!","%","^","&","*","-","+","=","~","|",".","<",">","/","?",":","+=","-=","*=","/","%=","<<=",">>=","&=","^=","|=","->","++","--","<<",">>","<=",">=","==","!=","&&","||"};
char b[30];
char fn[20]={'\0'},text1[1000]={'\0'},string[30]={'\0'},text2[1000]={'\0'},kuoru[30];
char hm[10][30],hz[10][30];
char * tempp;
int z=1,y;
int i=0,j=0,k=1,n=1,p=1,q=1,o=1,m=1,x=0,temp,k1=0,k2=0,keyy,key1=0,key2=0,key3=0,key4=0,key5=0,key6=0;
FILE * sfhead;
FILE * ofhead;
FILE * bsfhead;
FILE * zsclbhead;
FILE * fdsclbhead;
FILE * zfclbhead;
FILE * zfcclbhead;
FILE * fgfhead;
FILE * ysfhead;
FILE * blzhead;
FILE * krhead;
bool find1(char * p){
int i=0;
for(i=0;i<36;i++){
if(strcmp(key[i],p)==0)
return true;
}
return false;
} /*判断提取的字符串是否属于保留字*/
int bianma1(char * p){
int i=0;
for(i=0;i<36;i++){
if(strcmp(key[i],p)==0)
return i+1;
}
return -1; /*确定保留字的序号*/
}
bool find2(char p){
int i=0;
for(i=0;i<13;i++){
if(*limit[i]==p)
return true;
}
return false;
} /*判断提取的符号是否为分隔符*/
int bianma2(char p){
int i=0;
for(i=0;i<13;i++){
if(*limit[i]==p)
return i+1;
}
return -1;
} /*确定分割符的序号*/
bool find3(char p){
int i=0;
for(i=0;i<37;i++){
if(*ysf[i]==p)
return true;
}
return false;
} /*判断提取的符号是否为运算符*/
int bianma3(char * p){
int i=0;
for(i=0;i<37;i++){
if(strcmp(ysf[i],p)==0)
return i+1;
}
return -1;
} /*确定运算符的序号*/
int bianma4(char * p){
int i=0;
for(i=0;i<10;i++){
if(strcmp(hm[i],p)==0)
return i;
}
return -1;
}
bool search(FILE * fp,char * p){
char a[30],c[30];
rewind(fp); /*将fp指向文件头部*/
while(!feof(fp)){
fscanf(fp,"%s",a);
if(strcmp(a,p)==0){ /*保存编码*/
fgets(b,30,fp);
return true;
}else
fgets(c,30,fp);
}
return false;
}
void clnmb(char * text){ /*处理以数字开头的函数*/
bool l=true;
string[j]=text[i];
i++;j++;
while(((text[i]>='0')&&(text[i]<='9'))||text[i]=='.'||text[i]=='e'||text[i]=='E'||text[i]=='-'){
string[j]=text[i];
if(text[i]=='.')
l=false;
i++;j++; /*判断数字字符串中有无小数点,如果有则证明位浮点数*/
}
if(l){
if(search(zsclbhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(zsclbhead,"\n\r%s\t",string);
fprintf(zsclbhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else{
fprintf(zsclbhead,"\n\r%s\t",string);
fprintf(zsclbhead,"4\t");
fprintf(zsclbhead,"0\t");
fprintf(zsclbhead,"%d\t\n\r",m);
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"4\t");
fprintf(ofhead,"0\t");
fprintf(ofhead,"%d\t\n\r",m);
m++; /*用m标记出现整数常量的地址*/
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
}else{
if(search(fdsclbhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(fdsclbhead,"\n\r%s\t",string);
fprintf(fdsclbhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else{
fprintf(fdsclbhead,"\n\r%s\t",string);
fprintf(fdsclbhead,"4\t");
fprintf(fdsclbhead,"1\t");
fprintf(fdsclbhead,"%d\t\n\r",o);
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"4\t");
fprintf(ofhead,"1\t");
fprintf(ofhead,"%d\t\n\r",o); /*用o标记出现的浮点数常量地址*/
o++;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
l=true;
}
}
void dayin(FILE * fp){
int i;
char temp[40];
rewind(fp);
while(!feof(fp)){
fgets(temp,40,fp);
printf("%s",temp);
}
for(i=0;i<40;i++)
temp[i]='\0';
}
/****************************************
扫描分析程序段
*****************************************/
void saomiao(char * text){
i=0;
while(text[i]!='\0'){
if((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')){ /*分析以字母开头的情况*/
while((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')||text[i]=='_'||(text[i]>='0'&&text[i]<='9')){
string[j]=text[i];
i++;j++;
}
if(find1(string)){ /*判断是否为保留字*/
fprintf(blzhead,"\n\r%s\t",string);
fprintf(blzhead,"0\t");
fprintf(blzhead,"%d\t\n\r",bianma1(string));
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"0\t");
fprintf(ofhead,"%d\t\n\r",bianma1(string)); /*将字符串直接写入相应的文件和输出文件*/
for(j=0;j<30;j++) /*将string数组清空,防止出现错误*/
string[j]='\0';
j=0;
}
else {
if((keyy=bianma4(string))!=-1){
temp=i;
tempp=text;
i=0;
for(j=0;j<30;j++) /*将string数组清空,防止出现错误*/
string[j]='\0';
j=0;
clnmb(hz[keyy]);
text=tempp;
i=temp;
}else
if(search(bsfhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(bsfhead,"\n\r%s\t",string);
fprintf(bsfhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else{
fprintf(bsfhead,"\n\r%s\t",string);
fprintf(bsfhead,"3\t");
fprintf(bsfhead,"%d\t\n\r",k);
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"3\t");
fprintf(ofhead,"%d\t\n\r",k);
k++; /*用k标记出现标识符的地址*/
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
}
}
else if((text[i]>='0')&&(text[i]<='9')) /*分析以数字开头的情况*/
clnmb(text);
else if(find2(text[i])){ /*分析以分隔符开头的情况*/
if(text[i]=='{') key1++;
if(text[i]=='}') key2++;
if(text[i]=='[') key3++;
if(text[i]==']') key4++;
if(text[i]=='(') key5++;
if(text[i]==')') key6++;
string[0]=text[i];
if(text[i]=='\"'){ /*考虑其中可能出现的一"开头的字符串类型常量*/
do{
string[j]=text[i];
j++;i++;
}while(text[i]!='\"');
string[j]=text[i];
i++;j++;
if(search(zfcclbhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(zfcclbhead,"\n\r%s\t",string);
fprintf(zfcclbhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else{
fprintf(zfcclbhead,"\n\r%s\t",string);
fprintf(zfcclbhead,"4\t");
fprintf(zfcclbhead,"3\t");
fprintf(zfcclbhead,"%d\t\n\r",q); /*用q标记出现字符串常量的地址*/
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"4\t");
fprintf(ofhead,"3\t");
fprintf(ofhead,"%d\t\n\r",q);
q++;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
}
if(text[i]=='\''){ /*考虑可能出现的一'开头的字符类型常量*/
string[0]=text[i];
while(text[i]!='\''){
string[j]=text[i];
i++;j++;
}
string[j]=text[i];
if(search(zfclbhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(zfclbhead,"\n\r%c\t",text[i]);
fprintf(zfclbhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
else{
fprintf(zfclbhead,"\n\r%c\t",text[i]);
fprintf(zfclbhead,"4\t");
fprintf(zfclbhead,"4\t");
fprintf(zfclbhead,"%d\t\n\r",p);
fprintf(ofhead,"\n\r%c\t",text[i]);
fprintf(ofhead,"4\t");
fprintf(ofhead,"4\t");
fprintf(ofhead,"%d\t\n\r",p);
p++;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
}
if(text[i]=='#'){
i++;
while((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')){
string[j]=text[i];
j++;i++;
}
if(strcmp(string,"include")==0){ /*括入文件处理程序段*/
if(text[i]=='\"'||text[i]=='<')i++;
while((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z'||text[i]=='.')){
kuoru[x]=text[i];
i++;x++;
}
if((krhead=fopen(kuoru,"r"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
while(!(feof(krhead)))
text2[y++]=fgetc(krhead);
text2[y]='\0';
y=0;
temp=i;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
saomiao(text2);
i=temp;
for(x=0;x<30;x++)
kuoru[x]='\0';
x=0;
i++;
}
if(strcmp(string,"define")==0){
for(j=0;j<30;j++)
string[j]='\0';
j=0;
while(!(text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z'))i++;
while((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')||text[i]=='_'||(text[i]>='0'&&text[i]<='9')){
hm[k1][k2]=text[i];
i++;k2++;
}
k2=0;
while(!(text[i]>='0')&&(text[i]<='9'))i++;
while((text[i]>='0')&&(text[i]<='9')||text[i]=='.'||text[i]=='e'||text[i]=='E'||text[i]=='-'){
hz[k1][k2]=text[i];
i++;k2++;
}
k1++;
k2=0;
}
}else{
if(search(fgfhead,string));
else{
fprintf(fgfhead,"\n\r%c\t",text[i]);
fprintf(fgfhead,"1\t");
fprintf(fgfhead,"%d\t\n\r",bianma2(text[i]));
}
fprintf(ofhead,"\n\r%c\t",text[i]);
fprintf(ofhead,"1\t");
fprintf(ofhead,"%d\t\n\r",bianma2(text[i]));
i++;
}
}else if(find3(text[i])){ /*分析一运算符开头的情况*/
while(find3(text[i])){
string[j]=text[i];
i++;j++; /*考虑到有多个字符组成的运算符,运算符的判断使用字符串*/
}
if(strcmp(string,"/*")==0){
while(!(text[i-1]=='*'&&text[i]=='/'))i++; /*去掉注释*/
if(text[i]=='/')i++;
}
if(strcmp(string,"//")==0)
while(!(text[i]=='\n'))
i++; /*去掉注释*/
if((bianma3(string)==-1)&&text[i-1]=='-'){
i=i-1;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
clnmb(text); /*处理负数的情况*/
}
if(search(ysfhead,string));
else{
if(bianma3(string)!=-1){
fprintf(ysfhead,"\n\r%s\t",string);
fprintf(ysfhead,"2\t");
fprintf(ysfhead,"%d\t\n\r",bianma3(string));
}
}
if(bianma3(string)!=-1){
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"2\t");
fprintf(ofhead,"%d\t\n\r",bianma3(string));
}
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else i++;
}
}
int main(){
printf("********************\nc语言分析程序\n********************\n");
printf("\n请输入文件名:");
scanf("%s",fn);
if((sfhead=fopen(fn,"r"))==NULL){
printf("不能打开源文件!\n");
exit(0);
}
if((ofhead=fopen("分解源文件所得文件.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((bsfhead=fopen("标识符表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((zsclbhead=fopen("整数常量表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((fdsclbhead=fopen("浮点数常量表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((zfclbhead=fopen("字符常量表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((zfcclbhead=fopen("字符串常量表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((fgfhead=fopen("分隔符表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((ysfhead=fopen("运算符表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((blzhead=fopen("保留字表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
fprintf(ofhead,"单词\t");
fprintf(ofhead,"类\t");
fprintf(ofhead,"编号\t地址\t\n\r");
fprintf(bsfhead,"单词\t");
fprintf(bsfhead,"类\t");
fprintf(bsfhead,"编号\t地址\t\n\r");
fprintf(zsclbhead,"单词\t");
fprintf(zsclbhead,"类\t");
fprintf(zsclbhead,"编号\t地址\t\n\r");
fprintf(zfclbhead,"单词\t");
fprintf(zfclbhead,"类\t");
fprintf(zfclbhead,"编号\t地址\t\n\r");
fprintf(zfcclbhead,"单词\t");
fprintf(zfcclbhead,"类\t");
fprintf(zfcclbhead,"编号\t地址\t\n\r");
fprintf(fdsclbhead,"单词\t");
fprintf(fdsclbhead,"类\t");
fprintf(fdsclbhead,"编号\t地址\t\n\r");
fprintf(fgfhead,"单词\t");
fprintf(fgfhead,"类\t");
fprintf(fgfhead,"编号\t地址\t\n\r");
fprintf(ysfhead,"单词\t");
fprintf(ysfhead,"类\t");
fprintf(ysfhead,"编号\t地址\t\n\r");
fprintf(blzhead,"单词\t");
fprintf(blzhead,"类\t");
fprintf(blzhead,"编号\t地址\t\n\r"); /*初始化所需要的文件*/
while(!feof(sfhead)) /*将原程序读入字符数组便于后面分析*/
text1[i++]=fgetc(sfhead);
text1[i++]='\0';
i=0;
saomiao(text1);
if(key1!=key2)
printf("ERROR:前后大括号个数不相等。\n");
if(key3!=key4)
printf("ERROR:前后中括号个数不相等。\n");
if(key5!=key6)
printf("ERROR:前后小括号个数不相等。\n");
while(z!=0){
printf("打印:\n1分析源文件所得文件\n2保留字表\n3分隔符表\n4运算符表\n5标识符表\n6整数类型常量表\n7浮点数类型常量表\n8字符类型常量表\n9字符串类型常量表\n\n0退出程序");
printf("\n\n请输入:");
scanf("%d",&z);
switch(z){
case 1 :{printf("**********分析源文件所得文件**********\n");dayin(ofhead);break;}
case 2 :{printf("***************保留字表***************\n");dayin(blzhead);break;}
case 3 :{printf("***************分隔符表***************\n");dayin(fgfhead);break;}
case 4 :{printf("***************运算符表***************\n");dayin(ysfhead);break;}
case 5 :{printf("***************标识符表***************\n");dayin(bsfhead);break;}
case 6 :{printf("************整数类型常量表************\n");dayin(zsclbhead);break;}
case 7 :{printf("***********浮点数类型常量表***********\n");dayin(fdsclbhead);break;}
case 8 :{printf("************字符类型常量表************\n");dayin(zfclbhead);break;}
case 9 :{printf("***********字符串类型常量表***********\n");dayin(zfcclbhead);break;}
case 10 :exit(0);
}
}
fclose(ofhead);
fclose(sfhead);
fclose(bsfhead);
fclose(fgfhead);
fclose(ysfhead);
fclose(blzhead);
fclose(fdsclbhead);
fclose(zfclbhead);
fclose(zfcclbhead);
fclose(zsclbhead);
}
⑷ 怎么用c语言编一个词法分析器
简而言之就是先画一个状态图,然后根据图来编码就行
一个简单的xml的词法分析器供参考
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
typedef
struct
{
char
*p;
int
len;
}
xml_Text;
typedef
enum
{
xml_tt_U,
/*
Unknow
*/
xml_tt_H,
/*
Head
<?xxx?>*/
xml_tt_E,
/*
End
</xxx>
*/
xml_tt_B,
/*
Begin
<xxx>
*/
xml_tt_BE,
/*
Begin
End
<xxx/>
*/
xml_tt_T
/*
Text
xxx
*/
}
xml_TokenType;
typedef
struct
{
xml_Text
text;
xml_TokenType
type;
}
xml_Token;
int
xml_initText(xml_Text
*pText,
char
*s)
{
pText->p
=
s;
pText->len
=
strlen(s);
return
0;
}
int
xml_initToken(xml_Token
*pToken,
xml_Text
*pText)
{
pToken->text.p
=
pText->p;
pToken->text.len
=
0;
pToken->type
=
xml_tt_U;
return
0;
}
int
xml_print(xml_Text
*pText)
{
int
i;
for
(i
=
0;
i
<
pText->len;
i++)
{
putchar(pText->p[i]);
}
return
0;
}
int
xml_println(xml_Text
*pText)
{
xml_print(pText);
putchar('\n');
return
0;
}
int
xml_getToken(xml_Text
*pText,
xml_Token
*pToken)
{
char
*start
=
pToken->text.p
+
pToken->text.len;
char
*p
=
start;
char
*end
=
pText->p
+
pText->len;
int
state
=
0;
pToken->text.p
=
p;
pToken->type
=
xml_tt_U;
for
(;
p
<
end;
p++)
{
switch(state)
{
case
0:
switch(*p)
{
case
'<':
state
=
1;
break;
default:
state
=
7;
break;
}
break;
case
1:
switch(*p)
{
case
'?':
state
=
2;
break;
case
'/':
state
=
4;
break;
default:
state
=
5;
break;
}
break;
case
2:
switch(*p)
{
case
'?':
state
=
3;
break;
default:
state
=
2;
break;
}
break;
case
3:
switch(*p)
{
case
'>':
pToken->text.len
=
p
-
start
+
1;
pToken->type
=
xml_tt_H;
return
1;
default:
state
=
-1;
break;
}
break;
case
4:
switch(*p)
{
case
'>':
pToken->text.len
=
p
-
start
+
1;
pToken->type
=
xml_tt_E;
return
1;
default:
state
=
4;
break;
}
break;
case
5:
switch(*p)
{
case
'>':
pToken->text.len
=
p
-
start
+
1;
pToken->type
=
xml_tt_B;
return
1;
case
'/':
state
=
6;
break;
default:
state
=
5;
break;
}
break;
case
6:
switch(*p)
{
case
'>':
pToken->text.len
=
p
-
start
+
1;
pToken->type
=
xml_tt_BE;
return
1;
default:
state
=
-1;
break;
}
break;
case
7:
switch(*p)
{
case
'<':
p--;
pToken->text.len
=
p
-
start
+
1;
pToken->type
=
xml_tt_T;
return
1;
default:
state
=
7;
break;
}
break;
default:
pToken->text.len
=
p
-
start
+
1;
pToken->type
=
xml_tt_T;
return
1;
}
}
return
0;
}
int
main()
{
int
ret
=
0;
xml_Text
xml;
xml_initText(&xml,
"<?xml?><root>
ss
<haha>hoho</haha></root>");
xml_Token
token;
xml_initToken(&token,
&xml);
ret
=
xml_getToken(&xml,
&token);
printf("ret=%d;text=",ret);
xml_print(&token.text);
printf(";type=%d;\n\n",
token.type);
ret
=
xml_getToken(&xml,
&token);
printf("ret=%d;text=",ret);
xml_print(&token.text);
printf(";type=%d;\n\n",
token.type);
ret
=
xml_getToken(&xml,
&token);
printf("ret=%d;text=",ret);
xml_print(&token.text);
printf(";type=%d;\n\n",
token.type);
ret
=
xml_getToken(&xml,
&token);
printf("ret=%d;text=",ret);
xml_print(&token.text);
printf(";type=%d;\n\n",
token.type);
ret
=
xml_getToken(&xml,
&token);
printf("ret=%d;text=",ret);
xml_print(&token.text);
printf(";type=%d;\n\n",
token.type);
ret
=
xml_getToken(&xml,
&token);
printf("ret=%d;text=",ret);
xml_print(&token.text);
printf(";type=%d;\n\n",
token.type);
ret
=
xml_getToken(&xml,
&token);
printf("ret=%d;text=",ret);
xml_print(&token.text);
printf(";type=%d;\n\n",
token.type);
return
0;
}
⑸ C语言描述的单词符号的词法分析程序
啥意思?没看懂,一头雾水
⑹ 编译原理课程设计-词法分析器设计(C语言)
#include"stdio.h"/*定义I/O库所用的某些宏和变量*/
#include"string.h"/*定义字符串库函数*/
#include"conio.h"/*提供有关屏幕窗口操作函数*/
#include"ctype.h"/*分类函数*/
charprog[80]={'