搜档网
当前位置:搜档网 › Linphone的编译与代码分析

Linphone的编译与代码分析

Linphone的编译与代码分析
Linphone的编译与代码分析

Linphone的编译与代码分析

2008-12-14

updatedb@https://www.sodocs.net/doc/ff13984502.html,

目录

1LINP HONE的编译3 1.1L INPHONE在ARM上的编译环境说明3 1.2L INPHONE依赖的库3 1.3L INPHONE编译脚本3 1.4编译过程中的问题4 2LINP HONE代码分析4 2.1L INPHONE的初始化分析4 2.1.1LINPHONEC的初始化5 2.1.2LINPHONE_CORE的初始化5 2.1.3O RTP的初始化5 2.1.4MEDIASTREAM2的初始化6 2.1.5E X OSIP的初始化6 2.2L INPHONE的通话过程分析6 2.2.1L INPHONE的命令处理分析7 2.2.2L INPHONE的呼叫过程分析7 2.2.3L INPHONE的通话过程分析8 2.2.4L INPHONE的响应过程分析8 2.3L INPHONE中创建以及应用自定义过滤器9 2.3.1过滤器的基本功能9 2.3.2过滤器的通用接口10 2.3.3自定义过滤器10

Linphone的编译与代码分析

1Linphone的编译

1.1Linphone在arm上的编译环境说明

Linphone在arm上编译的时候,时常会碰到一些问题,有时候想办法解决了相关的问题,但编译出来的Linphone在板子上的运行仍然不稳定,或者不能通话。

如果条件允许的话,当碰到这些问题之后,可以换其它的工具链进行编译。我最初编译Linphone的时候采用的是xscale270板子自带的工具链,GCC3.4.3以及uclibc。经过很痛苦的一番折腾之后,所以的代码最终都编译通过,但是编译出来的linphonec在板子上运行在通话开始之后总是崩溃。通过GDB调试,发现是多线程的问题引起的,于是编译了一个线程结构相当的程序,但是测试没有发现问题。

最后,我改用GCC4.0.0以及Glibc-2.3.5基本上没有碰到什么问题,直接编译通过,并且在板子上正常运行。

1.2Linphone依赖的库

除了上面所提到的Gcc,Glibc以及系统的基本库外我主要编译了下面的程序包。

序号库名称说明

1Read Line一个终端显示库,Linph on e会用到它时里面的事件循环机制来读取会话事件。

2ffmp eg音视频编解码库

3Speex专为通话过程设计的音频编码库

4libtheora视频压缩编码库

5libfaac mpeg4的音频编码器

6libfaad2AAC音频解码器

7SDL简单的视频支持层

8libos ip2SIP的简单实现

9libeXos ip2对libos ip2的调用进行封装,隐藏了多媒体会话建立过程中SIP的细节

10linpho ne-3.0lin phon e的主程序,包括m ed ias tream,o Rtp,coreapi以及conso le四个部分

1.3Linphone编译脚本

见附件。

1.4编译过程中的问题

1、ffmpeg的编译问题

在编译ffmpeg的时候会发现有不少编解码码器不能编译能过,在configure的时候禁用的就行了。

2、linphone的编译

linphone的编译过程中可能会出现mediastream2下面的test不能编译能过的问题,在mediastream2下面找到Makefile文件,找到SUBDIRS将tests删掉即可。

linphone下面的所有的库编译完成之后,linphonec的编译可能不能能过,原因是几个库不能找到,这时候其它那几个库用不着,重新修改Makefile即可(详见附件)。

2Linphone代码分析

Linphone代码的分析主要分为三个部分。在整个分析过程主要是对音频通话相关的内容进行分析,视频的流程类似,但有细节有很大的区别,请自行分析。如果在看代码的过程中碰到一些问题不能理解,推荐先看看SIP/RTP/RTCP等协议的基本内容,或者通过抓数据包对整个会话过程进行分析。

2.1Linphone的初始化分析

首先主要的流程在流程图里面都有表现,图是边看代码,边画出来的,不是很好。下面的分析主要是对图中的内容进行讲述。

先对图里面的标识解释一下:

实心箭头表示流程走向;

空心箭头表示调用关系;

指向出发点箭头表示循环调用;

黄色的框表示代相对独立的码块,红色表示关键函数,绿色表示成功;

虚线指向表示有相关性,但并非调用关系;

虚线框表示主要数据结构。

对Linphone的整个初始化过程进行分析可以分为下面的个部分。

2.1.1linphonec的初始化

在linphonec的初始化过程中,一共做了两件事。首先初始化linphone_core,如果成功,则进入linphonec的主循环,等待用户输入,如果有用户输入就会调用相应的命令处理函数。处理函数被注册在静态的数组LPC_COMMAND commands中。如果你想增加linphone处理其它的命令,最好在这儿添加。

2.1.2linphone_core的初始化

Linphone_core的初始化概括的讲的就产生一个唯一的linphone实例,该实例包括了显示,配置,数据流等内容。在配置linphone_core的实例的过程中,linphone会读取并分析配置文件,并调用相关的初始化函数。

Linphone_core初始化完成之后,会调用linphonec_initalize_readline,该函数将linphonec_idel_call注册到readline的事件循环中,并且每隔1秒调用一次,检查是否有等待处理的osip事件(比如有人发送INVITE消息)。

2.1.3Ortp的初始化

Ortp的初始化除了对数据结构的初始化外,主要的工作就是加载相关的PayloadT ype.

2.1.4mediastream2的初始化

主要是对filter以及声卡,网卡的初始化。详细解释见函数调用图,以及函数解释。

2.1.5eXosip的初始化

eXosip的核心是初始化osip,打开相关的网络接口,进入监听状态。

下面列出流程中主要的函数调用的用途:

1Linpho neco reVtab le用于初始化屏幕相关,以及输出相关

2o rtp_in it初始华ortp,并加载默认的Pay load Typ e(在avp rofile.c定义)。如果要定义新的过滤

器,在这儿也要注册相应的Pay lo ad Ty p e,当然,自定义的Pay load Ty pe可以只

在需要的时候再即用。

3ms_in it m ed iastream er2的初始化,首先注册所有的filter,这些filter在alld es cs.h中被表态保

存在ms_filter_d es c数组中。注册新的过滤器时,过滤器的描述结构应该被注册到

该数组中。同时也注册了声卡与摄像头,并且初始化每个设备,放到全局静态变量

M SSnd CardM an ag er和M SWeb Cam Man ag er中。

4lp_co nfig_new读取并分析配置文件

5XXX_con fig读取配置文件中XXX相关的配置到linp hon e_core中,包括读取网络配置,RTP配

置,解码器配置以及s ip/v iew/ui的配置。

6linp hon e_core_s et_s ip_po rt用于打开s ip端口,等待并接收s ip信息。

7exos ip_in it这个函数在libeXos ip中,而不是在linp hon e中。用于寢化eXos ip变量,在初始化

时eXos ip和os ip互相指向,用于后面的访问。eXos ip_call_t和vo id*j_thread没有

被初始化。接着对四种ex tl_p ro to col进行初始化,为os ip数据包传输做好准备。

8os ip_in it这个函数初始化了os ip_t数据结构,被启动了四个用于os ip数据处理的状态机。

每个新状态机都是一个trans itio n列表,每一个trans itio n时面包括s tate,type,处理

函数m ethod.四个状机代表四个不同的会话事务。每个会话事务,根据状态机不同

的状态,调用相应事务中eXos ip_set_callb acks中注册的处理函数,并改变事务状态。

9eXos ip_s et_callb acks调用os ip_s et_cb_s end_message和os ip_set_XXX_callb ack为os ip注册处理各种状态

