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

📄 scan.h

📁 一个简单的C语言子集的编译器,一个简单的C语言子集的编译器
💻 H
字号:


#ifndef SCAN_H_
#define SCAN_H_

#include <string>
#include <sstream>
#include <list>
#include "global.h"
#include "util.h"

using namespace std;
string inner_source=
	"int input(void){return 0;}\n"
	"void output(int x){}\n";
stringstream innersrc(inner_source);
typedef struct tokenunit{
	TokenType token;
	string tokenstring;
	int lineno;
} TokenUnit;
struct{
    char * word;
    TokenType type;
} ReservedWords[10]={
    {"if",IF},{"else",ELSE},{"while",WHILE},
    {"return",RETURN},{"void",VOID},{"int",INT},{""}
};
typedef enum{
    INID,INNUM,INLTEQ,INGTEQ,INEQ,INNEQ,
        INCOMMENT,START,DONE
} ScanState;

list<TokenUnit> tokenHist;
list<TokenUnit>::iterator tokenIt=tokenHist.end();

TokenType LookupReserved(string &token)
{
    int i=0;
    while(ReservedWords[i].word[0]!='\0')
    {
        if(token==ReservedWords[i].word)
            return ReservedWords[i].type;
        i++;
    }
    return ID;
}

TokenType GetToken()
{
    TokenType rettype;

	if(tokenIt!=tokenHist.end()){
		rettype=(*tokenIt).token;
		TokenString=(*tokenIt).tokenstring;
		lineno=(*tokenIt).lineno;
		++tokenIt;
		return rettype;
	}
    char ch;
    int save=1;
    ScanState state=START;
    TokenString="";
    while(state!=DONE)
    {
		istream *is;
		if(!innersrc.eof()){
			is=&innersrc;
			ch=is->get();
			if(ch==EOF) ch='\n';
		}
        else{
			is=&fsource;
			ch=is->get();
			if(ch=='\n') lineno++;
		}
        switch(state)
        {
        case START:
            if(isalpha(ch)) state=INID;
            else if(isdigit(ch)) state=INNUM;
            else if(ch=='<') state=INLTEQ;
            else if(ch=='>') state=INGTEQ;
            else if(ch=='=') state=INEQ;
            else if(ch=='!') state=INNEQ;
            else if(ch=='/') {
                if((ch=is->get())!='*') {
					is->putback(ch);
                    rettype=DIV;
                    state=DONE;
                }
                else{
                    state=INCOMMENT;
                    save=0;
                }
            }
            else if(ch==' ' || ch=='\n' || ch=='\t') {
				save=0;
			}
            else{
                switch(ch){
                case '+':
                    rettype=PLUS;
                    break;
                case '-':
                    rettype=MINUS;
                    break;
                case '*':
                    rettype=MUL;
                    break;
                case ';':
                    rettype=SEMI;
                    break;
                case ',':
                    rettype=COMMA;
                    break;
                case '(':
                    rettype=LPAREN;
                    break;
                case ')':
                    rettype=RPAREN;
                    break;
                case '[':
                    rettype=LSQUAR;
                    break;
                case ']':
                    rettype=RSQUAR;
                    break;
                case '{':
                    rettype=LBRACE;
                    break;
                case '}':
                    rettype=RBRACE;
                    break;
                case EOF:
                    save=0;
                    rettype=ENDFILE;
                    break;
                default:
                    save=0;
                    rettype=ERROR;
                    break;
                }
                state=DONE;
            }
            break;
        case INID:
            if(!isalpha(ch)) {
                is->putback(ch);
                rettype=ID;state=DONE;
                save=0;
            }
            break;
        case INNUM:
            if(!isdigit(ch)) {
                is->putback(ch);
                rettype=NUMBER;state=DONE;
                save=0;
            }
            break;
        case INLTEQ:
            if(ch=='=') {rettype=LTEQ;state=DONE;}
            else{is->putback(ch);rettype=LT;state=DONE;save=0;}
            break;
        case INGTEQ:
            if(ch=='=') {rettype=GTEQ;state=DONE;}
            else{is->putback(ch);rettype=GT;state=DONE;save=0;}
            break;
        case INEQ:
            if(ch=='=') {rettype=EQ;state=DONE;}
            else{is->putback(ch);rettype=ASSIGN;state=DONE;save=0;}
            break;
        case INNEQ:
            if(ch=='=') {rettype=LTEQ;state=DONE;}
            else{is->putback(ch);rettype=ERROR;state=DONE;save=0;}
            break;
        case INCOMMENT:
            if(ch=='*'){
                if(is->get()=='/')
                    state=START;
            }
            save=0;
            break;
        }
        if(save==1) TokenString+=ch;
        else save=1;
    }
    if(rettype==ID){
        rettype=LookupReserved(TokenString);
    }
	TokenUnit tu;
	tu.lineno=lineno;
	tu.token=rettype;
	tu.tokenstring=TokenString;
	tokenHist.push_back(tu);

    ftoken<<TokenString<<endl;
    return rettype;
}

list<TokenUnit>::iterator Backup()
{
	list<TokenUnit>::iterator it;
	if(tokenIt==tokenHist.end()) it=--tokenHist.end();
	else {
		it=--tokenIt;
		++tokenIt;
	}
	return it;
}
void Restore(list<TokenUnit>::iterator &it)
{
	tokenIt=it;
	token=GetToken();
}
#endif

⌨️ 快捷键说明

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