首页 > 其他分享 >《编译原理》第一次实验:词法分析

《编译原理》第一次实验:词法分析

时间:2023-04-30 16:45:54浏览次数:50  
标签:10 ch const semicolon back 词法 编译 ident 原理

该分类为本人在本学期《编译原理》课程上的实验报告,实验对象语言为教学用PL/0语言,实验所用语言为C++。全部报告仅供参考,如有缺漏或错误,烦请指出,Thanks ♪(・ω・)ノ


一. 设计思想

根据 PL/0 语言的文法规范,编写 PL/0 语言的词法分析程序。

1.单词种类及其正规式

(1)基本字

单词的值 单词类型  正规式 r 
begin beginsym begin
call callsym call
const  constsym const
do dosym do
end endsym end
if  ifsym if
odd oddsym odd
procedure proceduresym procedure 
read readsym read
then thensym then
var varsym var
while whilesym while
write  writesym write

(2)标识符

单词的值 单词类型 正规式 r
标识符 Ident (字母)(字母|数字)*

(3)常数

单词的值 单词类型 正规式 r
常数 number (数字)(数字)*

(4)运算符

单词的值 单词类型 正规式 r
+ plus +
- minus -
* times *
/ slash /
= eql =
<> neq <>
< lss <
<= leq <=
> gtr >
>= geq >=
:= becomes :=

(5)界符

单词的值 单词类型 正规式 r
( lparen (
) rparen )
, comma ,
; semicolon ;
. period .

2.NFA

3.DFA

4.最小化 DFA

二. 算法流程

三. 源程序

  1 #include <iostream>
  2 #include <string>
  3 #include <vector>
  4 using namespace std;
  5 
  6 void getChar(const string s,int& idx,char& ch)   // 取下个字符
  7 {
  8     ch=s[idx++];
  9     return;
 10 }
 11 
 12 void getBC(const string s,int& idx,char& ch)   // 跳过空格
 13 {
 14     while (ch==' ')
 15     {
 16         getChar(s,idx,ch);
 17     }
 18     return;
 19 }
 20 
 21 void concat(string& strToken,const char ch)   // 字符拼接
 22 {
 23     strToken+=ch;
 24     return;
 25 }
 26 
 27 void retract(int& idx,char& ch)   // 退一格
 28 {
 29     --idx;
 30     ch=' ';
 31     return;
 32 }
 33 // 基本字数组
 34 string basicWord[13]={"begin","call","const","do","end",
 35                         "if","odd","procedure","read",
 36                         "then","var","while","write"};
 37 // 处理基本字
 38 string basic(const string strToken)
 39 {
 40     bool isbasic=false;
 41     for (int i=0;i<13;++i)
 42     {
 43         if (strToken==basicWord[i])
 44         {
 45             isbasic=true;
 46             break;
 47         }
 48     }
 49     if (isbasic)   // 如果是基本字
 50     {
 51         return strToken;
 52     }
 53     else   // 否则是标识符
 54     {
 55         return "ident";
 56     }
 57 }
 58 
 59 
 60 int main()
 61 {
 62     vector<string> v;
 63     string s="";
 64     string str;
 65     while (cin>>str)   // 循环读入
 66     {
 67         s=s+' '+str;
 68     }
 69 
 70     int idx=0;
 71     while (idx<(int)s.length()){   // 处理每个字符
 72         char ch=' ';
 73         string strToken="";
 74         getChar(s,idx,ch);
 75         getBC(s,idx,ch);
 76         if (isalpha(ch))   // 如果是字母
 77         {
 78             while (isalnum(ch))   // 读字母或数字
 79             {
 80                 concat(strToken,ch);
 81                 getChar(s,idx,ch);
 82             }
 83             retract(idx,ch);
 84             string ret=basic(strToken);
 85             if (ret=="ident")
 86             {
 87                 v.push_back(string("(ident,"+strToken+')'));
 88             }
 89             else
 90             {
 91                 v.push_back(string('('+ret+"sym"+','+strToken+')'));
 92             }
 93         }
 94         else if (isdigit(ch))   // 如果是数字
 95         {
 96             while (isdigit(ch))   // 持续获取数字
 97             {
 98                 concat(strToken,ch);   // 将所有数字拼起来
 99                 getChar(s,idx,ch);   // 下一个字符
100             }
101             retract(idx,ch);
102             v.push_back(string(+"(number,"+strToken+')'));
103         }
104         else if (ch=='+')
105         {
106             v.push_back("(plus,+)");
107         }
108         else if (ch=='-')
109         {
110             v.push_back("(minus,-)");
111         }
112         else if (ch=='*')
113         {
114             v.push_back("(times,*)");
115         }
116         else if (ch=='/')
117         {
118             v.push_back("(slash,/)");
119         }
120         else if (ch=='=')
121         {
122             v.push_back("(eql,=)");
123         }
124         else if (ch=='<')   // '<'后有 <>、<= 两种可能
125         {
126             getChar(s,idx,ch);
127             if (ch=='>')
128             {
129                 v.push_back("(neq,<>)");
130             }
131             else if (ch=='=')
132             {
133                 v.push_back("(leq,<=)");
134             }
135             else
136             {
137                 retract(idx,ch);
138                 v.push_back("(les,<)");
139             }
140         }
141         else if (ch=='>')   // '>'后有 >= 的可能
142         {
143             getChar(s,idx,ch);
144             if (ch=='=')
145             {
146                 v.push_back("(geq,>=)");
147             }
148             else
149             {
150                 retract(idx,ch);
151                 v.push_back("(gtr,>)");
152             }
153         }
154         else if (ch==':')
155         {
156             getChar(s,idx,ch);
157             if (ch=='=')
158             {
159                 v.push_back("(becomes,:=)");
160             }
161         }
162         else if (ch=='(')
163         {
164             v.push_back("(lparen,()");
165         }
166         else if (ch==')')
167         {
168             v.push_back("(rparen,))");
169         }
170         else if (ch==',')
171         {
172             v.push_back("(comma,,)");
173         }
174         else if (ch==';')
175         {
176             v.push_back("(semicolon,;)");
177         }
178         else if (ch=='.')
179         {
180             v.push_back("(period,.)");
181         }
182         else
183         {
184             v.push_back("(OTHER,"+ch+')');
185         }
186     }
187     for (int i=0;i<(int)v.size();++i)   // 输出
188     {
189         cout<<v[i]<<endl;
190     }
191     return 0;
192 }
View Code