数据包的回调函数。初始化了os ip中ms g_callb acks,k ill_callb acks,

tp_erro r_callb acks,cb_s en d_m ess age几个最重要的数据。cb_send_m ess age这个函数

最终会根据协议的不同,调用不同的eXtl_p ro to col对像发送数据。

10eXos ip_lis ten_add r打开一个监听端口,用于接收连接,并启动一个线程专门牏sip数据包。根据不同

的数据传输类型打开不同的数据接收端口。

11os ip_thread_create创建一个线程,循环执行os ip_ex ecu te直至接收到退出或者异常信息。

12os ip_execu te这个函数会读取eXtl_XXX打开的so cket,然后遍历所有的状态机,看是否有事件

需要处理。

13eXos ip_read_mess ag e如果可以读取数据,那么将得到的数据交给数据处理函数,数据处理函数对数据进

行格式化,构造成为os ip数据结构及以os ip_even t,然后再通过os ip_ev net_t的类

型查找是那个trans actio n及对应的状态机。并且将事件加到trans ation所对应的

os ip_fifo_t*transaction ff中。

14os ip_timers_XiXt_ex ecu te依次检查四个状态机的所有tran saction,判断是否需要注册一个TIMEOUT_I/

TIMEOUT_H/TIM EOUT_G事件,如果需要则注册相应的事件。

15os ip_XiXs t_ex ecu te依次检查四个状态机的所有的trans actio n,看是否有需要执行的事件,如果有事件

要执行,则在状态机中调用相应的在s et_callb acks中注册的函数。

2.2Linphone的通话过程分析

在分析Linphone的通话过程之前,我们首先分析看看当前的状态:

linphonec_main_loop在等待用户输入。从而用户可以在自己的控制端进行操作,比如发起呼叫。

eXosip_listen_addr在监听端口,等远程连接。如果有数据,即可以接收,并解析数据,

放到事件队列中。

linphonec_idel_call每秒被调用一次,查看在有eXosip中是否有事件要处理。可以发现事件队列中的事件,并对其做出响应。

当通话双方都做好了通话准备的时候,双方都进入了上面所描述的状态。下面我们对通话过程的分析我们只对最主要的两个部分,即呼叫和应答进行分析。在流程图中,分为三个部门左上角为通话双方都相同的部分,命令处理。右上方是发起呼叫的过程。左下方是响应的过程。右下方是双方一致的通话过程。

对我Linphone的能话过程分析分为以下几个部分:

2.2.1Linphone的命令处理分析

该部分的主要功能是对用通输入的命令进行分析,然后通过在lpc_find_command找到对应的函数,并调用相应的函数。

比如当用户输入call sip:192.168.1.1的时候,linphone_call_invite命令将被调用。而当用户输入answer的时候,linphone_call_answer命令将会被调用。

主要调用的函数说明列表如下:

2.2.2Linphone的呼叫过程分析

1linph on e_core_in vite该函数会解析s ip URL,并构造一个发送一个INVITE消息。

2eXos ip_call_b u ild_in itial_inv ite创建最简单的INVITE请求。

3linph on e_call_n ew_ou tgo ing

4eXos ip_call_s end_in itial_inv ite该函数将已经构造好的INVITE信息发送。首先有eXos ip_call_t对

象,然后根据状态机的类型,以及初始化过程中创建的os ip,以及

INVITE请求信息,去初始化一个trans actio n。

5eXos ip_call_in it初始化一个Linph on eCall对象,并对该对象进行基本的初始化。每

个通话过程中保持一个Lin phon eCall对象。

6os ip_new_ou tgo in g_s ipm ess ag e该函数能过Inv ite的内容,为用户分创建一个新的事件。事件中

trans action的ID由os ip_tran saction_in it中初始化得到。

7os ip_trans actio n_in it初始化trans actio n。trans action的id是一个静态的递增值,在整个系

统运行的过程中是其值是唯一的。transactio n的初始化过程中的三个

最重要的动作是:1、将系统初始化时创建的o sip对象附给

trans action。2、初始化trans action的事件队列。3、根据状态机的类

型将trans action加入到状态机中。

8os ip_trans actio n_add_ev en t该函数将事件加入到transactio n的事件队列中。

9linph on e_s et_sdp将构造好的SDP数据包打包进入到通信数据中。

Linphone的呼叫从这儿正式开始了,但是我们可以看到请求事件还没有发送。但是这个不用担心,我们在系统初始化时的创建的eXosip_execute线程会不断的查询是否有数据需要处理。当它发现要状态机(ICT)中有需要处理的数据的时候,它会调用在系统初始化时eXosip_set_callbacks注册的事件处理函数。这些注册函数处理完数据后,发送eXosip_event,从而linphone可以调用eXosip_event对应的相应的处理函数。处理函数会将数据发送给通话的另一方。

在这个过程中linphone调用了函数linphone_core_init_media_stream,这个函数完成了对音视频通话的准备工作,我们将在响应过程分析中对其作详细的分析。

2.2.3Linphone的通话过程分析

通话的接收方在系统初始化完成之后,有着与呼叫方相同的状态。当eXosip_execute线程不断查询数据的过程中,发会接收到SIP数据,Linphone将SIP数据交给libosip进行分析与处理。处理的结果就是通过分析数据,将一个RCV_REQINVITE事件加入到(IST)状态机中等待处理。接着状态机奖被调用。

接下来的过程类似,双方利用sip完成下面的通话过程。

从上图我们可以看到双方通话过程包括发送SND_REQINVITE,收到RCV_STA TUS_ 1XX建立会话,然后再次接收到RCV_STA TUS_1XX响铃事件,然后会接收到RCV_ST ATUS_2XX的200事件,发送确认开始通话。这一部的的主要执行的代码就是在初始化时建立的eXosip_execute处理线程。

2.2.4Linphone的响应过程分析

对响应过程的分析我们从被呼叫方接收呼叫开始分析。调用过程中主要用的函数如下:1linp hon e_co re_ans wer命令行调用该函数,用于响应

2linp hon e_co re_accep t_call自动应答以及命令行调用,以响应用户行命令处理。它会首先停止响铃,然后

发送一个OK的信息给呼叫方。接着初始化音视频,开始通话。

3eXos ip_call_bu ild_ans wer该函数会构建一个200的响应s ip包

4linp hon e_co re_in it_m ed ia_s treams用于初始化Aud io Stream以及VideoStream。

5aud io_s tream_n ew创建新的Aud io Stream,并对RtpSess io n和filter rtpsend进行初始化。

2.3Linphone 中创建以及应用自定义过滤器

对Linphone 中自定义过滤器的分析主要分为:

2.3.1过滤器的基本功能

1)Filter 的基本功能就是将输入的数据进行处理,然后放到输出队列中。2)每个Filter 对数据只进行一组处理。

6eXos ip_call_send_ans wer

将相应的事件加入到状态机,并等待处理。

7linp hon e_co re_start_m ed ia_s treams 该函数取得lin phon e 系统初始化时调用s ound _co nfig _read 中初始化的声卡。8aud io _s tream_s tart_now 该函数只是对aud io_s tream _s tart_fu ll 的封装,没有特殊的功能。

9

aud o_s tream_s tart_fu ll

该函数的主要目标是完成对Aud io Stream 的初始化,设置该通话过程中要用的的声卡读写、Rtp 数据发送/接收、编码、编码器的过程。。首先该函数加载Rtp 的Pay Lo ad_Ty pe,以及jitter 补偿,同时调用ms _filter_call_m ethod 来对Rtp 的其它属性进行初始化。

10ms _snd_card_create_read er

