导航:首页 > 源码编译 > 编译原理实验文本提取

编译原理实验文本提取

发布时间:2023-03-18 11:18:53

编译原理 词法分析 要求输入一个源文件,或是text形式的,然后对该文件进行词法分析。要简单一点的。

#include <iostream>
#include <vector>
#include <string>
#include <fstream>

using namespace std;
/*用来存储目标文件名*/
string file_name;

/*提取文本文件中的信息。*/
string GetText();

/*获得一个单词符号,从位置i开始查找。
//并且有一个引用参数j,用来返回这个单词最后一个字符在str的位置。*/
string GetWord(string str,int i,int& j);

/*这个函数用来除去字符串中连续的空格和换行
//第一个参数为目标字符串,第二个参数为开始位置
//返回值为连续的空格和换行后的第一个有效字符在字符串的位置*/
int DeleteNull(string str,int i);

/*判断i当前所指的字符是否为一个分界符,是的话返回真,反之假*/
bool IsBoundary(string str,int i);

/*判断i当前所指的字符是否为一个运算符,是的话返回真,反之假*/
bool IsOperation(string str,int i);

/*此函数将一个pair数组输出到一个文件中*/
void OutFile(vector<pair<int,string> > v);

/*此函数接受一个字符串数组,对它进行词法分析,返回一个pair型数组*/
vector<pair<int,string> > analyst(vector<string> vec);

/*此函数判断传递的参数是否为关键字,是的话,返回真,反之返回假*/
bool IsKey(string str);

int main()
{
cout<<"*****************************\n";
cout<<"\n\nright: Archerzei\n\n\n";
cout<<"*****************************\n\n";
string com1=" ";
string com2="\n";
string fileline=GetText();
int begin=0,end=0;
vector<string> array;
do
{
begin=DeleteNull(fileline,begin);
string nowString;
nowString=GetWord(fileline,begin,end);
if(end==-1)
break;
if(nowString.compare(com1)&&nowString.compare(com2))
array.push_back(nowString);
begin=end+1;
}while(true);
vector<pair<int,string> > mid_result;
mid_result=analyst(array);
OutFile(mid_result);
cout<<"**********************************************************************\n";
cout<<"***程序已完成词法分析,分析结果已经存储在文件"<<file_name<<"中!!!***\n";
cout<<"**********************************************************************\n";
system("pause");
return 0;
}

/*提取文本文件中的信息*/
string GetText()
{
string file_name1;
cout<<"请输入源文件名(包括路径和后缀名):";
cin>>file_name1;
ifstream infile(file_name1.c_str(),ios::in);
if (!infile)
{
cerr<<"无法打开文件! "<<file_name1.c_str()<<" !!!"<<endl;
exit(-1);
}
cout<<endl;
char f[1000];
infile.getline(f,1000,EOF);
infile.close();
return f;
}

/*获得一个单词符号,从位置i开始查找。
//并且有一个引用参数j,用来返回这个单词最后一个字符在原字符串的位置。*/
string GetWord(string str,int i,int& j)
{
string no_use("(){} , ; \n+=*/-<>\"");
j=str.find_first_of(no_use,i);
if(j==-1)
return "";
if(i!=j)
j--;
return str.substr(i,j-i+1);
}

/*这个函数用来除去字符串中连续的空格和换行
//第一个参数为目标字符串,第二个参数为开始位置
//返回值为连续的空格和换行后的第一个有效字符在字符串的位置*/
int DeleteNull(string str,int i)
{
for(;;i++)
if(str[i]!=' '&&str[i]!='\n')
return i;
}

/*判断i当前所指的字符是否为一个分界符,是的话返回真,反之假*/
bool IsBoundary(string str,int i)
{
int t;
char arr[7]={',',';','{','}','(',')','\"'};
for (t=0;t<7;t++)
if(str[i]==arr[t])
return true;
return false;
}

/*判断i当前所指的字符是否为一个运算符,是的话返回真,反之假*/
bool IsOperation(string str,int i)
{
int t;
char arr[7]={'+','-','*','/','=','<','>'};
for (t=0;t<7;t++)
if(str[i]==arr[t])
return true;
return false;
}

/*此函数将一个个字符串数组输出到一个文件中*/
void OutFile(vector<pair<int,string> > v)
{
cout<<"请输入目标文件名(包括路径和后缀名):";
cin>>file_name;
ofstream outfile(file_name.c_str(),ios::out);
if (!outfile)
{
cerr<<"无法打开文件! "<<file_name.c_str()<<" !!!"<<endl;
exit(-1);
}
cout<<endl;
int i;
cout<<"*****************************\n";
cout<<"\n\nright: Archerzei\n\n\n";
cout<<"*****************************\n\n";
for(i=0;i<v.size();i++)
outfile<<"<"<<v[i].first<<" , \""<<v[i].second<<"\">"<<endl;
outfile<<"\n\n*********************************\n";
outfile.close();
return;
}

