编译原理 预测分析法实验

课 程 设 计 书

目 录

一、设计内容·····························································1 二、目的与基本要求·······················································1 三、语法分析器的功能·····················································1 四、算法分析····················································1 4.1相关理论介绍········································1 4.2设计原理····················································2 4.3构造LL(1)分析表·································3 4.4利用分析表进行预测分析的步骤······························5 4.5···································6 五、流程框图·················································6 六、函数相关说明··············································8 七、参考程序清单·············································8 八、程序运行结果···········································17 九、使用方法·················································19 十、····················································20 ···························································20

课 程 设 计 书

语 法 分 析 器

—预测分析法

一、设计内容

用预测分析法(即LL (1)分析法)构造文法G[E]:

E → E + T | T T → T * F | F

F → ( E ) | i | x | y

的预测分析程序(即语法分析器)。

二、目的与基本要求

1析的条件。

2、学会用C/C++LL (1)分析法的语法分析器; 3

4.1相关理论介绍

语法分析是编译过程的核心部分。语法分析的任务就是识别词法分析程序输出的单词序列是否为给定方法的正确句子,并确定其语法结构。尽管目前已提出很多语法分析方法,但总体上语法分析的方法可分为两大类:自顶向下的分析方法和自底向上的分析方法。

课 程 设 计 书

自底向上的分析方法就是归约的方法,即从待分析符号串出发,从底向上构造语法树,若能够造至树根(能够归约到方法开始符号),则表示该符号串是方法的句子。

自顶向下的分析法其实就是推导的方法,也就是从方法的开始符号出发,试图向下构造待分析符号串的语法树,若语法的叶结点可以构成该符号串(能够推导出该符号串),则表示这个符号串是方法的句子。自顶向下的分析方法又分为:带回溯的自顶向下分析方法和确定的自顶向下分析方法。一个文法如果要能进行确定的自顶向下分析,必须满足什么条件呢?

