编译技术的相关习题讲解我放在资料区下载(免费)
应该是期末考试范围类
给一个代码:(应该是什么上机或者大实验的,自己体会吧,毕竟不是其他专业的,你们拿去跑跑)
#include<fstream>
#include <iostream>
#include <string>
using namespace std;
//保留字
const string KeyWord[6] = { "main","int","float","if","else","while" };
int syn; //单词种别码
string token; //单词自身字符串.用于在程序整体中找到每个单位字符串
int sum; //INT整型里的码内值,整型数据的值(本来是字符串)
int i = 0;//循环索引(注意索引是共用的)
int x = 0;//对标识符计数
int y = 100;//对整型数计数
int z = 0;//对关键字与符号不计数
bool IsLetter(char ch); //判断是否为字母(空格后首字符是字母可能是关键字或者标识符)
bool IsDigit(char ch); //判断是否为数字
void scan(string s); //扫描
int main()
{
char str[20];
ifstream infile;
ofstream outfile1, outfile2;
//输入文件scource
infile.open("source.txt", ios::in);
//输出文件token与symble
outfile1.open("token.txt", ios::out);
outfile2.open("symble.txt", ios::out);
if (!infile)
{
cout << "读取特征文件失败!";
}
//a是被分析程序对应字符串
//string str = "";
//getline(cin, str);//接收一个输入字符串(需要包含#include<string>)
while (infile >> str) {
do {
scan(str);
if (syn <= 9 || (syn <= 29 && syn >= 13))
outfile1 << syn << " " << z << endl;//对关键字跟符号不计数(z恒等于0)
else if (syn == 10) {
outfile1 << syn << " " << x << " " << endl;//标识符从0计数
outfile2 << x << " " << token << endl;
}
else if (syn == 11 || syn == 12) {
outfile1 << syn << " " << y << " " << endl;//实(整)数从100计数
outfile2 << y << " " << sum << endl;
}
} while (i>strlen(str));
i = 0;
}
infile.close();
outfile1.close();
outfile2.close();
}
bool IsLetter(char ch) //判断是否为字母
{
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
return true;
else
return false;
}
bool IsDigit(char ch) //判断是否为数字
{
if (ch >= '0' && ch <= '9')
return true;
else
return false;
}
//关键就在于scan()扫描函数(结合各种条件与提前定义好的函数判断程序中每个单位字符串的种类,并且指定相应的syn种别码)
void scan(char s[]) //扫描
{
token = ""; //清空当前字符串(每次判断前都要清空上一次的记录)
// 1.判断字符是否为数字
if (IsDigit(s[i]))//空格后第一个字符是数字,则整个单元字符串一定是数
{
token = ""; //清空当前字符串
sum = 0;
while (IsDigit(s[i])) {
sum = sum * 10 + (s[i] - '0');
i++; //字符位置++
syn = 11; //INT种别码为11
}
y++;//从100开始计数
}
// 2.字符为字符串,表现为字母开头衔接任意个数字或字母
else if (IsLetter(s[i]))//空格后第一个字符是字母,是标识符或者关键字(先判断标识符再在其基础上判断关键字)
{
token = ""; //清空当前字符串
while (IsDigit(s[i]) || IsLetter(s[i])) {
token += s[i]; //加入token字符串
i++;
}
syn = 10; // 如果是标识符,种别码为10
x++;
//如果是关键字,则用for循环将token与keyword比较找对应的种别码
for (int j = 0; j < 6; j++)
{
if (token == KeyWord[j]) //如果都是string类型,可以直接=相比较,若相等则返回1,否则为0
{
syn = j + 1; //种别码从1开始所以要加1(在syn=10的基础上更新)
x--; //关键字不计数
break;
}
}
}
//3. 判断为符号
else {
token = ""; //清空当前字符串
switch (s[i]) {
case'=':
syn = 13;
i++;
token = "=";
if (s[i] == '=') {
syn = 22;
i++;
token = "==";
}
break;
case'+':
syn = 14;
i++;
token = "+";
break;
case'-':
syn = 15;
i++;
token = "-";
break;
case'*':
syn = 16;
i++;
token = "*";
break;
case'/':
syn = 17;
i++;
token = "/";
break;
case'(':
syn = 26;
i++;
token = "(";
break;
case')':
syn = 27;
i++;
token = ")";
break;
case'{':
syn = 28;
i++;
token = "[";
break;
case'}':
syn = 29;
i++;
token = "]";
break;
case',':
syn = 25;
i++;
token = ",";
break;
case';':
syn = 24;
i++;
token = ";";
break;
case'>':
syn = 20;
i++;
token = ">";
if (s[i] == '=')
{
syn = 21;
i++;
token = ">=";
}
break;
case'<':
syn = 18;
i++;
token = "<";
if (s[i] == '=')
{
syn = 19;
i++;
token = "<=";
}
break;
case'!':
syn = 9;
i++;
if (s[i] == '=')
{
syn = 23;
i++;
token = "!=";
}
break;
case'||':
syn = 7;
i++;
token = "||";
break;
case'&&':
syn = 8;
i++;
token = "&&";
break;
default:
syn = -1;
break;
}
}
}