/*此函数接受一个字符串数组,对它进行词法分析,返回一个pair型数组*/
vector<pair<int,string> > analyst(vector<string> vec)
{
vector<pair<int,string> > temp;
int i;
for(i=0;i<vec.size();i++)
{
if(vec[i].size()==1)
{
if((vec[i]==">"||vec[i]=="<"||vec[i]=="!")&&vec[i+1]=="=")
{
string jk=vec[i];
jk.append(vec[++i],0,1);
pair<int,string> pp(4,jk);
temp.push_back(pp);
continue;
}
if((vec[i]=="+"&&vec[i+1]=="+")||(vec[i]=="-"&&vec[i+1]=="-"))
{
string jk=vec[i];
jk.append(vec[++i],0,1);
pair<int,string> pp(4,jk);
temp.push_back(pp);
continue;
}
if(IsBoundary(vec[i],0))
{
pair<int,string> pp(5,vec[i]);
temp.push_back(pp);
}
else if(IsOperation(vec[i],0))
{
pair<int,string> pp(4,vec[i]);
temp.push_back(pp);
}
else if(vec[i][0]<='9'&&vec[i][0]>='0')
{
pair<int,string> pp(3,vec[i]);
temp.push_back(pp);
}
else
{
pair<int,string> pp(2,vec[i]);
temp.push_back(pp);
}
}
else if(vec[i][0]<='9'&&vec[i][0]>='0')
{
pair<int,string> pp(3,vec[i]);
temp.push_back(pp);
}
else if(IsKey(vec[i]))
{
pair<int,string> pp(1,vec[i]);
temp.push_back(pp);
}
else
{
pair<int,string> pp(2,vec[i]);
temp.push_back(pp);
}
}
return temp;
}

/*此函数判断传递的参数是否为关键字,是的话,返回真,反之返回假*/
bool IsKey(string str)
{
string p[16]={"char","double","int","long","double","float","for","while","do","break","continue","switch","short","case","return","if"};
vector<string> ppp(p,p+16);
int u;
for(u=0;u<ppp.size();u++)
if(!str.compare(ppp[u]))
return true;
return false;
}
/*finished*/

已经验收过了,在VC6.0上运行没有问题。程序很容易看懂的,报告的话自己写写就可以了。要是有分就好了…………哈哈!!!

㈡ 《Compilers Principles》txt下载在线阅读全文,求百度网盘云资源

《Compilers Principles编译原理》(Alfred V. Aho)电子书网盘下载免费在线阅读

链接: https://pan..com/s/1uTWbyl7EEuUO1EgQpbxOkg

pdf" data_size="12.26M" data_filelogo="https://gss0.bdstatic.com//yun-file-logo/file-logo-6.png" data_number="1" data_sharelink="https://pan..com/s/1uTWbyl7EEuUO1EgQpbxOkg" data_code="by1p">

提取码: by1p

书名:Compilers Principles编译原理

作者:Alfred V. Aho

豆瓣评分:9.2

出版社:机械工业出版社

出版年份:2011-1

页数:1009

内容简介:

本书是编译领域无可替代的经典着作,被广大计算机专业人士誉为“龙书”。本书上一版自1986年出版以来,被世界各地的着名高等院校和研究机构(包括美国哥伦比亚大学、斯坦福大学、哈佛大学、普林斯顿大学、贝尔实验室)作为本科生和研究生的编译原理课程的教材。该书对我国高等计算机教育领域也产生了重大影响。 第2版对每一章都进行了全面的修订,以反映自上一版出版20多年来软件工程。程序设计语言和计算机体系结构方面的发展对编译技术的影响。本书全面介绍了编译器的设计,并强调编译技术在软件设计和开发中的广泛应用。每章中都包含大量的习题和丰富的参考文献。 本书适合作为高等院校计算机专业本科生和研究生的编译原理与技术课程的教材,也可供广大计算机技术人员参考。

作者简介:

Alfred V.Aho,美国歌伦比亚大学教授,美国国家工程院院士,ACM和IEEE会士,曾获得IEEE的冯·诺伊曼奖。着有多部算法、数据结构、编译器、数据库系统及计算机科学基础方面的着作。

Monica S.Lam,斯坦福大学计算机科学系教授,曾任Tensilica的首席科学家,也是Moka5的首任CEO。曾经主持SUIF项目,该项目产生了最流行的研究用编译器之一。

Ravi Sethi,Avaya实验室总裁,曾任贝尔实验室高级副总裁和Lucent Technologies通信软件的CTO。他曾在宾夕法尼亚州立大学,亚利桑那州立大学和普林斯顿大学任教,是ACM会士。

Jefirey D.Ullman斯坦福大学计算机科学系教授和Gradiance CEO。他的研究兴趣包括数据库理论、数据库集成、数据挖掘和利用信息基础设施教学等。他是美国国家工程学院院士、IEEE会士,获得过ACM的Karlstrom杰出教育奖和Knuth奖。

㈢ 编译原理

C语言编译过程详解
C语言的编译链接过程是要把我们编写的一个C程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接。编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程。链接是把目标文件、操作系统的启动代码和用到的库文件进行组织形成最终生成可执行代码的过程。过程图解如下:

从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程。
一、编译过程
编译过程又可以分成两个阶段:编译和汇编。
1、编译
编译是读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,源文件的编译过程包含两个主要阶段:
第一个阶段是预处理阶段,在正式的编译阶段之前进行。预处理阶段将根据已放置在文件中的预处理指令来修改源文件的内容。如#include指令就是一个预处理指令,它把头文件的内容添加到.cpp文件中。这个在编译之前修改源文件的方式提供了很大的灵活性,以适应不同的计算机和操作系统环境的限制。一个环境需要的代码跟另一个环境所需的代码可能有所不同,因为可用的硬件或操作系统是不同的。在许多情况下,可以把用于不同环境的代码放在同一个文件中,再在预处理阶段修改代码,使之适应当前的环境。
主要是以下几方面的处理:
(1)宏定义指令,如 #define a b。
对于这种伪指令,预编译所要做的是将程序中的所有a用b替换,但作为字符串常量的 a则不被替换。还有 #undef,则将取消对某个宏的定义,使以后该串的出现不再被替换。
(2)条件编译指令,如#ifdef,#ifndef,#else,#elif,#endif等。
这些伪指令的引入使得程序员可以通过定义不同的宏来决定编译程序对哪些代码进行处理。预编译程序将根据有关的文件,将那些不必要的代码过滤掉
(3) 头文件包含指令,如#include "FileName"或者#include <FileName>等。
在头文件中一般用伪指令#define定义了大量的宏(最常见的是字符常量),同时包含有各种外部符号的声明。采用头文件的目的主要是为了使某些定义可以供多个不同的C源程序使用。因为在需要用到这些定义的C源程序中,只需加上一条#include语句即可,而不必再在此文件中将这些定义重复一遍。预编译程序将把头文件中的定义统统都加入到它所产生的输出文件中,以供编译程序对之进行处理。包含到C源程序中的头文件可以是系统提供的,这些头文件一般被放在/usr/include目录下。在程序中#include它们要使用尖括号(<>)。另外开发人员也可以定义自己的头文件,这些文件一般与C源程序放在同一目录下,此时在#include中要用双引号("")。
(4)特殊符号,预编译程序可以识别一些特殊的符号。
例如在源程序中出现的LINE标识将被解释为当前行号(十进制数),FILE则被解释为当前被编译的C源程序的名称。预编译程序对于在源程序中出现的这些串将用合适的值进行替换。
预编译程序所完成的基本上是对源程序的“替代”工作。经过此种替代,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。这个文件的含义同没有经过预处理的源文件是相同的,但内容有所不同。下一步,此输出文件将作为编译程序的输出而被翻译成为机器指令。
第二个阶段编译、优化阶段。经过预编译得到的输出文件中,只有常量;如数字、字符串、变量的定义,以及C语言的关键字,如main,if,else,for,while,{,}, +,-,*,\等等。
编译程序所要作得工作就是通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码。
优化处理是编译系统中一项比较艰深的技术。它涉及到的问题不仅同编译技术本身有关,而且同机器的硬件环境也有很大的关系。优化一部分是对中间代码的优化。这种优化不依赖于具体的计算机。另一种优化则主要针对目标代码的生成而进行的。
对于前一种优化,主要的工作是删除公共表达式、循环优化(代码外提、强度削弱、变换循环控制条件、已知量的合并等)、复写传播,以及无用赋值的删除,等等。
后一种类型的优化同机器的硬件结构密切相关,最主要的是考虑是如何充分利用机器的各个硬件寄存器存放的有关变量的值,以减少对于内存的访问次数。另外,如何根据机器硬件执行指令的特点(如流水线、RISC、CISC、VLIW等)而对指令进行一些调整使目标代码比较短,执行的效率比较高,也是一个重要的研究课题。
2、汇编
汇编实际上指把汇编语言代码翻译成目标机器指令的过程。对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。目标文件中所存放的也就是与源程序等效的目标的机器语言代码。目标文件由段组成。通常一个目标文件中至少有两个段:
代码段:该段中所包含的主要是程序的指令。该段一般是可读和可执行的,但一般却不可写。
数据段:主要存放程序中要用到的各种全局变量或静态的数据。一般数据段都是可读,可写,可执行的。
UNIX环境下主要有三种类型的目标文件:
(1)可重定位文件
其中包含有适合于其它目标文件链接来创建一个可执行的或者共享的目标文件的代码和数据。
(2)共享的目标文件
这种文件存放了适合于在两种上下文里链接的代码和数据。
第一种是链接程序可把它与其它可重定位文件及共享的目标文件一起处理来创建另一个 目标文件;
第二种是动态链接程序将它与另一个可执行文件及其它的共享目标文件结合到一起,创建一个进程映象。
(3)可执行文件
它包含了一个可以被操作系统创建一个进程来执行之的文件。汇编程序生成的实际上是第一种类型的目标文件。对于后两种还需要其他的一些处理方能得到,这个就是链接程序的工作了。
二、链接过程
由汇编程序生成的目标文件并不能立即就被执行,其中可能还有许多没有解决的问题。
例如,某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数,等等。所有的这些问题,都需要经链接程序的处理方能得以解决。
链接程序的主要工作就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。
根据开发人员指定的同库函数的链接方式的不同,链接处理可分为两种:
(1)静态链接
在这种链接方式下,函数的代码将从其所在地静态链接库中被拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态链接库实际上是一个目标文件的集合,其中的每个文件含有库中的一个或者一组相关函数的代码。
(2) 动态链接
在此种方式下,函数的代码被放到称作是动态链接库或共享对象的某个目标文件中。链接程序此时所作的只是在最终的可执行程序中记录下共享对象的名字以及其它少量的登记信息。在此可执行文件被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间。动态链接程序将根据可执行程序中记录的信息找到相应的函数代码。
对于可执行文件中的函数调用,可分别采用动态链接或静态链接的方法。使用动态链接能够使最终的可执行文件比较短小,并且当共享对象被多个进程使用时能节约一些内存,因为在内存中只需要保存一份此共享对象的代码。但并不是使用动态链接就一定比使用静态链接要优越。在某些情况下动态链接可能带来一些性能上损害。
我们在linux使用的gcc编译器便是把以上的几个过程进行捆绑,使用户只使用一次命令就把编译工作完成,这的确方便了编译工作,但对于初学者了解编译过程就很不利了,下图便是gcc代理的编译过程:

