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

📄 token.cpp

📁 词法分析,语法分析,文件中有语言的文法,根据文法写出的程序样例,还有根据样例进行词法分析得出的文件
💻 CPP
字号:
// 词法分析器 Token.cpp
// 作者: 吴建平
// 学号:20021071 班级:20021013
// 完成日期:2005-6-10
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;

//vector<string> identifiers;		// 存放标识符
map<char, int> boundaryChar;	// 界符及其所属种类
map<string, int> keyWords;		// 关键字及其所属种类
ofstream outFile("a.out");		// 输出文件

typedef map<char, int>::iterator pos_type;
pos_type IsBoundaryChar(char);
bool IsitKeywords(const string&);
bool IsitInteger(const string&);
void IsitIdentifier(const string&);
void WordsHandler(const string&);
void TokenParser(const char*);
void FillKeywords();
void FillBoundaryChar();

int main(int argc, char* argv[])
{
	if (argc != 2) {
		cerr << "Usage: Token fileName" << endl;
		return EXIT_FAILURE;
	}

	FillKeywords();
	FillBoundaryChar();
	TokenParser(argv[1]);
	return 0;
}

// 字符处理
void TokenParser(const char* filename)
{
	ifstream inFile(filename);
	if (!inFile) {
		cerr << "Can't open file \"" << inFile
			 << "\"" << endl;
		exit(EXIT_FAILURE);
	}

	char c;			// 从文件读入的字符
	string word;	// 由字符组成的单词
	while (inFile.get(c)) {
		map<char, int>::iterator pos = IsBoundaryChar(c);//是否界符
		if (pos != boundaryChar.end()) {
			if (word != "") {	// 如果为单词为空则不进行处理
				WordsHandler(word);
			}
			word = "";	// 将单词清空
			if (pos->second != -1) { // 不是空格、回车和TAB
				outFile << pos->second << '\t' << pos->second << '\n';
			}
		}
		else {
			word += c;
		}
	}
}

// 填充boundaryChar
void FillBoundaryChar()
{
	char boundary[] = {'(', ')', '{', '}', ';', '=',
		'+', '*', '>', '<', ','};
	for (int i = 0; i < sizeof(boundary)/sizeof(char); ++i) {
		boundaryChar.insert(make_pair(boundary[i], i+1));
	}
	boundaryChar.insert(make_pair(' ',  -1));
	boundaryChar.insert(make_pair('\n', -1));
	boundaryChar.insert(make_pair('\t', -1));
}

// 填充keyWords
void FillKeywords()
{
	string key[] = {"int", "if", "then", "else", "return"};
	for (int i = 0; i < 5; ++i) {
		keyWords.insert(make_pair(key[i], i+21));
	}
	keyWords.insert(make_pair(string("main"), 99));
}

// 单词处理
void WordsHandler(const string& word)
{
	if (!IsitKeywords(word))	// 是关键字
		if (!IsitInteger(word))	// 是整型常量
			IsitIdentifier(word);	// 是标识符
}

// 判断单词是否为关键字
// 以keyWords为依据,从头到尾扫描,如果在keyWords中找到,
// 则是关键字,否则不是。将其种类和内码值写入输出文件
bool IsitKeywords(const string& word)
{
	for (map<string, int>::iterator pos = keyWords.begin(); 
		pos != keyWords.end(); ++pos) {
		if (pos->first == word) {
			outFile << pos->second << '\t' << word << '\n';
			return true;
		}
	}	
	return false;
}

// 判断单词是否为整型常量
// 是的话将单词种类及内码值写入输出文件
// 内码值即该整型常量本身
bool IsitInteger(const string& word)
{
	for (int i = 0; i < word.size(); ++i) {
		if (!isdigit(word[i]))
			return false;
	}
	outFile << "20" << '\t' << word << '\n';
	return true;
}

// 单词为一般标识符,则将单词种类及内码值写入输出文件
// 单词内码值由该单词在源文件中出现的顺序决定
void IsitIdentifier(const string& word)
{
	if (isdigit(word[0])) {	// 标识符不得以数字开头
		outFile << "100" << '\t' << word << '\n';
		return;
	}
	outFile << '0' << '\t' << word << '\n';
}

// 判断是否为界符,返回其在boundaryChar中的位置(迭代器)
//之不理返回end表示不是界符
pos_type IsBoundaryChar(char c)
{
	for (map<char, int>::iterator pos = boundaryChar.begin(); 
		pos != boundaryChar.end(); ++pos) {
		if (pos->first == c) {
			return pos;
		}
	}
	return pos;
}

⌨️ 快捷键说明

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