该数据将声卡与声卡的读过滤器进行绑定。该函数会调用M SSn d Card Des c 的create_read er 函数,该函数将调用M SSn d Card Des c 的in it 函数。这一过程会初始化inpu t/o ut 以及数据的缓冲区。

11ms _snd_card_create_writer

该数据将声卡与声卡的写过滤器进行绑定。该函数会调用M SSn d Card Des c 的create_writer 函数,该函数将调用MSSn d Card Desc 的in it 函数。这一过程会初始化in pu t/out 以及数据的缓冲区。

12ms _filter_create_enco der

通过Aud io Stream 的参数查找Rtp Sess ion 中对应的p ay load ,然后根据payload 里面的m ime 类型创建编码器过滤器。首先找到符合M S_FILTER_ENCODER 和m im e 的MSFilterDesc 。通过ms_filter_n ew_from_des c 绑定MSFIlter 。

13ms _filter_create_d eco der

通过Aud io Stream 的参数查找Rtp Sess ion 中对应的p ay load ,然后根据payload 里面的m ime 类型创建解码器过滤器。首先找到符合M S_FILTER_DECODER 和m im e 的MSFilterDesc 。通过ms _filter_n ew_from _d esc 绑定M SFIlter 。

14ms _filter_lin k

该函数用于将各个M SFilter 连接起来。它会创建一个队列,该队列在两个filter 之前进行共享,作为前一个队列的输出,后一队列的输入。如果没有输入,只有输出,那个in =0,o ut=1;反之易然。举例说明一下:M SOs s Read in :0ou t:1//只有输出,也就是只是读取数据

M SSp eex En c in :1ou t:1//从M SOss Read 中取得数据,编码后输出M SRtp Send in :1ou t:0//从MSSpeex En c 中取得数据,并发送

M SRtp Recv in :0o u t:1//从网络接收数据,直接输出给下一个过滤器M SSp eex Dec in :1ou t:1M SDtm fGen in :1o ut:1

in :1ou t:0//从上一下过滤器取得数据并播放

15ms _tick er_n ew 该函数创建一个tick er ,在一个对话过程中,linpho ne 只维护一个tickers 。每次遍历处理所有的tick ers 之后,ticker++。

16ms _tick er_in it 初始化tick er ,初始化tick er 的基本参数,调用ms _tick er_s tart

17ms _tick er_s tart 该数据会调用ms_thread_create 运行ms_ticker_run ,它不断检查是否M SFilter 链表中有数据有处理。初始化时需要处理的MSFilter 为NULL 。

18ms _tick er_attach 用于将M SFilter 与M STick er 进行绑定。在这里分别绑定了s tream ->soun dread 和s tream ->rtp recv 。

19

find_filters

查找与参数中M SFilter 相关的Filter 链表。分别形成两个类似下面的队列。用于处理从声卡读取的数据:

M SOs s Read ->M SSpeex En c->M SRtp Send 用于处理网络数据的Filter 队列:

M SRtp Recv->M SSp eexDec->M SDtmfGen->M SOss Write 20g et_s ources

取得DESC->n inp u t=0,即是数据输入源的MSFilter.

21ms _filter_preprocess 该函数是filter 的预处理函数,其本身的定方在M SFilterDes c 中。在这里是对fin d_filters 找到的两个M SFilter 队列的预处理函数进行调用。

22ms _list_con cat 该函数用于向一个链表中附加元素。在这里被用于给ex ecute_list 附值,从而ms_tick er_s tart 线程得到输入数据。

23os s_s tart_r 在对oss_read _prep ro cess 的调用时,用于打开一个读取声卡数据的线程。

24os s_s tart_w 在对oss_write_p reprocess 的调用时,用于打开一个播放最终处理过的数据的线程。

25run_graphs 该函数对所有可用的ex ecu te_lis t 队列中的元素进行遍历。在遍历的过程中,对M SFilter 队列中的数据调用ms_filter_p ro ces s 进行处理。

26

ms _filter_pro cess

调用M SFilterDes c 中定义的p ro ces s 函数,对数据进行真正的处理。

3)不同的Filter可以连接起来。

2.3.2过滤器的通用接口

MSFilter的通用接口主要相关的文件都被放在mediastream下面。

如下表所述:

1alld es cs.h定义了所有的M SFilterDesc,包括声卡读写,RTP数据处理,各种音视频编解码器、文件的读取与播放。2allfilters.h定义了所有的M SFilterId的编号,该编号是唯一的。

3msfilter.h定义了M SFilter的分类,以及用于描述M SFilter分类的MSFilterDesc。M SFilter对象也在这里面被定义。4msfilter.c定义了对M SFilter对象的操作方法。包括注册,创建新的M SFilter,连接M SFIlter,以及Filter的p reprocess、p ro ces s、p os tprocess方法、以及用于取得M SFilter对象的状态的函数。

5mssnd card.h定义了声卡相关的数据结构。包括M SSnd CardDes c,M SSn d Card。

6mssnd card.c定义了声卡操作的数据接口,并且将声卡与过滤进行关联。

7mscommom.c定义了med ias tream的初始化函数,同时我们可以看到系统中内建的所有声卡被放在ms_sn d_card_d es cs 数组中。

8med ias tream下

主要定了过滤器的实际操作。

的其它文件

2.3.3自定义过滤器

自定义过滤器要作的主要的工作包括:

1、创建新的MSFilterDesc

2、创建新的编解码器,包括MSfilter的初始化函数、预处理函数、处理函数,清理函

数,参数相关的函数。

3、注册MSFilterDesc

4、创建新的PayloadType

5、注册PayloadType到RtpSession中

windows安装交叉编译环境

Duanxx的嵌入式学习: Win7安装交叉编译环境 ——Duanxx ——2015-09-15 ARM-linux的交叉编译环境,一般的教程都是在linux系统(比如ubuntu)上安装linaro的arm-linux-gnueabihf编译环境,然后再安装Eclipse和CDT,这样来实现交叉编译环境的安装。 我个人使用这种方法已经使用了几年了,因为我个人比较喜欢使用Linux系统(我使用的是CentOS),所以感觉很自然。但对于初学者而言,如果对linux系统不熟悉,这个方法非常的麻烦,仅仅是为了编译一个可以在ARM-linux上运行的elf文件,还要装虚拟机,学习linux系统的很多使用方法,挺麻烦的。 这两天试了一下在windows平台上安装交叉编译环境,成功了,这里将详细教程写下来,就当是做个记录。 目录 一、安装Eclipse (2) 二、安装CDT (3) 2.1Eclipse Marketplace 安装CDT (4) 2.2 Install New Software 安装CDT方案1 (4) 2.3 Install New Software 安装CDT方案2 (7) 2.4 手动安装CDT (9) 三、安装minGW (10) 四、安装Linaro ToolChain (10) 五、搭建交叉编译开发环境 (13) 六、RSE将可执行文件传输到ARM上 (26)

一、安装Eclipse Eclipse的下载网址是:https://www.sodocs.net/doc/ff13984502.html,/downloads/ 会有下面的这个网页,我打红色框的都可以直接使用,这里其实是无所谓的,因为Eclipse是基于插件的开发环境,如果只是为了开发C++的,可以考虑选择后面一个“Eclipse IDE for c/C++ Developers”。 Eclipse解压后就可以直接使用,见下图中的eclipse.exe,同时注意一下freatures和plugins文件夹。

清华大学版编译原理答案

