📄 main.cpp
字号:
// linpeiwen main.cpp
#include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>
//define the ReservedWords total num.
#define MAXRESERVED 6
//define the specialSymbols total num
#define MAXSPECIALSYMBOLS 21
using namespace std;
// define StateType,5 states.
typedef enum {
START,INCOMMENT,INNUM,INID,DONE
} StateType;
typedef enum {
/* reserved words */
IF,ELSE,INT,RETURN,VOID,WHILE,
/* multicharacter tokens */
ID,NUM,
/* special symbols */
PLUS,MINUS,MTPLUS,DEVIDE,EQ,ASSIGN,LT,MT,TIMES,LXKH,RXKH,LZKH,RZKH,LDKH,RDKH,SEMI,LE,ME,NOTEQ,FH,LZS,RZS,ZS,
/*stateToken */
ENDFILE,UNKNOWN,ERROR
} TokenType;
static struct {
char* str;
TokenType tt;
} specialSymbols[MAXSPECIALSYMBOLS] = { {"+",PLUS},{"-",MINUS},{"*",MTPLUS},{"/",DEVIDE},{"<",LT},{"<=",LE},{">",MT},
{">=",ME},{"==",EQ},{"!=",NOTEQ},{"=",ASSIGN},{",",SEMI},{";",FH},{"(",LXKH},
{")",RXKH},{"[",LZKH},{"]",RZKH},{"{",LDKH},{"}",RDKH},{"/*",LZS},{"*/",RZS}
};
static struct {
char* str;
TokenType tt;
} reservedWords[MAXRESERVED] = {{"if",IF},{"else",ELSE}, {"int",INT},
{"return",RETURN},{"void",VOID},{"while",WHILE}};
//judge if is digit.
bool isDigit(char c) {
string digit = "0123456789";
for(int i = 0;i < digit.size();i++) {
if(digit[i] == c) {
return true;
}
}
return false;
}
//judge if is a letter.
bool isLetter(char c) {
string alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for(int i = 0;i < alpha.size();i++) {
if(alpha[i] == c) {
return true;
}
}
return false;
}
//judge if is ReseredWords,if is return the reservedWords,if is not it is a ID.
TokenType isReservedWords(string str) {
for(int i = 0;i < MAXRESERVED;i++) {
if(str == reservedWords[i].str) {
return reservedWords[i].tt;
}
}
return ID;
}
//output to the outf filestream.
void outputFile(ofstream& outf,TokenType tt,string str) {
for(int i = 0;i < MAXRESERVED;i++) {
if(reservedWords[i].str == str) {
tt = reservedWords[i].tt;
outf << "ReservedWords: " << str<<endl;
}
}
for(int j=0;j<MAXSPECIALSYMBOLS;j++) {
if(specialSymbols[j].tt == tt) {
outf << "Special Symbol: " << str <<endl;
}
}
if(tt == ZS) {
outf << "ZS: " << str << endl;
}
if(tt == ID) {
outf<<"ID: "<< str <<endl;
}
if(tt == NUM) {
outf<<"NUM: "<< atoi(str.c_str()) <<endl;
}
if(tt == ERROR) {
outf << "ERROR: " << str << endl;
}
if(tt == UNKNOWN) {
outf << "UNKNOWN Symbol: " << str << endl;
}
}
// get the token,有穷自动机的实现
void getToken(ifstream& inf,ofstream& outf,int& lineno) {
TokenType tt;
StateType state = START;
string str = "";
static int flag = 1;
while(state != DONE) {
char c = inf.get();
if(flag == 1) {
outf << "-------------------------------------------" << endl;
outf << "In the line " << lineno << " : " <<endl;
flag = 0;
}
switch(state) {
case START: if(isLetter(c)) {
state = INID;
str += c;
} else if(isDigit(c)) {
state = INNUM;
str += c;
} else if(c == '\t' || c == ' ') {
} else if(c == '\n') {
//output the line number
lineno = lineno + 1;
outf << "-------------------------------------------" << endl;
outf << "In the line " << lineno << " : " <<endl;
} else if(c == '/' && inf.peek() == '*') {
str = str + c;
c = inf.get();
str = str + c;
state = INCOMMENT;
} else {
state = DONE;
str += c;
//judge is special symbols,if is not ,output UNKNOWN
switch(c) {
case EOF: tt = ENDFILE;break;
case '+': tt = PLUS;break;
case '-': tt = MINUS;break;
case '*': tt = MTPLUS;break;
case '/': tt = DEVIDE;break;
case ';': tt = FH;break;
case '(': tt = LXKH;break;
case ')': tt = RXKH;break;
case '=': //judge if is '=='
if(inf.peek() == '=') {
c = inf.get();
tt = EQ;
str+=c;
//judge if is '='
} else {
tt = ASSIGN;
} break;
case '<': //judge if is '<='
if(inf.peek() == '=') {
c = inf.get();
tt = LE;str+=c;
//judge if is '<'
} else {
tt = LT;
}break;
case '>': //judge if is '>='
if(inf.peek() == '=') {
c = inf.get();
tt = ME;
str+=c;
//judge if is '>'
} else {
tt = MT;
} break;
case ',': tt = SEMI;break;
case '[': tt = LZKH;break;
case ']': tt = RXKH;break;
case '{': tt = LDKH;break;
case '}': tt = RDKH;break;
case '!': c = inf.get();
if(c == '=') {
tt = NOTEQ;
str+=c;
} else {
inf.putback(c);
tt=UNKNOWN;
} break;
default: tt = UNKNOWN;break;
}
} break;
case INCOMMENT: if(c=='\n')lineno=lineno+1;
if(c == '*' && inf.peek() == '/') {
str = str + c;
c = inf.get();
state = DONE;tt=ZS;
} else if(inf.eof()) {
tt = ERROR;
state = DONE;
} str = str + c;break;
case INNUM: if(!isDigit(c)) {
// if is letter,it is error
if(isLetter(c)) {
str = str + c;
if(inf.peek() == ' ' || inf.peek() == '\t' || inf.peek() == '\n') {
tt = ERROR;state = DONE;
break;
}
//else correct
} else {
inf.putback(c);
tt=NUM;
state = DONE;
}
break;
} str += c;break;
case INID: if(!isLetter(c)) {
//if is digit, it is error
if(isDigit(c)) {
str = str + c;
if(inf.peek() == ' ' || inf.peek() == '\t' || inf.peek() == '\n') {
tt = ERROR;state = DONE;break;
}
//else correct
} else {
inf.putback(c);
tt=ID;state = DONE;
}
break;
}str += c;break;
case DONE:break;
default:
state = DONE;
tt = ERROR;
break;
}
}
// if is done output to the file the message.
if(state == DONE){
outputFile(outf,tt,str);
}
}
int main(int argc, char* argv[]) {
char *filename = NULL;
char *output = NULL;
//check the parameter needed.
if ( argc == 2 )
filename = argv[1];
else {
cerr << "Usage: " << argv[0] << " [-n] file" << endl;
return EXIT_FAILURE;
}
ofstream outf("output.txt");
ifstream inf(argv[1]);
//if inf is error,output the error message.
if ( !inf ) {
cerr << "cannot open " << filename << " for input" << endl;
return EXIT_FAILURE;
}
int lineno = 1;
while(true){
getToken(inf,outf,lineno);
if(inf == NULL) {
outf << "END OF FILE!" << endl;
break;
}
}
// file stream close
inf.close();
outf.close();
return 0;
}
///:~
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -