合肥工业大学编译原理 LL(1)自上而下文法分析

合肥工业大学编译原理 LL(1)自上而下文法分析
合肥工业大学编译原理 LL(1)自上而下文法分析

合肥工业大学计算机与信息学院计算机系2013级

编译原理课程设计报告

姓名:马骏

专业年级:信息安全13-1

学号:2013211869

提交时间:2016年07月

一、实验题目

自上而下的LL(1)文法分析

二、实验目的

了解掌握自上而下的LL(1)文法分析过程。

二、实验内容与要求

从语法分析树构造句型所有的推导的程序实现,接受用户任意输入的一个句型的语法分析树(其表示存于指定文件中),生成该语法分析树中包含的该句型的所有推导(显示输出)。构造一程序,实现教材P.78的FIRST(X)集合的构造算法。对任一给定的文法G,程序输出所有非终结符P的FIRST(P)。构造一程序,实现教材P.78的FIRST(X)集合的构造算法。对任一给定的文法G,程序输出所有非终结符P的FIRST(P)。在此基础上,构造一程序,实现教材P.79的FOLLOW(A)集合的构造算法。对任一给定的文法G,程序输出所有非终结符A的FOLLOW (A)。对于给定的一个LL(1)文法,假定所有非终结符号P的集合FIRST(P)和集合FOLLOW(P)都已知,构造其预测分析表(实现教材P.79给出的预测分析表构造算法)。对教材P.79给出的例4.7构造出预测分析表。程序显示输出预测分析表或输出到指定文件中。首先实现集合FIRST(X)构造算法和集合FOLLOW(A)构造算法,再实现教材P.79给出的预测分析表构造算法。程序显示输出预测分析表或输出到指定文件中。

对文法按教材P.76表4.1构造出G的预测分析程序,程序显示输出如P.78那样的匹配过程。

三、实验环境与工具

操作系统:Windows 7

开发语言:C++

四、开发过程

1)字符要求:

你的程序必须能够根据以下字符来处理语法:

- 终端字符:字母,数字,符号例如“+”,“—”,…;

- 非终端字母表中的大写字母。

符号“=”,“|”和“#”(替换“ε”,因为它更容易输入到文本文件)被保留用于语法的描述中,因此不能被用作终端。

2)初始状态

您的程序通过读取一个文件中的“文本”格式开始。

这个文件的结构可以随意构建,不做要求,但建议做成简单的

例如,程序描述以下语句:

E = E + T |T

T = T * F |F

F =(E)| 0 |1

在这种情况,我们可以很容易确定E,T和F是非终端,而符号“(”,“)”,“*”和“+”和数字“0”和“1”是在终端。

第一个非终端(第一衍生物)被认为是语法的公理。

结果必须存储在内存中,是一个您所选择的数据结构。然后,使用一个函数再取出数据,存储在内存中并屏幕上显示(以你选择的格式)。

在上面的图中,并在下文中,右列显示的程序的执行的过程,并左栏表示中使用的数据结构。

这些都是明显的例子。你可以使用任何你想要的格式。

3)消除传递

判断你的程序是否包含一个传递关系或没有。如果包含,递归应该被消除。

显示在屏幕

过程

文本结构(在内存中)

消除传递关系

遍历语句

判断:是否包含左传递

没有发现传递关系

发现传递关系

指向自己的判断:

您可以创建一个新的数据结构语句来表示其中传递关系已被删除,这有利于进一步加工。

在这种情况下,如果语法不包含判定递归的语句,程序当然必须使用第二数据结构的副本。

3)计算“first集”和“follow集”的集合

为了产生一个分析器,你现在必须计算,每个分支,“第一个”和“其后”的集合·。

结果被存储在数据结构,再次“你的选择。”

然后,这些集合被显示在屏幕上

图注释:Calcul des ensembles ? premiers ? et ? suivants ? 计算“第一个”和“其后”的集合Affichage des ensembles 显示集合premiers 第一个suivants其后

4)分析表的结构

具有非递归语法以及“第一个”和“其后”的集合,你的程序现在可以建立预测分析表。结果以表的形式显示在屏幕上。

图注释:Construction de la table d’analyse分析表的结构

table d’analyse 分析表Affichage de la table d’analyse 显示分析表

输入字符串的分析

最后一步:你的程序读取输入(键盘)的表达和分析。指出,结果是否符合语法。你要尽可能准确的鉴定结果:定位错误在没有辨认出表达式的情况下。

其次,你的程序必须能够完成对输入多个字符串作为输入,不要忘记重新启动你的程序。

五、程序实现

读取表达式

判断是否继续

六、程序代码

/*

不支持规则源文件中有空格

注意使用#表示空产生式使用$表示结束符#

*/

#include

#include

#include

#include

using namespace std;

const char* sourcefile="ma_grammaira.txt"; //定义源文件//const int max=100;

#define max 100

class sign

