
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define SPACE 0x20 //空格键
#define CHANGE 'c' //转义字符
#define STRING 'S' //引号里的字符串
#define BOUNDARY 'B' //界符
#define OPERATION 'O' //运算符
#define WORD 'I' //标识符
#define KEY_WORD 'K' //关键字
#define DIGIT 'n' //数字,包游谈括小数
#define DOTH 'd' //头文件,“.h”文件
#define INT 't'
#define VOID 'v'
#define IF 'f'
#define ELSE 'e'
#define WHILE 'w'
#define FOR 'r'
#define MAIN 'm'
#define PRINTF 'p'神冲碰
#define INCLUDE 'u'判穗
#define FLOAT 'l'
#define KEYNUM 10
#define BOUNDNUM 8
#define OPERNUM 7
#define VALUENUM 100
/************************************************************************/
/* data type */
/************************************************************************/
struct bianliang
{
int id
char name[20]
int value
}
struct changliang
{
int data
}
char KeyWord[KEYNUM][8]={"int","void","if","else","while","for","main","printf","include","float"}
char Boundary[BOUNDNUM]={'"','',',','(',')','#','{','}'}
char Operation[OPERNUM]={'+','-','*','/','=','<','>'}
char Logogram[KEYNUM]={INT,VOID,IF,ELSE,WHILE,FOR,MAIN,PRINTF,INCLUDE,FLOAT}
char Value[VALUENUM][8]
int Value_n=0
int ErrorLine=0
int QuotationCount=0//计算引号的数量
int QuotationFlag=0//引号数量为奇数时为1,偶数时为0
char LastOpera=0 //用于判断"=="号存前一个"="号
/************************************************************************/
/* function describe*/
/************************************************************************/
int isKeyWord(char* s) //是关键字返回1,否则返回0
{
int i
for (i=0i<KEYNUMi++)
{
if (strcmp(KeyWord[i],s)==0)
{
return i+1
}
}
return 0
}
int isBoundary(char ch) //是界符
{
int i
for (i=0i<BOUNDNUMi++)
{
if (Boundary[i]==ch)
{
return i+1
}
}
return 0
}
int isOperation(char ch) //是运算符
{
int i
for (i=0i<OPERNUMi++)
{
if (Operation[i]==ch)
{
return i+1
}
}
return 0
}
int isDigit(char *s) //是数字
{
int i,l=strlen(s)
for (i=0i<li++)
{
if (!isdigit(s[i]))
{
break
}
}
if (i>=l)
{
return 1
}
else
{
if ('.'==s[i])
{
i++
for (i<li++)
{
if (!isdigit(s[i]))
{
break
}
}
}
else
{
return 0
}
if (i>=l)
return 1
else
return 0
}
}
int isDotH(char *s) //是头文件
{
int i,l=strlen(s)
for (i=0i<li++)
{
if (!isalpha(s[i]))
{
break
}
}
if (i>=l)
{
return 0
}
else
{
if ('.'==s[i])
{
i++
if(s[i]=='h')
return 1
else
return 0
}
else
return 0
}
}
int isWord(char *s) //是标识符
{
int i=0,l=strlen(s)
if (isalpha(s[i]))
{
i++
for (i<li++)
{
if (!isalnum(s[i]))
{
break
}
}
}
if (i>=l)
{
return 1
}
else
return 0
}
void isWhat(int *i,char *str,FILE *fileOutput,FILE *fileOutput2) //判断字符串,并把相应类型存入文件
{
int n
struct bianliang temp
struct changliang t
FILE *file=fopen("num.txt","ab")
if(1!=*i)
{
str[--(*i)]='\0'
if(n=isKeyWord(str))
{
fputs(str,fileOutput)
fputc('\t',fileOutput)
fputc(KEY_WORD,fileOutput)
fputc('\t',fileOutput)
if(isKeyWord(str)>9)
fputc(isKeyWord(str)+'a'-10,fileOutput)
else
fputc(isKeyWord(str)+'0',fileOutput)
fputc('\t',fileOutput)
fputc(Logogram[n-1],fileOutput)
fputc('\n',fileOutput)
}
else if(isWord(str))
{
fputs(str,fileOutput)
fputc('\t',fileOutput)
fputc(WORD,fileOutput)
fputc('\t',fileOutput)
for(n=0n<Value_nn++)
{
if(0==strcmp(Value[n],str))
break
}
if(n==Value_n)
{
n=++Value_n
strcpy(Value[n-1],str)
temp.id=n-1
strcpy(temp.name,str)
temp.value=0
fwrite(&temp,sizeof(struct bianliang),1,fileOutput2)
fputc('0'+n,fileOutput)
}
else
{
fputc('0'+n+1,fileOutput)
}
fputc('\t',fileOutput)
fputc('i',fileOutput)
fputc('\n',fileOutput)
}
else if (isDotH(str))
{
fputs(str,fileOutput)
fputc('\t',fileOutput)
fputc('\t',fileOutput)
fputc('\t',fileOutput)
fputc(DOTH,fileOutput)
fputc('\n',fileOutput)
}
else if (isDigit(str))
{
fputs(str,fileOutput)
fputc('\t',fileOutput)
fputc('\t',fileOutput)
fputc('\t',fileOutput)
fputc(DIGIT,fileOutput)
fputc('\n',fileOutput)
t.data=atoi(str)
fwrite(&t,sizeof(struct changliang),1,file)
}
(*i)=0
}
fclose(file)
}
void writeMessage(FILE *f)
{
fputs("字符\t类型\t附加值\t缩写\n",f)
}
void error()
{
printf("%d line error!\n",ErrorLine)
exit(1)
}
/************************************************************************/
/*main */
/************************************************************************/
void main()
{
FILE*fileInput
FILE*fileOutput
FILE*fileOutput2
char ch,qtemp
char str[20]
int i
int flag=0
fileInput=fopen("1.cpp","r")
fileOutput=fopen("object.txt","w")
fileOutput2=fopen("variable.txt","w")
writeMessage(fileOutput)
if (NULL!=fileInput)
{
i=0
do
{
ch=fgetc(fileInput)
str[i++]=ch
if(isBoundary(ch))
{
if(1==isBoundary(ch))
{
QuotationCount++
if (0==QuotationCount%2)
{
QuotationFlag=0
}
else
QuotationFlag=1
}
isWhat(&i,str,fileOutput,fileOutput2)
fputc(ch,fileOutput)
fputc('\t',fileOutput)
fputc('B',fileOutput)
fputc('\t',fileOutput)
if(isBoundary(ch)>9)
fputc(isBoundary(ch)+'a'-10,fileOutput)
else
fputc(isBoundary(ch)+'0',fileOutput)
fputc('\t',fileOutput)
fputc(Boundary[isBoundary(ch)-1],fileOutput)
fputc('\n',fileOutput)
i=0
}
else if(isOperation(ch))
{
if(0==QuotationCount%2)
{
isWhat(&i,str,fileOutput,fileOutput2)
if ('='==ch)
{
qtemp=fgetc(fileInput)
if ('='==qtemp)
{
fputc('=',fileOutput)
fputc('=',fileOutput)
flag=1
}
else
{
fputc('=',fileOutput)
fseek(fileInput,-1,SEEK_CUR)
flag=0
}
}
else
fputc(ch,fileOutput)
fputc('\t',fileOutput)
fputc(OPERATION,fileOutput)
fputc('\t',fileOutput)
if(isOperation(ch)>9)
fputc(isOperation(ch)+'a'-10,fileOutput)
else
fputc(isOperation(ch)+'0',fileOutput)
fputc('\t',fileOutput)
if (flag)
{
fputc('q',fileOutput)
}
else
fputc(Operation[isOperation(ch)-1],fileOutput)
fputc('\n',fileOutput)
i=0
}
else
{
fputc(ch,fileOutput)
fputc('\t',fileOutput)
fputc('\t',fileOutput)
fputc('\t',fileOutput)
fputc('c',fileOutput)
fputc('\n',fileOutput)
i=0
}
}
else if('\n'==ch)
{
isWhat(&i,str,fileOutput,fileOutput2)
ErrorLine++
i=0
}
else if(SPACE==ch||'\t'==ch)
{
if(1<i)
isWhat(&i,str,fileOutput,fileOutput2)
else
i=0
}
else if ('\\'==ch)
{
if (1==QuotationFlag)
{
if (1!=i)
{
str[--i]='\0'
fputs(str,fileOutput)
fputc('\t',fileOutput)
fputc(STRING,fileOutput)
fputc('\n',fileOutput)
i=0
}
ch=fgetc(fileInput)
if ('t'==ch)
{
fputc('\\',fileOutput)
fputc('t',fileOutput)
fputc('\t',fileOutput)
fputc('\t',fileOutput)
fputc('\t',fileOutput)
fputc(CHANGE,fileOutput)
fputc('\n',fileOutput)
i=0
}
else if('b'==ch)
{
fputc('\\',fileOutput)
fputc('b',fileOutput)
fputc('\t',fileOutput)
fputc('\t',fileOutput)
fputc('\t',fileOutput)
fputc(CHANGE,fileOutput)
fputc('\n',fileOutput)
i=0
}
else if ('n'==ch)
{
fputc('\\',fileOutput)
fputc('b',fileOutput)
fputc('\t',fileOutput)
fputc('\t',fileOutput)
fputc('\t',fileOutput)
fputc(CHANGE,fileOutput)
fputc('\n',fileOutput)
i=0
}
}
else error()
}
else if (1==QuotationFlag)
{
continue
}
else if (isalnum(ch)||ch=='.')
{
}
else if (EOF!=ch)
{
error()
}
}while(EOF!=ch)
printf("词法分析完毕\n")
fclose(fileInput)
}
fclose(fileOutput)
fclose(fileOutput2)
}
/****************************************************/
/* 1.cpp 例子文件*/
#include <stdio.h>
void main ( )
{
int i
int j
int m
m=1
for(i=0i<5i=i+1)
{
printf("\t",i)
for(j=0j<ij=j+1)
{
printf("\b",i)
}
for(j=0j<mj=j+1)
{
printf("*",i)
}
printf("\n",i)
m=m+2
}
}
编译器会识别出来的;*号作为取值运算符时,扰纯优先级比作为乘号时要高;
所以编译器会根据后面的标识符是否是陆拿指针类型做判断,例如:缓悉咐
int *p = NULL
int a = 3 * p //编译器报错,非法指针运算
int a = 3 * *p //正确
至于你定义的id是什么类型就出现什么样的提示的。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)