《编译原理》课后习题 第1 章引论 第1 题解释下列术语: (1)编译程序:如果源语言为高级语言,目标语言为某台计算机上的汇编语言或机器语言,则此翻译程序称为编译程序。 (2)源程序:源语言编写的程序称为源程序。 (3)目标程序:目标语言书写的程序称为目标程序。 (4)编译程序的前端:它由这样一些阶段组成:这些阶段的工作主要依赖于源语言而与目标机无关。通常前端包括词法分析、语法分析、语义分析和中间代码生成这些阶 段,某些优化工作也可在前端做,也包括与前端每个阶段相关的出错处理工作和符 号表管理等工作。 (5)后端:指那些依赖于目标机而一般不依赖源语言,只与中间代码有关的那些阶段,即目标代码生成,以及相关出错处理和符号表操作。 (6)遍:是对源程序或其等价的中间语言程序从头到尾扫视并完成规定任务的过程。 第2 题 一个典型的编译程序通常由哪些部分组成?各部分的主要功能是什么?并画出编译程 序的总体结构图。 答案:一个典型的编译程序通常包含8 个组成部分,它们是词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、中间代码优化程序、目标代码生成程序、表格管理程序和错误处理程序。其各部分的主要功能简述如下。 词法分析程序:输人源程序,拼单词、检查单词和分析单词,输出单词的机内表达形式。语法分析程序:检查源程序中存在的形式语法错误,输出错误处理信息。 语义分析程序:进行语义检查和分析语义信息,并把分析的结果保存到各类语义信息表中。 中间代码生成程序:按照语义规则,将语法分析程序分析出的语法单位转换成一定形式 的中间语言代码,如三元式或四元式。 中间代码优化程序:为了产生高质量的目标代码,对中间代码进行等价变换处理。 目标代码生成程序:将优化后的中间代码程序转换成目标代码程序。 表格管理程序:负责建立、填写和查找等一系列表格工作。表格的作用是记录源程序的 各类信息和编译各阶段的进展情况,编译的每个阶段所需信息多数都从表格中读取,产生的中间结果都记录在相应的表格中。可以说整个编译过程就是造表、查表的工作过程。需要指出的是,这里的“表格管理程序”并不意味着它就是一个独立的表格管理模块,而是指编译程序具有的表格管理功能。 错误处理程序:处理和校正源程序中存在的词法、语法和语义错误。当编译程序发现源 程序中的错误时,错误处理程序负责报告出错的位置和错误性质等信息,同时对发现的错误进行适当的校正(修复),目的是使编译程序能够继续向下进行分析和处理。 第3 题何谓翻译程序、编译程序和解释程序?它们三者之间有何种关系? 答案:翻译程序是指将用某种语言编写的程序转换成另一种语言形式的程序的程序,如编译程序和汇编程序等。 编译程序是把用高级语言编写的源程序转换(加工)成与之等价的另一种用低级语言编 写的目标程序的翻译程序。 解释程序是解释、执行高级语言源程序的程序。解释方式一般分为两种:一种方式是, 源程序功能的实现完全由解释程序承担和完成,即每读出源程序的一条语句的第一个单词,则依据这个单词把控制转移到实现这条语句功能的程序部分,该部分负责完成这条语句的功

编译原理实验指导

编译原理实验指导 实验安排: 上机实践按小组完成实验任务。每小组三人,分别完成TEST语言的词法分析、语法分析、语义分析和中间代码生成三个题目,语法分析部分可任意选择一种语法分析方法。先各自调试运行,然后每小组将程序连接在一起调试,构成一个相对完整的编译器。 实验报告: 上机结束后提交实验报告,报告内容: 1.小组成员; 2.个人完成的任务; 3.分析及设计的过程; 4.程序的连接; 5.设计中遇到的问题及解决方案; 6.总结。

实验一词法分析 一、实验目的 通过设计编制调试TEST语言的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。 编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。 二、实验预习提示 1.词法分析器的功能和输出格式 词法分析器的功能是输入源程序,输出单词符号。词法分析器的单词符号常常表示 成以下的二元式(单词种别码,单词符号的属性值)。 2.TEST语言的词法规则 |ID|ID |NUM →a|b|…|z|A|B|…|Z →1|2|…|9|0 →+|-|*|/|=|(|)|{|}|:|,|;|<|>|! →>=|<=|!=|== →/* →*/ 三、实验过程和指导 1.阅读课本有关章节,明确语言的语法,画出状态图和词法分析算法流程图。 2.编制好程序。 3.准备好多组测试数据。 4.程序要求 程序输入/输出示例:

编译原理考试试卷

一、填空题(每空2分,共30分) 1、编译程序的整个过程可以从逻辑上划分为词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等几个阶段,另外还有两个重要的工作是表格管理和出错处理 2、规范规约中的可归约串是句柄,算符优先分析中的可归约串是最左素短语。 3、语法分析方法主要可分为自顶向下和自底向上两大类。 4、LR(0)文法的项目集中不会出现移进-归约冲突和归约-归约冲突。 5、数据空间的动存态储分配方式可分为栈式和堆式两种。 6、编译程序是指能将源语言程序翻译成目标语言程序的程序。 7、确定有穷自动机DFA是NFA 的一个特例。 8、表达式(a+b)*c 的逆波兰表示为ab+c* 。 二、选择题(每题2分,共20分) 1、L R语法分析栈中存放的状态是识别 B 的DFA状态。 A、前缀 B、可归前缀 C、项目 D、句柄 2、 D 不可能是目标代码。 A、汇编指令代码 B、可重定位指令代码 C、绝对机器指令代码 D、中间代码 3、一个控制流程图就是具有 C 的有向图 A、唯一入口结点 B、唯一出口结点 C、唯一首结点 D、唯一尾结点 4、设有文法G[S]:S→b|bB B→bS ,则该文法所描述的语言是 C 。 A、L(G)={b i|i≥0} B、L(G)={b2i|i≥0} C、L(G)={b2i+1|i≥0} D、L(G)={b2i+1|i≥1} 5、把汇编语言程序翻译成机器可执行的目标程序的工作是由 B 完成的。 A、编译器 B、汇编器 C、解释器 D、预处理器 6、在目标代码生成阶段,符号表用于 D 。 A、目标代码生成 B、语义检查 C、语法检查 D、预处理器地址分配0 7、规范归约是指 B 。 A、最左推导的逆过程 B、最右推导的逆过程 C、规范推导 D、最左归约逆过程

编译原理实验代码

[实验任务] 完成以下正则文法所描述的Pascal语言子集单词符号的词法分析程序。 <标识符>→字母︱<标识符>字母︱<标识符>数字 <无符号整数>→数字︱<无符号整数>数字 <单字符分界符> →+ ︱-︱* ︱; ︱(︱) <双字符分界符>→<大于>=︱<小于>=︱<小于>>︱<冒号>=︱<斜竖>* <小于>→< <等于>→= <大于>→> <冒号> →: <斜竖> →/ 该语言的保留字:begin end if then else for do while and or not 说明:1 该语言大小写不敏感。 2 字母为a-z A-Z,数字为0-9。 3可以对上述文法进行扩充和改造。 4 ‘/*……*/’为程序的注释部分。 [设计要求] 1、给出各单词符号的类别编码。 2、词法分析程序应能发现输入串中的错误。 3、词法分析作为单独一遍编写,词法分析结果为二元式序列组成的中间文件。 4、设计两个测试用例(尽可能完备),并给出测试结果。 demo.cpp #include #include #include #include "demo.h" char token[20]; int lookup(char *token) { for (int i = 0; i < 11; i++) { if (strcmp(token, KEY_WORDS[i]) == 0) { return i+1; } } return 0; } char getletter(FILE *fp) { return tolower(fgetc(fp)); } void out(FILE *fp, int c, char *value) {

编译原理作业参考答案

