【编译原理课程设计】说明语句的词法分析器

题目三  说明语句的词法分析器

一、设计目的

了解词法分析程序的基本构造原理,掌握词法分析程序的手工构造及自动构造方法。

二、设计内容

根据PASCAL语言的说明语句形式,用手工及自动方法构造一个对说明语句进行词法分析的程序。该程序能对从键盘输入或从文件读入的形如:

“const count=10,sum=81.5,char1=’f’,string1=”hj”, max=169;”

的常量说明串进行处理,分析常量说明串中各常量名、常量类型及常量值,并统计各种类型常量个数。

三、设计要求

1、输入的常量说明串,要求最后以分号作结束标志;

2、根据输入串或读入的文本文件中第一个单词是否为“const”判断输入串或文本文件是否为常量说明内容;

3、识别输入串或打开的文本文件中的常量名。常量名必须是标识符,定义为字母开头,后跟若干个字母,数字或下划线;

4、根据各常量名紧跟等号“=”后面的内容判断常量的类型。其中:字符型常量定义为放在单引号内的一个字符;字符串常量定义为放在双引号内所有内容;整型常量定义为带或不带+、- 号,不以0开头的若干数字的组合;实型常量定义为带或不带+、- 号,不以0开头的若干数字加上小数点再后跟若干数字的组合;

5、统计并输出串或文件中包含的各种类型的常量个数;

6、以二元组(类型,值)的形式输出各常量的类型和值;

7、根据常量说明串置于高级语言源程序中时可能出现的错误情况,模仿高级语言编译器对不同错误情况做出相应处理。

四、运行结果

1、输入如下正确的常量说明串:

const count=10,sum=81.5,char1=‘f’,max=169,str1=“h*54 2..4S!AAsj”, char2=‘@’,str2=“aa!+h”;

输出:

count(integer,10)

sum(float,81.5)

char1(char, ‘f’)

max(integer,169)

str1(string,“h*54  2..4S!AAsj”)

char2(char, ‘@’)

str2(string,“aa!+h”)

 

int_num=2;  char_num=2; string_num=2; float_num=1.

2、输入类似如下的保留字const错误的常量说明串:

Aconstt count=10,sum=81.5,char1=‘f’;

输出类似下面的错误提示信息:

It is not a constant declaration statement!

Please input a string again!

3、输入类似如下含常量名或常量值错误的常量说明串:

const count=10,12sum=81.5,char1=‘ff’,max=0016;

输出类似下面的错误提示信息:

count(integer,10)

12sum(Wrong! It is not a identifier!)

char1(Wrong! There are  more than one char in ‘’.)

max(Wrong! The integer can’t be started with ‘0’.)

int_num=1;  char_num=0; string_num=0; float_num=0.

4、其他类型的错误处理情况(略)。

五、提示

本课程设计重点有三个:一是作为常量名的标识符的识别;二是如何根据“=”后出现的内容来判断常量类型;三是对各种错误的处理。难点是对整型和实型常量的判断必须综合考虑多种可能情况。

提示:

用指针或数组与指针相结合来处理输入的常量说明串;

对整型和实型常量处理时,重点考虑常数中‘0’的位置。

 

六、分析与讨论

1、若考虑用E或e的科学计数法来表示整数和实数,应该如何实现?

2、若考虑布尔型常量,且规定其值只能为true或false,应该如何实现?

