我写好的.
scan.h
/*
* scan.h
* ccompiler
*
* Created by on 09-10-12.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#ifndef _SCAN_H_
#define _SCAN_H_
#include <string>
#include <fstream>
using namespace std;
typedef enum
{
ENDFILE,ERROR,
ELSE,IF,INT,RETURN,VOID,WHILE,
ID,NUM,
ASSIGN,EQ,LT,GT,LE,GE,NE,ADD,SUB,MUL,DIV,SEMI,LPAREN,RPAREN,LZK,RZK,LDK,RDK,COMMA
}
TokenType;
class Scan
{
private:
string tokenStr;
string linebuffer;
ifstream * in;
int linepos;
int lineno;
bool EOF_Flag;
bool traceScan;
void printToken(TokenType tt,const string &tok);
public:
Scan(ifstream * in)
{
this->in=in;
linepos=0;
linebuffer="";
lineno=0;
EOF_Flag=false
traceScan=true;
}
char getNextChar();
void ungetNextChar();
TokenType reservedLookup(string &s);
void setTraceScan(bool f);
bool getTraceScan();
TokenType getToken();
string getTokenStr();
};
#endif
scan.cpp
/*
* scan.cpp
* ccompiler
*
* Created by on 09-10-12.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
#include "scan.h"
typedef enum
{START,INNUM,INID,INNOTEQ,TEMPE,TEMPG,TEMPL,SLASH,INCOMMENT1,INCOMMENT2,DONE}
StateType;
static struct
{
string str;
TokenType tok;
} reservedWords[6]
={{"else",ELSE},{"if",IF},{"int",INT},{"return",RETURN},{"void",VOID},{"while",WHILE}};
char Scan::getNextChar()
{
if(linepos>=linebuffer.size())
{
if(getline(*in,linebuffer))
{
linebuffer+="\n";
lineno++;
linepos=0;
return linebuffer[linepos++];
}
else
{
EOF_Flag=true;
return EOF;
}
}
else
return linebuffer[linepos++];
}
void Scan::ungetNextChar()
{
if(!EOF_Flag) linepos--;
}
TokenType Scan::reservedLookup(string &s)
{
for(int i=0;i<6;i++)
if(s==reservedWords[i].str)
return reservedWords[i].tok;
return ID;
}
void Scan::setTraceScan(bool f)
{
traceScan=f;
}
bool Scan::getTraceScan()
{
return traceScan;
}
TokenType Scan::getToken()
{
tokenStr="";
TokenType currentToken;
StateType state=START;
while(state!=DONE)
{
bool save=false;
char c=getNextChar();
switch (state) {
case START:
if(c>='0'&&c<='9'){
state=INNUM;
save=true;
}
else if((c>='a'&&c<='z')||(c>='A'&&c<='Z')){
state=INID;
save=true;
}
else if(c==' '||c=='\t'||c=='\n')
{
state=START;
}
else if(c=='/'){
state=SLASH;
}
else if(c=='='){
state=TEMPE;
}
else if(c=='>')
state=TEMPG;
else if(c=='<')
state=TEMPL;
else if(c=='!')
state=INNOTEQ;
else
{
state=DONE;
switch (c) {
case EOF:
currentToken=ENDFILE;
break;
case '+':
currentToken=ADD;
break;
case '-':
currentToken=SUB;
break;
case '*':
currentToken=MUL;
break;
case '(':
currentToken=LPAREN;
break;
case ')':
currentToken=RPAREN;
break;
case '[':
currentToken=LZK;
break;
case ']':
currentToken=RZK;
break;
case '{':
currentToken=LDK;
break;
case '}':
currentToken=RDK;
break;
case ';':
currentToken=SEMI;
break;
case ',':
currentToken=COMMA;
break;
default:
currentToken=ERROR;
break;
}
}
break;
case INNUM:
if(c<'0'||c>'9')
{
ungetNextChar();
state=DONE;
currentToken=NUM;
}
else
save=true;
break;
case INID:
if(!((c>='a'&&c<='z')||(c>='A'&&c<='Z')))
{
ungetNextChar();
state=DONE;
currentToken=ID;
}
else
save=true;
break;
case SLASH:
if (c!='*')
{
state=DONE;
currentToken=DIV;
}
else
state=INCOMMENT1;
break;
case INCOMMENT1:
if (c!='*')
state=INCOMMENT1;
else if(c==EOF){
state=DONE;
currentToken=ENDFILE;
}
else
state=INCOMMENT2;
break;
case INCOMMENT2:
if (c=='*') {
state=INCOMMENT2;
}else if(c=='/'){
state=START;
}else if(c==EOF){
state=DONE;
currentToken=ENDFILE;
}else {
state=INCOMMENT1;
}
break;
case TEMPE:
if (c=='=') {
state=DONE;
currentToken=EQ;
}else{
state=DONE;
ungetNextChar();
currentToken=ASSIGN;
}
break;
case TEMPG:
if (c=='=') {
state=DONE;
currentToken=GE;
}else{
state=DONE;
ungetNextChar();
currentToken=GT;
}
break;
case TEMPL:
if (c=='=') {
state=DONE;
currentToken=LE;
}else{
state=DONE;
ungetNextChar();
currentToken=LT;
}
break;
case INNOTEQ:
if (c=='=') {
state=DONE;
currentToken=NE;
}else {
state=DONE;
ungetNextChar();
currentToken=ERROR;
}
break;
default:
cerr<<"Scanner Bug: state= "<<state<<endl;
state=DONE;
currentToken=ERROR;
break;
}
if(save){
string newChar(1,c);
tokenStr+=newChar;
}
if (state==DONE&¤tToken==ID)
currentToken=reservedLookup(tokenStr);
}
if (traceScan) {
cout<<"Scan at line "<<lineno<<" token: ";
printToken(currentToken, tokenStr);
cout<<endl;
}
return currentToken;
}
string Scan::getTokenStr()
{
return tokenStr;
}
void Scan::printToken(TokenType tt,const string &tok)
{
string type;
switch (tt) {
case ENDFILE:
type="EOF";
break;
case ERROR:
type="ERROR";
break;
case ELSE:
case IF:
case INT:
case RETURN:
case VOID:
case WHILE:
type="reserved word";
break;
case ID:
type="ID";
break;
case NUM:
type="NUM";
break;
case ASSIGN:
type="=";
break;
case EQ:
type="==";
break;
case LT:
type="<";
break;
case GT:
type=">";
break;
case LE:
type="<=";
break;
case GE:
type=">=";
break;
case NE:
type="!=";
break;
case ADD:
type="+";
break;
case SUB:
type="-";
break;
case MUL:
type="*";
break;
case DIV:
type="/";
break;
case SEMI:
type=";";
break;
case LPAREN:
type="(";
break;
case RPAREN:
type=")";
break;
case LZK:
type="[";
break;
case RZK:
type="]";
break;
case LDK:
type="{";
case RDK:
type="}";
break;
case COMMA:
type=",";
break;
default:
break;
}
cout << type<<": "<<tok;
}
main.cpp
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#include "scan.h"
int main (int argc, char * const argv[]) {
string fileName="/Users/huanglongyin/scan_in.txt";
//cout<< "File name: ";
//cin>>fileName;
ifstream in(fileName.c_str());
if(!in){
cerr<<"Error occurs when openning file "<<fileName<<endl;
return -1;
}
Scan scan(&in);
while(scan.getToken()!=ENDFILE);
return 0;
}
温馨提示:内容为网友见解,仅供参考