词法分析程序

直接贴代码

#include<cstdio>
#include<iostream>
#include<fstream>
#include<cstring>
#include<time.h>
#include<Windows.h>
using namespace std;
#define KeywordNum 36
bool isLetter(char C);
bool isDigit(char C);
void Cleartoken();
void ProgramScanner();
void table_insert();
int SToI();
double SToF();
int isKeyword();
int linenum;
int charnum;
int pos = 0;          //记录当前处理字符所在的列位置
/*****************************全局变量********************************/
char token[30];
int token_i = 0;
FILE* fptr;
FILE* recordptr;
char C;
int keywordrecord[1000] = { 0 };
int Indentryrecord[1000] = { 0 };
char keyword[KeywordNum][20] = { "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","include","main" ,"bool","FILE"};
static char operatorOrDelimiter[36][10] = {
	     "+", "-", "*", "/", "<", "<=", ">", ">=", "=", "==",
	     "!=", ";", "(", ")", "^", ",", "\"", "\'", "#", "&",
	     "&&", "|", "||", "%", "~", "<<", ">>", "[", "]", "{",
	     "}", "\\", ".", "\?", ":", "!"
	 };
char Indentry[1000][20];
int Indentry_num = 0;
/*********************************************************************/
int main() {
	fptr = fopen("源程序1.txt", "r");
	recordptr = fopen("错误信息.txt", "w");
	if (fptr == NULL || recordptr == NULL)
		cout << "can't open this file." << endl;
	else {
		linenum = 0;
		charnum = 0;
		char C;
		ProgramScanner();
		cout << endl << endl;
		cout << "总行数" << linenum<<"	";
		cout << "总字符数" << charnum << endl;
		cout << "输出标识符表:" << endl;
		for (int i = 0; i < Indentry_num; i++)
			cout <<"第"<<i+1<<"个标识符:	"<< Indentry[i] <<"   "<<Indentryrecord[i]<<"次"<< endl;
		cout << "end" << endl;


		fclose(fptr);
		fclose(recordptr);
	}
	system("pause");
	return 0;
}
bool isOperatorDelimiter(char C) {
	if (C == '+' || C == '-' || C == '*' ||  C == ';' || C == '(' || C == ')' || C == '^'
		|| C == ',' || C == '\"' || C == '\'' || C == '~' || C == '#' || C == '%' || C == '['
		|| C == ']' || C == '{' || C == '}' || C == '\\'  || C == '\?' || C == '='||C == '<'
		||C == '>'||C == ' '||C=='|'||C == '!'||C=='\n')
		return true;
	else
		return false;
}
bool isLetter(char C) {
	if ((C <= 'z'&&C >= 'a') || (C <= 'Z'&&C >= 'A') || (C == '_'))
		return true;
	else
		return false;
}
bool isDigit(char C) {
	if (C <= '9'&&C >= '0')
		return true;
	else
		return false;
}
void Cleartoken() {
	for (int i = 0; i < 30; i++)
		token[i] = '\0';
	token_i = 0;
}
void get_nbc() {
	while (C == ' '||C == '\n') {
		pos++;
		if (C == '\n') {
			linenum++;
			pos = 0;
		}
		C = fgetc(fptr);
		
	}
}
int isKeyword() {
	int i = 0;
	for (; i < KeywordNum; i++) {
		if (strcmp(keyword[i], token) == 0) {
			return i;
		}
	}
	return -1;
}
int SToI() {
	int p = 0;
	for (int i = 0; i < token_i; i++) {
		p = p * 10 + (token[i] - '0');
	}
	return p;
}
double SToF() {
	double main_p = 0;
	double p = 0;
	double pow = 1;
	bool flag = false;
	bool positive = 1;
	bool index = 0;              //表示不是指数
	for (int i = 0; i < token_i; i++) {
		if (token[i] <= '9'&&token[i] >= '0') {
			if (index == 0)
				main_p = main_p * 10 + (token[i] - '0');
			else {
				p = p * 10 + (token[i] - '0');
			}
			if (flag)
				pow = pow * 10;
		}
		else
			if (token[i] == '.')
				flag = true;
			else if (token[i] == 'E')
				index = 1;
			else if (token[i] == '-')
				positive = 0;
			else if (token[i] == '+')
				positive = 1;
	}
	double ans = main_p / pow;
	double t = 1;
	for (int i = 1; i <= p; i++)
		t = t * 10;
	if (positive == 0) {
		t = 1 / t;
	}
	ans = ans * t;
	return ans ;
}
void table_insert() {
	bool flag = false;
	int i = 0;
	for (; i < Indentry_num && !flag; i++) {
		if (strcmp(token, Indentry[i]) == 0) {
			flag = true;
			Indentryrecord[i]++;
		}
	}
	if (!flag) {
		strcpy(Indentry[i], token);
		Indentry_num++;
		Indentryrecord[i]++;
	}
}
void ProgramScanner() {
	int state = 0 ;
	int iskey = 0;
	int SToI_num = 0;
	double SToF_num = 0;
	while (!feof(fptr)) {
		switch (state) {
		case 0:
			token_i = 0;
			Cleartoken();
			C = fgetc(fptr);
			pos++;
			get_nbc();
			charnum++;
			if (isLetter(C)) {               //
				state = 1;
			}
			else if (isDigit(C)) {
				state = 2;
			}
			else if (C == '<')
				state = 8;
			else if (C == '>')
				state = 9;
			else if (C == '!')
				state = 10;
			else if (C == ':')
				state = 11;
			else if (C == '/')
				state = 12;
			else if (C == '&')
				state = 15;
			else if (C == '|')
				state = 16;
			else if (C == '"')
				state = 17;
			else if (C == '+') { state = 0; cout << "( + ,--)" << endl; }
			else if (C == '#') { state = 0; cout << "( # ,--)" << endl; }
			else if (C == '-') { state = 0; cout << "( - ,--)" << endl; }
			else if (C == '*') { state = 0; cout << "( * ,--)" << endl; }
			else if (C == '(') { state = 0; cout << "( ( ,--)" << endl; }
			else if (C == ')') { state = 0; cout << "( ) ,--)" << endl; }
			else if (C == '%') { state = 0; cout << "( % ,--)" << endl; }
			else if (C == '[') { state = 0; cout << "( [ ,--)" << endl; }
			else if (C == ']') { state = 0; cout << "( ] ,--)" << endl; }
			else if (C == '{') { state = 0; cout << "( { ,--)" << endl; }
			else if (C == '}') { state = 0; cout << "( } ,--)" << endl; }
			else if (C == '.') { state = 0; cout << "( . ,--)" << endl; }
			else if (C == '=') { state = 0; cout << "( = ,--)" << endl; }
			else if (C == ';') { state = 0; cout << "( ; ,--)" << endl; }
			else
				state = 30;     //错误处理 ;待更改
			break;

		case 1:
			token[token_i++] = C;
			C = fgetc(fptr);
			pos++;
			charnum++;
			if (isLetter(C) || isDigit(C))
				state = 1;
			else if(isOperatorDelimiter(C)) {
				fseek(fptr, -1, SEEK_CUR);          //指针回退
				charnum--;                          //指针回退,字符总数需要减少一个
				pos--;
				state = 0;
				iskey = isKeyword();                //如果是关键字
				if(iskey == -1) {                              //如果是标识符
					table_insert();                 //需要返回些什么吗
					cout << "(标识符," << token << ")" << endl;
				}
				else{
					keywordrecord[iskey]++;
					cout << "(" << token << ",--)" << endl;
				}
			}
			else {
				state = 30;
			}
			break;
		case 2:
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			if (isDigit(C))
				state = 2;
			else if (C == '.')
				state = 3;
			else if (C == 'E')
				state = 5;
			else if (isLetter(C)) {
				state = 30;
			}
			else{
				fseek(fptr, -1, SEEK_CUR);          //指针回退
				charnum--;
				pos--;
				state = 0;        //
				SToI_num = SToI();
				cout << "(常数," << SToI_num << ")" << endl;
			}
				break;
		case 3:                         //常数后紧跟一个小数点的情况
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			if (isDigit(C))
				state = 4;
			else
				state = 30;        //错误状态
			break;
		case 4:                      //浮点数情况
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			if (isDigit(C))
				state = 4;
			else if (C == 'E')
				state = 5;
			else {
				fseek(fptr, -1, SEEK_CUR);
				charnum--;
				pos--;
				state = 0;
				SToF_num = SToF();
				cout << "(浮点数," << SToF_num << ")" << endl;
				}
				///输出这个浮点数
				break;
		case 5:                         //指数状态
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			if (isDigit(C))
				state = 7;
			else if (C == '+' || C == '-') {
				state = 6;
			}
			else {
				fseek(fptr, -1, SEEK_CUR);
				charnum--;
				pos--;
				state = 30;
			}
			break;
		case 6:
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			if (isDigit(C))
				state = 7;
			else {
				fseek(fptr, -1, SEEK_CUR);
				charnum--;
				pos--;
				state = 30;
			}
			break;
		case 7:
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			if (isDigit(C))
				state = 7;
			else {
				fseek(fptr, -1, SEEK_CUR);
				charnum--;
				pos--;
				state = 0;
				SToF_num = SToF();
				cout << "(浮点数," << SToF_num << ")" << endl;
				/返回无符号数
			}
			break;
		case 8:                                 // < 情况
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			if (C == '=') {
				token[token_i++] = C;
				state = 0;
				cout << "(relop, LE)" << endl;
			}
			else if (C == '>') {
				token[token_i++] = C;
				state = 0;
				cout << "(relop, NE)" << endl;
			}
			else {                          //可能少考虑了一种情况
				state = 0;
				fseek(fptr, -1, SEEK_CUR);
				charnum--;
				pos--;
				cout << "(relop,LT)"  << endl;
			}
			break;
		case 9:                            // > 情况
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			if (C == '=') {
				token[token_i++] = C;
				state = 0;
				cout << "(relop, GE)" << endl;
			}
			else {
				fseek(fptr, -1, SEEK_CUR);
				charnum--;
				pos--;
				state = 0;
				cout << "(relop,GT)" <<endl;
			}
			break;
		case 10:                     // !  情况
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			if (C == '=') {
				token[token_i++] = C;
				state = 0;
				cout << "(" <<token<<",-)"<< endl;          //unfinished
			}
			else {
				fseek(fptr, -1, SEEK_CUR);
				charnum--;
				pos--;
				state = 0;
				cout << "(" << token << ",-)" << endl;     //unfinished
			}
			break;
		case 11:                         // ":" 情况
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			if (C == '=') {
				token[token_i++] = C;
				state = 0;
				cout << "(" << token << ",-)" << endl;          //unfinished
			}
			else {
				fseek(fptr, -1, SEEK_CUR);
				charnum--;
				pos--;
				state = 0;
				cout << "(" << token << ",-)" << endl;     //unfinished
			}
			break;
		case 12:                          //  /  情况
			token[token_i++] = C;
			C = fgetc(fptr);
			if (C == '/') {
				state = 13;
			}
			else if (C == '*') {
				state = 14;
			}
			else {
				fseek(fptr, -1, SEEK_CUR);
				pos--;
				charnum--;
				state = 0;
			}
			break;
		case 13:                     //  "//"
			C = fgetc(fptr);
			while (C != '\n') C = fgetc(fptr);
			linenum++;
			state = 0;
			break;
		case 14:
			C = fgetc(fptr);
			while (C != '*') {
				if (C == '\n')
					linenum++;
				pos = 0;
				C = fgetc(fptr);
			}
			C = fgetc(fptr);
			if (C == '/')
				state = 0;
			else
				state = 14;
			break;
		case 15:
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			if (C == '&') {
				token[token_i++] = C;
				state = 0;
				cout << "(" << token << ",-)" << endl;
			}
			else {
				fseek(fptr, -1, SEEK_CUR);
				charnum--;
				pos--;
				state = 0;
			}
			break;
		case 16:                      //" |"
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			if (C == '|') {
				token[token_i++] = C;
				state = 0;
				cout << "(" << token << ",-)" << endl;
			}
			else {
				fseek(fptr, -1, SEEK_CUR);
				charnum--;
				pos--;
				state = 30;
			}
			break;
		case 17:                 //" " "情况
			token[token_i++] = C;
			C = fgetc(fptr);
			charnum++;
			pos++;
			while (C != '"')
				C = fgetc(fptr);
			token[token_i++] = C;
			cout << "(" << token << ",-)" << endl;
			state = 0;
			break;
		case 30:
			while (1) {
				if (C == ' ' || C == '\n')
					break;
				token[token_i++] = C;
				C = fgetc(fptr);
				
			}
			cout << "坐标位置(" << linenum+1 <<","<<pos<< ")出现错误" <<token<<",请注意更改,现已直接略过" << endl;
			fputs("坐标位置(", recordptr);
			fputc(linenum + '1', recordptr);
			fputs(",", recordptr);
			fputc(pos, recordptr);
			fputs(")出现错误, 错误信息为", recordptr);
			fputs(token, recordptr);
			fseek(fptr, -1, SEEK_CUR);
			//Sleep(1000);
			state = 0;
			break;
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值