从上图可以看到:
预编译
将.c 文件转化成 .i文件
使用的gcc命令是:gcc –E
对应于预处理命令cpp
编译
将.c/.h文件转换成.s文件
使用的gcc命令是:gcc –S
对应于编译命令 cc –S
汇编
将.s 文件转化成 .o文件
使用的gcc 命令是:gcc –c
对应于汇编命令是 as
链接
将.o文件转化成可执行程序
使用的gcc 命令是: gcc
对应于链接命令是 ld
总结起来编译过程就上面的四个过程:预编译、编译、汇编、链接。了解这四个过程中所做的工作,对我们理解头文件、库等的工作过程是有帮助的,而且清楚的了解编译链接过程还对我们在编程时定位错误,以及编程时尽量调动编译器的检测错误会有很大的帮助的。
是否可以解决您的问题?

㈣ 《编译原理》txt下载在线阅读全文,求百度网盘云资源

《编译原理》(陈意云)电子书网盘下载免费在线阅读

链接: https://pan..com/s/1BOpMeUxvK5kF_TeMACnD6Q

提取码: zptp

书名:编译原理

作者:陈意云

豆瓣评分:6.2

出版社:高等教育出版社

出版年份:2003-1

页数:381

内容简介:

《编译原理》介绍编译器构造的一般原理和基本实现方法,主要内容包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等。除了介绍命令式编程语言的编译技术外,《编译原理》还介绍面向对象语言和函数式编程语言的实现技术。《编译原理》还强调一些相关的理论知识,如形式语言和自动机理论、语法制导的定义和属性文法、类型论和类型系统等。

《编译原理》取材广泛新颖、图文并茂,注意理论联系实际。为满足教师教学和学生自学及考研需求,《编译原理》作者编写了配套教学参考书《编译原理习题精选与解析》(高等教育出版社2005年8月出版),同时提供本课程的电子教案,可从高等教育出版社高等理工教学资源网免费下载。《编译原理》可作为高等学校计算机科学及相关专业的教材,也可供计算机软件工程技术人员参考使用。

㈤ c(a/g/w)ll选择哪个

热门频道

首页

博客

研修院

VIP

APP

问答

下载

社区

推荐频道

活动

招聘

专题

打开CSDN APP
Copyright © 1999-2020, CSDN.NET, All Rights Reserved

打开APP

c语言lr文法还是ll文法,编译原理复习题 转载
2021-05-20 05:05:24

Tim Pan

码龄4年

关注
一、单项选择题 概述部分

1.构造编译程序应掌握 。D A. 源程序 B. 目标语言 C. 编译方法 D. 以上三项都是 2.编译程序绝大多数时间花在 上。D

A. 出错处理

B. 词法分析

C. 目标代码生成

D. 表格管理 3.编译程序是对 。D

A. 汇编程序的翻译

B. 高级语言程序的解释执行

C. 机器语言的执行

D. 高级语言的翻译 4. 将编译程序分成若干“遍”,是为了 。B

A. 提高程序的执行效率

B. 使程序的结构更为清晰 C 利用有限的机器内存并提高机器的执行效率 D. 利用有限的机器内存但降低了机器的执行效率

词法分析部分

1.DFA M(见图1-1)接受的字集为 。D A. 以0开头的二进制数组成的集合

B. 以0结尾的二进制数组成的集合

.png

C. 含奇数个0的二进制数组成的集合

D. 含偶数个0的二进制数组成的集合

2.词法分析器的输出结果是 。C

A. 单词的种别编码

B. 单词在符号表中的位置

C. 单词的种别编码和自身值

D. 单词自身值 3.正规式M1和M2等价是指 。C A. M1和M2的状态数相等 B. M1和M2的有向边条数相等 C. M1和M2所识别的语言集相等 D. M1和M2状态数和有向边条数相等 4.词法分析器的加工对象是 。 C A .中间代码 B .单词 C .源程序 D .元程序 5.同正规式(a|b )*等价的正规式为 。D A .(a|b)+ B .a*|b* C .(ab)* D .(a*|b*)+ 6. 两个DFA 等价是指: 。 D A. 这两个DFA 的状态数相同

B. 这两个DFA 的状态数和有向弧条数都相等

C. 这两个DFA 的有向弧条数相等

D. 这两个DFA 接受的语言相同