3、如何对手工构造的词法分析程序做进一步的优化,以提高代码质量和运行效率?

 

 

  1 #include<iostream>
  2 using namespace std;
  3 char example[10000]; //缓冲区
  4 int example_p;//缓冲区指针
  5 
  6 char token[10];//常量名
  7 int token_p;//常量名指针
  8 
  9 char num[10000];//数据
 10 int num_p;//数据指针
 11 char ch;
 12 
 13 int int_num = 0, char_num = 0, float_num = 0, string_num = 0;
 14 
 15 //字符是字母
 16 bool is_letter(char ch) {
 17     if ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z'))
 18         return true;
 19     else
 20         return false;
 21 }
 22 //字符是数字
 23 bool is_digit(char ch) {
 24     if (ch >= '0'&&ch <= '9')
 25         return true;
 26     else
 27         return false;
 28 }
 29 
 30 
 31 //消除空格
 32 void space() {
 33     while (ch == ' ') {
 34         example_p++;
 35         ch = example[example_p];
 36     }
 37 }
 38 
 39 //const检查
 40 bool inspect() {
 41     int token_p = 0;
 42     if (ch != 'c')
 43         return false;
 44     else {
 45         while (is_letter(ch)) {
 46             token[token_p] = ch;
 47             token_p++;
 48             example_p++;
 49             ch = example[example_p];
 50         }
 51         //const比对
 52         if (strcmp(token, "const") == 0) {
 53             return true;
 54         }
 55         else
 56             return false;
 57     }
 58         
 59 }
 60 
 61 //串扫描 将常量名存入token 数据存入num
 62 void scan() {
 63     memset(token, 0, sizeof(token)); //数组清零
 64     memset(num, 0, sizeof(num));
 65 
 66     token_p = 0;
 67     num_p = 0;
 68     //消除空格
 69     space();
 70     //获取=前的常量名存入token
 71     while (ch != '=') {
 72         token[token_p] = ch;
 73         token_p++;
 74         example_p++;
 75         ch = example[example_p];
 76     }
 77     if (ch == '=') {
 78         example_p++;
 79         ch = example[example_p];
 80     }
 81     //消除空格
 82     space();
 83     //获取=后的数据 存入num 字符形式存入
 84     while (ch != ',') {
 85         num[num_p] = ch;
 86         num_p++;
 87         example_p++;
 88         ch = example[example_p];
 89         if (ch == ';')
 90             break;
 91     }
 92     if (ch == ',') {
 93         example_p++;
 94         ch = example[example_p];
 95     }
 96     
 97 }
 98 
 99 //判断数据类型
100 const char* type(char* num) {
101     //字符型第一个字符为单引号
102     if (num[0] == '\'') {
103         
104         return "char";
105     }
106     //字符串型第一个字符为双引号
107     else if (num[0] == '"') {
108         
109         return "string";
110     }
111     else {
112         for (int i = 0;i < sizeof(num);i++) {
113             if (num[i] == '.') {
114                 
115                 return "float";
116             }
117         }
118         
119         return "interger";
120     }
121 }
122 
123 
124 
125 int main() {
126     
127     example_p = 0;
128     char str;
129     do {
130         str = getchar();
131         example[example_p] = str;
132         example_p++;
133     } while (str != ';');
134 
135     example_p = 0;
136     ch = example[example_p];
137     
138     //测试案例
139     //const count=10,sum=81.5,char1='f',max=169,str1="h*54 2..4S!AAsj", char2='@',str2="aa!+h";
140     //Aconstt count=10,sum=81.5,char1='f';
141     //const count=10,12sum=81.5,char1='ff',max=0016;
142 
143     if (inspect()) {
144         do {
145             scan();
146             if (is_digit(token[0])){
147                 //变量名以数字开头
148                 cout<<token<<"(Wrong! It is not a identifier!)"<<endl;
149                 
150 
151             }
152             //字符类型有多个字符
153             else if (strcmp(type(num), "char") == 0 && sizeof(num) > 4) {
154                 cout << token << "(There are  more than one char in ''.)" << endl;
155                 
156             }
157             //整数第一个字符不能为0
158             else if (strcmp(type(num),"interger")==0&&num[0]=='0') {
159                 cout<<token<<"(Wrong! The integer can’t be started with ‘0’.)"<<endl;
160                 
161 
162             }
163             else {
164                 cout << token << "(" << type(num) << "," << num << "" << endl;
165                 //统计不同类型数据的个数
166                 if (strcmp(type(num), "interger") == 0)
167                     int_num++;
168                 else if (strcmp(type(num), "char") == 0)
169                     char_num++;
170                 else if (strcmp(type(num), "string") == 0)
171                     string_num++;
172                 else
173                     float_num++;
174             }
175             //到达末尾时结束
176         } while (ch != ';');
177         cout << endl;
178         cout << "int_num=" << int_num << " " << "char_num=" << char_num << " " << "string_num=" << string_num << " " << "float_num=" << float_num;
179     }else {
180         cout << "It is not a constant declaration statement! " << endl;
181         cout << "Please input a string again!" << endl;
182     }
183 
184     system("pause");
185     return 0;
186 }
posted @ 2020-01-04 20:42  An_Wen  阅读(615)  评论(0编辑  收藏  举报