直接贴代码
#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;
}
}
}