作业5 词法分析程序的设计与实现

词法分析程序(Lexical Analyzer)要求:

- 从左至右扫描构成源程序的字符流

-  识别出有词法意义的单词(Lexemes

-  返回单词记录(单词类别,单词本身)

-  滤掉空格

-  跳过注释

-  发现词法错误

程序结构:

输入:字符流(什么输入方式,什么数据结构保存)

处理:

–遍历(什么遍历方式)

–词法规则

输出:单词流(什么输出形式)

–二元组

单词类别:

1.标识符(10)

2.无符号数(11)

3.保留字(一词一码)

4.运算符(一词一码)

5.界符(一词一码)

单词符号

种别码

单词符号

种别码

main

1

,

13

int

2

;

14

if

3

(

15

else

4

)

16

while

5

{

17

do

6

}

18

7

+

19

8

-

20

!=

9

*

21

>=

10

/

22

<=

11

=

23

==

12

 

 

  1 #include <iostream>
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<stdlib.h>
  5 using namespace std;
  6  
  7 //关键字 
  8 string key[6]={"main","int","if","else","while","do"}; 
  9 
 10 //关键字的种别码
 11 int keyNum[6]={1,2,3,4,5,6}; 
 12 
 13 //运算符和界符 
 14 string symbol[17]={"<",">","!=",">=","<=","==",",",";","(",")","{","}","+","-","*","/","="};
 15 
 16 //运算符和界符的种别码 
 17 int symbolNum[17]={7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
 18 
 19 //存放文件取出的字符 
 20 string letter[1000];
 21 
 22 int length; //保存程序中字符的数目 
 23 int num;
 24 
 25 //判断运算符和界符  
 26 int isSymbol(string s){ 
 27      int i;
 28      for(i=0;i<17;i++){
 29           if(s==symbol[i])
 30                return symbolNum[i]; 
 31      }
 32      return 0;
 33 } 
 34  
 35 //判断是否为数字 
 36 bool isNum(string s){
 37      if(s>="0" && s<="9")
 38           return true;
 39      return false;
 40 }
 41  
 42 //判断是否为字母 
 43 bool isLetter(string s){
 44      if(s>="a" && s<="z")
 45           return true;
 46      return false;
 47 }
 48  
 49 //判断是否为关键字,是返回种别码 
 50 int isKeyWord(string s){
 51      int i;
 52      for(i=0;i<6;i++){
 53           if(s==key[i])
 54                return keyNum[i];
 55      }
 56      return 0;
 57 }
 58  
 59 //返回单个字符的类型 
 60 int typeword(string str){
 61      if(str>="a" && str<="z") // 字母 
 62           return 1;
 63  
 64      if(str>="0" && str<="9") //数字 
 65           return 2;
 66  
 67      if(str==">"||str=="="||str=="<"||str=="!"||str==","||str==";"||str=="("||str==")"||str=="{"||str=="}"||str=="+"||str=="-"||str=="*"||str=="/") //判断运算符和界符 
 68           return 3; 
 69 }
 70 //标识符的连接 
 71 string identifier(string s,int n){
 72      int j=n+1;
 73      int flag=1;
 74  
 75      while(flag){
 76           if(isNum(letter[j]) || isLetter(letter[j])){
 77                s=(s+letter[j]);
 78                if(isKeyWord(s)){
 79                 j++;
 80                 num=j;
 81                 return s;
 82                }
 83                j++;
 84           }else{
 85                flag=0;
 86           }
 87      } 
 88  
 89      num=j;
 90      return s;
 91 }
 92 
 93 //符号和界符的连接  
 94 string symbolStr(string s,int n){
 95      int j=n+1;
 96      string str=letter[j];
 97      if(str==">"||str=="="||str=="<"||str=="!") {
 98           s=(s+letter[j]);
 99           j++;
100      }
101      num=j;
102      return s;
103 }
104 
105 //数字的连接 
106 string Number(string s,int n){
107      int j=n+1;
108      int flag=1;
109  
110      while(flag){
111           if(isNum(letter[j])){
112                s=(s+letter[j]);
113                j++;
114           }else{
115                flag=0;
116           }
117      }
118  
119      num=j;
120      return s;
121 }
122 
123 //输出 
124 void print(string s,int n){
125      cout<<"("<<s<<","<<n<<")"<<endl;
126 }
127 
128 //取单词 
129 void TakeWord(){  
130      int k;
131  
132      for(num=0;num<length;){
133           string str1,str;
134           str=letter[num];
135           k=typeword(str);
136           switch(k){
137                case 1:{
138                  str1=identifier(str,num);
139                  if(isKeyWord(str1))
140                       print(str1,isKeyWord(str1));
141                  else
142                       print(str1,0);
143                  break;
144             }
145  
146                case 2:{
147                  str1=Number(str,num);
148                  print(str1,24);
149                  break;
150             }
151  
152                case 3:{
153                  str1=symbolStr(str,num);
154                  print(str1,isSymbol(str1));
155                  break; 
156             }
157  
158           }
159      } 
160 }
161  
162 int main(){
163      char w;
164      int i,j;
165  
166      freopen("s.txt","r",stdin);
167  
168      length=0;
169      while(cin>>w){
170           if(w!=' '){
171                letter[length]=w;
172                length++;
173           } //去掉程序中的空格
174      }
175  
176      TakeWord();
177  
178      fclose(stdin);//关闭文件 
179      return 0;
180 }

实验文本:

 实验结果:

 该实验的代码是参考网上代码修改的,逻辑大概能理清,但是没有实现跳过注释的功能。

原文地址:https://www.cnblogs.com/m2362563619/p/11656569.html