Rso's Jotter

日々の開発の知見のメモやその他雑記

課題

時間もやる気もなくなってきたので
行き当たりばったりなプログラムになりましたわ
ちょっと長いので重いかも

//************ここからmain*******************

//main

#include<iostream>
#include<string>
#include"hmap.h"
#include"readfile.h"


using namespace std;

enum strtype{
	LETTER,		//英字
	DIGIT,		//数字
	DELIMITER,	//記号
	OPERATE,		//演算子
	
};

int init();
string searchdeclarator(readfile &rf,string& declaratorname);	//型宣言子を探す
int searchfunctionname(string str,string& retfname);	//関数名を探す
int entryVariable(const string str,VariableTable& vtclass,VariableInfo vinfo); //変数を登録

char chlist[255];		//文字の種類を分類する配列

string declaratorlist[] = {"int","char","BTREE","FILE","_bannin"};	//型宣言子

int main(){

	init();

	readfile rf;
	string bufline,bufline2="";

	VariableTable vtclass;
	VariableInfo vinfo;

	//メインまでスキップ
	string functionname="",declaratorname="";

	while(functionname != "main"){
	bufline = searchdeclarator(rf,declaratorname);
		if(bufline != ""){
			searchfunctionname(bufline,functionname);
		}
	}
	vinfo.Scope = "main";

	while(!rf.eof()){
		bufline = searchdeclarator(rf,declaratorname);
		if(bufline != ""){
			if(searchfunctionname(bufline,functionname) == 1){	//新しい関数が見つかった
				//登録してある変数を出力
				vtclass.output();
				cout << endl;
				vtclass.clear();	//マップを初期化

				vinfo.Scope = functionname;
			}
			else {
				vinfo.Type = declaratorname;
				//変数を登録
				entryVariable(bufline,vtclass,vinfo);
			}
		}
	}

	return 0;
}

//初期化関数
int init()
{
	for(int i=0;i < 255;i++)chlist[i] = DELIMITER;		//記号
	for(i='A';i<='Z';i++)	chlist[i] = LETTER;		//A〜ZをLETTERとする
	for(i='a';i<='z';i++)	chlist[i] = LETTER;		//a〜zをLETTER
	for(i='0';i<='9';i++)	chlist[i] = DIGIT;		//0〜9はDIGIT
	chlist['+'] = chlist['-'] = chlist['*'] = chlist['/'] = OPERATE;

	return 0;
}

//型宣言子を探す
string searchdeclarator(readfile &rf,string& declaratorname){
	string fncline,checkline="",retline;
	declaratorname = "";
	fncline = rf.GetLine();
	int i =0;
		while(fncline[i] == ' ' || fncline[i] == '\t'){	//先頭の空白とタブは飛ばす
			i++;
		}
		while(chlist[fncline[i]] == LETTER){
			declaratorname += fncline[i];
			i++;
		}
		for(int j=0; declaratorlist[j] != "_bannin";j++){	//型宣言子かどうかチェック
			if(declaratorname == declaratorlist[j]){
				retline.assign( fncline,i+1, MAX_LINESIZE );  
				return retline;
			}

		}

		fncline = "";	//型宣言子が見つからなかった場合は空の文字列を返す
		return fncline;
}

int searchfunctionname(const string str,string& retfname){
	retfname="";
	
	for(int i=0;chlist[str[i]] == LETTER;i++){
		retfname += str[i];
	}
	if(str[i] != '(' ){	//こいつは関数じゃない
		retfname = "";
		return 0;
	}
		return 1;
}

//変数を登録
int entryVariable(const string str,VariableTable& vtclass,VariableInfo vinfo){
	
	string vname="";
	for(int i=0;str[i] != ';' ;i++){	//セミコロンまで検索
		
		if(str[i] == '='){
			while(str[i] != ',' && str[i] != ';'){	//初期化子は無視
				i++;
			}		
		}
		if(str[i] == ','){
			vtclass.insert(vname,vinfo);
			vname="";
			continue;
		}
		
		vname += str[i];
	}
	vtclass.insert(vname,vinfo);

	return 0;
}

//************ここからreadfile.h*******************
#ifndef READ_FILE_H
#define READ_FILE_H

#define MAX_LINESIZE 100 //読み込むソースの1行あたり最大の文字数
#include<iostream>
#include<fstream>
#include<string>

using namespace std;

class readfile{
	ifstream fin;

public:
	readfile();
	string GetLine();		//1行読み取り
	bool eof();				//ファイルの終わりを判定
};

#endif

//************ここからreadfile.cpp*******************
#include"readfile.h"

readfile::readfile(){
	fin.open("BtreeE.c");
	if(!fin){
		cout << "ファイルのオープン失敗" << endl;
	}
}

//1行読み込み
string readfile::GetLine(){
	char strtmp[MAX_LINESIZE];
	char ch;
	string stemp;

	while(fin.peek() == '\n'){
		fin.get(ch);	//改行を捨てる
	}

	fin.get(strtmp,MAX_LINESIZE,'\n');
	stemp = strtmp;
	
	return stemp;
}

bool readfile::eof(){
	if(fin.eof()){
		return true;
	}
	else
		return false;
}

//************ここからhmap.h*******************
#ifndef HMAP_H
#define HMAP_H

#include <iostream>
#include <string>
#include <map>
#include <utility>

using namespace std;



struct VariableInfo{	//変数の情報
	string Type;	//型名
	string Scope;	//所属関数名
};

class VariableTable{
	map<string,VariableInfo> m_VariableInfo;	//変数表 
public:
	int insert(string,VariableInfo);			//変数表に変数を登録する
	int search(string);							//変数表から変数を検索する
	int output();								//変数表に登録されている変数をすべて表示する
	void clear();								//マップの中身をすべて削除
	friend ostream &operator<<(ostream &stream,map<string,VariableInfo>::iterator p);
};

typedef map<string,VariableInfo> VTABLEMAP;	//長ったらしいのでtypedef



#endif

//************ここからhmap.cpp*******************
#include"hmap.h"

//抽出子
ostream &operator<<(ostream &stream,VTABLEMAP::iterator p){
	stream << "変数名:" << p->first << "\t型:" << p->second.Type << "\t有効範囲:" << p->second.Scope << endl;
	return stream;
}

//マップにデータを登録
int VariableTable::insert(string sVariableName,VariableInfo vinfo){

	m_VariableInfo.insert(make_pair(sVariableName,vinfo));
	return 0;
}

//マップからデータを検索
int VariableTable::search(string sVariableName){
	const VTABLEMAP::iterator p = m_VariableInfo.find(sVariableName);
	if(p != m_VariableInfo.end()){	//変数が見つかった
		cout << p;		
	}
	else{	//見つからなかった
		cout << sVariableName << "は登録されていません" << endl;
	}
	return 0;
}

//マップに登録されているデータをすべて表示
int VariableTable::output(){
	VTABLEMAP::iterator p = m_VariableInfo.begin();
	while(p != m_VariableInfo.end()){	//マップに登録されている変数をすべて表示する
		cout << p;		
		p++;
	}
	return 0;
}

//マップの中身をすべて削除
void VariableTable::clear(){
	this->m_VariableInfo.clear();
}

ビルドできねぇってかよく分からん人はゆってくれたらプロジェクトあげます