7. 下列符号串不可以由符号集S ={a,b}上的正闭包运算产生的是:(A ) A. ε B. a C. aa D. ab 8.称有限自动机A1和A2等价是指________。D A .A1和A2都是定义在一个字母表上的有限自动机 B .A1和A2状态数和有向边数相等

图1-1

1

相关资源:编译原理赋值语句的翻译LL文法LR文法简单优先法-专业指导文档类...
文章知识点与官方知识档案匹配
C技能树首页概览
110422 人正在系统学习中
打开CSDN APP,看更多技术内容

编译原理五 LR(1)分析法【C语言实现】_wangkay88的博客
1、使用 LR 的优点: (1)LR 分析器能够构造来识别所有能用上下文无关文法写的程序设计语言的结构。 (2)LR 分析方法是已知的最一般的无回溯移进-归约方法,它能够和其他移进-归约方法 一样有效地实现。 (3)LR 方法能分析的文法...
lr参数与C语言函数参数的区别_weixin_30254435的博客
LR参数是lr自己封装的一个钟对象, LR参数的表达方式:{ParamName}
编译原理习题——第2章 文法和语言试卷
第2章 文法和语言试卷 1. 文法:G:S→xSx|y所识别的语言是(D)。 A. xyx B. (xyx)* C.x*yx* D. xnyxn(n≥0) 2. 给定文法A→bA|ca,为该文法句子的是(C)。 A. bba B. cab C. bca D. cba 3. 文法G产生的(D)的全体是该文法描述的语言。 A. 句型 B. 终结符集 C. 非终结符集 D. 句子 4. 若文法G...
继续访问
编译原理习题(含答案)——2程序设计语言及其文法——哈工大陈鄞配套版本
程序设计语言及其文法1 文法:G:S→xSx | y所识别的语言是( )。 2 给定文法A→bA|ca,为该文法句子的是( )。A. bbaB. cabC. bcaD. Cba 3 设有文法G[S]:S->S1|S0|Sa|Sc|a|b|c,下列符号串中是该文法的句子有( )。A. ab0B. a0b01C. a0b0aD. bc10 4 文法G产生的( )的全体是该文法描述的语言。A. ...
继续访问
c语言lr分析器的设计与实现_[源码和文档分享]基于LR分析法的简单分析法...
通过设计、编制、调试一个简单计算器程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。 二、课程设计内容及步骤 本次课程设计需要使用 LR 分析法完成简单计算器的设计,其中算术表达式的文法如下: ...
C语言实现编译原理的LR分析法,编译原理LR(0)分析器(C语言).pdf
1LR 分析法 LR LR “ 分析法是一种自底向上进行的规范规约的语法分析方法, 指 自左向 右扫描和自底向上进行归约”。LR 分析法的一个主要缺点是,若用手工构造分析 LR 器则工作量相当大,因此必须求助于自动产生 分析器的产生器。
编译原理 第三章 词法分析
1、词法分析器的输出结果是单词的种类编码和自身值 2、词法分析器不能发现括号不匹配 3、不存在语言能被确定的有穷自动机识别但不能用正则表达式表示 4、两个有穷自动机等价实质它们的所识别的语言相等 5、词法分析器用于识别单词 6、正则表达式R1和R2等价是指R1和R2代表同一正则集 7、已知文法G[S]:S->A1, A->A1|S0|0,与G等价的正规式是0(1|10)^1 8、与(a...
继续访问
【编译原理-练习题-1】概述部分与词法分析部分选择,填空,判断,多选题
一、单项选择题 1.构造编译程序应掌握 (D ) 。 a. 源程序 b. 目标语言 c. 编译方法 d. 以上三项都是 2.编译程序绝大多数时间花在 (D) 上。 a. 出错处理 b. 词法分析 c. 目标代码生成 d. 表格管理 3.DFA M(见图1-1)接受的字集为(D ) 。 a. 以0开头的二进制数组成的集合 b. 以0结尾的二进制数组成的集合 ...
继续访问
LR中用C语言比较两个字符串变量_花露丝雨的博客
6.lr_save_string( "We can see the string:nancy","string1" ); 7.lr_save_string( "We can see the string:nancy","string2" ); 8.lr_output_message("the string1 is %s.",lr_eval_string("{string1}")); ...
c语言字符串变量的比较,LR中用C语言比较两个字符串变量.doc_梦符佳月...
LR中用C语言比较两个字符串变量 Zee的早期文档.一:以下脚本,定义两个一样的字符数组,对比后,打印出result的值: vuser_init() { int result; ? ???char string1[] = "We can see the string:zee"; ...
最新发布 编译原理刷题(个人向)
编译原理刷题
继续访问
【编译原理】课后习题
1.构造编译程序应掌握:源程序、目标语言、编译方法 2.编译程序绝大多数时间花在表格管理上 3. 4.一个程序是正确的,包括两层含义:一是书写正确;二是含义正确 (合乎语法规则、合乎语义规则) 5.描述高级语言语法常用的方法有语法树、BNF范式、扩充的BNF范式等 6.程序语言一般可以分为低级语言和高级语言两大类,其中低级语言通常又称为面向机器的语言。面向机器语言指的是特定计算机系统所...
继续访问
C语言实现编译原理的LR分析法,实验三编译原理综合实验报告——(LR...
注意:本例是利用LR(0)分析来实现的语法分析,同学在写实验报告的时候,在结果分析这一块可以选用课堂讲过的LR(0)文法来说明验证结果即可。 同时附上你所选用的文法对应的LR(0)分析表。
编译原理总结,看这一篇就够了!_LeeDuo.的博客_编译原理
1.词法分析:对源程序的字符串进行扫描和分解,识别出每个单词符号。 2.语法分析:根据语言的语法规则,把单词符号分解成各类语法单位。 3.语义分析与中间代码生成:对各种语法范畴进行静态语义检查,若正确则进行中间代码翻译。 4.代码优化:...
C语言LR(1)文法
用C语言编写,对一个LR(1)文法分析,文法为:实现两个数的加减乘除四则运算。并能得出计算结果。
热门推荐 编译原理习题(含答案)——3词法分析——哈工大陈鄞配套版本
词法分析1 词法分析器的输出结果是( )。A. 单词自身值B. 单词在符号表中的位置C. 单词的种别编码 D. 单词的种别编码和自身值2 词法分析器不能( )。A. 识别出数值常量B. 过滤源程序中的注释C. 扫描源程序并识别记号D. 发现括号不匹配 3 ( )这样一些语言,它们能被确定的有穷自动机识别,但不能用正则表达式表示。A. 存在B. 不存在C. 无法判定是否存在D. 以上答案都不对 4 ...
继续访问
C--编译器:C--编译器,实现LL(1)\ LR(0)\ SLR \ LR(1)并生成语义分析和MIPS
实现了自制的C--语言的一遍扫描编译,包括词法分析,LR(1)语法分析,属性文法+中间代码生成,MIPS编译生成编译脚本由python实现,兼容python2.7与3.7,图形界面由WPF实现,使用了IronPython进行脚本执行 支持以下特性: 一种基本类型int 赋值表达式,循环/选择/判断/跳出语句 函数定义与函数调用 未实现: 浮点数,字符,字符串 斑点 错误检查
编译原理之LR(0)分析算法的c实现
LR(0)分析器的构造算法如下: 对一个文法构造了它的LR(0)分析表后就可以在LR分析器的总控程序(驱动程序)控制下对输入串进行分析,即根据输入串的当前符号和分析栈的栈顶状态查找分析表应采取的动作,对状态栈和符号栈进行相应的操作即移进、归约、接受或报错。具体说明如下: (1)若ACTION[S,a]=Sj,a为终结符,则把a移入符号栈,j移入状态栈; (2)若ACTION[S,a]=rj,
继续访问
编译原理第一章自测题
第一章 高级语言与编译程序概述 一、单项选择题 1.将编译程序分成若干个“遍”是为了____ 。 A. 提高程序的执行效率 B. 使程序的结构更加清晰 C. 利用有限的机器内存并提高机器的执行效率 D. 利用有限的机器内存但降低了机器的执行效率 2.构造编译程序应掌握 ____ 。 A. 源程序 B. 目标语言 C. 编译方法 D. 以上三项都是 3.编译程序绝大多数时间花在 ____ 上。 A. 出错处理 B. 词法分析 C. 目标代码生成 D. 管理表格
C语言语法分析程序(编译原理:LR)
北邮大三编译原理课程序 注释很详细
用c++实现LR语法分析器
通过LR分析表及三个栈形成对输入表达式的判断! 。
c语言lr文法还是ll文法,编译原理第五章语法分析课后题
(先补到这里,后面如果有需要的话,垃圾博主还会回来继续更的。。。)5.1 递归子程序法属于()语法分析方法A. 自顶向下B. 自底向上C. 自左向右D. 自右向左5.2 采用确定的自顶向下分析时,必须()A. 消除左递归B. 消除右递归C. 避免回溯D. 提取左公因子5.3 自上而下语法分析的主要分析动作是A. 推导B. 移进C. 归约D. 匹配5.4 一个字符属于FOLLOW(S),这个字符的含...
继续访问
编译原理,C语言实现LR(0)分析(扩展文法的生成、项目集规范簇的生成、ACTION GOTO表的生成、句子的分析)
编译原理,C语言实现LR(0)分析(扩展文法的生成、项目集规范簇的生成、ACTION GOTO表的生成、句子的分析) (1)根据提示输入文法的个数 (2)输入文法 (3)扩展文法的生成、项目集规范簇的生成、ACTION GOTO表的生成 (3)分析句子 (4)生成分析过程 C语言实现LR(0)分析源代码
继续访问

编译程序基本原理
编译程序和解释程序 人们利用高级语言与计算机进行交互, 但计算机仍然只能理解和执行由 0, 1序列构成的机器语言, 因此高级程序设计语言需要翻译, 担负这一任务的程序称为"语言处理程序", 由于应用的不同, 语言之间的翻译也是多种多样的. 大致可分为 汇编程序、解释程序和编译程序. 用某种高级语言或汇编语言编写的程序称为 源程序, 源程序不能直接在计算机上执行. 如果源程序是用汇编语言写的, ...
继续访问
LR脚本用户自定义C语言函数
LR脚本实战:用户自定义C语言函数 Loadrunner可以使用标准C语言的函数,因此我们可以在脚本中编写自己的函数用于调用,把脚本结构化,更好的进行重用。 先看一个例子: Action() { int i,j; j = 1; for (i=0;i<10;i++) { lr_message("i+j=%d",sum(i,j)); j++; } ...
继续访问
编译原理,第一章绪论
编译过程和编译程序结构 五个阶段: 词法分析 语法分析 语义分析和中间代码生成 优化 目标代码生成 编译程序的开发 自编译:用某种高级语言编写自己的编译程序称为自编译, 交叉编译:用A机器上的编译程序来产生可在B机器上运行的目标代码 自展:首先确定一个非常简单的核心语言L0,然后用机器语言或者汇编语言写出它的编译程序T0,再把语言L0扩充到L1,用L0编写L1的编译程序T1,这样不断扩展下去...
继续访问

c语言是 ll文法和lr文法哪个好
c语言lr文法还是ll文法
写评论

评论

收藏

点赞



分享

㈥ 编译原理-LL1文法详细讲解

我们知道2型文法( CFG ),它的每个产生式类型都是 α→β ,其中 α ∈ VN , β ∈ (VN∪VT)*。

例如, 一个表达式的文法:

最终推导出 id + (id + id) 的句子,那么它的推导过程就会构成一颗树,即 CFG 分析树:

从分析树可以看出,我们从文法开始符号起,不断地利用产生式的右部替换产生式左部的非终结符,最终推导出我们想要的句子。这种方式我们称为自顶向下分析法。

从文法开始符号起,不断用非终结符的候选式(即产生式)替换当前句型中的非终结符,最终得到相应的句子。
在每一步推导过程中,我们需要做两个选择:

因为一个句型中,可能存在多个非终结符,我们就不确定选择那一个非终结符进行替换。
对于这种情况,我们就需要做强制规定,每次都选择句型中第一个非终结符进行替换(或者每次都选择句型中最后一个非终结符进行替换)。

自顶向下的语法分析采用最左推导方式,即总是选择每个句型的最左非终结符进行替换。

最终的结果是要推导出一个特定句子(例如 id + (id + id) )。
我们将特定句子看成一个输入字符串,而每一个非终结符对应一个处理方法,这个处理方法用来匹配输入字符串的部分,算法如下:

方法解析:

这种方式称为递归下降分析( Recursive-Descent Parsing ):

当选择的候选式不正确,就需要回溯( backtracking ),重新选择候选式,进行下一次尝试匹配。因为要不断的回溯,导致分析效率比较低。

这种方式叫做预测分析( Predictive Parsing ):

要实现预测分析,我们必须保证从文法开始符号起,每一个推导过程中,当前句型最左非终结符 A 对于当前输入字符 a ,只能得到唯一的 A 候选式。

根据上面的解决方法,我们首先想到,如果非终结符 A 的候选式只有一个以终结符 a 开头候选式不就行了么。
进而我们可以得出,如果一个非终结符 A ,它的候选式都是以终结符开头,并且这些终结符都各不相同,那么本身就符合预测分析了。

这就是S_文法,满足下面两个条件:

例子:

这就是一个典型的S_文法,它的每一个非终结符遇到任一终结符得到候选式是确定的。如 S -> aA | bAB , 只有遇到终结符 a 和 b 的时候,才能返回 S 的候选式,遇到其他终结符时,直接报错,匹配不成功。

虽然S_文法可以实现预测分析,但是从它的定义上看,S_文法不支持空产生式(ε产生式),极大地限制了它的应用。

什么是空产生式(ε产生式)?

例子

这里 A 有了空产生式,那么 S 的产生式组 S -> aA | bAB ,就可以是 a | bB ,这样 a , bb , bc 就变成这个文法 G 的新句子了。

根据预测分析的定义,非终结符对于任一终结符得到的产生式是确定的,要么能获取唯一的产生式,要么不匹配直接报错。

那么空产生式何时被选择呢?

由此可以引入非终结符 A 的后继符号集的概念:
定义: 由文法 G 推导出来的所有句型,可以出现在非终结符 A 后边的终结符 a 的集合,就是这个非终结符 A 的后继符号集,记为 FOLLOW(A) 。

因此对于 A -> ε 空产生式,只要遇到非终结符 A 的后继符号集中的字符,可以选择这个空产生式。
那么对于 A -> a 这样的产生式,只要遇到终结符 a 就可以选择了。

由此我们引入的产生式可选集概念:
定义: 在进行推导时,选用非终结符 A 一个产生式 A→β 对应的输入符号的集合,记为 SELECT(A→β)

因为预测分析要求非终结符 A 对于输入字符 a ,只能得到唯一的 A 候选式。
那么对于一个文法 G 的所有产生式组,要求有相同左部的产生式,它们的可选集不相交。

在 S_文法基础上,我们允许有空产生式,但是要做限制:

将上面例子中的文法改造:

但是q_文法的产生式不能是非终结符打头,这就限制了其应用,因此引入LL(1)文法。

LL(1)文法允许产生式的右部首字符是非终结符,那么怎么得到这个产生式可选集。
我们知道对于产生式:

定义: 给定一个文法符号串 α , α 的 串首终结符集 FIRST(α) 被定义为可以从 α 推导出的所有串首终结符构成的集合。

定义已经了解清楚了,那么该如何求呢?
例如一个文法符号串 BCDe , 其中 B C D 都是非终结符, e 是终结符。

因此对于一个文法符号串 X1X2 … Xn ,求解 串首终结符集 FIRST(X1X2 … Xn) 算法:

但是这里有一个关键点,如何求非终结符的串首终结符集?

因此对于一个非终结符 A , 求解 串首终结符集 FIRST(A) 算法:

这里大家可能有个疑惑,怎么能将 FIRST(Bβ) 添加到 FIRST(A) 中,如果问文法符号串 Bβ 中包含非终结符 A ,就产生了循环调用的情况,该怎么办?

对于 串首终结符集 ,我想大家疑惑的点就是,串首终结符集到底是针对 文法符号串 的,还是针对 非终结符 的,这个容易弄混。
其实我们应该知道, 非终结符 本身就属于一个特殊的 文法符号串
而求解 文法符号串 的串首终结符集,其实就是要知道文法符号串中每个字符的串首终结符集:

上面章节我们知道了,对于非终结符 A 的 后继符号集 :
就是由文法 G 推导出来的所有句型,可以出现在非终结符 A 后边的终结符的集合,记为 FOLLOW(A) 。

仔细想一下,什么样的终结符可以出现在非终结符 A 后面,应该是在产生式中就位于 A 后面的终结符。例如 S -> Aa ,那么终结符 a 肯定属于 FOLLOW(A) 。

因此求非终结符 A 的 后继符号集 算法:

如果非终结符 A 是产生式结尾,那么说明这个产生式左部非终结符后面能出现的终结符,也都可以出现在非终结符 A 后面。

我们可以求出 LL(1) 文法中每个产生式可选集:

根据产生式可选集,我们可以构建一个预测分析表,表中的每一行都是一个非终结符,表中的每一列都是一个终结符,包括结束符号 $ ,而表中的值就是产生式。
这样进行语法推导的时候,非终结符遇到当前输入字符,就可以从预测分析表中获取对应的产生式了。

有了预测分析表,我们就可以进行预测分析了,具体流程:

可以这么理解:

我们知道要实现预测分析,要求相同左部的产生式,它们的可选集是不相交。
但是有的文法结构不符合这个要求,要进行改造。

如果相同左部的多个产生式有共同前缀,那么它们的可选集必然相交。
例如:

那么如何进行改造呢?
其实很简单,进行如下转换:

如此文法的相同左部的产生式,它们的可选集是不相交,符合现预测分析。

这种改造方法称为 提取公因子算法

当我们自顶向下的语法分析时,就需要采用最左推导方式。
而这个时候,如果产生式左部和产生式右部首字符一样(即A→Aα),那么推导就可能陷入无限循环。
例如:

因此对于:

文法中不能包含这两种形式,不然最左推导就没办法进行。

例如:

它能够推导出如下:

你会惊奇的发现,它能推导出 b 和 (a)* (即由 0 个 a 或者无数个 a 生成的文法符号串)。其实就可以改造成:

因此消除 直接左递归 算法的一般形式:

例如:

消除间接左递归的方法就是直接带入消除,即

消除间接左递归算法:

这个算法看起来描述很多,其实理解起来很简单:

思考 : 我们通过 Ai -> Ajβ 来判断是不是间接左递归,那如果有产生式 Ai -> BAjβ 且 B -> ε ,那么它是不是间接左递归呢?
间接地我们可以推出如果一个产生式 Ai -> αAjβ 且 FIRST(α) 包括空串ε,那么这个产生式是不是间接左递归。

㈦ 求《OPENMP编译原理及实现技术》全文免费下载百度网盘资源,谢谢~

《OPENMP编译原理及实现技术》网络网盘pdf最新全集下载:
链接:https://pan..com/s/122Xvd3cLwtzPFlh9XrJLUA

?pwd=t16g 提取码:t16g
简介:OpenMP制导指令将C语言扩展为一个并行语言,但OpenMP本身不是一种独立的并行语言,而是为多处理器上编写并行程序而设计的、指导共享内存,OpenMP编程模型以线程为基础,通过编译制导指令来显示地指导并行化

阅读全文

与编译原理实验文本提取相关的资料

热点内容
橙app如何开启聊天 浏览:899
访问服务器公网地址 浏览:666
pdf打印底色去掉 浏览:463
java快递接口 浏览:397
哪个app可以教新爸爸 浏览:210
如何查看服务器系统版本信息 浏览:524
成都市土地出让金算法 浏览:702
钢筋加密标记 浏览:576
ps中扩展功能在文件夹的什么位置 浏览:904
双极压缩机为什么要先高压 浏览:527
苹果手机服务器填什么 浏览:832
android移动动画效果 浏览:691
电子和服务器是什么意思 浏览:691
phpurl中文乱码问题 浏览:893
程序员那么可爱大结局陆漓产子 浏览:538
java如何从云服务器读取本地文件 浏览:924
压缩空气软管制作方法 浏览:912
天河三号算法 浏览:926
php队列教程 浏览:634
洪水命令 浏览:531