此程序主要功能是将字符串类型的源码转换为**
输入:
1、使用string对象存放保留字并使用数组存放对应的id值
vector reserve = { "void","int","float","double","if","else","for","do","while" };
const int num_reserve[] = { 2,3,4,5,6,7,8,9,10 };
2、使用string类对象管理字符串,便于向文件中打印
string temp("");
temp += ch;
fprintf(fp, "<%d,%s>", 11, temp.c_str());
函数名称 | 主要功能 |
---|---|
int main(); | 负责实际的词法分析工作,将源代码中的不同部分分类并输出到文件以供后续的语法分析或其他处理使用。 |
int is_reserve(string& temp); | 用于判断给定的字符串 temp 是否是保留字(关键字)。它会在预定义的保留字列表中查找 temp ,如果找到匹配项,则返回相应的类别编码;否则返回0。 |
int is_letter(char& ch); | 用于判断一个字符 ch 是否是字母。如果字符是字母,它返回1,否则返回0。 |
int is_number(char ch); | 用于判断一个字符 ch 是否是数字。如果字符是数字,它返回1,否则返回0。 |
int is_single_delimiter(char& ch); | 用于判断一个字符 ch 是否是单字符分界符。如果字符是单字符分界符,它返回1,否则返回0。 |
main
函数内部调用函数来帮助判断字符的类型:is_reserve
用于判断是否是关键字。
is_letter
用于判断是否是字母。
is_number
用于判断是否是数字。
is_single_delimiter
用于判断是否是单字符分界符。
该程序主要根据文法来写出程序,main函数通过从文件中不断的读出字符,进行类别的判断,最后输出二元组
到文件中
改编后的文法如下:
<单词符号>→<标识符>|<无符号整数>|<单字符分界符>|<双字符分界符>
<标识符>→字母|<标识符>字母|<标识符>d
<无符号整数>→数字︱ <无符号整数>数字
<单字符分界符>→+ ︱- ︱* ︱;︱, ︱(︱) ︱{︱}|/|!|>|<|=|&
<双字符分界符>→<大于>=︱<小于>=︱<感叹号>=︱<等于>=︱<斜竖>* |<加号>+|<减号>-|
<大于> >|<小于><|<加号>=|<减号>=|<乘号>=|<斜竖>=|<与>&|<竖线>| |
<小于>→<
<等于>→=
<大于>→>
<斜竖> →/
<感叹号>→!
<加号>→+
<减号>→-
<乘号>→*
<与>→&
<竖线>→|
每类字符的类别编码如下:
单词符号 | 类别编码 |
---|---|
标识符 | 1 |
void | 2 |
int | 3 |
float | 4 |
double | 5 |
if | 6 |
else | 7 |
for | 8 |
do | 9 |
while | 10 |
无符号数 | 11 |
单字符分界符 | 12 |
双字节分界符 | 13 |
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
using namespace std;
vector<string> reserve = { "void","int","float","double","if","else","for","do","while" };
const int num_reserve[] = { 2,3,4,5,6,7,8,9,10 };
//判断是否是保留字 如果是的话返回对应的类别编码,否则返回0
int is_reserve(string& temp)
{
for (int i = 0; i < reserve.size(); i++)
{
if (reserve[i] == temp)
{
return num_reserve[i];
}
}
return 0;
}
//是字母返回值为1 否则返回值为0
int is_letter(char& ch)
{
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
{
return 1;
}
return 0;
}
//如果是数字返回1 否则返回0
int is_number(char ch)
{
if (ch >= '0' && ch <= '9')
{
return 1;
}
return 0;
}
//判断是否是单字符分界符,如果是返回1,否则返回0
int is_single_delimiter(char& ch)
{
switch (ch)
{
case ';':
return 1;
case ',':
return 1;
case '(':
return 1;
case ')':
return 1;
case '{':
return 1;
case '}':
return 1;
case '[':
return 1;
case ']':
return 1;
default:
return 0;
}
}
int main()
{
char ch;
FILE* ptr = fopen("input.txt", "r");
if (!ptr)
{
perror("input文件打开失败");
return -1;
}
FILE* fp = fopen("output.txt", "a+");
if (!fp)
{
perror("output文件打开失败");
return -1;
}
ch = fgetc(ptr);
while (ch != EOF)
{
if (ch == ' ' || ch == '\t')
{
ch = fgetc(ptr);
continue;
}
else if (ch == '\n')
{
fprintf(fp, "%c", ch);
ch = fgetc(ptr);
}
else if (is_letter(ch))
{
string temp("");
temp += ch;
ch = fgetc(ptr);
while (is_letter(ch) || is_number(ch))
{
temp += ch;
ch = fgetc(ptr);
}
//fseek(ptr, -1, SEEK_CUR);
int id = is_reserve(temp);
if (id != 0)
{
fprintf(fp, "<%d,%s>", id, temp.c_str());
}
else
{
fprintf(fp, "<%d,%s>", 1, temp.c_str());
}
}
else if (is_number(ch))
{
string temp("");
temp += ch;
ch = fgetc(ptr);
while (is_number(ch))
{
temp += ch;
ch = fgetc(ptr);
}
fprintf(fp, "<%d,%s>", 11, temp.c_str());
}
else if (is_single_delimiter(ch))
{
fprintf(fp, "<12,%c>", ch);
ch = fgetc(ptr);
}
else if (ch == '<')
{
string temp("");
temp += ch;
ch = fgetc(ptr);
if (ch == '<')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else if (ch == '=')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else
{
fprintf(fp, "<13,%s>", temp.c_str());
}
}
else if (ch == '=')
{
string temp("");
temp += ch;
ch = fgetc(ptr);
if (ch == '=')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else
{
fprintf(fp, "<13,%s>", temp.c_str());
}
}
else if (ch == '>')
{
string temp("");
temp += ch;
ch = fgetc(ptr);
if (ch == '>')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else if (ch == '=')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else
{
fprintf(fp, "<13,%s>", temp.c_str());
}
}
else if (ch == '/')
{
string temp("");
temp += ch;
ch = fgetc(ptr);
if (ch == '*')
{
fprintf(fp, "注释处理开始");
ch = fgetc(ptr);
while (ch != EOF)
{
if (ch == '*')
{
ch = fgetc(ptr);
if (ch == '/')
{
break;
}
else
{
continue;
}
}
ch = fgetc(ptr);
}
if (ch == '/')
{
fprintf(fp, "注释处理完成");
ch = fgetc(ptr);
}
}
else if (ch == '=')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else
{
fprintf(fp, "<12,%s>", temp.c_str());
}
}
else if (ch == '!')
{
string temp("");
temp += ch;
ch = fgetc(ptr);
if (ch == '=')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else
{
fprintf(fp, "<12,%s>", temp.c_str());
}
}
else if (ch == '+')
{
string temp("");
temp += ch;
ch = fgetc(ptr);
if (ch == '=')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else if (ch == '+')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else
{
fprintf(fp, "<12,%s>", temp.c_str());
}
}
else if (ch == '-')
{
string temp("");
temp += ch;
ch = fgetc(ptr);
if (ch == '=')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else if (ch == '-')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else
{
fprintf(fp, "<12,%s>", temp.c_str());
}
}
else if (ch == '*')
{
string temp("");
temp += ch;
ch = fgetc(ptr);
if (ch == '=')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else
{
fprintf(fp, "<12,%s>", temp.c_str());
}
}
else if (ch == '&')
{
string temp("");
temp += ch;
ch = fgetc(ptr);
if (ch == '&')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else
{
fprintf(fp, "<12,%s>", temp.c_str());
}
}
else if (ch == '|')
{
string temp("");
temp += ch;
ch = fgetc(ptr);
if (ch == '|')
{
temp += ch;
fprintf(fp, "<13,%s>", temp.c_str());
ch = fgetc(ptr);
}
else
{
fprintf(fp, "<12,%s>", temp.c_str());
}
}
}
fclose(ptr);
fclose(fp);
return 0;
}