⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bylr.c

📁 本次实验
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <malloc.h>
#include "stack.h"

struct  symbolRecord
{
	char symbol[10];
	int id;
}record[15];
//读入属性
struct entryType
{
	char idName[16];
	int address;
	char *type;
	int value;
	struct entryType* next;
};
//数表
struct digitTable
{
	int address;
	int digit;
	struct digitTable *next;
};
//token字
struct tokenType
{
	int id;
	int entry;
	struct tokenType* next;
};
//语法分析产生语法分析树
struct creat
{
	int id;
	int length;
	char left;
	char string[32];
}grammar[20];
//非终结符
struct term
{
	int id;
	char character;
}nonTerminate[10];
//四元式
struct equal
{
	int id;
	char first[16];
	char second[16];
	char third[16];
	char forth[16];
}equalExp[32];

int entry=0, digit=0, instruction=0;
int line=0, row=0, cursor=-1;
char stringBuffer[128];
char* file=NULL;
char strToken[20];
int fileLength=0;

int i,j;

struct entryType *headEntry,*tailEntry;
struct digitTable *headDigit,*tailDigit;
struct tokenType  *headToken, *tailToken;

char *keywords[]={"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"};     //32个关键字

int gotoTable[30][7]={0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  5,0,6,0,7,0,0,
					  0,0,0,10,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,11,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,13,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
				      0,0,0,0,0,0,19,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,26,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,27,
					  0,0,0,0,0,0,28,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0};//goto表
int actionTable[30][14]={1001,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,1002,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,1003,0,
						 0,0,0,0,1004,0,0,0,0,0,0,0,0,0,
						 0,1008,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,4,0,1009,0,0,0,0,0,0,0,0,
						 0,0,0,3,0,3,0,0,0,0,0,0,0,0,
						 0,0,0,1012,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,6,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,-1,
						 0,0,0,1014,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,1015,1016,0,0,0,0,0,0,
						 0,0,0,0,0,0,8,8,0,0,0,0,0,0,
						 0,0,0,2,0,2,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,1017,0,0,0,0,0,
						 0,0,0,5,0,5,0,0,0,0,0,0,0,0,
						 0,0,0,1018,0,0,0,0,0,0,0,0,0,0,
						 0,0,1022,1021,0,0,0,0,0,0,0,1020,0,0,
						 0,0,0,0,0,0,7,7,0,0,0,0,0,0,
						 0,0,0,0,0,0,1023,0,0,1024,1025,0,0,0,
						 0,0,1022,1021,0,0,0,0,0,0,0,1020,0,0,
						 0,0,0,0,0,0,13,0,0,13,13,0,13,0,
						 0,0,0,0,0,0,14,0,0,14,14,0,14,0,
						 0,0,0,9,0,9,0,0,0,0,0,0,0,0,
						 0,0,1022,1021,0,0,0,0,0,0,0,1020,0,0,
						 0,0,1022,1021,0,0,0,0,0,0,0,1020,0,0,
						 0,0,0,0,0,0,0,0,0,1024,1025,0,1029,0,
						 0,0,0,0,0,0,10,0,0,10,1025,0,10,0,
						 0,0,0,0,0,0,11,0,0,11,11,0,11,0,
						 0,0,0,0,0,0,12,0,0,12,12,0,12,0};//action表
struct tokenType* position;

struct  place_E
{
	char strName[16];
	int value;
}place_E[32];
int nextQuad=0;//下一四元组
int nextList_P, nextList_S,nextList_D;
int	quad_M;
char relop[16];
char type_T[16];
int list_L[32];							//变量地址
char tempVariable[32][16];
int num_E=0, num_L=0;
int tempNum=0;

void panner(int i,Stack tokenStack);
void readGrammar();
char getCharacter();

void recogId(char);
void recogDigit(char);
void recogOther(char);

void  f1();
void  f2();
void  f3();
void  f4();
void  f5();
void  f6();
void  f7(Stack tokenStack);
void  f8(Stack tokenStack);
void  f9(Stack tokenStack);
void f10();
void f11();
void f12();
void f13(Stack tokenStack);
void f14(Stack tokenStack);


//初始化符号表
void initRecord()
{
	int i;
	char ch;
	int j=0, k=0;
	FILE *inFile;

	for(i = 0; i < 15; i++)
		record[i].id = i;

	if((inFile=fopen("symbol.txt","r"))==NULL)
	{
		printf("Cannot open file.");
		getchar();
		exit(0);
	}
	while((ch = getc(inFile)) != EOF ) {
		while((ch != '\n') && (ch != EOF)) {
			if((ch != ' ') && (ch != '\t'))
				record[j].symbol[k++] = ch;
			ch = getc(inFile);
		}
		record[j++].symbol[k] = '\0';
		k = 0;
	}
	fclose(inFile);
}

