Description
设一语言的关键词、运算符、分界符的个数与单词如下:
struct { int number; string str[10]; } keywords={3,"int","main","return"} ; //关键词
struct { int number; string str[10]; } operators ={5,"+","*","=","+=","*="}; //运算符
struct { int number; string str[10]; } boundaries ={6,"(",")","{","}",",",";"} ; //分界符
struct { int number; string str[100];} identifieres={0}; //标识符
struct { int number; string str[100];} Unsigned_integer={0}; //无符号整数
以上类号分别为1~5,序号从0开始;
标识符是字母开头的字母数字串;常量为无符号整数;
用C++设计一程序实现词法分析。
Input
输入一程序,结束符用”#”;
Output
输出单词数对:<类号,序号>。 输出标识符表,用空格分隔; 输出无符号整数表,用空格分隔;
Sample Input
main() { int a=2,b=3; return 2*b+a; }#
Sample Output
<1,1><3,0><3,1><3,2><1,0><4,0><2,2><5,0><3,4><4,1><2,2><5,1><3,5><1,2><5,0><2,1> <4,1><2,0><4,0><3,5><3,3> identifieres:a b Unsigned_integer:2 3
解:
用cin>>str读入输入,会以换行和空格分隔,读入一个字符串后,先将其切分为若干个子字符串(切分规则:连续的数字和字母不切开,其他的字符分开),再分别将子字符串转化为单词对,标识符和无符号整数第一次出现时放入表中,代码:
#include<string>
#include<iostream>
#include<vector>
#include<sstream>
using namespace std;
struct { int number; string str[10]; } keywords={3,"int","main","return"} ; //关键词
struct { int number; string str[10]; } operators ={5,"+","*","=","+=","*="}; //运算符
struct { int number; string str[10]; } boundaries ={6,"(",")","{","}",",",";"} ; //分界符
struct { int number; string str[100];} identifieres={0}; //标识符
struct { int number; string str[100];} Unsigned_integer={0}; //无符号整数
bool isLetter(char temp) {
if ('a' <= temp && 'z' >= temp) return true;
if ('A' <= temp && 'Z' >= temp) return true;
return false;
}
bool isDigit(char temp) {
if (temp >= '0' && temp <= '9') return true;
return false;
}
vector<pair<int, string> > split(string str) {
vector<pair<int, string> > temp;
int len = str.length();
string letter = "";
string digit = "";
for (int i = 0; i < len; i++) {
if (isLetter(str[i])) {
letter += str[i];
if (i+1 == len || !isLetter(str[i+1])) {
temp.push_back(make_pair(1,letter));
letter = "";
}
} else if (isDigit(str[i])) {
digit += str[i];
if (i+1 == len || !isDigit(str[i+1])) {
temp.push_back(make_pair(2,digit));
digit = "";
}
} else {
string s;
stringstream stream;
stream << str[i];
s = stream.str();
temp.push_back(make_pair(3, s));
}
}
return temp;
}
void dealLetters(string str) {
bool temp = true;
for (int i = 0; i < 3; i++)
if (str == keywords.str[i]) {
cout << "<1," << i << ">";
temp = false;
break;
}
if (temp) {
bool temp1 = true;
for (int i = 0; i < identifieres.number; i++) {
if (identifieres.str[i] == str) {
cout << "<4," << i << ">";
temp1 = false;
break;
}
}
if (temp1) {
cout << "<4," << identifieres.number << ">";
identifieres.str[identifieres.number++] = str;
}
}
}
void dealDigits(string str) {
bool temp = true;
for (int i = 0; i < Unsigned_integer.number; i++) {
if (Unsigned_integer.str[i] == str) {
cout << "<5," << i << ">";
temp = false;
break;
}
}
if (temp) {
cout << "<5," << Unsigned_integer.number << ">";
Unsigned_integer.str[Unsigned_integer.number++] = str;
}
}
bool dealOthers(string str) {
if (str == "#") return true;
for (int i = 0; i < 5; i++) {
if (operators.str[i] == str) {
cout << "<2," << i << ">";
return false;
}
}
for (int i = 0; i < 6; i++) {
if (boundaries.str[i] == str) {
cout << "<3," << i << ">";
return false;
}
}
return false;
}
int main() {
string str;
while(cin >> str) {
bool end = false;
vector<pair<int, string> > temp = split(str);
for (int i = 0; i < temp.size(); i++) {
if (temp[i].first == 1) dealLetters(temp[i].second);
if (temp[i].first == 2) dealDigits(temp[i].second);
else end = dealOthers(temp[i].second);
}
if (end == true) break;
}
cout << "\nidentifieres:";
for (int i = 0; i< identifieres.number; i++) cout << identifieres.str[i] << " ";
cout << "\nUnsigned_integer:";
for (int i = 0; i< Unsigned_integer.number; i++) cout << Unsigned_integer.str[i] << " ";
}
测试: