📄 词法分析.cpp
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#define SIZE 100
#define TRUE 1
#define FALSE 0
#define NULL 0
#define OK 1
typedef struct WORD { /*识别出来的二元组*/
int syn;
int location;
char value[20];
}WORD;
FILE *fr,*fw,*fe,*ff1,*ff2;
char strSource[SIZE]; /*用来存放源程序*/
int column, row, locate, locateStart,m=0,i,j;
WORD word;
char str[SIZE][30]; /*标识符数组*/
int Dig[SIZE]; /*整型常数数组*/
char strDig[SIZE][20]; /*字符串常数数组*/
char *KEYWORDS[32] = {"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","union","unsigned","void",
"volatile","while"};
/*以上显示了能够识别的关键字*/
///////////////////////////////////////////////////////////////////////
int IsDigit(char ch) ; /*检查是不是数字*/
int IsChar(char ch); /*检查是不是字母*/
void TagChar(char *strSource); /*找到断点*/
void TagDigit(char *strSource); /*找到断点*/
int EndOfTag(char *strSource); /*识别该单词*/
int EndOfDigit(char *strSource); /*识别该整型数字*/
void Start(char *strSource); /*开始识别某个符号或单词或整型数字*/
void PrintWord(WORD word); /*输出识别的结果*/
////////////////////////////////////////////////////////////////////////
void main() {
long length=0;
//int k=0;
column=1;
row=0;
i=j=0;
locate=locateStart=0;
fw=fopen("D:\\out.txt","wr");
fe=fopen("D:\\error.txt","wr");
ff1=fopen("D:\\符号表1.txt","wr");
ff2=fopen("D:\\符号表2.txt","wr");
if((fr=fopen("D:\\read.txt","r"))==NULL) {
printf("Cannot open file<read.txt>.\n");
exit(0);
}
while(!feof(fr))
{fread(&strSource[length],sizeof(char),sizeof(char),fr);length++;} /*将程序读到strSource数组中*/
fclose(fr);
printf("length=%d\n",length);
while (locate<length-1) { /*分析源程序*/
Start(strSource);
PrintWord(word);
}
if(m==0){
fprintf(fe,"没有错误\n");
}
fclose(fw);
fclose(fe);
fclose(ff1);
fclose(ff2);
}
///////////////////////////////////////////////////////////////////////////////
int IsDigit(char ch) { /*检查是不是数字*/
if(ch<='9'&&ch>='0')
return 1;
else return 0;
}
/////////////////////////////////////////////////////////////////////////////////
int IsChar(char ch) { /*检查是不是字母*/
if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A'))
return 1;
else return 0;
}
//////////////////////////////////////////////////////////////////////////////////
void TagChar(char *strSource) { /*找到断点*/
locate++;
if(IsChar(strSource[locate])) {
TagChar(strSource);
}
else {row++;
EndOfTag(strSource);
}
}
///////////////////////////////////////////////////////////////////////////////
void TagDigit(char *strSource) { /*找到断点*/
locate++;
if(IsDigit(strSource[locate])) {
TagDigit(strSource);
}
else {row++;
EndOfDigit(strSource);
}
}
/////////////////////////////////////////////////////////////////////////////////
int EndOfTag(char *strSource) { /*识别保留字*/
int loop=0;
int w=0;
word.syn=34;
strncpy(word.value,strSource+locateStart,locate-locateStart);
word.value[locate-locateStart]='\0';
while(loop<32) {
if(!strcmp(KEYWORDS[loop],word.value)) {
word.syn=loop+1;
break; return TRUE;
}
loop++;
}
if(word.syn==34)
{
while(w<i){
if(!(strcmp(str[w],word.value)))
{word.location=w+1;return FALSE;}
w++;
}
strcpy(str[i],word.value);
i++;
word.location=i;
fprintf(ff1,"%s\t\t|\t(%d)\n",word.value,word.location);
return FALSE;
}
}
/////////////////////////////////////////////////////////////////////////////////
int EndOfDigit(char *strSource) { /*识别该整型数字*/
int w=0;
word.syn=38;
strncpy(word.value,strSource+locateStart,locate-locateStart);
word.value[locate-locateStart]='\0';
locate--;
while(w<j){
if(!(strcmp(strDig[w],word.value)))
{word.location=w+1;return OK;}
w++;
}
strcpy(strDig[j],word.value);
j++;
word.location=j;
fprintf(ff2,"%s\t\t|\t(%d)\n",word.value,word.location);
return OK;
}
//////////////////////////////////////////////////////////////////////////////////
void Start(char *strSource) { /*开始识别某个符号或单词或整型数字*/
locateStart=locate;
switch(strSource[locate]) {
case '+': {
word.syn=39;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
break;
}
case '-': {
word.syn=40;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
break;
}
case '*': {
if(strSource[locate+1]=='/'){ /*识别 */
locate++;
row++;
word.syn=60;
strcpy(word.value,"*/");
word.value[2]='\0';
}
else{ /*识别* */
word.syn=41;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
}
break;
}
case '/': {
if(strSource[locate+1]=='*'){ /*识别/* */
locate++;
row++;
word.syn=59;
strcpy(word.value,"/*");
word.value[2]='\0';
}
else{ /*识别/ */
word.syn=42;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
}
break;
}
case '=': {
word.syn=43;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
break;
}
case '<': {
if(strSource[locate+1]=='=') { /*识别<=*/
locate++;
row++;
word.syn=55;
strcpy(word.value,"<=");
word.value[2]='\0';
}
else {
if(strSource[locate+1]=='>'){ /*识别<>*/
locate++;
row++;
word.syn=54;
strcpy(word.value,"<>");
word.value[2]='\0';
}
else { /*识别<*/
word.syn=44;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
}
}
break;
}
case '>': {
if(strSource[locate+1]=='=') { /*识别>=*/
locate++;
row++;
word.syn=56;
strcpy(word.value,">=");
word.value[2]='\0';
}
else { /*识别>*/
word.syn=45;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
}
break;
}
case '(': {
word.syn=46;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
break;
}
case ')': {
word.syn=47;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
break;
}
case '[': {
word.syn=48;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
break;
}
case ']': {
word.syn=49;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
break;
}
case ':': {
if(strSource[locate+1]=='='){ /*识别:=*/
locate++;
row++;
word.syn=57;
strcpy(word.value,":=");
word.value[2]='\0';
}
else{ /*识别:*/
word.syn=50;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
}
break;
}
case '.': {
if(strSource[locate+1]=='.'){ /*识别..*/
locate++;
row++;
word.syn=58;
strcpy(word.value,"..");
word.value[2]='\0';
}
else{ /*识别. */
word.syn=51;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
}
break;
}
case ';': {
word.syn=52;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
break;
}
case ',': {
word.syn=53;
strcpy(word.value,&strSource[locate]);
locate++;
row++;
break;
}
default: {
if(IsChar(strSource[locate])) { /*识别单词的处理*/
TagChar(strSource);
}
else {if(IsDigit(strSource[locate])) { /*识别数字的处理*/
TagDigit(strSource);
}
else { /*如果是空格、换行、回车则忽略 如果是别的字符就进行出错处理*/
if(strSource[locate]!=' '&&strSource[locate]!='\t'&&strSource[locate]!='\n') {
strcpy(word.value,&strSource[locate]);word.value[1]='\0';word.syn=-1;
row++;
m++;
}
else {
if(strSource[locate]=='\n') {
column++;word.syn=0;
row=0;
}
else word.syn=0;
}
}
locate++;
break;
}
}//switch
}//void Start(char *strSource)
}
void PrintWord(WORD word) { /*向中OUT.txt中写识别结果*/
if(word.syn<=32&& word.syn>=1) { /*保留字*/
fprintf(fw,"%s\t\t(%d,-)\n",word.value,word.syn);
}
else {
if(word.syn==34) /*标识符*/
{fprintf(fw,"%s\t\t(34,%d)\n",word.value,word.location);}
else {
if(word.syn==36) /*整型常数*/
{fprintf(fw,"%s\t\t(36,%d)\n",word.value,word.location);}
else {
if(word.syn==38) /*字符串常数*/
{fprintf(fw,"%s\t\t(38,%d)\n",word.value,word.location);}
else {
if(word.syn>=39&&word.syn<=53) /*单界符常数*/
{fprintf(fw,"%c\t\t(%d,-)\n",word.value[0],word.syn);}
else {
if(word.syn>=54&&word.syn<=60) /*双界符常数*/
{fprintf(fw,"%s\t\t(%d,-)\n",word.value,word.syn);}
else{
if(word.syn==-1){
fprintf(fw,"%s\n",word.value);
fprintf(fe,"行%d的第%d个: %s 无法识别\n",column,row,word.value);
}
}
}
}
}
}
}
}//PrintWord
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -