Rso's Jotter

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

計言語

計言語の字句解析の課題
課題の仕様が適当なので細部も適当.
実用性は皆無


追記
定数,変数(関数),演算子予約語を解析
変数と関数は区別しない
演算子は+-*/=しか認識しない
その他もろもろの不具合あり

#include <iostream>
#include <cstdio>
#include <string>
#define MAXLINE 120	//1行の最大文字数

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

using namespace std;

int init();	//初期化関数
int end();	//終了関数
char nextChar();	//文字読み取り


string reserveword[] = {"auto","const","double","float","int","short","struct","unsigned",
						"break","continue","else","for","long","signed","switch","void",
						"case","default","enum","goto","register","sizeof","typedef",
						"char","do","extern","if","return","static","union","while",
						"_bannin"//番人
}; //予約語リスト
FILE *fp;	//ソースファイル
char chlist[255];		//文字の種類を分類する配列



int main()
{
	init();

	string temp,str;
	char ch;
	ch = nextChar();
	while(true){
			if(chlist[ch]==DIGIT){		//定数の読み取り
			while(chlist[ch] == DIGIT){
				temp += ch;		
				ch = nextChar();
				if(chlist[ch] == LETTER){
					cout << "ERROR" << (temp += ch) << endl;
				}

			}
			cout << "定数 ";
			temp = "";
		}

		else if(chlist[ch] == LETTER){	//変数(関数)読み取り
			while(chlist[ch] != DELIMITER && chlist[ch] != OPERATE){	//記号か演算子が発生するまで読み取り
				temp += ch;
				ch = nextChar();
			}
			str = "変数(関数) ";
			for(int i=0;reserveword[i] != "_bannin";i++){	//予約語かどうかチェック
				if(temp == reserveword[i]){
					str = "予約語 ";
					break;
				}
			}
			cout << str;
			temp = "";
		}
	else if(chlist[ch]==OPERATE){
				str = "演算子 ";
				cout << str;
				ch = nextChar();
			}
		else {
			ch = nextChar();
		}
	}

	end();
	return 0;
}

//------------------初期化関数-------------------
int init()
{
	int i;

	if((fp = fopen( "source.txt", "r" )) == NULL){	//ファイルのオープン
		cout << "ファイルの読み取りエラー" << endl;
		exit(-1);
	}

	for(i=0;i < 255;i++)chlist[i] = DELIMITER;		//LETTERとDIGITとOPARATE以外は記号とする
	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['/'] = chlist['='] = OPERATE;
	
	return 0;
}
//------------------終了関数--------------------
int end()
{
	fclose(fp);
	return 0;
}

char nextChar()
{
	static char line[MAXLINE];
	static char lineIndex = -1;
	char ch;

	if(lineIndex == -1){					//ファイルを1行読む
		if(fgets(line,MAXLINE,fp) != NULL){
			lineIndex = 0;
		}
		else{
			cout << "end file" << endl;
			exit(1);
		}
	}

	if((ch = line[lineIndex++]) == '\n')
	{
		lineIndex = -1;
		cout << endl;
	}
	return ch;
}