四. 调试数据

1.样例输入:

1 const a=10;
2 var b,c;
3 begin
4 read(b);
5 c:=a+b;
6 write(c)
7 end.

样例输出:

(constsym,const)
(ident,a)
(eql,=)
(number,10)
(semicolon,;)
(varsym,var)
(ident,b)
(comma,,)
(ident,c)
(semicolon,;)
(beginsym,begin)
(readsym,read)
(lparen,()
(ident,b)
(rparen,))
(semicolon,;)
(ident,c)
(becomes,:=)
(ident,a)
(plus,+)
(ident,b)
(semicolon,;)
(writesym,write)
(lparen,()
(ident,c)
(rparen,))
(endsym,end)
(period,.)

图片展示:

2. 样例输入:

1 const a=10;
2 var b,c,d;
3 begin
4 read(b);
5 read(c);
6 d:=a+b+c;
7 write(d)
8 end.

样例输出:

 1 (constsym,const)
 2 (ident,a)
 3 (eql,=)
 4 (number,10)
 5 (semicolon,;)
 6 (varsym,var)
 7 (ident,b)
 8 (comma,,)
 9 (ident,c)
10 (comma,,)
11 (ident,d)
12 (semicolon,;)
13 (beginsym,begin)
14 (readsym,read)
15 (lparen,()
16 (ident,b)
17 (rparen,))
18 (semicolon,;)
19 (readsym,read)
20 (lparen,()
21 (ident,c)
22 (rparen,))
23 (semicolon,;)
24 (ident,d)
25 (becomes,:=)
26 (ident,a)
27 (plus,+)
28 (ident,b)
29 (plus,+)
30 (ident,c)
31 (semicolon,;)
32 (writesym,write)
33 (lparen,()
34 (ident,d)
35 (rparen,))
36 (endsym,end)
37 (period,.)

图片展示:

3.样例输入:

1 const a=10;
2 const b=10;
3 var c;
4 begin
5 c:=a+b;
6 write(c)
7 end.

样例输出:

 1 (constsym,const)
 2 (ident,a)
 3 (eql,=)
 4 (number,10)
 5 (semicolon,;)
 6 (constsym,const)
 7 (ident,b)
 8 (eql,=)
 9 (number,10)
10 (semicolon,;)
11 (varsym,var)
12 (ident,c)
13 (semicolon,;)
14 (beginsym,begin)
15 (ident,c)
16 (becomes,:=)
17 (ident,a)
18 (plus,+)
19 (ident,b)
20 (semicolon,;)
21 (writesym,write)
22 (lparen,()
23 (ident,c)
24 (rparen,))
25 (endsym,end)
26 (period,.)

