语法分析器(基于mini-C的源程序)

合集下载

编译原理语法分析

编译原理语法分析

实验二语法分析一、实验目的设计MiniC的上下文无关文法,利用JavaCC生成调试递归下降分析程序,以便对任意输入的符号串进行分析。

本次实验的目的主要是加深对递归下降分析法的理解。

二、实验内容在JavaCC的文法规范文件中,不仅可以描述语言的语法规范,而且可以描述词法规范,本次实习中,利用JavaCC以MiniC语言构造一个不含语义分析的编译器前端,包括词法分析、语法分析,并要考虑语法分析中的错误恢复问题。

通过使用JavaCC, 可以体会LL(k)文法的编写特点,掌握编写JavaCC文法规范文件的方法。

利用JavaCC生成一个MiniC的语法分析器,具体要求如下:1、用流的形式读入要分析的C语言程序,或者通过命令行输入源程序;2、具有错误检查的能力,如果有能力可以输出错误所在的行号,并简单提示;3、如果输入的源程序符合MiniC的语法规范,输出该程序的层次结构的语法树。

三、实验过程1、完善实验指导中给定的文法〈程序〉→(〈函数〉)+〈函数〉→〈类型〉(<MAIN> | ID)(){ (语句块)* }〈类型〉→ <VOID> | <INT> | <FLOAT> | <DOUBLE> | <CHAR>〈语句块〉→〈语句〉 | { (〈语句块〉)* }〈语句〉→〈顺序语句〉|〈条件语句〉|〈循环语句〉〈顺序语句〉→〈声明语句〉| 〈赋值语句〉| 〈return语句〉| 〈break语句〉| 〈continue语句〉〈声明语句〉→〈类型〉ID ( , ID )*;〈赋值语句〉→ID=〈表达式〉;〈return语句〉→<RETURN>;〈break语句〉→<BREAK>;〈continue语句〉→<CONTINUE>;〈条件语句〉→<IF>(〈布尔表达式〉)〈语句块〉(LOOKAHEAD(1) else 〈语句块〉)?〈布尔表达式〉→〈表达式〉(〈关系符〉〈表达式〉)*〈循环语句〉→<WHILE> (〈布尔表达式〉)〈语句块〉〈表达式〉→〈表达式〉〈运算符〉〈表达式〉|(〈表达式〉)| ID | NUM 〈运算符〉→ + | - | * | /〈关系符〉→< | <= | > | >= | == | !=注:以上各产生式并不符合文法产生式的要求,为简便是按在JavaCC中的编写语法分析子程序时语法格式给出的。

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

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

规则右部首符号是终结

