题目要求:对给定的C语言程序,识别出关键字、整型常量、实型常量(包括1.23E-23这样的科学计数法)、标识符、分隔符、运算符。
语言:C++
集成环境:VS 2017
算法:使用状态转换图实现
程序代码:
/*
关键字:<AUTO, >;标示符:<IDENT,my_name>;整型常量<200,数值>;实型常量<300,数值>;分隔符:<400-408, >;运算符:<500-, >
*/
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <cassert>
#include <sstream>
#include <map>
using namespace std;
struct Tuple{
string val;
string content;
};
vector<string> constant = { "AUTO","BREAK","CASE","CHAR","CONST","CONTINUE","DEFAULT","DO","DOUBLE","ELSE",
"ENUM","EXTERN","FLOAT","FOR","GOTO","IF","INT","LONG","REGISTER","RETURN","SHORT","SIGNED","SIZEOF","STATIC",
"STRUCT","SWITCH","TYPEDEF","UNSIGNED","VOID","VOLATILE","WHILE"};
vector<Tuple> result;
vector<char>file_content;
vector<string> keyword = { "auto","break","case","char","const","continue","default","do","double","else"
,"enum","extern","float","for","goto","if","int","long","register","return","short","signed","sizeof","static"
,"struct","switch","typedef","unsigned","void","volatile","while" };
vector<char>separater = { ';',',','{','}','[',']','(',')' };
vector<char>operators = { '+','-','*','/','>','<','=','!','&','|'};
void GetFile(string file_name)
{
ifstream in_file;
in_file.open(file_name.data());
assert(in_file.is_open());
char c;
in_file >> noskipws;
while (!in_file.eof())
{
in_file >> c;
file_content.push_back(c);
}
in_file.close();
}
bool IsLetter(char c)
{
if ((c >= 'A'&&c <= 'Z') || (c >= 'a'&&c <= 'z'))
return true;
return false;
}
bool IsBlank(char c)
{
if (c == ' ')
return true;
return false;
}
bool IsNumber(char c)
{
if (c >= '0'&&c <= '9')
return true;
return false;
}
int IsKeyword(string str)
{
for (int i = 0; i < keyword.size(); i++)
if (str == keyword[i])
return i+1;
return 0;
}
bool IsInteger(string str)
{
for (int i = 0; i < str.size(); i++)
{
if (!IsNumber(str[i]))
return false;
return true;
}
}
int IsSeparater(char c)
{
for (int i = 0; i < separater.size(); i++)
if (c == separater[i])
return i + 1;
return 0;
}
bool IsOperator(char c)
{
for (int i = 0; i < operators.size(); i++)
if (c == operators[i])
return true;
return false;
}
int MatchOperator(char c)
{
for (int i = 0; i < operators.size(); i++)
if (c == operators[i])
return i + 1;
return 0;
}
void LexicalAnalyzer()
{
char temp_ch=' ';
for (int i = 0; i < file_content.size();)
{
string temp_word = "";
temp_ch = file_content[i];
if (IsBlank(temp_ch))
{
i++;
continue;
}
if (IsLetter(temp_ch))
{
while (IsLetter(temp_ch)||IsNumber(temp_ch)||temp_ch=='_')
{
temp_word += temp_ch;
temp_ch = file_content[++i];
}
int index = IsKeyword(temp_word);
Tuple temp_tuple;
if (index!=0)
{
temp_tuple.val = constant[index - 1];
temp_tuple.content = "";
result.push_back(temp_tuple);
}
else
{
temp_tuple.val = "IDENT";
temp_tuple.content = temp_word;
result.push_back(temp_tuple);
}
continue;
}
if (IsNumber(temp_ch))
{
while (IsNumber(temp_ch)||temp_ch=='.'||temp_ch=='E'|temp_ch=='e'||
(temp_ch=='+'&&(file_content[i-1]=='E'||file_content[i-1]=='e'))||
(temp_ch=='-'&&(file_content[i - 1] == 'E' || file_content[i - 1] == 'e')))
{
temp_word += temp_ch;
temp_ch = file_content[++i];
}
Tuple temp_tuple;
temp_tuple.content = temp_word;
if (IsInteger(temp_word))
temp_tuple.val = "200";
else
temp_tuple.val = "300";
result.push_back(temp_tuple);
continue;
}
if (IsSeparater(temp_ch) != 0)
{
Tuple temp_tuple;
temp_tuple.val = to_string(400 + IsSeparater(temp_ch));
temp_tuple.content = temp_word;
result.push_back(temp_tuple);
i++;
continue;
}
if (IsOperator(temp_ch))
{
while (IsOperator(temp_ch))
{
temp_word += temp_ch;
temp_ch = file_content[++i];
}
Tuple temp_tuple;
if (temp_word == "++")
{
temp_tuple.val = "500";
temp_tuple.content = " ";
}
if (temp_word == "--")
{
temp_tuple.val = "501";
temp_tuple.content = " ";
}
if (temp_word == "&&")
{
temp_tuple.val = "502";
temp_tuple.content = " ";
}
if (temp_word == "||")
{
temp_tuple.val = "503";
temp_tuple.content = " ";
}
else
{
if (temp_word.size() == 1)
{
char ch = temp_word[0];
temp_tuple.val = to_string(503 + MatchOperator(ch));
temp_tuple.content = " ";
}
else
{
temp_tuple.val = "UNKNOWN";
temp_tuple.content = " ";
}
}
result.push_back(temp_tuple);
continue;
}
i++;
}
}
void PrintResult()
{
for (int i = 0; i < result.size(); i++)
{
cout << "<" << result[i].val << "," << result[i].content <<">"<< endl;
}
}
int main()
{
GetFile("test_c.txt");
LexicalAnalyzer();
PrintResult();
system("pause");
return 0;
}
被读取的text_c.txt文件:
int main()
{
int i=1;
char c;
if(i==1)
{
i++;
c='a';
}
return 0;
}
运行结果:
完整程序下载链接:https://download.csdn.net/download/NiZjiTouA/12605353