【问题描述】通过设计c语言常见单词的正规文法或正规式,而后得到NFA,再确定化得到DFA,根据DFA的转换矩阵或转换图,用c++语言实现词法分析器。
【输入形式】输入一段完整的c语言程序
【输出形式】各类单词的token字
【样例输入】
int main(){int a &#61; 10;double b &#61; -20.9;if(a<&#61;b)a&#43;&#61;b;return a;
}
【样例输出】
line1:(type, int)line1:(keyword, main)line1:(bracket, ()line1:(bracket, ))line1:(bracket, {)line2:(type, int)line2:(identify, a)line2:(OPT, &#61;)line2:(integer, 10)line2:(bracket, ;)line3:(type, double)line3:(identify, b)line3:(OPT, &#61;)line3:(decimal, -20.9)line3:(bracket, ;)line4:(keyword, if)line4:(bracket, ()line4:(identify, a)line4:(OPT, <&#61;)line4:(identify, b)line4:(bracket, ))line5:(identify, a)line5:(OPT, &#43;&#61;)line5:(identify, b)line5:(bracket, ;)line6:(identify, a)line6:(OPT, &#61;)line6:(integer, 0)line6:(bracket, ;)line7:(keyword, return)line7:(identify, a)line7:(bracket, ;)line8:(bracket, })
【样例说明】需要识别的关键字包括main, return, if, else, do, while, for, scanf, printf, sqrt, abs&#xff1b;type类型包括void, int, double, float, char&#xff1b;运算符(算术、关系、逻辑、位)&#xff1b;需要识别的其他单词有标识符, 整数&#xff08;十进制形式、指数形式&#xff09;&#xff0c;实数&#xff08;十进制形式、指数形式&#xff09;&#xff0c;字符串&#xff08;输出类型名为string&#xff09;&#xff1b;过滤注释及空格。
【评分标准】根据设计文档的质量、lex文件的正确性&#xff0c;代码的正确性、代码的时间空间复杂度、识别单词的种类等综合评分
实现代码&#xff1a;
#include
#include
#include
#include using namespace std;vector<string> keyword &#61; {"scanf", "printf", "if", "else", "for", "while", "return", "do", "main", "abs", "sqrt"};
vector<string> type &#61; {"int", "void", "char", "double", "short", "float"};
vector<char> bracket &#61; {&#39;,&#39;, &#39;\\&#39;, &#39;;&#39;, &#39;:&#39;, &#39;(&#39;, &#39;)&#39;, &#39;[&#39;, &#39;]&#39;, &#39;{&#39;, &#39;}&#39;, &#39;"&#39;, &#39;\&#39;&#39;};struct Node
{int line &#61; 0;string type;string word;
};vector<Node> stack;
int line &#61; 1;
char text[int(1e5)] &#61; "";
char ch &#61; &#39; &#39;;
int len &#61; 0;
int i &#61; 0;
string word;
Node temp;void makeword(string s)
{temp.line &#61; line;temp.type &#61; s;temp.word &#61; word;stack.push_back(temp);word.clear();
}void JudgeE()
{word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];if (ch &#61;&#61; &#39;&#43;&#39; || ch &#61;&#61; &#39;-&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];}if (ch >&#61; &#39;1&#39; && ch <&#61; &#39;9&#39;){word &#43;&#61; ch;while ((ch &#61; text[&#43;&#43;i]) && (ch >&#61; &#39;0&#39; && ch <&#61; &#39;9&#39;))word &#43;&#61; ch;makeword("float");}else{cout << "Error at Line " << line << ": Illegal floating point number \"" << word << "\".\n";exit(-1);}
}void jump()
{while (ch &#61;&#61; &#39; &#39; || ch &#61;&#61; &#39;\n&#39;){if (ch &#61;&#61; &#39;\n&#39;)line&#43;&#43;;ch &#61; text[&#43;&#43;i];}
}void makenumber()
{while (ch >&#61; &#39;0&#39; && ch <&#61; &#39;9&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];}if (ch &#61;&#61; &#39;.&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];while (ch >&#61; &#39;0&#39; && ch <&#61; &#39;9&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];}if (ch &#61;&#61; &#39;e&#39;)JudgeE();elsemakeword("decimal");}else if (ch &#61;&#61; &#39;e&#39;)JudgeE();elsemakeword("integer");
}void fun()
{ch &#61; text[i];jump();while (ch !&#61; &#39;\0&#39; && ch !&#61; EOF){jump();if (ch &#61;&#61; &#39;&#43;&#39; || ch &#61;&#61; &#39;-&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];if (ch &#61;&#61; &#39;&#61;&#39;){word &#43;&#61; ch;makeword("OPT");ch &#61; text[&#43;&#43;i];}elsemakenumber();}if (ch >&#61; &#39;0&#39; && ch <&#61; &#39;9&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];makenumber();}if (isalnum(ch) || ch &#61;&#61; &#39;_&#39;){while (isalnum(ch) || ch &#61;&#61; &#39;_&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];}if (find(keyword.begin(), keyword.end(), word) !&#61; keyword.end())makeword("keyword");else if (find(type.begin(), type.end(), word) !&#61; type.end())makeword("type");elsemakeword("identify");}if (ch &#61;&#61; &#39;/&#39;){char temp &#61; text[&#43;&#43;i];if (temp &#61;&#61; &#39;/&#39;)do{ch &#61; text[&#43;&#43;i];} while (ch !&#61; &#39;\n&#39;);else if (temp &#61;&#61; &#39;*&#39;){do{ch &#61; text[&#43;&#43;i];} while (ch !&#61; &#39;/&#39;);ch &#61; text[&#43;&#43;i];}else if (temp &#61;&#61; &#39;&#61;&#39;){word &#43;&#61; "/&#61;";makeword("OPT");ch &#61; text[&#43;&#43;i];}else{word &#43;&#61; &#39;/&#39;;makeword("OPT");ch &#61; text[&#43;&#43;i];}}if (ch &#61;&#61; &#39;0&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];makeword("integer");}if (ch &#61;&#61; &#39;%&#39; || ch &#61;&#61; &#39;&&#39;){if (isalnum(text[i&#43;1])){word &#43;&#61; ch;word &#43;&#61; text[&#43;&#43;i];ch &#61; text[&#43;&#43;i];makeword("typeidentify");}}if (find(bracket.begin(), bracket.end(), ch) !&#61; bracket.end()){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];makeword("bracket");}if (ch &#61;&#61; &#39;*&#39; || ch &#61;&#61; &#39;&#61;&#39; || ch &#61;&#61; &#39;<&#39; || ch &#61;&#61; &#39;>&#39; || ch &#61;&#61; &#39;!&#39;){word &#43;&#61; ch;if (text[i &#43; 1] &#61;&#61; &#39;&#61;&#39;)word &#43;&#61; text[&#43;&#43;i];ch &#61; text[&#43;&#43;i];makeword("OPT");}}
}int main()
{text[len] &#61; getchar();while (text[len] !&#61; &#39;\0&#39; && text[len] !&#61; EOF){text[&#43;&#43;len] &#61; getchar();}fun();for (vector<Node>::iterator iter &#61; stack.begin(); iter !&#61; stack.end(); iter&#43;&#43;)cout << "line" << (*iter).line << ":(" << (*iter).type << ", " << (*iter).word << &#39;)&#39; << endl;
}