第1章引言 1、解释下列各词 源语言:编写源程序的语言(基本符号,关键字),各种程序设计语言都可以作为源语言。 源程序: 用接近自然语言(数学语言)的源语言(基本符号,关键字)编写的程序,它是翻译程序处理的对象。 目标程序: 目标程序是源程序经过翻译程序加工最后得到的程序。目标程序 (结果程序)一般可由计算机直接执行。 低级语言:机器语言和汇编语言。 高级语言:是人们根据描述实际问题的需要而设计的一个记号系统。如同自然语言(接近数学语言和工程语言)一样,语言的基本单位是语句,由符号组和一组用来组织它们成为有确定意义的组合规则。 翻译程序: 能够把某一种语言程序(源语言程序)改变成另一种语言程序(目标语言程序),后者与前者在逻辑上是等价的。其中包括:编译程序,解释程序,汇编程序。 编译程序: 把输入的源程序翻译成等价的目标程序(汇编语言或机器语言), 然后再执行目标程序(先编译后执行),执行翻译工作的程序称为编译程序。 解释程序: 以该语言写的源程序作为输入,但不产生目标程序。按源程序中语句动态顺序逐句的边解释边执行的过程,完成翻译工作的程序称为解释程序。 2、什么叫“遍”? 指对源程序或源程序的中间形式(如单词,中间代码)从头到尾扫描一次,并作相应的加工处理,称为一遍。 3、简述编译程序的基本过程的任务。 编译程序的工作是指从输入源程序开始到输出目标程序为止的整个过程,整个过程可以划分5个阶段。 词法分析:输入源程序,进行词法分析,输出单词符号。 语法分析:在词法分析的基础上,根据语言的语法规则把单词符号串分解成各类语法单位,并判断输入串是否构成语法正确的“程序”。 中间代码生成:按照语义规则把语法分析器归约(或推导)出的语法单位翻译成一定形式的中间代码。 优化:对中间代码进行优化处理。 目标代码生成:把中间代码翻译成目标语言程序。 4、编译程序与解释程序的区别? 编译程序生成目标程序后,再执行目标程序;然而解释程序不生成目标程序,边解释边执行。 5、有人认为编译程序的五个组成部分缺一不可,这种看法正确吗? 编译程序的5个阶段中,词法分析,语法分析,语义分析和代码生成生成是必须完成的。而中间代码生成和代码优化并不是必不可少的。优化的目的是为了提高目标程序的质量,没有这一部分工作,仍然能够得到目标代码。 6、编译程序的分类 目前基本分为:诊断编译程序,优化编译程序,交叉编译程序,可变目标编译程序。

嵌入式交叉编译环境的搭建

实验二、嵌入式交叉编译环境的搭建 1、实验目的: 通过本实验使学生掌握交叉编译环境的建立,了解在S3C2440上交叉编译环境搭建的原理及步骤。 2、实验设备及说明 1、安装ubuntu10及vmware的计算机 2、天嵌2440的开发板 3、实验指导书 4、天嵌开发板的超级终端设置 5、天嵌开发板开发文档 6、TQ2440使用手册v2.3---20100125 3、实验内容和步骤 1、安装交叉编译器:EABI4.3.3 ●解压EABI 工具包 命令:tar zxvf /mnt/hgfs/(根据本机压缩包存储路径输入)/EABI 4.3.3.tar.gz –C / ##将压缩包解压到根目录下 ●添加路径至全局变量PATH中 命令:PATH=$PAHT:/opt/EmbedSky/4.3.3/bin (此路径应根据本机的具体情况输入) ●查看全局变量PATH 命令:echo PATH ###查看刚才的添加是否成功 ●查看交叉编译命令是否能够使用 命令:arm-linux-gcc –v ###如果刚才解压、添加变量成功,此时输入命令后,即可以显示命令的版本信息。

2、minicom

●在线安装minicom 命令:apt-get install minicom ●在命令行中键入“minicom”,这就启动了minicom软件。 ●Minicom在启动时默认会进行初始化配置minicom -s ?CTRL+A Z,来查看minicom的帮助 ?CTRL-A O配置minicom的串口参数,选择“Serial port setup”子项,上面列出的配置是minicom启动是的默认配置,用户可以通过键入每一项前的大写字母,分别对每一项进行更改.要对波特率、数据位和停止位进行配置,键入“E”,在该配置界面中,可以键入相应波特率、停止位等对应的字母,即可实现配置,配置完成后按回车键就退出了该配置界面。在确认配置正确后,可键入回车返回上级配置界面,并将其保存为默认配置。 ?

实验1-3 《编译原理》词法分析程序设计方案