由可选集的定义可知,规则A →x 的可选集SELECT (A →x 推导出的下一个终结符号的集合。因此利用SELECT 据当前输入的符号有目的的选择产生式。

U →X i )(i=1,2,3,„,n ) ,求可选集。这样,U ,待输入符号为a, 且a ∈SELECT (U →X i 一定能推导出等输入符号a 。

a ∉SELECT (U (,n,i ≠j ) 。

一个非终结符A A x 1 |x2|„|xn ,满足SELECT (A →x i )⋂SELECT(A→x j )=φ„,即同一个非终结符各规则的SELECT 集两两不相交。

LL (1)分析法等, 下面详细介绍预测,的相关理论,分析表构造,预测分析过程。

4.2设计原理

所谓LL (1)分析法,就是指从左到右扫描输入串(源程序),同时采用最左推导,且对每次直接推导只需向前看一个输入符号,便可确定当前所应当选择的规则。实现LL (1)分析的程序又称为LL (1)分析程序或LL (1)分析器。

我们知道一个文法要能进行LL (1)分析,那么这个文法应该满足:无二义性,无左递归,无左公因子。当文法满足条件后,再分别构造文法每个非终结符的FIRST 和

课 程 设 计 书

FOLLOW 集合,然后根据FIRST 和FOLLOW 集合构造LL (1)分析表,最后利用分析表,根据LL(1)语法分析构造一个分析器。LL (1)的语法分析程序包含了三个部分,总控程序,预测分析表函数,先进先出的语法分析栈,本程序也是采用了同样的方法进行语法分析,该程序是采用了C++语言来编写,其逻辑结构图如下:

4.3 构造LL(1)分析表

考查文法G[E]:

E →E+T | T

T →T*F | F

F →( E ) | i | x | y

课 程 设 计 书

我们容易看出此文法没有左公因子也没有二义性,但却存在两个直接左递归,这里我们利用引入新非终结符的方法来消除它使方法满足要求,即:

对形如:U →Ux|y的产生式(其中x,y ∈V + ,y 不以U 开头),引入一个新的非终结符U ’后,可以等价地改写成为:

U →yU ’

U ’→x U’|ε

显然改写后,U 和U ’都不是左递归的非终结符。因此文法G [E 归后可等价地写成:

E →TP

P→+TP | ε T→FQ

Q→*FQ | ε

F →( E ) | i | x | y

在构造LL(1)FIRST 和FOLLOW ①FIRST 集合的构造算法:

(1)若X ∈V T ,则FIRST ((2)若X ∈V N X a 加入到FIRST(X)中;若X →ε也是一条产生式,则把ε(3)若X →Y V N ,则把FIRST(Y)中的所有非ε-元素都加到FIRST(X)中;若Y 1Y 2k Y 1,„,Y i-1都是非终结符,而且,对于任何j ,1≤j ≤j ε(即Y 1„Y i-1*⇒ε),则把FIRST(Yj ) 中的所有非ε-FIRST(Yj ) 均含有ε,j=1,2,„,k ,则把ε加到FIRST 不再增大为止。

S ,置#于FOLLOW(S)中;

(2)若→αB β是一个产生式,则把FIRST(β)| {ε}加至FOLLOW(B)中; (3)若A →αB 是一个产生式,或A →αB β是一个产生式而β⇒ε(即ε∈FIRST(β) ),则把FOLLOW(A)加至FOLLOW(B)中。

连续使用上面的规则,直至每个集合FOLLOW 不再增大为止。

根据以上描述的算法,可以构造文法G [E ]的FIRST 和FOLLOW 集合如下:

FIRST(E) = {( , i,x ,y } FOLLOW(E) = { ) , # }

课 程 设 计 书

FIRST(P) = { + ,ε} FIRST(T) = { ( , i,x ,y } FIRST(Q) = { * , ε} FIRST(F) = { ( , i,x ,y } FOLLOW(P) = { ) , # } FOLLOW(T) = { + , ) , # } FOLLOW(Q) = { + , ) , # } FOLLOW(F) = { * , + , ) , # }

现在来构造G [E ]的LL (1)预测分析表。预测分析表M[A, a]是如下形式的一个矩阵。A 为非终结符,a 是终结符或‘#’。矩阵元素 M[A, a]中存放这一条关于A 的产

课 程 设 计 书

4.5预测分析程序的总控程序的算法描述

实现LL(1)的一种有效方法是使用一张分析表和一个栈进行联合控制。如果前面已经设计好了分析表和栈的话,那么现在就开始具体实现这个LL(1)LL(1)分析程序的算法的描述如下:

BEGIN

首先把‘#’然后把文法开始符号推进STACK 分析栈; 把第一个输入符号读进a ; FLAG = TURE; WHILE FLAG DO BEGIN

把STACK IF X∈V T THEN

a ELSE ‘ →X 1X 2„„X k } THEN 把X k-1X 1,一一推进STACK 栈 若1X k = ε,不推进什么进栈 */ 分析成功 */

五、流程框图

课 程 设 计 书

课 程 设 计 书

六、函数相关说明

分析栈可以采取许多的存储方法来设计,在这里采用的顺序栈。这里定义了一个类Stack ,将所有对栈的操作封装在Stack 类中,作为它的成员函数。

根据预测分析器模型,LL(1)分析器的实现关键在于分析栈和分析表是采用何种数据结构来实现。分析表是一个矩阵,当我们要调用分析表来分析时,就根据栈顶的非终结符和当前输入的终结符来决定执行哪种过程。具体设计思想如下:

//声明:每个Event 执行一个特定的进栈处理,Error 将抛出错误 void Event1(); void Event2(); void Event3(); void Event4(); void Event5(); void Event6(); void Event7(); void Error();

typedef void (*Action)();

// };

#if !defined(AFX_STACK_H__AA8994AF_8B3A_477C_A4CC_6F18499CA9BE__INCLUDED_)

#define AFX_STACK_H__AA8994AF_8B3A_477C_A4CC_6F18499CA9BE__INCLUDED_

#if _MSC_VER > 1000 #pragma once

课 程 设 计 书

#endif // _MSC_VER > 1000

class Stack {

public:

Stack(); ~Stack();

void push(char token); char pop(); bool isEmpty();

private:

char *_stack; int _top; int _bottom; };

#endif

// D_)

// stack

// Construction/Destruction

Stack::Stack() {

_stack=new char [InitStackSize]; _top=_bottom=-1;

课 程 设 计 书

}

Stack::~Stack() {

_top=_bottom=-1; delete _stack; }

// Attributes

void Stack::push(char token) {

if(_top>=InitStackSize-1) {

exit(1); }

_top++;

_stack[_top]=token; }

{

{

}

}

bool Stack::isEmpty() {

if(_top==_bottom) return true; else

课 程 设 计 书

return false; }

// 分析表的构造 #include "Stack.h" #include

using namespace std;

const int NonterminalNum=5; //非终结符个数 const int TerminalNum=7; //终结符个数

char nonterminal[]={'E', 'P', 'T', 'Q','F'}; //

定义终结符 Stack stack;

// 事件描述与LL (1)分析表

void Event1(); void Event2(); void Event3(); void Event4(); void Event5(); void Event6();

{Event4, Error, Error, Event4, Error, Error}, {Error, Event3, Event5, Error, Event3, Event3}, {Event6, Error, Error, Event7, Error, Error} };

// 定义事件

课 程 设 计 书

void Event1() {

stack.push('P'); stack.push('T'); };

void Event2() {

stack.push('P'); stack.push('T'); stack.push('+'); };

void Event3() { };

void Event4() {

stack.push('Q'); };

{

void Event6() {

stack.push('i'); stack.push('x'); stack.push('y'); };

课 程 设 计 书

void Event7() {

stack.push(')'); stack.push('E'); stack.push('('); };

// 出错处理

void Error() {

cerr

// 判断 Token

bool isVt(char ch) {

{

// 字符串入 Stack 分析栈

void pushTogether(char nonterminal, char terminal) {

switch(nonterminal) {

课 程 设 计 书

case 'E':

switch(terminal) {

case 'i': ParseTable[4][0](); break; case 'x': ParseTable[4][1](); break; case 'y': ParseTable[4][2](); break; case '+': ParseTable[4][3](); break; case '*': ParseTable[4][4](); break; case '(': ParseTable[4][5](); break; case ')': ParseTable[4][6](); break; case '#': ParseTable[4][7](); break; default: break; }

break;

case 'P':

switch(terminal) {

case 'i': case 'x': case 'y': switch(terminal) {

case 'i': ParseTable[4][0](); break; case 'x': ParseTable[4][1](); break; case 'y': ParseTable[4][2](); break; case '+': ParseTable[4][3](); break; case '*': ParseTable[4][4](); break;

课 程 设 计 书

case '(': case ')': case '#': default: }

break;

ParseTable[4][5](); break; ParseTable[4][6](); break; ParseTable[4][7](); break; break;

case 'Q':

switch(terminal) {

case 'i': ParseTable[4][0](); break; case 'x': ParseTable[4][1](); break; case 'y': ParseTable[4][2](); break; case '+': case '*': case '(': case ')': case '#': default: break; }

break;

case 'F':

{

ParseTable[4][2](); break; ParseTable[4][3](); break; ParseTable[4][4](); break; ParseTable[4][5](); break; case ')': ParseTable[4][6](); break; case '#': ParseTable[4][7](); break; default: break; }

break; default:

课 程 设 计 书

Error(); break; } }

// LL(1)分析程序 #include #include "Stack.h" #include "Parse.h"

using namespace std; void LL1Parse() {

stack.push('#'); stack.push('E');

char a;

cout

{

//match

Error(); {

if(X==a) //parse successfully flag=false; else

Error(); }

else //reverse, push into stack

课 程 设 计 书

pushTogether(X, a); }

if(stack.isEmpty())

cout

// 主程序

#include #include "LL1.h" using namespace std; void main() {

cout

cout

cout

cout

i+i*i#, 显示“分析成功”。

课 程 设 计 书

显示“分析失败!”。运行结果如下:

课 程 设 计 书

九、使用方法

程序在VC++6.0下调试通过。打开VC6.0执行“文件”—>“新建”, 编辑上面的源程序,完成后单击“保存”(aa.cpp ),再单击菜单栏的“编译”—>“编译 aa.cpp”或按Ctrl+F7;“编译”—>“构件 aa.exe”或按F7;“编译”—>“执行 aa.exe”或按Ctrl+F5。

当然你也可以找aa.cpp 文件所在目录的“debug 目录”aa.exe, 拷贝到别的目录下面再在DOS 下来执行它。这里我把它拷到“然后执行“Win+R”,输入“CMD ”进入DOS, 接着执行“cd\”C:\录,再执行aa 回车。如下图:

课 程 设 计 书

十、课程设计心得

本次课程设计完成了语法分析器-预测分析法(即LL (1)分析法)的算法分析到实现的全部过程,结果满足设计要求,验证无误。在整整一个星期的日子里同时做两个课程设计,可以说是苦多于甜,但是可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课刻,掌握得不够牢固等等。

经努力过。

[1. 重庆大学出版社,2005年8月。

[2语言程序设计. 清华大学出版社,2005年月1月。

《编译原理》课程设计—预测分析法LL (1) 第21页

课 程 设 计 书

目 录

一、设计内容·····························································1 二、目的与基本要求·······················································1 三、语法分析器的功能·····················································1 四、算法分析····················································1 4.1相关理论介绍········································1 4.2设计原理····················································2 4.3构造LL(1)分析表·································3 4.4利用分析表进行预测分析的步骤······························5 4.5···································6 五、流程框图·················································6 六、函数相关说明··············································8 七、参考程序清单·············································8 八、程序运行结果···········································17 九、使用方法·················································19 十、····················································20 ···························································20

课 程 设 计 书

语 法 分 析 器

—预测分析法

一、设计内容

用预测分析法(即LL (1)分析法)构造文法G[E]:

E → E + T | T T → T * F | F

F → ( E ) | i | x | y

的预测分析程序(即语法分析器)。

二、目的与基本要求

1析的条件。

2、学会用C/C++LL (1)分析法的语法分析器; 3

4.1相关理论介绍

语法分析是编译过程的核心部分。语法分析的任务就是识别词法分析程序输出的单词序列是否为给定方法的正确句子,并确定其语法结构。尽管目前已提出很多语法分析方法,但总体上语法分析的方法可分为两大类:自顶向下的分析方法和自底向上的分析方法。

课 程 设 计 书

自底向上的分析方法就是归约的方法,即从待分析符号串出发,从底向上构造语法树,若能够造至树根(能够归约到方法开始符号),则表示该符号串是方法的句子。

自顶向下的分析法其实就是推导的方法,也就是从方法的开始符号出发,试图向下构造待分析符号串的语法树,若语法的叶结点可以构成该符号串(能够推导出该符号串),则表示这个符号串是方法的句子。自顶向下的分析方法又分为:带回溯的自顶向下分析方法和确定的自顶向下分析方法。一个文法如果要能进行确定的自顶向下分析,必须满足什么条件呢?

由可选集的定义可知,规则A →x 的可选集SELECT (A →x 推导出的下一个终结符号的集合。因此利用SELECT 据当前输入的符号有目的的选择产生式。

U →X i )(i=1,2,3,„,n ) ,求可选集。这样,U ,待输入符号为a, 且a ∈SELECT (U →X i 一定能推导出等输入符号a 。

a ∉SELECT (U (,n,i ≠j ) 。

一个非终结符A A x 1 |x2|„|xn ,满足SELECT (A →x i )⋂SELECT(A→x j )=φ„,即同一个非终结符各规则的SELECT 集两两不相交。

LL (1)分析法等, 下面详细介绍预测,的相关理论,分析表构造,预测分析过程。

4.2设计原理

所谓LL (1)分析法,就是指从左到右扫描输入串(源程序),同时采用最左推导,且对每次直接推导只需向前看一个输入符号,便可确定当前所应当选择的规则。实现LL (1)分析的程序又称为LL (1)分析程序或LL (1)分析器。

我们知道一个文法要能进行LL (1)分析,那么这个文法应该满足:无二义性,无左递归,无左公因子。当文法满足条件后,再分别构造文法每个非终结符的FIRST 和

课 程 设 计 书

FOLLOW 集合,然后根据FIRST 和FOLLOW 集合构造LL (1)分析表,最后利用分析表,根据LL(1)语法分析构造一个分析器。LL (1)的语法分析程序包含了三个部分,总控程序,预测分析表函数,先进先出的语法分析栈,本程序也是采用了同样的方法进行语法分析,该程序是采用了C++语言来编写,其逻辑结构图如下:

4.3 构造LL(1)分析表

考查文法G[E]:

E →E+T | T

T →T*F | F

F →( E ) | i | x | y

课 程 设 计 书

我们容易看出此文法没有左公因子也没有二义性,但却存在两个直接左递归,这里我们利用引入新非终结符的方法来消除它使方法满足要求,即:

对形如:U →Ux|y的产生式(其中x,y ∈V + ,y 不以U 开头),引入一个新的非终结符U ’后,可以等价地改写成为:

U →yU ’

U ’→x U’|ε

显然改写后,U 和U ’都不是左递归的非终结符。因此文法G [E 归后可等价地写成:

E →TP

P→+TP | ε T→FQ

Q→*FQ | ε

F →( E ) | i | x | y

在构造LL(1)FIRST 和FOLLOW ①FIRST 集合的构造算法:

(1)若X ∈V T ,则FIRST ((2)若X ∈V N X a 加入到FIRST(X)中;若X →ε也是一条产生式,则把ε(3)若X →Y V N ,则把FIRST(Y)中的所有非ε-元素都加到FIRST(X)中;若Y 1Y 2k Y 1,„,Y i-1都是非终结符,而且,对于任何j ,1≤j ≤j ε(即Y 1„Y i-1*⇒ε),则把FIRST(Yj ) 中的所有非ε-FIRST(Yj ) 均含有ε,j=1,2,„,k ,则把ε加到FIRST 不再增大为止。

S ,置#于FOLLOW(S)中;

(2)若→αB β是一个产生式,则把FIRST(β)| {ε}加至FOLLOW(B)中; (3)若A →αB 是一个产生式,或A →αB β是一个产生式而β⇒ε(即ε∈FIRST(β) ),则把FOLLOW(A)加至FOLLOW(B)中。

连续使用上面的规则,直至每个集合FOLLOW 不再增大为止。

根据以上描述的算法,可以构造文法G [E ]的FIRST 和FOLLOW 集合如下:

FIRST(E) = {( , i,x ,y } FOLLOW(E) = { ) , # }

课 程 设 计 书

FIRST(P) = { + ,ε} FIRST(T) = { ( , i,x ,y } FIRST(Q) = { * , ε} FIRST(F) = { ( , i,x ,y } FOLLOW(P) = { ) , # } FOLLOW(T) = { + , ) , # } FOLLOW(Q) = { + , ) , # } FOLLOW(F) = { * , + , ) , # }

现在来构造G [E ]的LL (1)预测分析表。预测分析表M[A, a]是如下形式的一个矩阵。A 为非终结符,a 是终结符或‘#’。矩阵元素 M[A, a]中存放这一条关于A 的产

课 程 设 计 书

4.5预测分析程序的总控程序的算法描述

实现LL(1)的一种有效方法是使用一张分析表和一个栈进行联合控制。如果前面已经设计好了分析表和栈的话,那么现在就开始具体实现这个LL(1)LL(1)分析程序的算法的描述如下:

BEGIN

首先把‘#’然后把文法开始符号推进STACK 分析栈; 把第一个输入符号读进a ; FLAG = TURE; WHILE FLAG DO BEGIN

把STACK IF X∈V T THEN

a ELSE ‘ →X 1X 2„„X k } THEN 把X k-1X 1,一一推进STACK 栈 若1X k = ε,不推进什么进栈 */ 分析成功 */

五、流程框图

课 程 设 计 书

课 程 设 计 书

六、函数相关说明

分析栈可以采取许多的存储方法来设计,在这里采用的顺序栈。这里定义了一个类Stack ,将所有对栈的操作封装在Stack 类中,作为它的成员函数。

根据预测分析器模型,LL(1)分析器的实现关键在于分析栈和分析表是采用何种数据结构来实现。分析表是一个矩阵,当我们要调用分析表来分析时,就根据栈顶的非终结符和当前输入的终结符来决定执行哪种过程。具体设计思想如下:

//声明:每个Event 执行一个特定的进栈处理,Error 将抛出错误 void Event1(); void Event2(); void Event3(); void Event4(); void Event5(); void Event6(); void Event7(); void Error();

typedef void (*Action)();

// };

#if !defined(AFX_STACK_H__AA8994AF_8B3A_477C_A4CC_6F18499CA9BE__INCLUDED_)

#define AFX_STACK_H__AA8994AF_8B3A_477C_A4CC_6F18499CA9BE__INCLUDED_

#if _MSC_VER > 1000 #pragma once

课 程 设 计 书

#endif // _MSC_VER > 1000

class Stack {

public:

Stack(); ~Stack();

void push(char token); char pop(); bool isEmpty();

private:

char *_stack; int _top; int _bottom; };

#endif

// D_)

// stack

// Construction/Destruction

Stack::Stack() {

_stack=new char [InitStackSize]; _top=_bottom=-1;

课 程 设 计 书

}

Stack::~Stack() {

_top=_bottom=-1; delete _stack; }

// Attributes

void Stack::push(char token) {

if(_top>=InitStackSize-1) {

exit(1); }

_top++;

_stack[_top]=token; }

{

{

}

}

bool Stack::isEmpty() {

if(_top==_bottom) return true; else

课 程 设 计 书

return false; }

// 分析表的构造 #include "Stack.h" #include

using namespace std;

const int NonterminalNum=5; //非终结符个数 const int TerminalNum=7; //终结符个数

char nonterminal[]={'E', 'P', 'T', 'Q','F'}; //

定义终结符 Stack stack;

// 事件描述与LL (1)分析表

void Event1(); void Event2(); void Event3(); void Event4(); void Event5(); void Event6();

{Event4, Error, Error, Event4, Error, Error}, {Error, Event3, Event5, Error, Event3, Event3}, {Event6, Error, Error, Event7, Error, Error} };

// 定义事件

课 程 设 计 书

void Event1() {

stack.push('P'); stack.push('T'); };

void Event2() {

stack.push('P'); stack.push('T'); stack.push('+'); };

void Event3() { };

void Event4() {

stack.push('Q'); };

{

void Event6() {

stack.push('i'); stack.push('x'); stack.push('y'); };

课 程 设 计 书

void Event7() {

stack.push(')'); stack.push('E'); stack.push('('); };

// 出错处理

void Error() {

cerr

// 判断 Token

bool isVt(char ch) {

{

// 字符串入 Stack 分析栈

void pushTogether(char nonterminal, char terminal) {

switch(nonterminal) {

课 程 设 计 书

case 'E':

switch(terminal) {

case 'i': ParseTable[4][0](); break; case 'x': ParseTable[4][1](); break; case 'y': ParseTable[4][2](); break; case '+': ParseTable[4][3](); break; case '*': ParseTable[4][4](); break; case '(': ParseTable[4][5](); break; case ')': ParseTable[4][6](); break; case '#': ParseTable[4][7](); break; default: break; }

break;

case 'P':

switch(terminal) {

case 'i': case 'x': case 'y': switch(terminal) {

case 'i': ParseTable[4][0](); break; case 'x': ParseTable[4][1](); break; case 'y': ParseTable[4][2](); break; case '+': ParseTable[4][3](); break; case '*': ParseTable[4][4](); break;

课 程 设 计 书

case '(': case ')': case '#': default: }

break;

ParseTable[4][5](); break; ParseTable[4][6](); break; ParseTable[4][7](); break; break;

case 'Q':

switch(terminal) {

case 'i': ParseTable[4][0](); break; case 'x': ParseTable[4][1](); break; case 'y': ParseTable[4][2](); break; case '+': case '*': case '(': case ')': case '#': default: break; }

break;

case 'F':

{

ParseTable[4][2](); break; ParseTable[4][3](); break; ParseTable[4][4](); break; ParseTable[4][5](); break; case ')': ParseTable[4][6](); break; case '#': ParseTable[4][7](); break; default: break; }

break; default:

课 程 设 计 书

Error(); break; } }

// LL(1)分析程序 #include #include "Stack.h" #include "Parse.h"

using namespace std; void LL1Parse() {

stack.push('#'); stack.push('E');

char a;

cout

{

//match

Error(); {

if(X==a) //parse successfully flag=false; else

Error(); }

else //reverse, push into stack

课 程 设 计 书

pushTogether(X, a); }

if(stack.isEmpty())

cout

// 主程序

#include #include "LL1.h" using namespace std; void main() {

cout

cout

cout

cout

i+i*i#, 显示“分析成功”。

课 程 设 计 书

显示“分析失败!”。运行结果如下:

课 程 设 计 书

九、使用方法

程序在VC++6.0下调试通过。打开VC6.0执行“文件”—>“新建”, 编辑上面的源程序,完成后单击“保存”(aa.cpp ),再单击菜单栏的“编译”—>“编译 aa.cpp”或按Ctrl+F7;“编译”—>“构件 aa.exe”或按F7;“编译”—>“执行 aa.exe”或按Ctrl+F5。

当然你也可以找aa.cpp 文件所在目录的“debug 目录”aa.exe, 拷贝到别的目录下面再在DOS 下来执行它。这里我把它拷到“然后执行“Win+R”,输入“CMD ”进入DOS, 接着执行“cd\”C:\录,再执行aa 回车。如下图:

课 程 设 计 书

十、课程设计心得

本次课程设计完成了语法分析器-预测分析法(即LL (1)分析法)的算法分析到实现的全部过程,结果满足设计要求,验证无误。在整整一个星期的日子里同时做两个课程设计,可以说是苦多于甜,但是可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课刻,掌握得不够牢固等等。

经努力过。

[1. 重庆大学出版社,2005年8月。

[2语言程序设计. 清华大学出版社,2005年月1月。

《编译原理》课程设计—预测分析法LL (1) 第21页


相关文章

  • 语法分析程序的设计与实现
  • 语法分析程序的设计与实现 一:实验内容: ................................................................................................... ...查看


  • 编译原理答案++陈意云+高等教育出版社
  • <编译原理>习题参考答案(一) Bug report: [email protected] find: 电一楼二楼全球计算实验室 李兆鹏 第二章 2.3 叙述由下列正规式描述的语言 a) 0(0|1)*0 b) (( ...查看


  • 编译原理实验指导书
  • 实验一 词法分析 一. 实验目的 编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字.标识符.常数.运算符.分隔符五大类.并依次输出各个单词的内部编码及单词符号自身值. 二. 实验题目 如源程序为C语言.输入如 ...查看


  • 编译原理课程教学研究
  • [摘 要]目前的编译原理课程的教学中存在以下问题:1.教学内容偏重于原理:2.实验内容的语言不合理:3.实践环节太薄弱.针对此做出了如下的改变:1.区分不同层次的学生合理组织教学:2.灵活应用多种教学方法:3.加强学生动手能力. [关键词] ...查看


  • 2016编译原理课程设计心得体会 2篇
  • 2016编译原理课程设计心得体会 2篇 经过一个星期的编译原理课程设计,本人在刘贞老师的指导下,顺利完成该课程设计.通过该课程设计,收获颇多. 一.对实验原理有更深的理解 通过该课程设计,掌握了什么是编译程序,编译程序工作的基本过程及其各阶 ...查看


  • 计算机组成原理-半加器实验报告
  • 课 程 设 计 报 告 课程设计名称:课程设计题目: 院(系):专 业:班 级:学 号:姓 名:指导教师:完成日期: 计算机组成原理课程设计半加器和全加器设计开发 目 录 1.1 实验目的 ......................... ...查看


  • 编译原理上机实验
  • 实验1简单的词法分析子程序 [实验目的] ● 理解词法分析在编译程序中的作用 ● 初步了解和掌握词法分析程序的实现方法和技术 [实验内容] 1. 编写程序,输入一串字符,判断该字符串是否为合法标识符或合法整型常量. 2. 无符号数的算术四则 ...查看


  • 编译原理实验指导书---2014年修订版
  • 编译原理实验指导 石家庄经济学院信息工程学院 2014-01-25 "编译原理"是计算机类专业一门理论性和实践性强的专业课程,在本专业的课程体系中处于十分重要的地位,属于必修课.本课程的内容主要介绍高级程序设计语言实现的 ...查看


  • 词法分析器编译原理C++实现实验报告
  • 学 生 实 验 报 告 学 院: 软件与通信工程学院 课程名称: 编译原理 专业班级: 姓 名: 学 号: 学生实验报告 一.实验综述 1.实验目的及要求 使用任意语言实现词法分析器 2.实验仪器.设备或软件 Visual C++. 二.实 ...查看


热门内容