图片展示:

五. 实验调试情况及体会


参考博客:

标签:10,ch,const,semicolon,back,词法,编译,ident,原理
From: https://www.cnblogs.com/hell0er/p/17365404.html

相关文章

  • 万能修改串号imei软件技术原理
    在智能手机用户中,有一些人因为特定需求需要修改手机串号,例如解锁手机、绕过应用程序检测等。而万能修改串号IMEI软件成为了其中的一种解决方案。那么,这种技术的原理是什么呢?首先,我们需要了解万能修改串号IMEI软件的基本原理。IMEI是手机的唯一标识符,由15位数字组成。当手机......
  • 改手机串号技术原理能绕过APP检测
    随着智能手机的普及,应用程序的数量和种类也在不断增加。不同的应用程序可能需要不同的硬件和软件支持,导致一些应用程序无法在所有手机上运行。于是,一些用户开始探索绕过应用程序检测的方法,以使用这些应用程序。其中一个方法是修改手机串号。那么,改手机串号技术原理是否能够......
  • 安卓一键改串号免root技术原理
    在智能手机用户中,有一部分人因为种种原因需要改变手机串号,比如解锁手机、绕过应用程序检测等。然而,传统的修改串号方法需要root权限,对普通用户来说比较困难。近年来,出现了一些安卓一键改串号免root技术,让用户可以更方便地修改手机串号。那么,这种技术的原理是什么呢?首先,我们......
  • ActiveMQ学习(二)——MQ的工作原理…
    如图所示首先来看本地通讯的情况,应用程序A和应用程序B运行于同一系统A,它们之间可以借助消息队列技术进行彼此的通讯:应用程序A向队列1发送一条信息,而当应用程序B需要时就可以得到该信息。其次是远程通讯的情况,如果信息传输的目标改为在系统B上的应用程序C,这种变化不会对应用程序A......
  • 修改手机串号技术原理犯法吗
    随着智能手机的普及和功能的不断增强,越来越多的人开始依赖手机处理日常事务和娱乐活动。然而,一些用户可能会发现自己的手机无法使用某些功能,或者受到特定运营商的限制。于是,一些用户开始探索修改手机串号的方法,以解除这些限制。但是,这个做法是否犯法呢?首先,我们需要了解修改......
  • 手机串号修改技术原理
    随着现代技术的不断发展,手机串号(IMEI号)修改技术越来越普及,这种技术让许多用户可以使用多张手机卡在同一台手机上。手机串号修改技术的原理是什么呢?在这篇文章中,我们将深入探讨手机串号修改技术的原理和相关问题。首先,什么是手机串号(IMEI号)?手机串号是手机的唯一识别码,由15位数字组......
  • 手机串号 有什么用?串号是什么技术原理
    手机串号是指手机的国际移动设备身份码(IMEI),是一串15位数字,每台手机都有唯一的一个串号。手机串号可以用来跟踪手机的使用情况,防止手机被盗或丢失后被他人使用。手机串号可以在手机拨打*#06#后显示出来,也可以在手机后盖上找到。除了IMEI之外,还有其他的一些类似的串号,如MEID、ESN和......
  • 安卓手机虚拟定位技术原理
    随着互联网技术的发展,人们对于移动设备的需求越来越高,同时也希望通过移动设备实现更多的功能。手机定位功能就是其中一个重要的功能之一,它可以实现位置服务,帮助我们方便地找到目的地、搜索周边、定位人员等。但是在某些情况下,我们需要修改手机的位置信息,来达到某种特定的目的,这就......
  • 解决项目编译对SVN依赖的相关问题
    一、背景软件打包发布并在机器部署后并生命周期没有结束,后续会随着使用发现各种各样的Bug,整个生命周期都与Bug为伴,发现Bug并解决Bug就是软件产品的一部分,通常软件出现异常会有日志记录,当问题出现后,如何知道一个软件库的版本,从而快速从源码库拉取对应版本的源码,调试并修复呢?这就需......
  • koa-cors 源码及基本原理解析
    cors: 跨域资源共享(Cross-OriginResourceSharing)是一种机制,用来允许不同源服务器上的指定资源可以被特定的Web应用访问。在koa项目中使用cors中间件:eg:1varkoa=require('koa');2varroute=require('koa-route');3varcors=require('koa-cors');4varapp......