编译原理实验之词法分析
来源:互联网 发布:域名不备案可以解析吗 编辑:程序博客网 时间:2024/06/07 02:23
内容有更新哦~~~
能识别小数,科学记数法表示的数,负数亦可。
不多解释,代码先上:
#include <cstdio>#include <iostream>#include <string>#include <cstring>#include <algorithm>#include <cctype>#include <fstream>#include <map>#include <cstdlib>#include <cmath>using namespace std;const int maxn = 1002;const int n_key = 40;const int n_oper = 21;char c;string key_word[n_key] = {"auto", "enum", "restrict", "unsigned", "break", "extern", "return", "void", "case", "float", "short", "volatile", "char", "for", "signed", "while", "const", "goto", "sizeof", "_Bool", "continue", "if", "static", "_Complex", "default", "inline", "struct", "_Imaginary", "do", "int", "switch", "double", "long", "typedef", "else", "register", "union", "main", "scanf", "printf"};string oper[] = {"+", "-", "*", "/", "^", "<", ">", "++", "--", "==", "*=", "/=", ">=", "<=", "<<", ">>", ">>=", "<<=", "%", "&", "^"};char bound[] = {',', ';', '(', ')', '[', ']', '{', '}'};struct Word{ //词结构体 int id; string value;};struct Num{ int id; int vi; double vd;};Num n[maxn]; //数字Word w[maxn]; //词map<string, int> m; //标识符int f = 0, ff = 0;bool is_oper(string s){ for(int i=0; i<n_oper; i++) if(s == oper[i]) return true; return false;}bool is_bound(char c){ for(int i=0; i<sizeof(bound); i++) if(c == bound[i]) return true; return false;}bool is_key(string s){ for(int i=0; i<n_key; i++) if(s == key_word[i]) return true; return false;}int stoi(string s){ //get int int ans = 0; for(int i=0; i<s.size(); i++) ans = ans * 10 + s[i] - '0'; return ans;}double stof(string s){ //get double long long ans = 0; int fd = -1, fe = -1; for(int i=0; i<s.size(); i++){ if(s[i] == '.'){ fd = i; continue; } if(s[i] == 'e'){ fe = i; continue; } ans = ans * 10 + s[i] - '0'; } if(fd != -1 && fe == -1) return double(ans)/(pow(10, s.size() - fd - 1)); else if(fd == -1 && fe != -1){ long long temp = ans % (long long)pow(10, s.size() - fe - 1); //得到e后的数字 ans /= pow(10, s.size() - fe - 1); //得到e前的数字 return double(ans*pow(10, temp)); } else{ long long temp = ans % (long long)pow(10, s.size() - fe - 1); //得到e后的数字 ans /= pow(10, s.size() - fe - 1); //得到e前的数字 long long tt = (s.size() - fd - 1) - (s.size() - fe - 1) - 1; //得到.后的数字 return (double)ans/pow(10, tt) * (pow(10, temp)); }}void getword(char filename[]){ freopen(filename, "r", stdin); //重定向 string str = ""; int flag, is_end; is_end = scanf("%c", &c); while(is_end != EOF){ flag = 0; if(isspace(c)){ str = ""; while(isspace(c) && is_end != EOF){ //滤空格 is_end = scanf("%c", &c); } } if(isalpha(c)){ //以字母开头 str = ""; while(isalnum(c) || c == '_'){ str += c; is_end = scanf("%c", &c); } w[++f].value = str; if(is_key(str)) w[f].id = 1; //保留字 else{ w[f].id = 2; //标识符 m[str] ++; } flag = 1; } if(isdigit(c)){ //数字 int fd = 0, fe = 0, fflag = 0, is_neg = 0; if(str == "-") is_neg = 1; str = ""; while(isdigit(c) || c == '.' || c == 'e'){ if(c == '.') fd ++; if(c == 'e') fe ++; if(c == '.' && fe) fflag = 1; str += c; is_end = scanf("%c", &c); } if(str[str.size()-1] == '.' || str[str.size()-1] == 'e') fflag = 1; if(fflag){ cout<<"错误-->不合法数字:"<<(is_neg ? "-" + str : str)<<endl; //忽略不合法输入 } else{ if(!fd && !fe){ n[++ff].vi = (is_neg ? -stoi(str) : stoi(str)); n[ff].id = 1; } else{ n[++ff].vd = (is_neg ? -stof(str) : stof(str)); n[ff].id = 2; } w[++f].id = 3; w[f].value = (is_neg ? "-" + str : str); } flag = 1; } if(is_bound(c)){ //界符 str = ""; str += c; w[++f].value = str; w[f].id = 4; is_end = scanf("%c", &c); flag = 1; } string ss = ""; ss += c; if(is_oper(ss)){ bool is_lastdigt = isdigit(str[str.size()-1]); str = ""; while(is_oper(ss)){ str += c; is_end = scanf("%c", &c); ss += c; } if(str == "-" && !is_lastdigt && isdigit(c)) continue; if(is_oper(str)){ w[++f].value = str; w[f].id = 5; } flag = 1; } if(!flag && is_end != EOF){ str = ""; str += c; w[++f].value = str; w[f].id = 6; is_end = scanf("%c", &c); } } freopen("CON", "r", stdin); //关闭重定向,恢复标准}void to_file1(){ //主表 char filename[20]; puts("请输入词法分析主表要保存到的地址:"); scanf("%s", filename); fstream out; out.open(filename, ios::out); out<<"1.保留字 2.标识符 3.数字 4.界符 5.操作符 6.其他"<<endl<<endl; for(int i=1; i<=f; i++) out<<w[i].id<<" "<<w[i].value<<endl; out.close();}void to_file2(){ //标识符表 ofstream out; char filename[20]; puts("请输入词法分析标识符表要保存到的地址:"); scanf("%s", filename); out.open(filename, ios::out); map<string, int>::iterator it; for(it=m.begin(); it!=m.end(); it++) out<<it->first<<endl; out.close();}void to_file3(){ //数字表 ofstream out; char filename[20]; puts("请输入词法分析数字表要保存到的地址:"); scanf("%s", filename); out.open(filename, ios::out); out<<"1.int 2.double"<<endl<<endl; for(int i=1; i<=ff; i++) out<<n[i].id<<" "<<(n[i].id == 1 ? n[i].vi : n[i].vd)<<endl; out.close();}int main(){ char filename[20]; puts("请输入您要打开的文件地址:"); scanf("%s", filename); getword(filename); to_file1(); to_file2(); to_file3(); return 0;}
编译原理之词法分析实验终于写完了,收工啦~~~
PS:本人还是比较满意的o(^▽^)o
0 0
- 编译原理实验 之 词法分析
- 编译原理实验之词法分析
- 编译原理实验----词法分析
- 编译原理实验---词法分析
- 编译原理 之 词法分析
- 编译原理之词法分析
- 编译原理之词法分析
- 编译原理之词法分析
- 编译原理之词法分析
- 编译原理之词法分析
- 编译原理之词法分析
- 编译原理--实验一 词法分析
- 编译原理实验改进版(词法分析)
- 【编译原理】实验1.词法分析
- 编译原理实验1-词法分析
- 编译原理课程实验--词法分析
- 编译原理实验一 词法分析程序
- 哈工大编译原理实验一词法分析
- 挂起一个任务
- VIM使用技巧2
- 使用javascript写了一款BPO行业文字生成器
- 在csdn学院开了一门课 欢迎指教 谢谢
- 7.3 Close系统调用
- 编译原理实验之词法分析
- Binary Tree & BST
- 如何搜索网盘资源
- 为什么我们不选择自行车上下班?
- eclipse修改morkspace目录
- VIM使用技巧3
- xmlTree标签树形菜单应用实例:B2C网站部门管理
- iOS-UIView动画
- dwz教程