实验1-3 《编译原理》S语言词法分析程序设计方案 一、实验目的 了解词法分析程序的两种设计方法之一:根据状态转换图直接编程的方式; 二、实验内容 1.根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。在此,词法分析程序作为单独的一遍,如下图所示。 具体任务有: (1)组织源程序的输入 (2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件 (3)删除注释、空格和无用符号 (4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。将错误信息输出到屏幕上。 (5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。 标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址 注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。 常量表结构:常量名,常量值 三、实验要求 1.能对任何S语言源程序进行分析 在运行词法分析程序时,应该用问答形式输入要被分析的S源语言程序的文件名,然后对该程序完成词法分析任务。 2.能检查并处理某些词法分析错误 词法分析程序能给出的错误信息包括:总的出错个数,每个错误所在的行号,错误的编号及错误信息。 本实验要求处理以下两种错误(编号分别为1,2): 1:非法字符:单词表中不存在的字符处理为非法字符,处理方式是删除该字符,给出错误信息,“某某字符非法”。 2:源程序文件结束而注释未结束。注释格式为:/* …… */ 四、保留字和特殊符号表

编译原理实验:目标代码的生成

5. 目标代码生成 本章实验为实验四,是最后一次实验,其任务是在词法分析、语法分析、语义分析和中间代码生成程序的基础上,将C 源代码翻译为MIPS32指令序列(可以包含伪指令),并在SPIM Simulator上运行。当你完成实验四之后,你就拥有了一个自己独立编写、可以实际运行的编译器。 选择MIPS作为目标体系结构是因为它属于RISC范畴,与x86等体系结构相比形式简单便于我们处理。如果你对于MIPS体系结构或汇编语言不熟悉并不要紧,我们会提供详细的参考资料。 需要注意的是,由于本次实验的代码会与之前实验中你已经写好的代码进行对接,因此保持一个良好的代码风格、系统地设计代码结构和各模块之间的接口对于整个实验来讲相当重要。 5.1 实验内容 5.1.1 实验要求 为了完成实验四,我们建议你首先下载并安装SPIM Simulator用于对生成的目标代码进行检查和调试,SPIM Simulator的官方下载地址为:https://www.sodocs.net/doc/ff13984502.html,/~larus/spim.html。这是由原Wisconsin-Madison的Jame Larus教授(现在在微软)领导编写的一个功能强大的MIPS32汇编语言的汇编器和模拟器,其最新的图形界面版本QtSPIM由于使用了Qt组件因而可以在各大操作系统平台如Windows、Linux、Mac等上运行,推荐安装。我们会在后面介绍有关SPIM Simulator的使用方法。 你需要做的就是将实验三中得到的中间代码经过与具体体系结构相关的指令选择、寄存器选择以及栈管理之后,转换为MIPS32汇编代码。我们要求你的程序能输出正确的汇编代码。“正确”是指该汇编代码在SPIM Simulator(命令行或Qt版本均可)上运行结果正确。因此,以下几个方面不属于检查范围: 1)寄存器的使用与指派可以不必遵循MIPS32的约定。只要不影响在SPIM Simulator中的 正常运行,你可以随意分配MIPS体系结构中的32个通用寄存器,而不必在意哪些寄存器应该存放参数、哪些存放返回值、哪些由调用者负责保存、哪些由被调用者负责保存,等等。 2)栈的管理(包括栈帧中的内容及存放顺序)也不必遵循MIPS32的约定。你甚至可以使 用栈以外的方式对过程调用间各种数据的传递进行管理,前提是你输出的目标代码(即MIPS32汇编代码)能运行正确。

编译原理实验题目及报告要求

编译原理上机实验试题 一、实验目的 通过本实验使学生进一步熟悉和掌握程序设计语言的词法分析程序的设计原理及相关的设计技术, 如何针对确定的有限状态自动机进行编程序;熟悉和 掌握程序设计语言的语法分析程序的设计原理、熟悉 和掌握算符优先分析方法。 二、实验要求 本实验要求:①要求能熟练使用程序设计语言编程;②在上机之前要有详细的设计报告(预习报告); ③要编写出完成相应任务的程序并在计算机上准确 地运行;④实验结束后要写出上机实验报告。 三、实验题目 针对下面文法G(S): S→v = E E→E+E│E-E│E*E│E/E│(E)│v │i 其中,v为标识符,i为整型或实型数。要求完成 ①使用自动机技术实现一个词法分析程序; ②使用算符优先分析方法实现其语法分析程序,在 语法分析过程中同时完成常量表达式的计算。

1、题目(见“编译原理---实验题目.doc,“实验题目”中的第一项) 2、目的与要求(见“编译原理---实验题目.doc”) 3、设计原理: (1)单词分类:标识符,保留字,常数,运算符,分隔符等等 (2)单词类型编码 (3)自动机 4、程序流程框图 5、函数原型(参数,返回值) 6、关键代码(可打印,只打印关键代码) 7、调试: (1)调试过程中遇到的错误,如何改进的; (2)需要准备测试用例(至少3个,包含输入和输出)——(可打印) 8、思考: (1)你编写的程序有哪些要求是没有完成的,你觉得该采用什么方法去完成; (2)或者是你觉得程序有哪些地方可以进一步完善,简述你的完善方案。

1、题目(见“编译原理---实验题目.doc,“实验题目”中的第二项) 2、目的与要求(见“编译原理---实验题目.doc”) 3、设计原理:构造出算法优先关系表 4、程序流程框图 5、函数原型(参数,返回值) 6、关键代码(可打印,只打印关键代码) 7、调试: (1)调试过程中遇到的错误,如何改进的; (2)需要准备测试用例(至少3个,包含输入和输出)——(可打印) 8、思考: (1)你编写的程序有哪些要求是没有完成的,你觉得该采用什么方法去完成; (2)或者是你觉得程序有哪些地方可以进一步完善,简述你的完善方案。

ubuntu10.04全过程创建交叉编译环境

ubuntu10.04下建立交叉编译工具链(支持软浮点)全过程 参考了网上的不少的资料,花了五个小时终于完成了,记录下全过程供大家分享。 用到的源码包如下,建议新手全部放在/home/usr/downloads/ 目录下。以下操作在用户权限下进行。 ======================================================================= arm-linux-gcc-3.4.1.tar.gz glibc-2.3.3.tar.gz linux-2.6.8.tar.gz crosstool-0.43.tar.gz binutils-2.15.tar.gz glibc-linuxthreads-2.3.3.tar.gz binutils-2.18.tar.gz --安装用 编译一次至少要花半个小时,如果因为依赖软件没有安装中途会报错退出,只有从头再来,那样很浪费时间的。 sudo apt-get install bison flex build-essential patch libncurses5-dev 由于ubuntu10.04自带的ld ,as版本太高的原因,需要安装binutils的2.18版本,然后替换系统中的2.20版本。方法如下: $cd downloads $tar xzvf binutils-2.18.tar.gz $cd binutils-2.18 $./configure --prefix=/tmp/binutils --disable-nls (-prefix后面的是生成可执行文件存放的位置可以自己定义) $make all $make install 编译成功后在/tmp/binutils/bin/中就生成了ld和as程序的可执行文件 重新链接/usr/bin/ld 和/usr/bin/as文件 $sudo rm /usr/bin/ld /usr/bin/as //删除2.20的ld,as $sudo ln –s /tmp/binutils/bin/ld /usr/bin/ $sudo ln –s /tmp/binutils/bin/as /usr/bin/ 然后可运行ld –v 和as –v 查看版本是否为2.18。 安装2.18版本可解决出现的 ld as " version too old "问题。 2. ubuntu10.04下默认的GCC版本是4.4.3,但这个不是版本越高越好,版本太高,对语法什么的要求也高,编译不成功,降低版本吧: #sudo apt-get install gcc-4.1 //安装4.1的GCC,需要联网 #sudo rm /usr/bin/gcc //删除之前4.4.3的快捷方式,4.4.3的GCC并未删除#sudo ln -s /usr/bin/gcc-4.1 /usr/bin/gcc //建立4.1的快捷方式 这是由于crosstool中定义了GCC的版本的上下线,最高也就到4.1,在其配置的时候会对这个版本信息进行检测,不在其规定范围就报错了。 3.修改sh版本 如果运行

编译原理

一、选择 1.将编译程序分成若干个“遍”是为了_使程序的结构更加清晰__。 2.正规式 MI 和 M2 等价是指__.M1 和 M2 所识别的语言集相等_。 3.中间代码生成时所依据的是 _语义规则_。 4.后缀式 ab+cd+/可用表达式__(a+b)/(c+d)_来表示。 6.一个编译程序中,不仅包含词法分析,_语法分析 ____,中间代码生成,代码优化,目标代码生成等五个部分。 7.词法分析器用于识别__单词___。 8.语法分析器则可以发现源程序中的___语法错误__。 9.下面关于解释程序的描述正确的是__解释程序的特点是处理程序时不产生目标代码 ___。 10.解释程序处理语言时 , 大多数采用的是__先将源程序转化为中间代码 , 再解释执行___方法。 11.编译过程中 , 语法分析器的任务就是__(2)(3)(4)___。 (1) 分析单词是怎样构成的 (2) 分析单词串是如何构成语句和说明的 (3) 分析语句和说明是如何构成程序的 (4) 分析程序的结构 12.编译程序是一种__解释程序__。 13.文法 G 所描述的语言是_由文法的开始符号推出的所有终极符串___的集合。 14.文法分为四种类型,即 0 型、1 型、2 型、3 型。其中 3 型文法是___正则文法__。 15.一个上下文无关文法 G 包括四个组成部分,它们是:一组非终结符号,一组终结符号,一个开始符号,以及一组 _产生式__。 16.通常一个编译程序中,不仅包含词法分析,语法分析,中间代码生成,代码优化,目标代码生成等五个部分,还应包括_表格处理和出错处理__。 17.文法 G[N]= ( {b} , {N , B} , N , {N→b│ bB , B→bN} ),该文法所描述的语言是L(G[N])={b2i+1│ i ≥0} 18.一个句型中的最左_简单短语___称为该句型的句柄。 19.设 G 是一个给定的文法,S 是文法的开始符号,如果 S->x( 其中 x∈V*), 则称 x 是 文法 G 的一个__句型__。 21.若一个文法是递归的,则它所产生的语言的句子_是无穷多个___。 22.词法分析器用于识别_单词_。 23.在语法分析处理中, FIRST 集合、 FOLLOW 集合、 SELECT 集合均是_终极符集 ___。 24.在自底向上的语法分析方法中,分析的关键是_寻找句柄 ___。 25.在 LR 分析法中,分析栈中存放的状态是识别规范句型__活前缀__的 DFA 状态。 26.文法 G 产生的__句子___的全体是该文法描述的语言。 27.若文法 G 定义的语言是无限集,则文法必然是 __递归的_ 28.四种形式语言文法中,1 型文法又称为 _短语结构文法__文法。 29.一个文法所描述的语言是_唯一的__。 30. _中间代码生成___和代码优化部分不是每个编译程序都必需的。 31._解释程序和编译程序___是两类程序语言处理程序。 32.数组的内情向量中肯定不含有数组的_维数___的信息。 33. 一个上下文无关文法 G 包括四个组成部分,它们是:一组非终结符号,一组终结符号,一个开始符号,以及一组__D___。 34.文法分为四种类型,即 0 型、1 型、2 型、3 型。其中 2 型文法是__上下文无关文法__。 35.一个上下文无关文法 G 包括四个组成部分,它们是:一组非终结符号,一组终结符号,一个开始符号,以及一组 __产生式___。 36.__ BASIC ___是一种典型的解释型语言。 37.与编译系统相比,解释系统___比较简单 , 可移植性好 , 执行速度慢__。 38.用高级语言编写的程序经编译后产生的程序叫__目标程序___。 39.编写一个计算机高级语言的源程序后 , 到正式上机运行之前,一般要经过__(1)(2)(3)__这几步: (1) 编辑 (2) 编译 (3) 连接 (4) 运行 40.把汇编语言程序翻译成机器可执行的目标程序的工作是由__编译器__完成的。 41.词法分析器的输出结果是__单词的种别编码和自身值__。 42.文法 G :S→xSx|y 所识别的语言是_ xnyxn(n≥0)___。 43.如果文法 G 是无二义的,则它的任何句子α__最左推导和最右推导对应的语法树必定相同_。 44.构造编译程序应掌握___源程序目标语言编译方法___。 45.四元式之间的联系是通过__临时变量___实现的。 46.表达式( ┐ A ∨B)∧(C∨D)的逆波兰表示为___ A ┐ B∨CD∨∧__。 47. 优化可生成__运行时间短且占用存储空间小___的目标代码。 48.下列__删除多余运算 ____优化方法不是针对循环优化进行的。 49.编译程序使用__说明标识符的过程或函数的静态层次___区别标识符的作用域。 50.编译程序绝大多数时间花在___表格管理__ 上。 51.编译程序是对__高级语言的翻译___。

编译原理实验 中间代码生成

实验四中间代码生成 一.实验目的: 掌握中间代码的四种形式(逆波兰式、语法树、三元式、四元式)。 二.实验内容: 1、逆波兰式定义:将运算对象写在前面,而把运算符号写在后面。用这种表示法表示的表 达式也称做后缀式。 2、抽象(语法)树:运算对象作为叶子结点,运算符作为内部结点。 3、三元式:形式序号:(op,arg1,arg2) 4、四元式:形式(op,arg1,arg2,result) 三、以逆波兰式为例的实验设计思想及算法 (1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。 (2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。 (3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。 (4)如果不是数字,该字符则是运算符,此时需比较优先关系。 做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。 (5)重复上述操作(1)-(2)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。 四、程序代码: //这是一个由中缀式生成后缀式的程序 #include<> #include<> #include<> #include<> #define maxbuffer 64 void main() { char display_out(char out_ch[maxbuffer], char ch[32]); //int caculate_array(char out_ch[32]); static int i=0; static int j=0; char ch[maxbuffer],s[maxbuffer],out[maxbuffer]; cout<<"请输入中缀表达式: ";

编译原理实验 (词法语法分析报告 附源代码

编译原理实验报告 ******************************************************************************* ******************************************************************************* PL0语言功能简单、结构清晰、可读性强,而又具备了一般高级程序设计语言的必须部分,因而PL0语言的编译程序能充分体现一个高级语言编译程序实现的基本方法和技术。PL/0语言文法的EBNF表示如下: <程序>::=<分程序>. <分程序> ::=[<常量说明>][<变量说明>][<过程说明>]<语句> <常量说明> ::=CONST<常量定义>{,<常量定义>}; <常量定义> ::=<标识符>=<无符号整数> <无符号整数> ::= <数字>{<数字>} <变量说明> ::=VAR <标识符>{, <标识符>}; <标识符> ::=<字母>{<字母>|<数字>} <过程说明> ::=<过程首部><分程序>{; <过程说明> }; <过程首部> ::=PROCEDURE <标识符>; <语句> ::=<赋值语句>|<条件语句>|<当循环语句>|<过程调用语句> |<复合语句>|<读语句><写语句>|<空> <赋值语句> ::=<标识符>:=<表达式> <复合语句> ::=BEGIN <语句> {;<语句> }END <条件语句> ::= <表达式> <关系运算符> <表达式> |ODD<表达式> <表达式> ::= [+|-]<项>{<加法运算符> <项>} <项> ::= <因子>{<乘法运算符> <因子>} <因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’ <加法运算符> ::= +|- <乘法运算符> ::= *|/ <关系运算符> ::= =|#|<|<=|>|>= <条件语句> ::= IF <条件> THEN <语句> <过程调用语句> ::= CALL 标识符 <当循环语句> ::= WHILE <条件> DO <语句> <读语句> ::= READ‘(’<标识符>{,<标识符>}‘)’ <写语句> ::= WRITE‘(’<表达式>{,<表达式>}‘)’ <字母> ::= a|b|…|X|Y|Z <数字> ::= 0|1|…|8|9 【预处理】 对于一个pl0文法首先应该进行一定的预处理,提取左公因式,消除左递归(直接或间接),接着就可以根据所得的文法进行编写代码。 【实验一】词法分析 【实验目的】给出PL/0文法规,要求编写PL/0语言的词法分析程序。 【实验容】已给PL/0语言文法,输出单词(关键字、专用符号以及其它标记)。

完整版编译原理名词解释

1. 源语言:书写源程序所使用的语言 2. 源程序:用程序设计语言书写的程序 3. 目标语言:计算机的机器指令。目标语言可以是机器语言,也可以是汇编语言, 或者是其他中间语言,但最终结果必是机器语言。 4. 目标程序:由机器指令构成的程序。目标程序是经过翻译程序加工后用目标语言 表示的程序。 5. 翻译程序:能够把某一种语言程序(源程序)改造成另一种语言程序(目标程序)将 源程序译成逻辑上等价的目标程序的程序。翻译程序有两种工作方式:编译和解释。 6. 编译程序:也称翻译程序 7. 解释程序:有些翻译程序在翻译过程中并不产生完整的目标程序,而是翻译一句, 解释执行一句,这样的称为解释程序。 8. 汇编程序:由汇编语言写成的程序 9. 词法分析:执行词法分析的程序成为词法分析器,词法分析依据的是语言构词规 则。词法分析器从文件读入源程序,由字符拼接单词。每当识别出一个单词,词法分析器就输出这个单词的内部码。 10. 语法分析:执行语法分析的程序叫做语法分析器。语法分析的任务就是根据语言 的规则,将词法分析器所提供的单词种别分成各类语法范畴。 11. 中间代码生成:中间代码产生有时称为语义分析,执行中间代码产生的程序称为 中间代码生成器。他的任务时按照语法分析器所识别出的语法范畴产生相应的中间代码,并建立符号表、常数表,等各种表格。 12. 目标代码生成:执行目标代码生成的程序称为目标代码生成器。他的任务是根据 中间代码和表格信息,确定各类数据在内存中的位置,选择合适的指令代码,将中间代码翻译成汇编语言或机器指令,这部分工作与计算机硬件有关。 13. 符号表:用于记录源程序中出现的标识符,一个标识符往往具有一系列的语义 值,她包括标识符的名称、种属、类型、值存放的地址等等。 14. 常数表:用于记录在源程序中出现的常数。 15. 编译程序前端:是由词法分析器、语法分析器和中间代码产生器组成的。她的特 点是依赖于被编译的源程序,输出结果用中间代码描述,和目标机器无关。16. 编译程序后端:是由目标代码生成器组成,他的特点是和源程序无关,以中间代 码形式的源程序为输入进行处理,输出结果依赖于目标机器。 17. 文本文件:文本文件的内容由94个图形字符‘!‘-' ~ '(33-126)和4个 控制字符换行(10)、回车(13)、空格(32)、TAB( 9)构成,文本文件又称为 ASCII码文件,扩展名通常为TXT,文件尾用控制字符EOF( 26)指示。 18. 二进制文件:由机器指令即二进制数构成,因二进制数可能是26 (文件结束控制 符),故文件尾用文件长度(文件的字节数)指示,扩展名通常为EX E。 19. 源代码(source code)—预处理器(preprocessor) —编译器(compiler) —汇编程序 (assembler)—目标代码(object code)—链接器(Linker) —可执行程序 (executables) 20. 编译程序的流程是: 源程序―》词法分析―》语法分析―》语义分析(中间代码产生)―》目标 代码生成-》目标程序

编译原理习题及答案

第一章 1、将编译程序分成若干个“遍”是为了。 a.提高程序的执行效率 b.使程序的结构更加清晰 c.利用有限的机器内存并提高机器的执行效率 d.利用有限的机器内存但降低了机器的执行效率 2、构造编译程序应掌握。 a.源程序b.目标语言 c.编译方法d.以上三项都是 3、变量应当。 a.持有左值b.持有右值 c.既持有左值又持有右值d.既不持有左值也不持有右值 4、编译程序绝大多数时间花在上。 a.出错处理b.词法分析 c.目标代码生成d.管理表格 5、不可能是目标代码。 a.汇编指令代码b.可重定位指令代码 c.绝对指令代码d.中间代码 6、使用可以定义一个程序的意义。 a.语义规则b.语法规则 c.产生规则d.词法规则 7、词法分析器的输入是。 a.单词符号串b.源程序 c.语法单位d.目标程序 8、中间代码生成时所遵循的是- 。 a.语法规则b.词法规则 c.语义规则d.等价变换规则 9、编译程序是对。 a.汇编程序的翻译b.高级语言程序的解释执行 c.机器语言的执行d.高级语言的翻译 10、语法分析应遵循。 a.语义规则b.语法规则 c.构词规则d.等价变换规则 二、多项选择题 1、编译程序各阶段的工作都涉及到。 a.语法分析b.表格管理c.出错处理 d.语义分析e.词法分析 2、编译程序工作时,通常有阶段。 a.词法分析b.语法分析c.中间代码生成 d.语义检查e.目标代码生成 三、填空题 1、解释程序和编译程序的区别在于。 2、编译过程通常可分为5个阶段,分别是、语法分析、代码优化和目标代码生成。 3、编译程序工作过程中,第一段输入是,最后阶段的输出为程序。 4、编译程序是指将程序翻译成程序的程序。 单选解答 1、将编译程序分成若干个“遍”是为了使编译程序的结构更加清晰,故选b。 2、构造编译程序应掌握源程序、目标语言及编译方法等三方面的知识,故选d。 3、对编译而言,变量既持有左值又持有右值,故选c。 4、编译程序打交道最多的就是各种表格,因此选d。 5、目标代码包括汇编指令代码、可重定位指令代码和绝对指令代码3种,因此不是目标代码的只能选d。 6、词法分析遵循的是构词规则,语法分析遵循的是语法规则,中间代码生成遵循的是语义规则,并且语义规则可以定义一个程序的意义。因此选a。 7、b 8、c 9、d 10、c 多选解答 1.b、c 2. a、b、c、e 填空解答

编译原理实验-递归下降分析资料报告器地设计(含源代码和运行结果)

《编译原理》实验报告 实验3 递归下降分析器的设计 学号班级计科1001班 时间:2012/4/15 地点:文波 同组人:无 指导教师:朱少林 实验目的 使用递归子程序法设计一个语法分析程序,理解自顶向下分析方法的原理,掌握手工编写递归下降语法分析程序的方法。 实验容 a.运用所学知识,编程实现递归下降语法分析程序。使用递归下降分析算法分析表达式 是否符合下文法: exp →exp addop term | term Addop →+ | - term→term mulop factor | factor mulop →* | / factor →(exp) | id | number 其中number可以是多位的十进制数字串(整数即可),因此这里还需要一个小的词法分析器来得到id 和number的值。 b.从数据文件中读出符号串,输出表达式并给出其正误评判。 实验数据文件中应该有多个表达式,可能有正确的也应该有错误的表达式;表达式有形式简

单的也应该有复杂的。每个表达式写在一行,以回车结束。 实验环境 软件:VC++6.0 实验前准备 1、方案设计: ①准备模拟数据:本实验中使用“work..cpp” ②程序思想: 为了使用递归向下的分析,为每个非终结符根据其产生式写一个分析程序,由于写入读出的操作频繁。所以程序中还有一个match(char t)函数,该函数是将字符写入文件打印输出同时从文件中读取下一个字符,而由于id和number可能是多个字符构成,故写了number()和id()来分析数字和标识符,它们的功能仅仅是把整个number或id完整的读取出来并写入文件,打印输出。 由于分析的文件中可能出现非法字符,而一旦发现非法字符就无需再接着分析,所以在每次读取一个字符时调用islegal函数判断是否是合法字符,并返回0或1. 在main()函数中,while((lookahead=='\n'||lookahead==' ')&&lookahead!=EOF) fscanf(resource,"%c",&lookahead); 是为了忽略分析文件中的换行或空格,之后进入分析阶段,根据返回值判断是否是合法的表达式。在该程序中只有发现了非法字符才会返回0,否则就返回1,而对于合法的表达式,递归程序最后分析的字符就是换行符,不合法的表达式在未分析到换行符就会停止分析,所以根据最后分析的字符是否为换行符进一步确定是否为合法的表达式。

Linux交叉编译环境

开发编译环境 1.交叉编译器的安装,与使用 以ubuntu-14.04.4-desktop-amd64 为例 将附录1的arm_toolchain.tar.gz 选择一个目录COPY过去,(此处以/opt为例) tar zxvf arm_toolchain.tar.gz 修改~/.bashrc 在最后一行添加 将/opt/X3改成你解压的所在目录即可 source ~/.bashrc 在终端查看是否正确,输入arm后按TAB键若出现 安交叉编译器安装正确 若不添加该环境变量,则在使用该编译器时,请使用绝对路径 如: 部分LINUX操作系统,可能存在所需的库并未安装,在编译时若提示未能找到相关库,请自行搜索该库的相应安装 若出现 arm-Linux-gcc /usr/local/arm/4.3.2/bin/arm-linux-gcc: 行3: /usr/local/arm/4.3.2/bin/arm-none-linux-gnueabi-gcc: 没有那个文件或目录(No such file or directory) 且进入external-toolchain/bin/ 直接运行./ arm-none-linux-gnueabi-gcc出现同样提示,则可能原因是64位系统需要安装32位相应库 解决方法: 方法一: sudo apt-get install lib32z1 方法二: sudo apt-get install g++-multilib 方法三: $ sudo dpkg --add-architecture i386 $ sudo apt-get update $ sudo apt-get install ia32-libs (工具:附录1-arm_toolchain.tar.gz)

相关主题