.
.
{ first[r].append(1,a); break;// 添加并结束
}
if(U.find(P[i][j])!=string::npos)// 规则右部首符号是非终结符 ,形如 X:: =Y1Y2...Yk
{
s=U.find(P[i][ j]);
//cout<<P[i][ j]<<":\n";
arfa=beta=""; for( j=0;j<100&&P[j][0]!=' ';j++) {
if(P[ j][0]==U[i]) {
if(P[ j][4]==U[i])// 产生式 j 有左递归 {
flagg=1;
.
.
for(temp=5;P[j][temp]!=' ';temp++) arfa.append(1,P[
{
int i,j,r,s,tmp;
string* first=new string[n];
char a;
int step=100;// 最大推导步数
while(step--){
// cout<<"step"<<100-step<<endl;
for(i=0;i<k;i++)
{
//cout<<P[i]<<endl;
j][temp]);
if(P[ j+1][4]==U[i]) arfa.append("|");//

语法分析器

语法分析器

语法分析器一.实验目的设计,编制并调试一个语法分析程序,加深对语法分析原理的理解。

可以编译c语言的基本结构,包括循环嵌套和条件嵌套。

二.实验的输入输出(1)执行程序时,可输入源程序的路径,如果输入为空的话,将会编译默认的源程序“./input.dat”(2)如果编译发现有错误,则会输出错误行数,并在结束编译时输出“Complete!”三.语法结构程序:=main()<语句块>语句块:=’{’ <赋值语句> ’}’赋值语句valueStatement: = <int|char> id = expression{,id = expression};循环语句的分析recycleStatement := while(condition){statementBlock}条件语句conditionStatement := if(condition)"{"statementBlock"}"{else if conditionStatement} | else statementBlock条件的分析condition := expression(>= | <= | == | > | < | !=)expression因子的分析factor := (expression)|id|number项的分析term := facto人{*factor|/factor)}表达式的分析expression := term{+term|-term}四.分析器主要代码/** 表达式的分析 expression = term{+term|-term}*/private void expression() {this.term();this.scanNext();while (this.match("+") || this.match("-")) {this.term();this.scanNext();}this.scanBack();}/** 项的分析 term = facto人{*factor|/factor)}*/private void term() {this.factor();this.scanNext();while (this.match("*") || this.match("\\")) {this.factor();this.scanNext();}this.scanBack();}/** 因子的分析 factor = (expression)|id|number*/private void factor() {this.scanNext();if (this.match("id") || this.match("number")) {// ---------------------------------------------------} else if (this.match("(")) {this.expression();this.matchNext(")");} else {System.out.println(row + " Error: factor error!");}}/** 条件的分析 condition = expression(>= | <= | == | > | < | !=)expression */private void condition() {this.expression();this.scanNext();if (this.match("<=") || this.match("==") || this.match(">=") || this.match(">") || this.match("<") || this.match("!=")) {} else {System.out.println(row + " ERROR: condition error!");}this.expression();}/** 条件语句 conditionStatement =if(condition)"{"statementBlock"}"{else* conditionStatement}|else statementBlock*/private void conditionStatement() {this.matchNext("if");this.matchNext("(");this.condition();this.matchNext(")");this.statementBlock();this.scanNext();if (this.match("else")) {this.scanNext();if (this.match("{")) {this.scanBack();this.statementBlock();} else if (this.match("if")) {this.scanBack();this.conditionStatement();} else {System.out.println(row + " ERROR: conditionStatement error!");}} else {this.scanBack();}}/** 循环语句的分析 recycleStatement = while(condition){statementBlock} */private void recycleStatement() {this.matchNext("while");this.matchNext("(");this.condition();this.matchNext(")");this.statementBlock();}/** 赋值语句分析 valueStatement = <int|char> id = expression{,id = expression};*/private void intValueStatement() {int nowRow = this.row;this.matchNext("int");this.matchNext("id");this.scanNext();if (this.match("=")) {this.expression();} else {this.scanBack();}this.scanNext();while (this.match(",")) {this.matchNext("id");this.scanNext();if (this.match("=")) {this.expression();} else {this.scanBack();}if (this.row != nowRow) {System.out.println(row + " ERROR: intValueStatement error!");}this.scanNext();}this.scanBack();}private void charValueStatement() {int nowRow = this.row;this.matchNext("char");this.matchNext("id");this.scanNext();if (this.match("=")) {this.expression();} else {this.scanBack();}this.scanNext();while (this.match(",")) {this.matchNext("id");this.scanNext();if (this.match("=")) {this.expression();} else {this.scanBack();}if (this.row != nowRow) {System.out.println(row + " ERROR: intValueStatement error!");}this.scanNext();}this.scanBack();}/** 语句块的分析*/private void statementBlock() {this.matchNext("{");this.statementSequence();this.matchNext("}");}/** 语句串的分析*/private void statementSequence() {this.scanNext();while (this.match("if") || this.match("while") ||this.match("id")|| this.match(";") || this.match("int") ||this.match("char")) {if (this.match("if")) {this.scanBack();this.conditionStatement();} else if (this.match("while")) {this.scanBack();this.recycleStatement();} else if (this.match("id")) {this.matchNext("=");this.expression();this.matchNext(";");} else if (this.match("int")) {this.scanBack();this.intValueStatement();} else if (this.match("char")) {this.scanBack();this.charValueStatement();} else if (this.match(";")) {}this.scanNext();}this.scanBack();}public void parseMain() {this.matchNext("main");this.matchNext("(");this.matchNext(")");this.statementBlock();System.out.println("Complete!");}五.小结通过此次语法分析器的编写,不仅使我更清楚的熟悉了语法分析文法,同时也再次巩固了词法分析的知识。

语法分析器计

语法分析器计

1.2 语法分析器设计语法分析是编译程序的核心部分,其主要任务是确定语法结构,检查 语法错误,报告错误的性质和位置,并进行适当的纠错工作.法分析的方法有多 种多样,常用的方法有递归子程序方法、运算符优先数法、状态矩阵法、LL(K) 方法和 LR(K)方法。

归纳起来,大体上可分为两大类,即自顶向下分析方法和 自底向上分析方法. Syntax 进行语法分析.对于语法分析,这里采用 LR(1)分析 法,判断程序是否满足规定的结构.构造 LR(1)分析程序,利用它进行语法分析, 判断给出的符号串是否为该文法识别的句子,了解 LR(K)分析方法是严格的从 左向右扫描,和自底向上的语法分析方法。

1.2.1 LR分析过程的设计思想及算法1:LR-table.txt:存放分析表,其中正数表示移进,负数表示归约,100 表示接受状态, 0 表示不操作。

2:grammar.txt 存放文法开始符号 3:lengh.txt 存放产生式右部字符长度 4:inpur.txt 输入的程序语法规则定义的文法,如下: (0) Z---S (1) S---AB (2) A---->CDE (3) C---void (4) D---main (5) E---() (6) B---{F} (7) F---GF (8) F---G (9) G--->HIJ (10) H--int (11) I--KLM (12) K--character(13) L--= (14) M--->num (15) J--;根据上面文法画出的分层有限自动机并根据分层自动机构造的 LR(1)分析表:vo m ( { i ch = nu S A B C D E F G H I J K L M } ; #id ai )n armnt021831Ac2-33454-45676-57-281909-11205111 13511121-261235111-43581-47115612701-1621117981--811551--9992220122-1132232242 32-4142-5111.2.2 程序核心代码和注释:public void analyzer() { //*************************** //循环读取grammar.txt //*************************** /*此处代码略*/ //*************************** //循环读取 lengh.txt //*************************** /*此处代码略*/ //**************************** // 读入文件,进行语法分析 //**************************** string strReadFile; strReadFile="input.txt"; myTextRead.myStreamReader=new StreamReader(strReadFile); string strBufferText; int wid =0; Console.WriteLine("分析读入程序(记号ID):\n"); do { strBufferText =myTextRead.myStreamReader.ReadLine();if(strBufferText==null) break;foreach (String subString in strBufferText.Split()) {if(subString!="") {int ll; if(subString!=null) {ll= subString.Length; //每一个长度 } else {break; } int a=ll+1; char[] b = new char[a];StringReader sr = new StringReader(subString);sr.Read(b, 0, ll);//把substring 读到char[]数组里int sort=(int)b[0];// word[i] 和 wordNum[i]对应//先识别出一整个串,再根据开头识别是数字还是字母Word[wid]=subString;if(subString.Equals("void")){wordNum[wid]=0;}else{if(subString.Equals("main")){wordNum[wid]=1;}else{if(subString.Equals("()")){wordNum[wid]=2;}else{if(subString.Equals("{")){wordNum[wid]=3;}else{if(subString.Equals("int")){wordNum[wid]=4;}else{if(subString.Equals("=")){wordNum[wid]=6;}else{if(subString.Equals("}")){wordNum[wid]=22;}else{if(subString.Equals(";")){wordNum[wid]=23;}else //识别变量和数字{if(sort>47&sort<58){wordNum[wid]=7;}else{wordNum[wid]=5;}}}} } } } } } Console.Write(subString+"("+wordNum[wid]+")"+" ");wid++; } } Console.WriteLine("\n"); }while (strBufferText!=null); wordNum[wid]=24; myTextRead.myStreamReader.Close();//********************************* //读入LR分析表 // //***********************************/*此处代码略*/int[] state = new int[100]; string[] symbol =new string[100]; state[0]=0; symbol[0]="#"; int p1=0; int p2=0; Console.WriteLine("\n按文法规则归约顺序如下:\n"); //*************** // 归约算法如下所显示 //*************** while(true) {int j,k;j=state[p2];k=wordNum[p1]; t=LR[j,k]; //当出现t为0的时候 if(t==0) {//错误类型 string error;"+error);if(k==0) error="void";else if(k==1) error="main";else if(k==2) error="()";else if(k==3) error="{";else if(k==4) error="int";else if(k==6) error="=";else if(k==22) error="}";else if(k==23) error=";";else error="其他错误符号";Console.WriteLine("\n检测结果:"); Console.WriteLine("代码中存在语法错误"); Console.WriteLine("错误状况:错误状态编号为 "+j+" 读头下符号为break;}else{if(t==-100)//-100为达到接受状态{Console.WriteLine("\n");Console.WriteLine("\n检测结果:");Console.WriteLine("代码通过语法检测");break;}if(t<0&&t!=-100)//归约{string m=grammar[-t];Console.Write(m+" ");//输出开始符int length=lengh[-t]; p2=p2-(length-1); Search mySearch=new Search(); int right=mySearch.search(m); if(right==0) {Console.WriteLine("\n"); Console.WriteLine("代码中有语法错误"); break; } int a=state[p2-1]; int LRresult= LR[a,right]; state[p2]=LRresult; symbol[p2]=m; } if(t>0) { p2=p2+1; state[p2]=t; symbol[p2]=Convert.ToString(wordNum[p1]); p1=p1+1; } }} myTextRead.myStreamReader.Close(); Console.Read(); }示例:1:void main () {int i = 8 ; int aa = 10 ; int j = 9 ; }2:void main (){ intq i = 8 ; int aa = 10 ; int j = 9 ; } 对于 intq i=8 中 intq 这个错误类型,词法分析通过,而语法分析正确识别出了错误,达到 预期目标 产生出错信息: 运行显示如下:1.3 中间代码生成器设计进入编译程序的第三阶段:中间代码产生阶段。

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

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

山东大学编译技术课程设计班级软件一班学号**********XX姓名软件一班万岁指导老师贺老师二零一一年三月一、目的<<编译技术>>是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。

从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。

二、任务及要求基本要求:1.词法分析器产生下述小语言的单词序列这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:对于这个小语言,有几点重要的限制:首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。

所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。

例如,下面的写法是绝对禁止的:IF(5)=x其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。

也就是说,对于关键字不专设对应的转换图。

但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。

当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。

再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。

例如,一个条件语句应写为IF i>0 i= 1;而绝对不要写成IFi>0 i=1;因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。

这个小语言的单词符号的状态转换图,如下图:2.语法分析器能识别由加+ 减- 乘* 除/ 乘方^ 括号()操作数所组成的算术表达式,其文法如下:E→E+T|E-T|TT→T*F|T/F|FF→P^F|Pp→(E)|i使用的算法可以是:预测分析法;递归下降分析法;算符优先分析法;LR分析法等。

3.中间代码生成器产生上述算术表达式的中间代码(四元式序列)三、实现过程说明给出各题目的详细算法描述,数据结构和函数说明,流程图。

编译原理小题答案

编译原理小题答案

《编译原理》常见题型一、填空题1。

编译程序的工作过程一般可以划分为词法分析,语法分析, 中间代码生成,代码优化(可省) ,目标代码生成等几个基本阶段。

2.若源程序是用高级语言编写的,目标程序是机器语言程序或汇编程序,则其翻译程序称为编译程序.3。

编译方式与解释方式的根本区别在于是否生成目标代码。

5.对编译程序而言,输入数据是源程序,输出结果是目标程序。

7。

若源程序是用高级语言编写的,目标程序是机器语言程序或汇编程序,则其翻译程序称为编译程序。

8.一个典型的编译程序中,不仅包括词法分析、语法分析、中间代码生成、代码优化、目标代码生成等五个部分,还应包括表格处理和出错处理。

其中,词法分析器用于识别单词。

10.一个上下文无关文法所含四个组成部分是一组终结符号、一组非终结符号、一个开始符号、一组产生式。

12.产生式是用于定义语法成分的一种书写规则.13.设G[S]是给定文法,则由文法G所定义的语言L(G)可描述为:L(G)={x│S=〉*x,x∈VT*}。

14。

设G是一个给定的文法,S是文法的开始符号,如果S*⇒x(其中x∈V*),则称x是文法的一个句型。

15。

设G是一个给定的文法,S是文法的开始符号,如果S*⇒x(其中x∈V T*),则称x是文法的一个句子 .16.扫描器的任务是从源程序中识别出一个个单词符号。

17.语法分析最常用的两类方法是自上而下和自下而上分析法.18。

语法分析的任务是识别给定的终结符串是否为给定文法的句子.19。

递归下降法不允许任一非终结符是直接左递归的。

20.自顶向下的语法分析方法的关键是如何选择候选式的问题。

21。

递归下降分析法是自顶向下分析方法.22.自顶向下的语法分析方法的基本思想是:从文法的开始符号开始,根据给定的输入串并按照文法的产生式一步一步的向下进行直接推导,试图推导出文法的句子,使之与给定的输入串匹配。

23。

自底向上的语法分析方法的基本思想是:从给定的终结符串开始,根据文法的规则一步一步的向上进行直接归约,试图归约到文法的开始符号.24。

《编译原理》考试试题及答案

《编译原理》考试试题及答案

《编译原理》考试试题及答案(附录)一、判断题:1.一个上下文无关文法的开始符,可以是终结符或非终结符。

( X )2.一个句型的直接短语是唯一的。

( X )3.已经证明文法的二义性是可判定的。

( X )4.每个基本块可用一个DAG表示。

(√)5.每个过程的活动记录的体积在编译时可静态确定。

(√)6.2型文法一定是3型文法。

( x )7.一个句型一定句子。

( X )8.算符优先分析法每次都是对句柄进行归约。

(应是最左素短语) ( X )9.采用三元式实现三地址代码时,不利于对中间代码进行优化。

(√)10.编译过程中,语法分析器的任务是分析单词是怎样构成的。

( x )11.一个优先表一定存在相应的优先函数。

( x )12.目标代码生成时,应考虑如何充分利用计算机的寄存器的问题。

( )13.递归下降分析法是一种自下而上分析法。

( )14.并不是每个文法都能改写成LL(1)文法。

( )15.每个基本块只有一个入口和一个出口。

( )16.一个LL(1)文法一定是无二义的。

( )17.逆波兰法表示的表达试亦称前缀式。

( )18.目标代码生成时,应考虑如何充分利用计算机的寄存器的问题。

( )19.正规文法产生的语言都可以用上下文无关文法来描述。

( )20.一个优先表一定存在相应的优先函数。

( )21.3型文法一定是2型文法。

( )22.如果一个文法存在某个句子对应两棵不同的语法树,则文法是二义性的。

( )二、填空题:1.( 最右推导 )称为规范推导。

2.编译过程可分为(词法分析),(语法分析),(语义分析和中间代码生成),(代码优化)和(目标代码生成)五个阶段。

3.如果一个文法存在某个句子对应两棵不同的语法树,则称这个文法是()。

4.从功能上说,程序语言的语句大体可分为()语句和()语句两大类。

5.语法分析器的输入是(),其输出是()。

6.扫描器的任务是从()中识别出一个个()。

编译原理实验二:LL(1)语法分析器

编译原理实验二:LL(1)语法分析器

编译原理实验⼆:LL(1)语法分析器⼀、实验要求 1. 提取左公因⼦或消除左递归(实现了消除左递归) 2. 递归求First集和Follow集 其它的只要按照课本上的步骤顺序写下来就好(但是代码量超多...),下⾯我贴出实验的⼀些关键代码和算法思想。

⼆、基于预测分析表法的语法分析 2.1 代码结构 2.1.1 Grammar类 功能:主要⽤来处理输⼊的⽂法,包括将⽂法中的终结符和⾮终结符分别存储,检测直接左递归和左公因⼦,消除直接左递归,获得所有⾮终结符的First集,Follow集以及产⽣式的Select集。

#ifndef GRAMMAR_H#define GRAMMAR_H#include <string>#include <cstring>#include <iostream>#include <vector>#include <set>#include <iomanip>#include <algorithm>using namespace std;const int maxn = 110;//产⽣式结构体struct EXP{char left; //左部string right; //右部};class Grammar{public:Grammar(); //构造函数bool isNotTer(char x); //判断是否是终结符int getTer(char x); //获取终结符下标int getNonTer(char x); //获取⾮终结符下标void getFirst(char x); //获取某个⾮终结符的First集void getFollow(char x); //获取某个⾮终结符的Follow集void getSelect(char x); //获取产⽣式的Select集void input(); //输⼊⽂法void scanExp(); //扫描输⼊的产⽣式,检测是否有左递归和左公因⼦void remove(); //消除左递归void solve(); //处理⽂法,获得所有First集,Follow集以及Select集void display(); //打印First集,Follow集,Select集void debug(); //⽤于debug的函数~Grammar(); //析构函数protected:int cnt; //产⽣式数⽬EXP exp[maxn]; //产⽣式集合set<char> First[maxn]; //First集set<char> Follow[maxn]; //Follow集set<char> Select[maxn]; //select集vector<char> ter_copy; //去掉$的终结符vector<char> ter; //终结符vector<char> not_ter; //⾮终结符};#endif 2.1.2 AnalyzTable类 功能:得到预测分析表,判断输⼊的⽂法是否是LL(1)⽂法,⽤预测分析表法判断输⼊的符号串是否符合刚才输⼊的⽂法,并打印出分析过程。

语法分析器实验报告

语法分析器实验报告

语法分析器的设计实验报告一、实验内容语法分析程序用LL(1)语法分析方法。

首先输入定义好的文法书写文件(所用的文法可以用LL(1)分析),先求出所输入的文法的每个非终结符是否能推出空,再分别计算非终结符号的FIRST集合,每个非终结符号的FOLLOW集合,以及每个规则的SELECT集合,并判断任意一个非终结符号的任意两个规则的SELECT集的交集是不是都为空,如果是,则输入文法符合LL(1)文法,可以进行分析。

对于文法:G[E]:E->E+T|TT->T*F|FF->i|(E)分析句子i+i*i是否符合文法。

二、基本思想1、语法分析器实现语法分析是编译过程的核心部分,它的主要任务是按照程序的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行词法检查,为语义分析和代码生成作准备。

这里采用自顶向下的LL(1)分析方法。

语法分析程序的流程图如图5-4所示。

语法分析程序流程图该程序可分为如下几步:(1)读入文法(2)判断正误(3)若无误,判断是否为LL(1)文法(4)若是,构造分析表;(5)由句型判别算法判断输入符号串是为该文法的句型。

三、核心思想该分析程序有15部分组成:(1)首先定义各种需要用到的常量和变量;(2)判断一个字符是否在指定字符串中;(3)读入一个文法;(4)将单个符号或符号串并入另一符号串;(5)求所有能直接推出&的符号;(6)求某一符号能否推出‘& ’;(7)判断读入的文法是否正确;(8)求单个符号的FIRST;(9)求各产生式右部的FIRST;(10)求各产生式左部的FOLLOW;(11)判断读入文法是否为一个LL(1)文法;(12)构造分析表M;(13)句型判别算法;(14)一个用户调用函数;(15)主函数;下面是其中几部分程序段的算法思想:1、求能推出空的非终结符集Ⅰ、实例中求直接推出空的empty集的算法描述如下:void emp(char c){ 参数c为空符号char temp[10];定义临时数组int i;for(i=0;i<=count-1;i++)从文法的第一个产生式开始查找{if 产生式右部第一个符号是空符号并且右部长度为1,then将该条产生式左部符号保存在临时数组temp中将临时数组中的元素合并到记录可推出&符号的数组empty中。

编译原理考试题及答案

编译原理考试题及答案

编译原理考试题及答案一、选择题(每题2分,共10分)1. 在编译原理中,词法分析的主要任务是什么?A. 将源程序代码转换为中间代码B. 识别源程序中的词法单位并生成词法单元C. 检查源程序的语法正确性D. 优化生成的代码答案:B2. 下列哪个不是编译器的组成部分?A. 词法分析器B. 语法分析器C. 代码生成器D. 运行时库答案:D3. 在编译过程中,语义分析的主要作用是什么?A. 识别词法错误B. 检查语法错误C. 检查类型错误D. 生成目标代码答案:C4. 编译器中的中间代码表示通常采用哪种形式?A. 三地址代码B. 后缀表达式C. 抽象语法树D. 逆波兰表示答案:A5. 编译器优化的主要目标是什么?A. 增加程序的可读性B. 提高程序的执行效率C. 减少程序的存储空间D. 以上都是答案:D二、填空题(每题2分,共10分)1. 编译器的前端主要包括词法分析、______和语义分析。

答案:语法分析2. 编译器的后端主要包括代码优化、______和目标代码生成。

答案:代码生成3. 词法分析器通常使用______来识别词法单位。

答案:有限自动机4. 语法分析器可以使用______文法来描述语言的语法结构。

答案:上下5. 编译器优化中,______优化可以减少程序的运行时间。

答案:时间三、简答题(每题5分,共20分)1. 简述编译器的主要功能。

答案:编译器的主要功能包括将高级语言编写的源程序转换成等价的目标程序,同时进行语法、语义和运行时错误检查,以及代码优化以提高程序的执行效率。

2. 描述编译过程中的词法分析阶段的主要任务。

答案:词法分析阶段的主要任务是将源程序的字符序列分割成一系列的标记(token),这些标记是源程序中最小的有意义的单位,如关键字、标识符、常量等,并为后续的语法分析阶段提供输入。

3. 什么是语法分析?它在编译过程中的作用是什么?答案:语法分析是编译过程中的一个阶段,其任务是根据语言的语法规则检查源程序是否符合语法结构,并构建出抽象语法树(AST)。

编译原理填空题

编译原理填空题

1.设G是一个给定的文法,S是文法的开始符号,如果S->x(其中x∈VT*),则称x是文法的一个__句子___。

2.递归下降法不允许任一非终极符是直接__左___递归的。

3.自顶向下的语法分析方法的基本思想是:从文法的__开始符号____开始,根据给定的输入串并按照文法的产生式一步一步的向下进行__直接推导____,试图推导出文法的__句子____,使之与给定的输入串___匹配___。

4.自底向上的语法分析方法的基本思想是:从输入串入手,利用文法的产生式一步一步地向上进行___直接归约__,力求归约到文法的__开始符号___。

5.常用的参数传递方式有___传地址__,传值和传名。

6.在使用高级语言编程时,首先可通过编译程序发现源程序的全部__语法___错误和语义部分错误。

1.编译程序的工作过程一般可以划分为词法分析,语法分析,语义分析,中间代码生成,代码优化等几个基本阶段,同时还会伴有__表格处理___和___出错处理__。

2.若源程序是用高级语言编写的,___目标程序__是机器语言程序或汇编程序,则其翻译程序称为___编译程序__。

3.编译方式与解释方式的根本区别在于__是否生成目标代码___。

4.对编译程序而言,输入数据是___源程序__,输出结果是__目标程序___。

5.产生式是用于定义___语法成分__的一种书写规则。

6.语法分析最常用的两类方法是___自上而下__和___自下而上__分析法。

1.一个句型中的最左简单短语称为该句型的___句柄__2.对于文法的每个产生式都配备了一组属性的计算规则,称为__语义规则___。

3.一个典型的编译程序中,不仅包括__词法分析___、__语法分析___、__中间代码生成___、代码优化、目标代码生成等五个部分,还应包括表格处理和出错处理。

4.从功能上说,程序语言的语句大体可分为__执行性___语句和__说明性___语句两大类。

5.扫描器的任务是从__源程序___中识别出一个个___单词符号__。

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

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

编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字.标示符.无符号整数.运算符.和界符。

三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

2、程序流程图(1)主程序(2)扫描子程序3五、实验内容:1、实验分析编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k(int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符。

字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。

2 实验词法分析器源程序:#include <>#include <>#include <>int i,j,k;char c,s,a[20],token[20]={'0'};int letter(char s){if((s>=97)&&(s<=122)) return(1);else return(0);}int digit(char s){if((s>=48)&&(s<=57)) return(1);else return(0);}void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else")==0) return(3);else if(strcmp(token,"switch")==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf("please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!='#');i=1;j=0;get();while(s!='#'){ memset(token,0,20);switch(s){case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'q':case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z':while(letter(s)||digit(s)){token[j]=s;j=j+1;get();}retract();k=lookup(token);if(k==0)printf("(%d,%s)",6,token);else printf("(%d,-)",k);break;case '0':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':while(digit(s)){token[j]=s;j=j+1;get();}retract();printf("%d,%s",7,token);break;case '+':printf("('+',NULL)");break;case '-':printf("('-',null)");break; case '*':printf("('*',null)");break;case '<':get();if(s=='=') printf("(relop,LE)");else{retract();printf("(relop,LT)");}break;case '=':get();if(s=='=')printf("(relop,EQ)");else{retract();printf("('=',null)");}break;case ';':printf("(;,null)");break;case ' ':break;default:printf("!\n");}j=0;get();} }六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术。

语法分析器实验报告

语法分析器实验报告

语法分析器的设计实验报告一、实验内容语法分析程序用LL(1)语法分析方式。

第一输入概念好的文法书写文件(所用的文法能够用LL(1)分析),先求出所输入的文法的每一个非终结符是不是能推出空,再别离计算非终结符号的FIRST 集合,每一个非终结符号的FOLLOW集合,和每一个规那么的SELECT集合,并判定任意一个非终结符号的任意两个规那么的SELECT集的交集是不是都为空,若是是,那么输入文法符合LL(1)文法,能够进行分析。

关于文法:G[E]:E->E+T|TT->T*F|FF->i|(E)分析句子i+i*i是不是符合文法。

二、大体思想一、语法分析器实现语法分析是编译进程的核心部份,它的要紧任务是依照程序的语法规那么,从由词法分析输出的源程序符号串中识别出各类语法成份,同时进行词法检查,为语义分析和代码生成作预备。

那个地址采纳自顶向下的LL(1)分析方式。

语法分析程序的流程图如图5-4所示。

语法分析程序流程图该程序可分为如下几步:(1)读入文法(2)判定正误(3)假设无误,判定是不是为LL(1)文法(4)假设是,构造分析表;(5)由句型判别算法判定输入符号串是为该文法的句型。

三、核心思想该分析程序有15部份组成:(1)第一概念各类需要用到的常量和变量;(2)判定一个字符是不是在指定字符串中;(3)读入一个文法;(4)将单个符号或符号串并入另一符号串;(5)求所有能直接推出&的符号;(6)求某一符号可否推出‘& ’;(7)判定读入的文法是不是正确;(8)求单个符号的FIRST;(9)求各产生式右部的FIRST;(10)求各产生式左部的FOLLOW;(11)判定读入文法是不是为一个LL(1)文法;(12)构造分析表M;(13)句型判别算法;(14)一个用户挪用函数;(15)主函数;下面是其中几部份程序段的算法思想:1、求能推出空的非终结符集Ⅰ、实例中求直接推出空的empty集的算法描述如下:void emp(char c){ 参数c为空符号char temp[10];概念临时数组int i;for(i=0;i<=count-1;i++)从文法的第一个产生式开始查找{if 产生式右部第一个符号是空符号而且右部长度为1,then将该条产生式左部符号保留在临时数组temp中将临时数组中的元素归并到记录可推出&符号的数组empty中。

编译原理试题及答案3

编译原理试题及答案3

编译原理复习题一、填空题:1、编译方式与解释方式的根本区别在于(是否生成目标代码)。

2、对编译程序而言,输入数据是(源程序),输出结果是(目标程序)。

3、如果编译程序生成的目标程序是机器代码程序,则源程序的执行分为两大阶段:(编译阶段)和(运行阶段)。

4、如果编译程序生成的目标程序是汇编语言程序,则源程序的执行分成三个阶段:(编译阶段)、(汇编阶段)和(运行阶段)。

5、自顶向下语法分析方法会遇到的主要问题有(回溯)和((左递归带来的)无限循环)。

6、LL(k)分析法中,第一个L的含义是(从左到右进行分析),第二个L的含义是(每次进行最左推导),“k”的含义是(向输入串中查看K个输入符号)。

7、LL(1)分析法中,第一个L的含义是(从左到右进行分析),第二个L的含义是(每次进行最左推导),“1”的含义是(向输入串中查看1个输入符号)。

8、自顶向下语法分析方法的基本思想是:从(识别符号)出发,不断建立(直接推导),试图构造一个推导序列,最终由它推导出与输入符号相同的(符号串)。

9、自底向上语法分析方法的基本思想是:从待输入的符号串开始,利用文法的规则步步向上进行(直接归约),试图(归约)到文法的(识别符号|开始符号)。

10、LR(0)分析法的名字中,“L”的含义是(从左到右进行分析),“R”的含义是(采用最右推导的逆过程---最左归约),“0”的含义是(向貌似句柄的符号串后查看0个输入符号)。

11、LR(1)分析法的名字中,“L”的含义是(从左到右进行分析),“R”的含义是(采用最右推导的逆过程---最左归约),“1”的含义是(向貌似句柄的符号串后查看1个输入符号)。

12、SLR(1)分析法的名字中,“S”的含义是(简单的),“L”的含义是(从左到右进行分析),“R”的含义是(采用最右推导的逆过程---最左归约),“1”的含义是(向貌似句柄的符号串后查看1个输入符号)。

13、在编译过程中,常见的中间语言形式有(逆波兰表示)、(三元式)、(四元式)和(树形表示)。

语法分析器实验报告

语法分析器实验报告

杭州电子科技大学班级: 12052312 专业: 计算机科学与技术实验报告【实验名称】实验二语法分析一. 实验目的编写一个语法分析程序, 实现对词法分析程序所提供的单词序列的语法检查和结构分析。

二. 实验内容利用编程语言实现语法分析程序, 并对简单语言进行语法分析。

2.1 待分析的简单语言的语法用扩充的BNF表示如下:⑴<程序>: : =begin<语句串>end⑵<语句串>: : =<语句>{;<语句>}⑶<语句>: : =<赋值语句>⑷<赋值语句>: : =ID: =<表达式>⑸<表达式>: : =<项>{+<项> | -<项>}⑹<项>: : =<因子>{*<因子> | /<因子>⑺<因子>: : =ID | NUM | (<表达式>)2.2 实验要求说明输入单词串, 以“#”结束, 如果是文法正确的句子, 则输出成功信息, 打印“success”, 否则输出“error”。

例如:输入begin a:=9; x:=2*3; b:=a+x end #输出success!输入x:=a+b*c end #输出error测试以上输入的分析, 并完成实验报告。

2.3 语法分析程序的算法思想(1)主程序示意图如图2-1所示。

图2-1 语法分析主程序示意图(2)递归下降分析程序示意图如图2-2所示。

(3)语句串分析过程示意图如图2-3所示。

图2-3 语句串分析示意图图2-2 递归下降分析程序示意图(4)statement 语句分析程序流程如图2-4.2-5.2-6.2-7所示。

图2-4 statement 语句分析函数示意图 图2-5 expression 表达式分析函数示意图图2-7 factor 分析过程示意图三.个人心得一、 通过该实验, 主要有以下几方面收获: 二、 对实验原理有更深的理解。

minic语法树

minic语法树

minic语法树
MiniC语法树是一种数据结构,用于表示MiniC语言的语法结构。

MiniC是一种简化的C语言,它包含了C语言的基本语
法和常用特性。

简单来说,MiniC语法树由一个根节点和多个子节点组成,根
节点表示整个程序,而每个子节点表示程序中的语句、表达式、声明等。

以下是MiniC语法树的一部分示例:
Program (程序)
└── Declaration (声明)
└── VariableDeclaration (变量声明)
├── TypeSpecifier (类型说明符)
│ └── int (整型)
└── Identifier (标识符)
└── x (变量名)
上述示例表示了一个简单的整型变量声明,声明了一个名为x
的整型变量。

MiniC语法树可以进一步扩展以包含更多的语法结构,例如控
制流语句(if、while等)、函数声明、函数调用等。

需要注意的是,MiniC语法树只描述语法结构,而不包含语义
信息。

当进行语义分析时,可以根据语法树进行类型检查和符
号表查找等操作。

以上所述是MiniC语法树的一个简单示例,实际上MiniC语法树的结构和规模会更加复杂和庞大,根据具体的MiniC语言规范和需求进行设计和实现。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

语法分析器LEX代码段:%{#include <stdlib.h>#include "calc3.h"#include "y.tab.h"void yyerror(char *);%}%%[a-z] {yylval.sIndex = *yytext - 'a';return VARIABLE;}[0-9]+ {yylval.iValue = atoi(yytext);return INTEGER;}[-()<>=+*/;{}.] {return *yytext;}">=" return GE;"<=" return LE;"==" return EQ;"!=" return NE; "while" return WHILE; "for" r eturn FOR;"if" return IF;"else" return ELSE; "print" return PRINT; "return" return RETURN;[ \t\n]+ ; /* ignore whitespace */ . yyerror("Unknown character"); %%int yywrap(void) {return 1;}YACC代码段:%{#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include "calc3.h"/* prototypes */nodeType *opr(int oper, int nops, ...); nodeType *id(int i);nodeType *con(int value);void freeNode(nodeType *p);int ex(nodeType *p);int yylex(void);void yyerror(char *s);int sym[26]; /* symbol table */%}%union {int iValue; /* integer value */char sIndex; /* symbol table index */nodeType *nPtr; /* node pointer */};%token <iValue> INTEGER%token <sIndex> VARIABLE%token WHILE FOR IF PRINT RETURN%nonassoc IFX%nonassoc ELSE%left GE LE EQ NE '>' '<'%left '+' '-'%left '*' '/'%nonassoc UMINUS%type <nPtr> stmt expr stmt_list%%program:function { exit(0); };function:function stmt { ex($2); freeNode($2); }| /* NULL */;stmt:';' { $$ = opr(';', 2, NULL, NULL); }| expr ';' { $$ = $1; }| PRINT expr ';' { $$ = opr(PRINT, 1, $2); }| RETURN expr ';' { $$ = opr(RETURN, 1, $2); }| VARIABLE '=' expr ';' { $$ = opr('=', 2, id($1), $3); }| WHILE '(' expr ')' stmt { $$ = opr(WHILE, 2, $3, $5); }| FOR '(' stmt expr ';' stmt ')' stmt { $$ = opr(FOR, 4, $3, $4,$6,$8); } | IF '(' expr ')' stmt %prec IFX { $$ = opr(IF, 2, $3, $5); }| IF '(' expr ')' stmt ELSE stmt{ $$ = opr(IF, 3, $3, $5, $7); }| '{' stmt_list '}' { $$ = $2; };stmt_list:stmt { $$ = $1; }| stmt_list stmt { $$ = opr(';', 2, $1, $2); };expr:INTEGER { $$ = con($1); }| VARIABLE { $$ = id($1); }| '-' expr %prec UMINUS { $$ = opr(UMINUS, 1, $2); }| expr '+' expr { $$ = opr('+', 2, $1, $3); }| expr '-' expr { $$ = opr('-', 2, $1, $3); }| expr '*' expr { $$ = opr('*', 2, $1, $3); }| expr '/' expr { $$ = opr('/', 2, $1, $3); }| expr '<' expr { $$ = opr('<', 2, $1, $3); }| expr '>' expr { $$ = opr('>', 2, $1, $3); }| expr GE expr { $$ = opr(GE, 2, $1, $3); }| expr LE expr { $$ = opr(LE, 2, $1, $3); }| expr NE expr { $$ = opr(NE, 2, $1, $3); }| expr EQ expr { $$ = opr(EQ, 2, $1, $3); }| '(' expr ')' { $$ = $2; };%%#define SIZEOF_NODETYPE ((char *)&p->con - (char *)p)nodeType *con(int value) {nodeType *p;size_t nodeSize;/* allocate node */nodeSize = SIZEOF_NODETYPE + sizeof(conNodeType);if ((p = malloc(nodeSize)) == NULL)yyerror("out of memory");/* copy information */p->type = typeCon;p->con.value = value;return p;}nodeType *id(int i) {nodeType *p;size_t nodeSize;/* allocate node */nodeSize = SIZEOF_NODETYPE + sizeof(idNodeType);if ((p = malloc(nodeSize)) == NULL)yyerror("out of memory");/* copy information */p->type = typeId;p->id.i = i;return p;}nodeType *opr(int oper, int nops, ...) {va_list ap;nodeType *p;size_t nodeSize;int i;/* allocate node */nodeSize = SIZEOF_NODETYPE + sizeof(oprNodeType) + (nops - 1) * sizeof(nodeType*);if ((p = malloc(nodeSize)) == NULL)yyerror("out of memory");/* copy information */p->type = typeOpr;p->opr.oper = oper;p->opr.nops = nops;va_start(ap, nops);for (i = 0; i < nops; i++)p->opr.op[i] = va_arg(ap, nodeType*);va_end(ap);return p;}void freeNode(nodeType *p) {int i;if (!p) return;if (p->type == typeOpr) {for (i = 0; i < p->opr.nops; i++)freeNode(p->opr.op[i]);}free (p);}void yyerror(char *s) {fprintf(stdout, "%s\n", s);}int main(void) {yyparse();return 0;}测试程序:x=1;while(x<3){print(x);x = x+1;if(x>10)x=7;elsex=9;return x;}for(x=0 ; x<10 ; x=x+1;) {x = x+2;print(x);return x;}图形生成:Graph 0:[=]||----|| |id(X) c(1)Graph 1:while||-------------------------------------|| |[<] [;]| ||----| |-------------------------------|| | | | id(X) c(3) [;] return| ||----------------------------| || | |[;] if id(X)| ||----------| |---------------------|| | | | |print [=] [>] [=] [=]| | | | || |-------| |-----| |----| |----|| | | | | | | | |id(X) id(X) [+] id(X) c(10) id(X) c(7) id(X) c(9)||----|| |id(X) c(1)Graph 2:for||-----------|-------------|-----------------------|| | | |[=] [<] [=] [;]| | | ||----| |-----| |-------| |--------------|| | | | | | | |id(X) c(0) id(X) c(10) id(X) [+] [;] return| | ||----| |-----------| || | | | |id(X) c(1) [=] print id(X)| ||-------| || | | id(X) [+] id(X)||----|| |id(X) c(2)。

相关文档
最新文档