任务描述
本关任务:用 C/C++ 编写一个 C 语言的语法分析器程序。
相关知识
为了完成本关任务,你需要掌握:1.DFA NFA,2.C/C++ 编程语言基础。3. C 语言的基本结构知识
自动机
在编译原理课堂上已经教授了大家相关知识。在完成本实训前,一定要先设计相关自动机,再开始相关功能的实现。切勿,想到哪里,就编程到哪里,以至于代码一团糟,可维护性与可读性都很差。
C/C++
本实训涉及函数、结构体,标准流输入输出,字符串等操作
C语言基本结构
C 语言子集。 第一类:标识符 第二类:常数 第三类:保留字(32
)
auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while
第四类:界符 /*
、//
、 ()
、 { }
、[ ]
、" "
、 '
等 第五类:运算符 <
、<=
、>
、>=
、=
、+
、-
、*
、/
、^
等
**所有语言元素集合在 c_keys.txt **文件中。 注意,C_key.txt中缺少“//注释”的情况,请也映射到编号79!
auto 1 break 2 case 3 char 4 const 5 continue 6 default 7 do 8 double 9 else 10 enum 11 extern 12 float 13 for 14 goto 15 if 16 int 17 long 18 register 19 return 20 short 21 signed 22 sizeof 23 static 24 struct 25 switch 26 typedef 27 union 28 unsigned 29 void 30 volatile 31 while 32 - 33 -- 34 -= 35 -> 36 ! 37 != 38 % 39 %= 40 & 41 && 42 &= 43 ( 44 ) 45 * 46 *= 47 , 48 . 49 / 50 /= 51 : 52 ; 53 ? 54 [ 55 ] 56 ^ 57 ^= 58 { 59 | 60 || 61 |= 62 } 63 ~ 64 + 65 ++ 66 += 67 < 68 << 69 <<= 70 <= 71 = 72 == 73 > 74 >= 75 >> 76 >>= 77 " 78 /*注释*/ 79 常数 80 标识符 81
编程要求
请仔细阅读该部分
输入
样例输入放在prog.txt
文件中 样例1输入
int main() { printf("HelloWorld"); return 0; }
输出
输出要满足以下要求
计数: <符号名,符号标号>
注意,冒号后边有一个空格 样例1输出
1: <int,17> 2: <main,81> 3: <(,44> 4: <),45> 5: <{,59> 6: <printf,81> 7: <(,44> 8: <",78> 9: <HelloWorld,81> 10: <",78> 11: <),45> 12: <;,53> 13: <return,20> 14: <0,80> 15: <;,53> 16: <},63>
注意,输出不能有多余的空格,回车等符号。请注意样例输出最后一行后是没有回车的!输出的符号都是英文的半角符号。
ERROR
本实训不考虑错误处理,我保证输入的所有代码块是合法的 C 语言代码。
开始你的任务吧,祝你成功!
// C语言词法分析器 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <string> #include <fstream> #include <sstream> #include <vector> using namespace std; string keyword[40]={"","auto","break","case","char","const","continue", "default","do","double","else","enum" ,"extern","float","for","goto", "if","int","long","register","return","short","signed","sizeof", "static","struct"," switch","typedef","union","unsigned","void", "volatile","while"}; string mark[50]={"","-","--","-=","->","!","!=","%","%=","&","&&", "&=","(",")","*","*=",",",".","/","/=",":",";","?","[","]","^", "^=","{","|","||","|=","}","~","+","++","+=","<","<<","<<=","<=", "=","==",">",">=",">>",">>=","\""}; string prog; int cnt=1; /* 不要修改这个标准输入函数 */ void read_prog(string& prog) { char c; while(scanf("%c",&c)!=EOF){ prog += c; } } /* 判断函数 */ bool isnum(char c) { if(c >= '0' && c<= '9') return true; return false; } bool isletter(char c) { if( (c>='a' && c<='z') || (c>='A' && c<='Z')) return true; return false; } bool iskeyword(string s) { for(int i=1;i<=32;i++) if(s==keyword[i]) { if(cnt!=1) cout<<endl; cout<<cnt<<": "<<"<"<<s<<","<<i<<">"; cnt++; return true; } return false; } /* 查找函数 */ int numtoken(int l) { //找出整个数字 int r=l; while(isnum(prog[r])) r++; string s = prog.substr(l,r-l); //输出 if(cnt!=1) cout<<endl; cout<<cnt<<": "<<"<"<<s<<","<<80<<">"; cnt++; return r; } int lettertoken(int l) { //找出整个单词 int r=l; while(isletter(prog[r]) || isnum(prog[r])) r++; string s = prog.substr(l,r-l); if(iskeyword(s)) return r; //输出 if(cnt!=1) cout<<endl; cout<<cnt<<": "<<"<"<<s<<","<<81<<">"; cnt++; return r; } int note1(int l)// //注释 { int r=l; while(prog[r]!='\n') r++; string s = prog.substr(l,r-l); if(cnt!=1) cout<<endl; cout<<cnt<<": "<<"<"<<s<<","<<79<<">"; cnt++; return r; } int note2(int l)// /*注释 { int r=l; while(1) { if(prog[r]=='*' && prog[r+1]=='/') break; r++; } r=r+2; string s = prog.substr(l,r-l); if(cnt!=1) cout<<endl; cout<<cnt<<": "<<"<"<<s<<","<<79<<">"; cnt++; return r; } int operatortoken(int l) { for(int j=3;j>=1;j--) for(int i=1;i<=46;i++) if(prog.substr(l,j)==mark[i]) { if(cnt!=1) cout<<endl; cout<<cnt<<": "<<"<"<<prog.substr(l,j)<<","<<i+32<<">"; cnt++; return l+j; } return l+1; } void Analysis() { read_prog(prog); /* 骚年们 请开始你们的表演 */ int ptr=0,k=0; while(ptr<prog.length()){ while(prog[ptr]==' ' || prog[ptr]=='\n') ptr++; if(ptr>=prog.length()) break; if(isnum(prog[ptr]))//常数 ptr=numtoken(ptr); else if(isletter(prog[ptr]))//关键字和变量名 ptr=lettertoken(ptr); else { //两种注释 if(prog[ptr]=='/' && prog[ptr+1]=='/') ptr=note1(ptr); else if(prog[ptr]=='/' && prog[ptr+1]=='*') ptr=note2(ptr); else if(prog[ptr]=='%' && isletter(prog[ptr+1]) ) { if(cnt!=1) cout<<endl; cout<<cnt<<": "<<"<"<<prog.substr(ptr,2)<<","<<81<<">"; cnt++; ptr=ptr+2; } else ptr=operatortoken(ptr); } } } int main() { Analysis(); return 0; }
标签:cnt,语法分析,int,C++,return,++,prog,编写,ptr From: https://www.cnblogs.com/hfang/p/17890927.html