{

public:

sign(){}

sign(int check,char fu)

{

if(check!=0&&check!=1) //符号属性只有0和1

{

cout<<"error sign creat!"<

}

else

{

identity=check; //设置符号属性

id=fu; //设置非终结符符号

funnumber=0;//设置符号规则数为0

firstnumber=0;

follownumber=0;

}

}

void add(string sl)//添加产生规则

{

fun[funnumber]=sl;

funnumber++;

}

void pop(int q)//删除某一规则

{

if(q>=funnumber||q<0)

{

cout<<"error wrong delete fun in sign!";

return;

}

for(int x=q;x

fun[x]=fun[x+1];

funnumber--;

}

void pop_first(char q)//从first集删除某一节点{

for(int x=0;x

{

if(first[x]==q)

{

for(int y=x;y

first[y]=first[y+1];

firstnumber--;

x--;//为了接着上次检查点

}

}

}

void pop_follow(char q)//从first集删除某一节点{

for(int x=0;x

{

if(follow[x]==q)

{

for(int y=x;y

follow[y]=follow[y+1];

follownumber--;

x--;//为了接着上次检查点

}

}

}

void add_first(char q)//向first添加元素

{

for(int x=0;x

{

if(first[x]==q)return;

}

first[firstnumber]=q;

firstnumber++;

}

void add_follow(char q)//向follow添加元素

{

for(int x=0;x

{

if(follow[x]==q)return;

}

follow[follownumber]=q;

follownumber++;

}

int identity; //符号属性0为非终结符1为终结符char id; //符号

string fun[max];//符号产生规则

int funnumber; //符号产生规则数量

char first[max];//first集

int firstnumber;

char follow[max];//follow集

int follownumber;

};

class cell //分析表的单元格结构

{

public: char cell_unendsign;//终结符

char cell_endsign;//非终结符

string cell_fun;//产生式

};

cell table[max][max]; //分析表数据结构

int table_unend_number;//非终结符数

int table_end_number;//终结符数

sign unendsign[max];//非终结点集合

int unendsignnumber=0;

sign endsign[max];//终结点集合

int endsignnumber=0;

void readsource(const char*sf) //读取源文件ma_grammaira.txt

{

int x;

unendsignnumber=0;

endsignnumber=0;

ifstream ifs;

ifs.open(sourcefile);

char buf[max];

for(x=0;x

buf[x]='\0';

while(ifs.getline(buf,sizeof(buf))) //一行一行读取

{

unendsign[unendsignnumber]=sign(0,buf[0]);

unendsignnumber++;

string rule;

for(int x=2;x

{

if(buf[x]=='\0')

{

break;

}

if(buf[x]=='|')

{

// cout<

unendsign[unendsignnumber-1].fun[unendsign[unendsignnumber-1].funnumber]=rule;//规则放在每个非终结符实例中

unendsign[unendsignnumber-1].funnumber++;

rule="";

continue;

}

rule+=buf[x];

char kk=buf[x];

}

unendsign[unendsignnumber-1].fun[unendsign[unendsignnumber-1].funnumber]=rule;

unendsign[unendsignnumber-1].funnumber++;

// cout<

}

}

void addendsign(char sg) //添加终结符

{

for(int x=0;x

{

if(endsign[x].id==sg)

return;

}

endsign[endsignnumber].id=sg;

endsign[endsignnumber].identity=1;

endsignnumber++;

}

void dealend()//由非终结符产生式得到终结符

{

for(int x=0;x

{

for(int y=0;y

{

for(int z=0;z

{

char kk=unendsign[x].fun[y][z];

if(int(kk)>=65&&int(kk)<=90)continue; //A到Z为非终结符

else addendsign(kk);

}

}

}

}

bool exit_endsign(char sg) //终结符表是否有sg

{

int x;

for(x=0;x

{ if(endsign[x].id==sg)

return true;

}

return false;

}

bool exit_unendsign(char sg) //非终结符表是否有sg

{

for(int x=0;x

{

if(unendsign[x].id==sg)

return true;

}

return false;

}

sign get_unendsign(char sg)//从非终结符表中得到非终结符为sg的实例

{

for(int x=0;x

{

if(unendsign[x].id==sg)return unendsign[x];

}

cout<<"error get no unend sign!"<

sign er;

return er;

}

int get_unendsign_number(char sg)//从非终结符表中得到非终结符为sg的下标

{

for(int x=0;x

{

if(unendsign[x].id==sg)return x;

}

cout<<"error get no unend sign!"<

return 0;

}

int get_endsign_number(char sg)//从非终结符表中得到终结符为sg的下标

{

for(int x=0;x

{

if(endsign[x].id==sg)return x;

}

cout<<"error get no end sign!"<

return 0;

}

bool rule_first_check(sign m_sign,char sg)//查看非终结符实例m_sign 产生式首是否为sg {

int y;

for(y=0;y

{

if(m_sign.fun[y][0]==sg) return true;

}

int check=0;

for(y=0;y

{

if(exit_unendsign(m_sign.fun[y][0]))

{

sign msg=get_unendsign(m_sign.fun[y][0]);

if(rule_first_check(msg,sg))

{

check=1;

break;

}

}

}

if(check)return true;

else return false;

}

bool check_L_recursion()//检查是否含有直接左递归和传递左递归true表示有false表示没有

{

int x,y;

for(x=0;x

{

for(y=0;y

{

if(unendsign[x].fun[y][0]==unendsign[x].id) return true;

}

}

for(x=0;x

{

if(rule_first_check(unendsign[x],unendsign[x].id))

return true;

}

return false;

}

sign new_unendsign() //创建一个新非终结符即用于规则p=p..... 需要p'

{

char a=65;

while(1)

{

if(a>90||unendsignnumber>26)

{

cout<<"error no more size for unend sign!"<

break;

}

int check=1;

for(int x=0;x

{

if(unendsign[x].id==a)

{

a++;

check=0;

break;

}

}

if(check)

{

unendsign[unendsignnumber].id=a;

unendsign[unendsignnumber].identity=0;

unendsignnumber++;

break;

}

}

return unendsign[unendsignnumber-1];

}

void pop_unendsign(char sg) //删除某一非终结符

{

for(int x=0;x

{

if(unendsign[x].id==sg)

{

for(int y=x;y

unendsign[y]=unendsign[y+1];

unendsignnumber--;

return;

}

}

cout<<"error no unend sign for pop"<

return;

}

void deal_direct_L_recursion(int thisnumber) //消除unendsign[thisnumber]的直接左递归在deal_L_total_recursion()中调用

{

int i;

if(!check_L_recursion())

return;

int check=0;

for(i=0;i

{

if(unendsign[thisnumber].fun[i][0]==unendsign[thisnumber].id)

{

check=1;

break;

}

}

if(check)

{

new_unendsign();

int kp=unendsignnumber-1;

for(i=0;ib0p'|b1p'

{

if(unendsign[thisnumber].fun[i][0]==unendsign[thisnumber].id)

{

string ss="";

for(int x=1;x

ss+=unendsign[thisnumber].fun[i][x];

if(ss=="#")

{

cout<<"error can't deal whith P->P# "<

return;

}

ss=ss+unendsign[kp].id;

unendsign[kp].add(ss);

}

else

{

if(unendsign[thisnumber].fun[i]!="#")

{

unendsign[thisnumber].fun[i]=unendsign[thisnumber].fun[i]+unendsign[kp].id;

}

if(unendsign[thisnumber].fun[i]=="#")

{

string ss="";

ss+=unendsign[kp].id;

unendsign[thisnumber].add(ss);

}

}

}

unendsign[kp].add("#");//为p'增加p-># 的规则

for(i=0;ip... 的产生式

{

if(unendsign[thisnumber].fun[i][0]==unendsign[thisnumber].id)

{

unendsign[thisnumber].pop(i);

i=0;

}

}

}

}

void deal_L_total_recursion()//消除所有左递归

{

int i,j,t,k,qq;

for(i=0;i

{

for(j=0;j

{

for( t=0;t

{

if(unendsign[i].fun[t][0]==unendsign[j].id)

{

string say="";

for( k=1;k

say+=unendsign[i].fun[t][k];

unendsign[i].pop(t);

for( qq=0;qq

{

string sp=unendsign[j].fun[qq];

if(sp!="#")

{

sp+=say;

unendsign[i].add(sp);

}

}

}

}

}

deal_direct_L_recursion(i); //消除Pi 的直接左递归}

}

void deal_first_club()//求各节点的first集

{

int x,t;

for(x=0;x

{

endsign[x].add_first(endsign[x].id);

}

int check=1;

while(check)

{

check=0;

for(x=0;x

{

int oldnumber=unendsign[x].firstnumber; //用于记录first集是否再增大

for(t=0;t

{

unendsign[x].add_first(unendsign[x].fun[t][0]);

}

for(t=0;t

{

if(exit_unendsign(unendsign[x].first[t]))

{

int kp=get_unendsign_number(unendsign[x].first[t]);

for(int q=0;q

{

if(unendsign[kp].first[q]!='#')

unendsign[x].add_first(unendsign[kp].first[q]);

}

}

}

if(unendsign[x].firstnumber!=oldnumber)check=1;

}

}

check=1;

while(check)

{

check=0;

for(x=0;x

{

for(int y=0;y

{

int overcheck=1;

for(int t=0;t

{

if(exit_unendsign(unendsign[x].fun[y][t]))continue;

else

{

overcheck=0;

break;

}

}

if(overcheck)//如果存在P->ABCD.....

{

int thischeck=1;

for(int t=0;t

{

int oop=get_unendsign_number(unendsign[x].fun[y][t]);

int incheck=0;

for(int z=0;z

{

if(unendsign[oop].first[z]=='#')

{

incheck=1;

break;

}

}

if(incheck) continue;

else

{

thischeck=0;

break;

}

}

if(thischeck)

{

int sp=unendsign[x].firstnumber;

unendsign[x].add_first('#');

if(sp!=unendsign[x].firstnumber) check=1;

}

}

}

}

}

for(x=0;x

{

for(int y=0;y

{

if(exit_unendsign(unendsign[x].first[y]))

{

unendsign[x].pop_first(unendsign[x].first[y]);

y--;

}

}

}

}

void deal_follow_club() //求每个非终结符的follow集

{

int x,y,z,t;

unendsign[0].add_follow('$');//在开始符号的follow集中添加结束符$

int check=1;

while(check) //循环至follow集不在增大

{

check=0;

for(x=0;x

{

for( y=0;y

{

for( z=0;z

{

if(exit_unendsign(unendsign[x].fun[y][z])&&z...Aa...

{

int kp=get_unendsign_number(unendsign[x].fun[y][z]);

int ss=unendsign[kp].follownumber;

if(unendsign[x].fun[y][z+1]!='#')

unendsign[kp].add_follow(unendsign[x].fun[y][z+1]);

if(unendsign[kp].follownumber!=ss)

check=1;

}

if(z==unendsign[x].fun[y].length()-1&&exit_unendsign(unendsign[x].fun[y][z])) //p->....B

{

int kp=get_unendsign_number(unendsign[x].fun[y][z]);

for(t=0;t

{

int ssp=unendsign[kp].follownumber;

unendsign[kp].add_follow(unendsign[x].follow[t]);

if(unendsign[kp].follownumber!=ssp)

check=1;

}

}

if(exit_unendsign(unendsign[x].fun[y][z])&&z

{

int thischeck=1; // 判断p->....SABC 其中#在ABC的first集中

for(int i=z+1;i

{

if(exit_unendsign(unendsign[x].fun[y][i]))

{

int thisthischeck=0;

int kp=get_unendsign_number(unendsign[x].fun[y][i]);

for(int pp=0;pp

{

if(unendsign[kp].first[pp]=='#')

编译原理课程设计-词法语法分析器

编译原理课程设计Course Design of Compiling (课程代码3273526) 半期题目:词法和语法分析器 实验学期:大三第二学期 学生班级:2014级软件四班 学生学号:2014112218 学生姓名:何华均 任课教师:丁光耀 信息科学与技术学院 2017.6

课程设计1-C语言词法分析器 1.题目 C语言词法分析 2.内容 选一个能正常运行的c语言程序,以该程序出现的字符作为单词符号集,不用处理c语言的所有单词符号。 将解析到的单词符号对应的二元组输出到文件中保存 可以将扫描缓冲区与输入缓冲区合成一个缓冲区,一次性输入源程序后就可以进行预处理了 3.设计目的 掌握词法分析算法,设计、编制并调试一个词法分析程序,加深对词法分析原理的理解 4.设计环境(电脑语言环境) 语言环境:C语言 CPU:i7HQ6700 内存:8G 5.概要设计(单词符号表,状态转换图) 5.1词法分析器的结构 词法分析程序的功能:

输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 词法分析程序可以单独为一个程序;也可以作为整个编译程序的一个子程序,当需要一个单词时,就调用此法分析子程序返回一个单词. 为便于程序实现,假设每个单词间都有界符或运算符或空格隔开,并引入下面的全局变量及子程序: 1) ch 存放最新读进的源程序字符 2) strToken 存放构成单词符号的字符串 3) Buffer 字符缓冲区 4)struct keyType 存放保留字的符号和种别 5.2待分析的简单词法 (1)保留字 break、case、char、const、int、do、while… (2)运算符和界符 = 、+、-、* 、/、%、,、;、(、)、?、# 5.3各种单词符号对应的种别码

唐益明的简介(合肥工业大学副研究员)_2015年6月

唐益明 合肥工业大学副研究员,博士,硕士生导师,CCF会员、IEEE会员. 学术兼职: 中国计算机学会多值逻辑与模糊逻辑专业委员会委员 中国计算机学会协同计算专业委员会委员 中国人工智能学会粗糙集与软计算专业委员会委员 Associate Editor: Journal of Mathematics and Informatics 审稿人:1) IEEE Transactions on Fuzzy Systems (SCI) 2) Information Sciences (SCI) 3) ISPRS Journal of Photogrammetry and Remote Sensing (SCI) 4) International Journal of Electrical Power & Energy Systems (SCI) 5) Signal Processing (SCI) 6) International Journal of fuzzy Systems (SCI) 7) 计算机学报(EI)主要论著 [1] Yiming Tang, Xiaoping Liu. Differently implicational universal triple I method of (1, 2, 2) type. Computers & Mathematics with Applications, 2010. (SCI, EI) [2] Xiaoping Liu, Yiming Tang, et al. A formal model of collaborative discussion for problem-solving. Chinese Journal of Electronics, 2012. (SCI,EI) [3] Yiming Tang, Fuji Ren, et al. Differently implicational α-universal triple I restriction method of (1, 2, 2) type. Journal of Systems Engineering and Electronics, 2012. (SCI,EI) [4] Yiming Tang, Fuji Ren. Universal triple I method for fuzzy reasoning and fuzzy controller. Iranian Journal of Fuzzy Systems, 2013. (SCI)[1-2] 目录 1简历 2研究方向 3学术兼职 4主要论著 5教学情况 1简历 唐益明,男,1982年出生,合肥工业大学副研究员,博士,硕士生导师,CCF多值逻辑与模糊逻辑专业委员会委员,CCF协同计算专业委员会委员,CAAI

编译原理语法分析实验报告

编译原理语法分析实验报告 - 班级:XXX 学号:XXX 姓名:XXX 年月日 1、摘要: 用递归子程序法实现对pascal的子集程序设计语言的分析程序 2、实验目的: 通过完成语法分析程序,了解语法分析的过程和作用 3、任务概述 实验要求:对源程序的内码流进行分析,如为文法定义的句子输出”是”否则输出”否”,根据需要处理说明语句填写写相应的符号表供以后代码生成时使用 4、实验依据的原理 递归子程序法是一种自顶向下的语法分析方法,它要求文法是LL(1)文法。通过对文法中每个非终结符编写一个递归过程,每个过程的功能是识别由该非终结符推出的串,当某非终结符的产生式有多个候选式时,程序能够按LL(1)形式唯一地确定选择某个候选式进行推导,最终识别输入串是否与文法匹配。 递归子程序法的缺点是:对文法要求高,必须满足LL(1)文法,当然在某些语言中个别产生式的推导当不满足LL(1)而满足LL(2)时,也可以采用多向前扫描一个符号的办法;它的另一个缺点是由于递归调用多,所以速度慢占用空间多,尽管这样,它还是许多高级语言,例如PASCAL,C等编译系统常常采用的语法分析方法。

为适合递归子程序法,对实验一词法分析中的文法改写成无左递归和无左共因子的,,,如下: <程序>?<程序首部><分程序>。 <程序首部>?PROGRAM标识符; <分程序>?<常量说明部分><变量说明部分><过程说明部分> <复合语句> <常量说明部分>?CONST<常量定义><常量定义后缀>;|ε <常量定义>?标识符=无符号整数 <常量定义后缀>?,<常量定义><常量定义后缀> |ε <变量说明部分>?VAR<变量定义><变量定义后缀> |ε <变量定义>?标识符<标识符后缀>:<类型>; <标识符后缀>?,标识符<标识符后缀> |ε <变量定义后缀>?<变量定义><变量定义后缀> |ε <类型>?INTEGER | LONG <过程说明部分>?<过程首部><分程序>;<过程说明部分后缀>|ε <过程首部>?PROCEDURE标识符<参数部分>; <参数部分>?(标识符: <类型>)|ε <过程说明部分后缀>?<过程首部><分程序>;<过程说明部分后缀>|ε <语句>?<赋值或调用语句>|<条件语句>|<当型循环语句>|<读语句> |<写语句>|<复合语句>|ε <赋值或调用语句>?标识符<后缀> <后缀>?:=<表达式>|(<表达式>)|ε <条件语句>?IF<条件>THEN<语句> <当型循环语句>?WHILE<条件>DO <语句> <读语句>?READ(标识符<标识符后缀>)

编译原理词法分析器语法分析器实验报告

编译技术 班级网络0802 学号3080610052姓名叶晨舟 指导老师朱玉全2011年 7 月 4 日

一、目的 编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。 二、任务及要求 基本要求: 1.词法分析器产生下述小语言的单词序列 这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表: 单词符号种别编码助记符内码值 DIM IF DO STOP END 标识符 常数(整)= + * ** , ( )1 2 3 4 5 6 7 8 9 10 11 12 13 14 $DIM $IF $DO $STOP $END $ID $INT $ASSIGN $PLUS $STAR $POWER $COMMA $LPAR $RPAR - - - - - - 内部字符串 标准二进形式 - - - - - - 对于这个小语言,有几点重要的限制: 首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。例如,下面的写法是绝对禁止的: IF(5)=x 其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。也就是说,对于关键字不专设对应的转换图。但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。 再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。例如,一个条件语句应写为

合肥工业大学期末复习

第一章 一、信息经济学的产生 起源于(1959)年马尔萨克的《信息经济学评论》 施蒂格勒——被誉为“信息经济学”和“管制经济学”的创始人。《信息经济学》、《劳动市场的信息》(1962)和《论寡占》 提出“搜寻”概念及其理论方法——施蒂格勒对微观信息经济学的主要贡献。 肯尼思·阿罗——无论何种信息共同具备两个明显特征:信息的使用具有不可分割性、信息难以被独占或垄断。 詹姆斯·莫里斯——经济激励机制问题,建立起(委托人—代理人)关系的基本模型,奠定了委托-代理关系的基本模型框架。 施蒂格利兹——对不完全信息条件下产品市场、资本市场和保险市场中经济行为的分析、信息在社会资源配置中的作用(特别是不利选择和道德风险导致的市场失败问题),以及微观信息市场分析三个领域 笼统地说,信息经济学就是研究经济行为中的信息现象及其规律的学科。 2、直至20世纪20年代。1921年,弗兰克·奈特对不确定性做了开拓性研究。 3、从假设条件角度分析,不确定性经济学主要研究不确定性形成的基础、方式、经济特征及其影响,同时也考虑如何减少不确定性的损失,但是,这种考虑不是建立在广泛研究信息对不确定性限制的基础上。近似地说,不确定性经济学是一门“被动的”信息经济学。 4、不确定性、风险和信息,构成信息经济学三个最基本的概念。 5、可以应用统计方法计算并预测其发生概率的风险,称为可保风险。不能用统计方法或其他方法计算并预测其发生概率的风险,称为不可保风险。 6、不确定性经济学认为,风险的完全不能转移与风险的完全转移一样,都是不经济的。 7、在现代社会中,没有其他制度能够像保险和股票市场那样通过市场并且以十分明确的形式来转移风险。通过保险市场和社会股票市场,企业一方面能够转移其可保风险,另一方面也可以转移其不可保风险。但是,无论企业或社会如何努力,它们都不可能通过保险市场转移其全部的可保风险,也不可能通过社会股票市场完全转移其不可保风险,因为无论是保险市场还是股票市场都存在着自身的局限。 第二章 1、信息的理论定义可近似地表述为:信息就是传递中的知识差。 2、(1)定义反映了信息发生的基础与过程。或者说,信息就是先验概率与后验概率之差。(2)定义揭示了信息价值的基础所在。信息之所以存在价值,关键在于存在知识差,后者能够使经济代理人改善决策环境而获得预期收益。(3)定义揭示了信息与经济知识增长之间的关系,知识差正是这种关系的中介,同时,知识差概念也显示了经济信息收集与处理活动的意义所在。(4)定义表明:信息具有层次性、不可分性和共享性,这是由知识差的层次性、不可分性和共享性决定的(5)定义说明了噪音、信息失真或误差的根本所在,是知识差在传递过程中必然存在绝对的损失。 3、信息商品正式得到社会承认的标志是知识产权的专利制度的确定 4、信息必须经过开发,把各类信息经过加工,整理成有序的、有应用价值的、有共享可能的信息才能成为信息资源 5、信息资源的开发和利用既是独立的又是重合的 信息资源开发和利用程度是衡量国家信息化水平的一个重要标志 信息资源的开发和利用是信息产业持续健康发展的根本保证 信息资源的开发利用不是一个一次性的工程建设问题,而是长期服务问题 政府的统计部门适宜做不进入市场竞争的统计信息服务工作,盈利性信息资源的开发利用交由企业做 第三章 1、1、商店的数量、价格的离散幅度构成市场价格离散的主要影响因素,但起决定作用的是价格在商店中离散的概率分布 2、价格离散幅度达的市场,价格离散率未必比离散幅度小的市场的价格离散率高 3、市场价格离散率不受市场平均价格的影响 2、1 价格离散程度越高,每次搜寻所获节省额就越大,有效搜寻次数就越多。2 购买商品的价格越高,或购买商品的数量越多,就越值得进行搜寻。 第四章 1、在完全竞争的简单模型中,一个生产澄汁的新厂商将会宣布它的产品已经准备好,以市场价格或低于市场价格出

编译原理-编写递归下降语法分析器

学号107 成绩 编译原理上机报告 名称:编写递归下降语法分析器 学院:信息与控制工程学院 专业:计算机科学与技术 班级:计算机1401班 姓名:叶达成 2016年10月31日

一、上机目的 通过设计、编制、调试一个递归下降语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,掌握常用的语法分析方法。通过本实验,应达到以下目标: 1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。 2、掌握词法分析的实现方法。 3、上机调试编出的词法分析程序。 二、基本原理和上机步骤 递归下降分析程序实现思想简单易懂。程序结构和语法产生式有直接的对应关系。因为每个过程表示一个非终结符号的处理,添加语义加工工作比较方便。 递归下降分析程序的实现思想是:识别程序由一组子程序组成。每个子程序对应于一个非终结符号。 每一个子程序的功能是:选择正确的右部,扫描完相应的字。在右部中有非终结符号时,调用该非终结符号对应的子程序来完成。 自上向下分析过程中,如果带回溯,则分析过程是穷举所有可能的推导,看是否能推导出待检查的符号串。分析速度慢。而无回溯的自上向下分析技术,当选择某非终结符的产生时,可根据输入串的当前符号以及各产生式右部首符号而进行,效率高,且不易出错。 无回溯的自上向下分析技术可用的先决条件是:无左递归和无回溯。 无左递归:既没有直接左递归,也没有间接左递归。 无回溯:对于任一非终结符号U的产生式右部x1|x2|…|x n,其对应的字的首终结符号两两不相交。 如果一个文法不含回路(形如P?+ P的推导),也不含以ε为右部的产生式,那么可以通过执行消除文法左递归的算法消除文法的一切左递归(改写后的文法可能含有以ε为右部的产生式)。 三、上机结果 测试数据: (1)输入一以#结束的符号串(包括+—*/()i#):在此位置输入符号串例如:i+i*i# (2)输出结果:i+i*i#为合法符号串 (3)输入一符号串如i+i*#,要求输出为“非法的符号串”。 程序清单: #include #include char str[50]; int index=0; void E(); //E->TX; void X(); //X->+TX | e void T(); //T->FY void Y(); //Y->*FY | e void F(); //F->(E) | i int main() /*递归分析*/ { int len; int m;

编译原理实验报告《LL(1)语法分析器构造》

《LL(1)分析器的构造》实验报告 一、实验名称 LL(1)分析器的构造 二、实验目的 设计、编制、调试一个LL(1)语法分析器,利用语法分析器对符号串的识别,加深对语法分析原理的理解。 三、实验内容和要求 设计并实现一个LL(1)语法分析器,实现对算术文法: G[E]:E->E+T|T T->T*F|F F->(E)|i 所定义的符号串进行识别,例如符号串i+i*i为文法所定义的句子,符号串ii+++*i+不是文法所定义的句子。 实验要求: 1、检测左递归,如果有则进行消除; 2、求解FIRST集和FOLLOW集; 3、构建LL(1)分析表; 4、构建LL分析程序,对于用户输入的句子,能够利用所构造的分析程序进行分析,并显示出分析过程。 四、主要仪器设备 硬件:微型计算机。 软件: Code blocks(也可以是其它集成开发环境)。 五、实验过程描述 1、程序主要框架 程序中编写了以下函数,各个函数实现的作用如下: void input_grammer(string *G);//输入文法G

//将文法G预处理得到产生式集合P,非终结符、终结符集合U、u, int eliminate_1(string *G,string *P,string U,string *GG);//消除文法G中所有直接左递归得到文法GG int* ifempty(string* P,string U,int k,int n);//判断各非终结符是否能推导为空 string* FIRST_X(string* P,string U,string u,int* empty,int k,int n);求所有非终结符的FIRST集 string FIRST(string U,string u,string* first,string s);//求符号串s=X1X2...Xn的FIRST集 string** create_table(string *P,string U,string u,int n,int t,int k,string* first);//构造分析表 void analyse(string **table,string U,string u,int t,string s);//分析符号串s 2、编写的源程序 #include #include #include using namespace std; void input_grammer(string *G)//输入文法G,n个非终结符 { int i=0;//计数 char ch='y'; while(ch=='y'){ cin>>G[i++]; cout<<"继续输入?(y/n)\n"; cin>>ch; } } void preprocess(string *G,string *P,string &U,string &u,int &n,int &t,int &k)//将文法G预处理产生式集合P,非终结符、终结符集合U、u, { int i,j,r,temp;//计数 char C;//记录规则中()后的符号 int flag;//检测到() n=t=k=0; for( i=0;i<50;i++) P[i]=" ";//字符串如果不初始化,在使用P[i][j]=a时将不能改变,可以用P[i].append(1,a) U=u=" ";//字符串如果不初始化,无法使用U[i]=a赋值,可以用U.append(1,a) for(n=0;!G[n].empty();n++) { U[n]=G[n][0]; }//非终结符集合,n为非终结符个数 for(i=0;i

编译原理 语法分析器 (java完美运行版)(精选.)

实验二语法分析器 一、实验目的 通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。有利于提高学生的专业素质,为培养适应社会多方面需要的能力。 二、实验内容 ◆根据某一文法编制调试LL (1 )分析程序,以便对任意输入的符号串 进行分析。 ◆构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分 析程序。 ◆分析法的功能是利用LL(1)控制程序根据显示栈栈顶内容、向前看符号 以及LL(1)分析表,对输入符号串自上而下的分析过程。 三、LL(1)分析法实验设计思想及算法 ◆模块结构: (1)定义部分:定义常量、变量、数据结构。 (2)初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等); (3)控制部分:从键盘输入一个表达式符号串; (4)利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。

四、实验要求 1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。 2、如果遇到错误的表达式,应输出错误提示信息。 3、对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG (2)G->+TG|—TG (3)G->ε (4)T->FS (5)S->*FS|/FS (6)S->ε (7)F->(E) (8)F->i 输出的格式如下:

五、实验源程序 LL1.java import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.sql.*; import java.util.Vector; public class LL1 extends JFrame implements ActionListener { /** * */ private static final long serialVersionUID = 1L; JTextField tf1; JTextField tf2; JLabel l; JButton b0; JPanel p1,p2,p3; JTextArea t1,t2,t3; JButton b1,b2,b3;

编译原理实验报告(语法分析器)

. 编译原理实验专业:13级网络工程

语法分析器1 一、实现方法描述 所给文法为G【E】; E->TE’ E’->+TE’|空 T->FT’ T’->*FT’|空 F->i|(E) 递归子程序法: 首先计算出五个非终结符的first集合follow集,然后根据五个产生式定义了五个函数。定义字符数组vocabulary来存储输入的句子,字符指针ch指向vocabulary。从非终结符E函数出发,如果首字符属于E的first集,则依次进入T函数和E’函数,开始递归调用。在每个函数中,都要判断指针所指字符是否属于该非终结符的first集,属于则根据产生式进入下一个函数进行调用,若first集中有空字符,还要判断是否属于该非终结符的follow集。以分号作为结束符。 二、实现代码 头文件shiyan3.h #include #include

#include using namespace std; #define num 100 char vocabulary[num]; char *ch; void judge_E(); void judge_EE(); void judge_T(); void judge_TT(); void judge_F(); 源文件 #include"shiyan3.h" void judge_E() { if(*ch==';') { cout<<"该句子符合此文法!"<

int a=0; cout<<"按1结束程序"<>a; if(a==1) exit(0); } else if(*ch=='('||*ch=='i') { judge_T(); judge_EE(); } else { cout<<"该句子不匹配此文法!"<>a; if(a==1) exit(0); }

合肥工业大学编译原理 LL(1)自上而下文法分析

合肥工业大学计算机与信息学院计算机系2013级 编译原理课程设计报告 姓名:马骏 专业年级:信息安全13-1 学号:2013211869 提交时间:2016年07月

一、实验题目 自上而下的LL(1)文法分析 二、实验目的 了解掌握自上而下的LL(1)文法分析过程。 二、实验内容与要求 从语法分析树构造句型所有的推导的程序实现,接受用户任意输入的一个句型的语法分析树(其表示存于指定文件中),生成该语法分析树中包含的该句型的所有推导(显示输出)。构造一程序,实现教材P.78的FIRST(X)集合的构造算法。对任一给定的文法G,程序输出所有非终结符P的FIRST(P)。构造一程序,实现教材P.78的FIRST(X)集合的构造算法。对任一给定的文法G,程序输出所有非终结符P的FIRST(P)。在此基础上,构造一程序,实现教材P.79的FOLLOW(A)集合的构造算法。对任一给定的文法G,程序输出所有非终结符A的FOLLOW (A)。对于给定的一个LL(1)文法,假定所有非终结符号P的集合FIRST(P)和集合FOLLOW(P)都已知,构造其预测分析表(实现教材P.79给出的预测分析表构造算法)。对教材P.79给出的例4.7构造出预测分析表。程序显示输出预测分析表或输出到指定文件中。首先实现集合FIRST(X)构造算法和集合FOLLOW(A)构造算法,再实现教材P.79给出的预测分析表构造算法。程序显示输出预测分析表或输出到指定文件中。 对文法按教材P.76表4.1构造出G的预测分析程序,程序显示输出如P.78那样的匹配过程。 三、实验环境与工具 操作系统:Windows 7 开发语言:C++ 四、开发过程 1)字符要求: 你的程序必须能够根据以下字符来处理语法: - 终端字符:字母,数字,符号例如“+”,“—”,…; - 非终端字母表中的大写字母。 符号“=”,“|”和“#”(替换“ε”,因为它更容易输入到文本文件)被保留用于语法的描述中,因此不能被用作终端。 2)初始状态 您的程序通过读取一个文件中的“文本”格式开始。 这个文件的结构可以随意构建,不做要求,但建议做成简单的。 例如,程序描述以下语句: E = E + T |T T = T * F |F F =(E)| 0 |1 在这种情况,我们可以很容易确定E,T和F是非终端,而符号“(”,“)”,“*”和“+”和数字“0”和“1”是在终端。 第一个非终端(第一衍生物)被认为是语法的公理。

编译原理词法分析和语法分析报告 代码(C语言版)

词法分析 三、词法分析程序的算法思想: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 3.1 主程序示意图: 扫描子程序主要部分流程图 其他

词法分析程序的C语言程序源代码: // 词法分析函数: void scan() // 数据传递: 形参fp接收指向文本文件头的文件指针; // 全局变量buffer与line对应保存源文件字符及其行号,char_num保存字符总数。 void scan() { char ch; int flag,j=0,i=-1; while(!feof(fp1)) { ch=fgetc(fp1); flag=judge(ch); printf("%c",ch);//显示打开的文件 if(flag==1||flag==2||flag==3) {i++;buffer[i]=ch;line[i]=row;} else if(flag==4) {i++;buffer[i]='?';line[i]=row;} else if(flag==5) {i++;buffer[i]='~';row++;} else if(flag==7) continue; else cout<<"\n请注意,第"<

编译原理实验报告-合肥工业大学版

编译原理实验报告 合肥工业大学计算机科学与技术 完成日期:2013.6.3 实验一词法分析设计 一、实验功能:

对输入的txt文件内的内容进行词法分析: 由文件流输入test.txt中的内容, 对文件中的各类字符进行词法分析 打印出分析后的结果; 二、程序结构描述:(源代码见附录) 1、利用Key[]进行构造并存储关键字表;利用optr[]进行构造并存储运算符表;利用separator[]进行构造并存储分界符表; 2、bool IsKey(string ss) {}判断是否是关键字函数若是关键字返回true,否则返回false; bool IsLetter(char c) {}判断当前字符是否字母,若是返回true,否则返回false; bool IsDigit(char c) {}判断当前字符是否是数字,若是返回true,否则返回false; bool IsOptr(string ss) {}判断当前字符是否是运算符,若是返回true,否则返回false; bool IsSeparator(string ss) {}判断当前字符是否是分界符,若是返回true,否则返回false; void analyse(ifstream &in) {}分析函数构造; 关系运算符通过switch来进行判断; 三、实验结果

实验总结: 词法分析的程序是自己亲手做的,在实现各个函数时花了不少功夫, 1、要考虑到什么时候该退一字符,否则将会导致字符漏读甚至造成字符重复读取。 2、在实现行数和列数打印时要考虑到row++和line++应该放在什么位置上才可以,如当读取一个\n时line要增加一,而row需要归0处理,在读取某一字符串或字符后row需要加一; 3、对于关系运算符用switch结构进行选择判断即可解决一个字符和两个字符的运算符之间的差异; 4、将自己学过的知识应用到实践中是件不怎么容易的事情,只有亲身尝试将知识转化成程序才能避免眼高手低,对于知识的理解也必将更加深刻。

编译原理-语法分析-算符优先文法分析器

编译原理实验报告 实验名称:编写语法分析分析器实验类型: 指导教师: 专业班级: 学号: 电子邮件: 实验地点: 实验成绩:

一、实验目的 通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。 1、选择最有代表性的语法分析方法,如LL(1) 语法分析程序、算符优先分析程序和LR分析分析程序,至少选一题。 2、选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。 二、实验过程 编写算符优先分析器。要求: (a)根据算符优先分析算法,编写一个分析对象的语法分析程序。读者可根据自己的能力选择以下三项(由易到难)之一作为分析算法中的输入: Ⅰ:通过构造算符优先关系表,设计编制并调试一个算法优先分析程序Ⅱ:输入FIRSTVT,LASTVT集合,由程序自动生成该文法的算符优先关系矩阵。 Ⅲ:输入已知文法,由程序自动生成该文法的算符优先关系矩阵。(b)程序具有通用性,即所编制的语法分析程序能够使用于不同文法以及各种输入单词串,并能判断该文法是否为算符文法和算符优先文法。 (c)有运行实例。对于输入的一个文法和一个单词串,所编制的语法分析程序应能正确地判断,此单词串是否为该文法的句子,并要求输出分析过程。 三、实验结果 算符优先分析器: 测试数据:E->E+T|T T->T*F|F F->(E)|i 实验结果:(输入串为i+i*i+i)

四、讨论与分析 自下而上分析技术-算符优先分析法: 算符文法:一个上下无关文法G,如果没有且没有P→..QR...(P ,Q ,R属于非终结符),则G是一个算符文法。 FIRSTVT集构造 1、若有产生式P →a...或P →Qa...,则a∈FIRSTVT(P)。 2、若有产生式P→...,则FIRSTVT(R)包含在FIRSTVT(P)中。由优先性低于的定义和firstVT集合的定义可以得出:若存在某个产生式:…P…,则对所有:b∈firstVT(P)都有:a≦b。 构造优先关系表: 1、如果每个非终结符的FIRSTVT和LASTVT集均已知,则可构造优先关系表。 2、若产生式右部有...aP...的形式,则对于每个b∈FIRSTVT(P)都有

编译原理LL(1)语法分析实验报告

学号20102798 专业软件工程姓名薛建东 实验日期2013.04.08 教师签字成绩实验报告 【实验名称】LL(1)语法分析 【实验目的】 通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。使了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练掌握开发应用程序的基本方法。 【实验内容】 ◆根据某一文法编制调试LL ( 1)分析程序,以便对任意输入的符号串进行分析。 ◆构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分析程序。 ◆分析法的功能是利用LL(1)控制程序根据显示栈栈顶内容、向前看符号以及LL(1) 分析表,对输入符号串自上而下的分析过程。 【设计思想】 (1)、LL(1)文法的定义 LL(1)分析法属于确定的自顶向下分析方法。LL(1)的含义是:第一个L表明自顶向下分析是从左向右扫描输入串,第2个L表明分析过程中将使用最左推导,1表明只需向右看一个符号便可决定如何推导,即选择哪个产生式(规则)进行推导。 LL(1)文法的判别需要依次计算FIRST集、FOLLOW集和SELLECT集,然后判断是否为LL(1)文法,最后再进行句子分析。 需要预测分析器对所给句型进行识别。即在LL(1)分析法中,每当在符号栈的栈顶出现非终极符时,要预测用哪个产生式的右部去替换该非终极符;当出现终结符时,判断其与剩余输入串的第一个字符是否匹配,如果匹配,则继续分析,否则报错。LL(1)分析方法要求文法满足如下条件:对于任一非终极符A的两个不同产生式A→α,A→β,都要满足下面条件:SELECT(A→α)∩SELECT(A→β)=? (2)、预测分析表构造 LL(1)分析表的作用是对当前非终极符和输入符号确定应该选择用哪个产生式进行推

合肥工业大学编译原理实验

宣城校区 实验报告 课程名称编译原理 专业班级计算机0001班 学生姓名及学号赵保飞 68 指导教师李芒宏 实验地点计算机中心楼第四机房 2017 ~ 2018 学年第一学期

《编译原理》课程实验报告实验名称词法分析设计 姓名赵保飞系院专业计算机科学 与技术 班级 计算机01 班 学号68 实验日期指导教师李芒宏成绩 一、实验目的和要求 通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设 计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的 理解,并能正确地、熟练地运用。 二、实验原理 (1)实验数据结构说明 K[]String数组-关键字表;s[]char数组—分界符;m[]char数组—算术运算符;r[]String数组—关系运算符;ArrayList型String数组ci—常数;ArrayList型String数组id—标识符(2)实验算法描述 (3)算法流程图

三、源程序代码和测试结果 package lexicalAnalysis; import.*; import.*; public class lexicalAnalysis{ static String k[]={"for","main","if","while","void","public","static","printf","scanf","asm","do","return","typedef ","auto","double","break","short","using","default","long"};ength()==1){quals(b))){ display(4,r[i],' ');ength()==2){quals(a))){

编译原理LL(1)语法分析实验报告

学号 20102798 专业软件工程姓名薛建东 实验日期2013.04.08 教师签字成绩 实验报告 【实验名称】LL(1)语法分析 【实验目的】 通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。使了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练掌握开发应用程序的基本方法。 【实验内容】 ◆根据某一文法编制调试LL (1 )分析程序,以便对任意输入的符号串进行分析。 ◆构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分析程序。 ◆分析法的功能是利用LL(1)控制程序根据显示栈栈顶内容、向前看符号以及LL (1)分析表,对输入符号串自上而下的分析过程。 【设计思想】 (1)、LL(1)文法的定义 LL(1)分析法属于确定的自顶向下分析方法。LL(1)的含义是:第一个L表明自顶向下分析是从左向右扫描输入串,第2个L表明分析过程中将使用最左推导,1表明只需向右看一个符号便可决定如何推导,即选择哪个产生式(规则)进行推导。 LL(1)文法的判别需要依次计算FIRST集、FOLLOW集和SELLECT集,然后判断是否为LL(1)文法,最后再进行句子分析。 需要预测分析器对所给句型进行识别。即在LL(1)分析法中,每当在符号栈的栈顶出现非终极符时,要预测用哪个产生式的右部去替换该非终极符;当出现终结符时,判断其与剩余输入串的第一个字符是否匹配,如果匹配,则继续分析,否则报错。LL(1)分析方法要求文法满足如下条件:对于任一非终极符A的两个不同产生式A→α,A→β,都要满足下面条件:SELECT(A→α)∩SELECT(A→β)=? (2)、预测分析表构造 LL(1)分析表的作用是对当前非终极符和输入符号确定应该选择用哪个产生式进行推导。它的行对应文法的非终极符,列对应终极符,表中的值有两种:一是产生式的右部的字符串,一是null。若用M表示LL(1)分析表,则M可表示如下:

合肥工业大学编译原理期末复习

编译原理基础题 一、选择题 1、在使用高级语言编程时,首先可通过编译程序发现源程序的全部( A)错误和部分语义错误。 A、语法 B、语义 C、语用 D、运行 2、编译过程中,语法分析器的任务是( B)。 (1)分析单词是怎样构成的; (2)分析单词串是如何构成语句和说明的; (3)分析语句和说明是如何构成程序的;(4)分析程序的结构 A、(2)(3) B、(2)(3)(4) C、(1)(2)(3) D、(1)(2)(3)(4) 3.生成能被5整除的正整数的文法G[Z]是_ C____。 A. G[Z]: Z→AC,A→BA|B,B→0|1|2|…|9,C→0|5 B. G[Z]: Z→AC,A→BA|ε,B→0|1|2|…|9,C→0|5 C. G[Z]:Z→DA0|A5,A→BA|ε,B→0|D,D→1|2|…|9 D. G[Z]:Z→AC|C,A→BA|B,B→0|1|2|…|9,C→0|5 4、编译程序中的语法分析器接受以( C)为单位的输入,并产生有关信息供以后各阶段使用。 A、表达式 B、产生式 C、单词 D、语句 5、算符优先分析法每次都是对( D)进行归约。 A、直接短语 B、句柄 C、素短语 D、最左素短语 6、过程调用时,参数的传递方法通常有( C )。 (1)传值;(2)传地址;(3)传结果;(4)传名 A、(1)(2) B、(1)(2)(3) C、(1)(2)(4) D、(1)(2)(3)(4) 7、在编译方法中,动态存储分配的含义是( A )。 A、在运行阶段对源程序中的量进行分配 B、在编译阶段对源程序中的量进行分配 C、在编译阶段对源程序中的量进行分配,在运行时这些量的地址可以根据需要改变 D、以上都不对 8、a:= a+b*c↑(d/e)/f的逆波兰记号表示是()。 A、aabc*+↑de/f/:= B、aabcde↑/*f/:= C、aabcde/↑*f/+:= D、以上都不对。 9.算符文法是指 A 的文法。 ①没有形如U→...VW...的规则(U,V,W VN) ②VT中任意两个符号之间至多存在一种算符优先关系

编译原理词法分析和语法分析报告+代码(C语言版)

词法分析 一、实验目的 设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 2.1 待分析的简单的词法 (1)关键字: begin if then while do end 所有的关键字都是小写。 (2)运算符和界符 : = + - * / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义: ID = letter (letter | digit)* NUM = digit digit* (4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。 2.2 各种单词符号对应的种别码: 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)…… 三、词法分析程序的算法思想: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

3.1 主程序示意图: 主程序示意图如图3-1所示。其中初始包括以下两个方面: ⑴关键字表的初值。 关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下: Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,}; 图3-1 (2)程序中需要用到的主要变量为syn,token和sum 3.2 扫描子程序的算法思想: 首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。

相关文档
最新文档