📄 token.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 + -