1 #include <iostream>
2 #include <stdlib.h>
3 #include <stdio.h>
4
5 using namespace std;
6 string KEYWORD[15]={"if","else","void","return","while","then","for","do", //关键字
7 "int","char","double","float","case","cin","cout"};
8 char SEPARATER[8]={';',',','{','}','[',']','(',')'}; //分隔符
9 char OPERATOR[8]={'+','-','*','/','>','<','=','!'}; //运算符
10 char FILTER[4]={' ','\t','\r','\n'}; //过滤符
11 const int IDENTIFIER=100; //标识符值
12 const int CONSTANT=101; //常数值
13 const int FILTER_VALUE=102; //过滤字符值
14
15
16 /**判断是否为关键字**/
17 bool IsKeyword(string word){
18 for(int i=0;i<15;i++){
19 if(KEYWORD[i]==word){
20 return true;
21 }
22 }
23 return false;
24 }
25 /**判断是否为分隔符**/
26 bool IsSeparater(char ch){
27 for(int i=0;i<8;i++){
28 if(SEPARATER[i]==ch){
29 return true;
30 }
31 }
32 return false;
33 }
34
35 /**判断是否为运算符**/
36 bool IsOperator(char ch){
37 for(int i=0;i<8;i++){
38 if(OPERATOR[i]==ch){
39 return true;
40 }
41 }
42 return false;
43 }
44 /**判断是否为过滤符**/
45 bool IsFilter(char ch){
46 for(int i=0;i<4;i++){
47 if(FILTER[i]==ch){
48 return true;
49 }
50 }
51 return false;
52 }
53 /**判断是否为大写字母**/
54 bool IsUpLetter(char ch){
55 if(ch>='A' && ch<='Z') return true;
56 return false;
57 }
58 /**判断是否为小写字母**/
59 bool IsLowLetter(char ch){
60 if(ch>='a' && ch<='z') return true;
61 return false;
62 }
63 /**判断是否为数字**/
64 bool IsDigit(char ch){
65 if(ch>='0' && ch<='9') return true;
66 return false;
67 }
68 /**返回每个字的值**/
69 template <class T>
70 int value(T *a,int n,T str){
71 for(int i=0;i<n;i++){
72 if(a[i]==str) return i+1;
73 }
74 return -1;
75 }
76 /**词法分析**/
77 void analyse(FILE * fpin){
78 char ch=' ';
79 string arr="";
80 while((ch=fgetc(fpin))!=EOF){
81 arr="";
82 if(IsFilter(ch)){} //判断是否为过滤符
83 else if(IsLowLetter(ch)){ //判断是否为关键字
84 while(IsLowLetter(ch)){
85 arr += ch;
86 ch=fgetc(fpin);
87 }
88 //fseek(fpin,-1L,SEEK_CUR);
89 if(IsKeyword(arr)){
90 printf("%3d ",value(KEYWORD,15,arr));
91 cout<<arr<<" 关键字"<<endl;
92 }
93 else
94 {
95 printf("%3d ",IDENTIFIER);
96 cout<<arr<<" 标识符"<<endl;
97 }
98 }
99 else if(IsDigit(ch)){ //判断是否为数字
100 while(IsDigit(ch)||(ch=='.'&&IsDigit(fgetc(fpin)))){
101 arr += ch;
102 ch=fgetc(fpin);
103 }
104 fseek(fpin,-1L,SEEK_CUR);
105 printf("%3d ",CONSTANT);
106 cout<<arr<<" 整形数"<<endl;
107 }
108 else if(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'){
109 while(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'||IsDigit(ch)){
110 arr += ch;
111 ch=fgetc(fpin);
112 }
113 fseek(fpin,-1L,SEEK_CUR);
114 printf("%3d ",CONSTANT);
115 cout<<arr<<" 标识符"<<endl;
116 }
117 else switch(ch){
118 case '+':
119 case '-':
120 case '*':
121 case '/':
122 case '>':
123 case '<':
124 case '=':
125 case '!':
126 {
127 arr += ch;
128 printf("%3d ",value(OPERATOR,8,*arr.data()));
129 cout<<arr<<" 运算符"<<endl;
130 break;
131 }
132 case ';':
133 case ',':
134 case '(':
135 case ')':
136 case '[':
137 case ']':
138 case '{':
139 case '}':
140 {
141 arr += ch;
142 printf("%3d ",value(SEPARATER,8,*arr.data()));
143 cout<<arr<<" 分隔符"<<endl;
144 break;
145 }
146 default :cout<<"\""<<ch<<"\":无法识别的字符!"<<endl;
147 }
148 }
149
150 }
151 int main()
152 {
153 char inFile[40];
154 FILE *fpin;
155 cout<<"请输入源文件名(包括路径和后缀):";
156 while(true){
157 cin>>inFile;
158 if((fpin=fopen(inFile,"r"))!=NULL)
159 break;
160 else{
161 cout<<"文件名错误!"<<endl;
162 cout<<"请输入源文件名(包括路径和后缀):";
163 }
164
165 }
166 cout<<"------词法分析如下------"<<endl;
167 analyse(fpin);
168 return 0;
169 }