能识别小数,科学记数法表示的数。
不多解释,代码先上:
#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后的数字 cout<<ans<<" "<<s.size() - fe - 1<<" "<<temp<<endl; ans /= pow(10, s.size() - fe - 1); //得到e前的数字 cout<<ans<<endl; long long tt = (s.size() - fd - 1) - (s.size() - fe - 1) - 1; //得到.后的数字 cout<<tt<<endl; 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)){ while(isspace(c) && is_end != EOF){ //滤空格 is_end = scanf("%c", &c); } } if(isalpha(c)){ //以字母开头 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] ++; } str = ""; flag = 1; } if(isdigit(c)){ //数字 int fd = 0, fe = 0, fflag = 0; 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<<"错误-->不合法数字:"<<str<<endl; //忽略不合法输入 } else{ if(!fd && !fe){ n[++ff].vi = stoi(str); n[ff].id = 1; } else{ n[++ff].vd = stof(str); n[ff].id = 2; } w[++f].id = 3; w[f].value = str; } str = ""; flag = 1; } if(is_bound(c)){ //界符 str += c; w[++f].value = str; w[f].id = 4; is_end = scanf("%c", &c); str = ""; flag = 1; } string ss = ""; ss += c; if(is_oper(ss)){ while(is_oper(ss)){ str += c; is_end = scanf("%c", &c); ss += c; } if(is_oper(str)){ w[++f].value = str; w[f].id = 5; } str = ""; flag = 1; } if(!flag && is_end != EOF){ str += c; w[++f].value = str; w[f].id = 6; is_end = scanf("%c", &c); str = ""; } } 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; }
时间: 2024-12-18 13:16:07