//插入数字
void insertDigit(int Digit)
{
	struct digitTable* tempDigitTable;
	tempDigitTable = (struct digitTable*) malloc(sizeof(struct digitTable));
	tempDigitTable->address = digit;
	tempDigitTable->digit = Digit;
	tempDigitTable->next = NULL;

	if(headDigit == NULL) {
		headDigit = tailDigit = tempDigitTable;
		digit++;
	} else {
		tailDigit = tailDigit->next = tempDigitTable;
		digit++;
	}
}
//插入token字
void insertToken(int id,int entry)
{
	struct tokenType *tempToken;
	tempToken= (struct tokenType*) malloc(sizeof(struct tokenType));
	tempToken->id = id;
	tempToken->entry = entry;
	tempToken->next = NULL;
	if(headToken == NULL) headToken = tailToken = tempToken;
	else tailToken = tailToken->next = tempToken;
}

//词法分析
void Scan()
{
	struct stat buffer;
	int i = 0;
	char ch;
	char filename[40];
	FILE *inFile;

	printf("Please input the file name:");
	gets(filename);
	stat("filename", &buffer);
	file = (char*)malloc(sizeof(buffer.st_size));

	if((inFile=fopen("source.txt","r"))==NULL)
	{
		printf("Cannot open file.");
		getchar();
		exit(0);
	}
	while((ch = getc(inFile)) != EOF)
		file[i++] = ch;
	fclose(inFile) ;

	file[i++] = '\0';
	fileLength = i;
	initRecord();
	printf("\n--------------词法分析----------------\n");
	while((ch = getCharacter()) != '\0') {
		if((ch != '\n') && (ch != ' ') && (ch != '\t')) {
			if( islower(ch) || isupper(ch) || ch == '_' )
				recogId(ch);
			else if(isdigit(ch))
				recogDigit(ch);
			else
				recogOther(ch);
		};
	}
	insertToken(13,-1);
}

int Reserve()
{
	int i,b=0; 
	for(i=0;i<32;i++)
    { 
		if(strcmp(strToken,keywords[i])==0)
			b=i;
    }
	return b;
}

void recogId(char ch)
{
	int i = 0;
	int code;
	int keyword = 0;
	strcpy(strToken,"");
	while(islower(ch) || isupper(ch) || isdigit(ch)) {
		strToken[i] = ch;
		ch = getCharacter();
		i++;
	}
	strToken[i] = '\0';
	cursor--;
	row--;
	
	code = Reserve();
	if (code)
		printf("%s\t关键字\n",strToken);
	else
		printf("%s\t标识符\n",strToken);
	
	for(i = 0; i < 13; i++) {
		if(strcmp(record[i].symbol,strToken) == 0) {
			insertToken(record[i].id, -1);
			keyword = 1;
		}
	}
	if(!keyword) {
		struct entryType *head, * tempEntry;
		int word = 0;
		if(headEntry == NULL) {
			head = (struct entryType*)malloc(sizeof(struct entryType));
			strcpy(head->idName, strToken);
			head->address = entry;
			head->type = NULL;
			head->next = NULL;
			headEntry = tailEntry = head;
			entry++;
			insertToken(3, entry - 1);
		}
		else {
			tempEntry = headEntry;
			while(tempEntry != NULL) {
				if(strcmp(tempEntry->idName, strToken) == 0) {
					insertToken(3, tempEntry->address);
					word = 1;
				}
				tempEntry = tempEntry->next;
			}
			if(!word) {
				head = (struct entryType*)malloc(sizeof(struct entryType));
				strcpy(head->idName, strToken);
				head->address = entry;
				head->type = NULL;
				head->next = NULL;
				tailEntry = tailEntry->next = head;
				entry++;
				insertToken(3, entry - 1);
			}
		}
	}
}

//识别数字
void recogDigit(char ch)
{
	int i = 0;
	do {
		i = i * 10 + ch - '0';
		ch = getCharacter();
	}while(isdigit(ch));
	row--;
	cursor--;
	printf("%d\t常  数\n",i);
	insertDigit(i);
	insertToken(2, digit - 1);
}

//识别界限符、运算符
void recogOther(char ch)
{
	switch(ch) {
	case '{': insertToken(4, -1); printf("%c\t界限符\n",ch); break;
	case '}': insertToken(5, -1); printf("%c\t界限符\n",ch); break;
	case ';': insertToken(6, -1); printf("%c\t界限符\n",ch); break;
	case ',': insertToken(7, -1); printf("%c\t界限符\n",ch); break;
	case '=': insertToken(8, -1); printf("%c\t运算符\n",ch); break;
	case '+': insertToken(9, -1); printf("%c\t运算符\n",ch); break;
	case '*': insertToken(10, -1); printf("%c\t运算符\n",ch); break;
	case '(': insertToken(11, -1); printf("%c\t界限符\n",ch); break;
	case ')': insertToken(12, -1); printf("%c\t界限符\n",ch); break;
	default:break;}
}

//查找下一个字符
char getCharacter()
{
	if(file[cursor] == '\n') {
		row = 1;
		line++;
		cursor++;
	} else {
		row++;
		cursor++;
	}
	return file[cursor];
}
//读入语法分析结果
void readGrammar()
{
	int i = 1;
	FILE *in;

	if((in=fopen("grammar.txt","r"))==NULL){
		printf("Cannot open file.");
		getchar();
		exit(0);
	}
	else{
		while(fgets(grammar[i].string, 20, in)!=NULL){
			grammar[i].id = i;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -