当前位置:文档之家› 实验二 语法分析(算符优先) (2)

实验二 语法分析(算符优先) (2)

实验二  语法分析(算符优先) (2)
实验二  语法分析(算符优先) (2)

编译原理实验报告实验名称:语法分析器设计

专业:计算机科学与技术

姓名:田莉莉

学号:201117906

语法分析—算符优先分析程序

一.实验要求

⑴选择最有代表性的语法分析方法,如算符优先法、递归子程序法或LR 分析法

⑵选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。

⑶实习时间为6学时。

二.实验内容及要求

(1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件);

(2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程)

(3)给定表达式文法为:

G(E’): E’→#E#

E→E+T | T

T→T*F |F

F→(E)|i

(4)分析的句子为:

(i+i)*i和i+i)*i

三.程序设计思想及实现步骤

程序的设计思想:

按照编译原理教材提供的算法,本程序的设计主要实现三个主要的过程:(1)求解FristVT集和LastVT集:利用CString数组存放VT集,利用数组下标对应非终结符关系;

(2)输出算符优先分析表:利用MFC中的ClistCtrl控件输出显示算符表,比利用二维数组对应其在内存中的关系。

(3)利用算符优先分析表进行归约:根据教材所给算法,并对其进行实现在屏幕上输出归约过程。

实现步骤:

1、为程序各变量设计存储形式,具体设计如下所示:

CString m_strTElem[T_LEN]; //终结符

CString m_strNTElem[NT_LEN]; //非终结符

CMapStringToPtr m_mapProdu; //存放产生式

CMapStringToPtr m_mapProduEX; //存放扩展产生式

CString m_strFristVT[NT_LEN]; //fristVT集

CString m_strLastVT[NT_LEN]; //lastVT集

int m_nPriSheet[T_LEN+1][T_LEN+1]; //优先表;无穷大表示空白,-1表示小于,0

表示相等,1表示大于

Find m_F[STACK_LEN]; //bool数组

CStrack m_stack; //堆栈

2、为程序设计各个过程,具体设计如下所示:

void CreateFristVT(Find* F); //为每一个非终结符创建FristVT集

void CreateLastVT(Find* F); //为每一个非终结符/创建LastVT集

void SearchPForFirtVT(Find& f); //搜索形如P->a….或P->Qa…. 的产生式

void SearchQForFristVT(void); //搜索形如P->....Q的产生式

void SearchPForLastVT(Find& f); //搜索形如P->...aQ或P->...a的产生式

void SearchQForLastVT(void); //搜索形如P->....Q的产生式OnBnClickedBtnAnasysic(); //点击按钮启动分析

3、对各个过程进行实现;

4、调试运行并检验实验结果,结果如图2.1和2.2所示:

图2.1 分析成功图

图2.2 分析失败图四.程序源码

产生式初始化:

//产生式

CString* str = new CString;

*str = _T("|E+T|T|");

m_mapProdu.SetAt(_T("E"),(void*)str);

CString* str1 = new CString;

*str1 = _T("|T*F|F|");

m_mapProdu.SetAt(_T("T"),(void*)str1);

CString* str2 = new CString ;

*str2 = _T("|(E)|i|");

m_mapProdu.SetAt(_T("F"),(void*)str2);

CString* str3 = new CString;

*str3 = _T("|E+T|F+F|F*F|E+F|T|F|");

m_mapProduEX.SetAt(_T("E"),(void*)str3);

CString* str4 = new CString;

*str4 = _T("|T*F|F|");

m_mapProduEX.SetAt(_T("T"),(void*)str4);

CString* str5 = new CString ;

*str5 = _T("|(E)|i|(F)|");

m_mapProduEX.SetAt(_T("F"),(void*)str5);

程序主要代码:

void CGrammarAnalysisDlg::InitFind(void) {

int i,j;

int k = 0;

while(k

for(i=0;i

for(j=0;j

{

m_F[k].m_strNTerm = m_strNTElem[i];

m_F[k].m_strTerm = m_strTElem[j]; m_F[k].m_bIsVT = FALSE; k++;

}

} }

//查找 P->a... 和 P->Qa...

void CGrammarAnalysisDlg::SearchPForFirtVT(Find& f) { CString* str;

m_mapProdu.Lookup(f.m_strNTerm,(void*&)str); int nFrist = 0; int nLen = 0; while(nLen+1 < str->GetLength())// P->a... P 和 P->Qa... { nFrist = nLen;

nLen = str->Find('|',nFrist+1);

CString strProduce = str->Mid(nFrist+1,nLen-nFrist-1); if(IsNT(strProduce,0) && IsT(strProduce,1)) { if(strProduce.GetAt(1) == f.m_strTerm) { if(!f.m_bIsVT) { f.m_bIsVT = TRUE; //CreateFristVT(f); m_stack.PushStack(f); }

}

}

if(IsT(strProduce,0)) { if(strProduce.GetAt(0) == f.m_strTerm) { if(!f.m_bIsVT) { f.m_bIsVT = TRUE; //CreateFristVT(f); m_stack.PushStack(f);

}

}

}

}

}

//判断产生式第nLocat 位置的字符是否是非终结符 BOOL CGrammarAnalysisDlg::IsNT(CString strProduc,int nLocat) { for(int i=0;i

return 1;

}

return 0;

}

//判断产生式第nLocat 位置的字符是否是终结符

BOOL CGrammarAnalysisDlg::IsT(CString strProduc, int nLocat) { for(int i=0;i

if(strProduc.GetAt(nLocat) == m_strTElem[i])

return 1;

}

if(strProduc.GetAt(nLocat) == '#')

return 1; return 0;

}

//遍历所有的产生式 P->Q

void CGrammarAnalysisDlg::SearchQForFristVT(void) { Find Q; CString strNT; CString* str;

while(m_stack.m_nTop != 0) {

m_stack.PopStack(Q); POSITION pos = m_mapProdu.GetStartPosition();

while(pos) { m_mapProdu.GetNextAssoc(pos,strNT,(void*&)str); int nFrist = 0; int nLen = 0;

while(nLen+1 < str->GetLength())

{

nFrist = nLen;

nLen = str->Find('|',nFrist+1); CString strProduce = str->Mid(nFrist+1,nLen-nFrist-1); if(IsNT(strProduce,0)) { if(strProduce.GetAt(0) == Q.m_strNTerm) { //Q.m_bIsVT = TRUE; for(int i=0;i

{ if(!m_F[i].m_bIsVT) {

m_F[i].m_bIsVT = TRUE; m_stack.PushStack(m_F[i]);

break; }

}

}

} }

}

}

}

}

// //P->...aQ 或P->...a

void CGrammarAnalysisDlg::SearchPForLastVT(Find& f) { CString* str;

m_mapProdu.Lookup(f.m_strNTerm,(void*&)str); int nFrist = 0; int nLen = 0; while(nLen+1 < str->GetLength())// P->a... P 和 P->Qa...

{ nFrist = nLen;

nLen = str->Find('|',nFrist+1); CString strProduce = str->Mid(nFrist+1,nLen-nFrist-1); int nLocat = strProduce.GetLength();

if(nLocat-2>0)

{ if(IsNT(strProduce,nLocat-1) && IsT(strProduce,nLocat-2)) {

if(strProduce.GetAt(nLocat-2) == f.m_strTerm) {

if(!f.m_bIsVT) {

f.m_bIsVT = TRUE;

m_stack.PushStack(f);

}

}

}

}

if(IsT(strProduce,nLocat-1)) { if(strProduce.GetAt(nLocat-1) == f.m_strTerm)

{

if(!f.m_bIsVT)

{

f.m_bIsVT = TRUE; m_stack.PushStack(f);

}

}

}

}

}

// //P->....Q

void CGrammarAnalysisDlg::SearchQForLastVT(void) { Find Q; CString strNT; CString* str;

while(m_stack.m_nTop != 0) {

m_stack.PopStack(Q);

POSITION pos = m_mapProdu.GetStartPosition();

while(pos) { m_mapProdu.GetNextAssoc(pos,strNT,(void*&)str);

int nFrist = 0; int nLen = 0;

while(nLen+1 < str->GetLength())

{ nFrist = nLen;

nLen = str->Find('|',nFrist+1);

CString strProduce = str->Mid(nFrist+1,nLen-nFrist-1); int nLocat = strProduce.GetLength(); if(IsNT(strProduce,nLocat-1)) { if(strProduce.GetAt(nLocat-1) == Q.m_strNTerm) { //Q.m_bIsVT = TRUE; for(int i=0;i

m_F[i].m_strTerm == Q.m_strTerm)

{ if(!m_F[i].m_bIsVT) {

m_F[i].m_bIsVT = TRUE; m_stack.PushStack(m_F[i]);

break; }

}

}

} }

}

}

}

}

void CGrammarAnalysisDlg::OnBnClickedBtnAnsysic() { // TODO: 在此添加控件通知处理程序代码 //初始化列表控件

//m_lbResult.AddString(_T("kjl")); m_lst.SetExtendedStyle(LVS_EX_AUTOSIZECOLUMNS|LVS_EX_GRIDLINE S); CRect rc;

m_lst.GetClientRect(rc);

int nWidth = rc.Width()/(T_LEN+2); int i = 0;

m_lst.InsertColumn(i,_T(""),LVCFMT_CENTER,nWidth);

for(i=1;i

}

m_lst.InsertColumn(i,_T("#"),LVCFMT_CENTER,nWidth);

for(i=0;i

m_lst.InsertItem(i,m_strTElem[i]);

} m_lst.InsertItem(i,_T("#"));

// //FirstVT

InitFind();

//Find f(_T("+"),_T("E")); for(int i=0;i

SearchPForFirtVT(m_F[i]);

SearchQForFristVT();

CreateFristVT(m_F);

//LastVT InitFind();

//Find f(_T("+"),_T("E")); for(int i=0;i

SearchPForLastVT(m_F[i]); SearchQForLastVT(); CreateLastVT(m_F);

//遍历产生式构造算符优先表 CString* str;

POSITION pos =m_mapProdu.GetStartPosition(); CString strNT; int nColumn; int nItem; while(pos) {

m_mapProdu.GetNextAssoc(pos,strNT,(void*&)str);

int nFrist = 0; int nLen = 0;

while(nLen+1 < str->GetLength()) {

nFrist = nLen;

nLen = str->Find('|',nFrist+1); CString strProduce = str->Mid(nFrist+1,nLen-nFrist-1); int nLocat = strProduce.GetLength(); for(int i=0;i

nVTLen = m_strFristVT[nNTLocat].GetLength();

for(int j=0;j

= FindTLocat(m_strFristVT[nNTLocat].GetAt(j));

m_nPriSheet[nItem][nColumn] = -1; m_lst.SetItemText(nItem,nColumn+1,_T("<"));

} } if(IsNT(strProduce,i) && IsT(strProduce,i+1)) { nColumn = FindTLocat(strProduce.GetAt(i+1)); int nNTLocat = FindNTLocat(strProduce.GetAt(i)); int nVTLen = m_strLastVT[nNTLocat].GetLength(); for(int j=0;j

nItem

=

FindTLocat(m_strLastVT[nNTLocat].GetAt(j));

m_nPriSheet[nItem][nColumn] = 1;

m_lst.SetItemText(nItem,nColumn+1,_T(">"));

}

}

}

}

}

//处理‘#',,行 nItem = T_LEN; wchar_t ch = '(';

for(int i=0;i

{

switch(m_nPriSheet[FindTLocat(ch)][i])

{ case 0:

break;

case INFI:

break;

case -1:

m_nPriSheet[nItem][i] = -1;

m_lst.SetItemText(nItem,i+1,_T("<"));

break;

case 1:

m_nPriSheet[nItem][i] = 1;

m_lst.SetItemText(nItem,i+1,_T(">")); break;

}

}

//处理‘#’,,列 nColumn = T_LEN; ch = ')';

for(int i=0;i

switch(m_nPriSheet[i][FindTLocat(ch)])

{ case 0: break; case INFI:

break;

case -1:

m_nPriSheet[i][nColumn] = -1;

m_lst.SetItemText(i,nColumn+1,_T("<"));

break;

case 1:

m_nPriSheet[i][nColumn] = 1;

m_lst.SetItemText(i,nColumn+1,_T(">"));

break;

}

}

//最后一角

nItem = T_LEN;

nColumn = T_LEN;

m_nPriSheet[nItem][nColumn] = 0;

m_lst.SetItemText(nItem,nColumn+1,_T("="));

}

void CGrammarAnalysisDlg::CreateFristVT(Find* F)

{

for(int i=0;i

{

if(F[i].m_bIsVT)

{

for(int j=0;j

{

if(F[i].m_strNTerm == m_strNTElem[j])

{

m_strFristVT[j] += F[i].m_strTerm;

break;

}

}

}

}

}

void CGrammarAnalysisDlg::CreateLastVT(Find* F)

{

for(int i=0;i

{

if(F[i].m_bIsVT)

{

for(int j=0;j

{

if(F[i].m_strNTerm == m_strNTElem[j])

{

m_strLastVT[j] += F[i].m_strTerm;

break;

}

}

}

}

}

int CGrammarAnalysisDlg::FindTLocat(wchar_t strT) {

for(int i=0;i

{

if(m_strTElem[i] == strT)

return i;

}

if(strT = '#')

return T_LEN;

}

int CGrammarAnalysisDlg::FindNTLocat(wchar_t strNT) {

for(int i=0;i

{

if(m_strNTElem[i] == strNT)

return i;

}

return 0;

}

void CGrammarAnalysisDlg::OnBnClickedBtnAnasysic() {

// TODO: 在此添加控件通知处理程序代码

//清空列表控件

int nCount = m_lbResult.GetCount();

for(int i=0;i

m_lbResult.DeleteString(0);

//

UpdateData();

//清空栈

m_stack.m_nTop = 0;

//初值

int j,k = 1;

CString Q;

m_stack.m_Ch[k] = (_T("#"));

//

//int nLen = m_strSen.GetLength();

m_strSen += _T("#");

int i = -1;

do

{

i++;

if(IsT(m_stack.m_Ch[k],0))

j = k;

else j = k-1;

int nItem = FindTLocat(m_stack.m_Ch[j].GetAt(0));

int nColumn = FindTLocat(m_strSen[i]);

while(m_nPriSheet[nItem][nColumn] == 1)

{

int nItem1,nColumn1;

do

{

Q = m_stack.m_Ch[j];

if(IsT(m_stack.m_Ch[j-1],0))

j = j-1;

else j= j-2;

nItem1 = FindTLocat(m_stack.m_Ch[j].GetAt(0));

nColumn1 = FindTLocat(Q.GetAt(0));

} while (m_nPriSheet[nItem1][nColumn1] != -1);

CString strToProduce;

for(int m = j+1;m<=k;m++)

{

strToProduce += m_stack.m_Ch[m];

}

//输出产生式

POSITION pos = m_mapProduEX.GetStartPosition();

CString strNT;

CString* str;

while(pos)

{

m_mapProduEX.GetNextAssoc(pos,strNT,(void*&)str);

int nFrist = 0;

int nLen = 0;

while(nLen+1 < str->GetLength()) {

nFrist = nLen;

nLen = str->Find('|',nFrist+1);

CString strProduce =

str->Mid(nFrist+1,nLen-nFrist-1);

if(strProduce == strToProduce)

{

CString strResult;

strResult = strNT;

strResult += _T("->");

strResult += strToProduce;

m_lbResult.AddString(strResult);

k = j+1;

m_stack.m_Ch[k] = strNT;

break;

}

}

}

nItem = FindTLocat(m_stack.m_Ch[j].GetAt(0));

nColumn = FindTLocat(m_strSen[i]); // }

nItem = FindTLocat(m_stack.m_Ch[j].GetAt(0));

nColumn = FindTLocat(m_strSen[i]);

if(m_nPriSheet[nItem][nColumn] == -1 || m_nPriSheet[nItem][nColumn] == 0)

{

k += 1;

m_stack.m_Ch[k] = m_strSen[i];

}

else

{

MessageBox(_T("错误!"));

return;

}

}while(m_strSen[i] != '#');

MessageBox(_T("成功!"));

}

五.结果分析及试验心得:

本次实验做起来有点复杂,我认为重点在对教材所给算法的理解及个变量存储形式的设计。好的存储形式不仅可简化对数据的操作,也可以精简程序的设计过程。

下面是我的有关变量存储形式的设计:

(1)产生式:通过分析对已知的产生式进行了扩展,将产生式放入

CMapStringToPtr的类型变量中存储,利用‘|’将统一非终结符的产生式隔开。

使用时对CString的变量遍历,每次输出一个产生式;

(2)终结符和非终结符:采用数组的形式存储,利用下标对应每一个字符;

(3)FristVT和LastVT:利CString类型的数组存放,每个位置的元素对

应了一个非终结符;

(4)算符优先表:利用二维数组存放其中无穷大表示空白,-1表示小于,0表示相

等,1表示大于。

虽然在有些结构的设计上还不是太合理,但在实验中这种结构的设计给我完成实验提供了不上的便利。

关于程序的一点思考:

对于算符优先分析我们知道最大的便利就是可以跳过许多单非产生式,但是在程序的实现起来却是不太好处理,一般可采用两种方法:(1)通过每次输入的产生式,寻找扩展文法,在归约是利用扩展文法;这种方法增加了存储空间,但加快了归约过程的时间。(2)在归约过程中对每一产生式进行处理,这样节省了存储空间,但在时间效率上没有第一种的好。本次试验我采用的是第一种方法,但是个人觉得第二种方法更利于实现。

本次实验虽然做完了,但是程序的功能在很多方面还不完善,如不能自动输入产生式、输出的结果不直观等。这些都还需要在以后继续改进!

算符优先分析器设计实验报告--宁剑

编译原理实验报告 题目: 算符优先分析法分析器 学 院 计算机科学与技术 专 业 xxxxxxxxxxxxxxxx 学 号 xxxxxxxxxxxx 姓 名 宁剑 指导教师 xxxx 2015年xx 月xx 日 算符优先分析法分析器 装 订 线

一、实验目的 1.理解自底向上优先分析,比较和自顶向下优先分析的不同。 2.理解算符优先分析的特点,体会其和简单优先分析方法的不同。 3.加深对编译器语法分析的理解。 二、实验原理 1.自底向上优先分析方法,也称移进-归约分析,粗略地说它的思想是对输入符号串自左向右进行扫描,并将输入符号逐个移入一个后进先出栈,边移入边分析,一旦栈顶符号串形成某个句型的句柄或可归约串时,就将该产生式的左部非终极符代替相应的右边文法符号串。 2.算符优先分析法的基本思想 首先确定算符(确切地说是终结符)之间的优先关系和结合性质,然后借助这种关系,比较相邻算符之间的优先级来确定句型的可归约串,并进行归约。 注意:算符优先分析过程是自下而上的归约过程,但它的可归约串未必是句柄,也就是说,算符优先分析过程不是一种规归约。 3.终结符号间优先关系的确定,用FIRSTVT和LASTVT计算。 4.最左素短语 所谓素短语是指这样一个短语,它至少含有一个终结符,并且除它自身之外不再含有其它素短语。最左素短语是指处于句型最左边的那个素短语。最左素短语是算符优先分析算法的可归约串。 5.计算得到所给文法的算符优先矩阵

6.算符优先分析的基本过程 三、实验要求 使用算符优先分析算法分析下面的文法: E’→#E# E→E+T|T T→T*F|F F→P^F|P

实验4 算符优先分析法.

实验名称: 实验任务: 对下述描述算符表达式的算符优先文法G[E],给出算符优先分析的实验结果。 实验容: 有上下无关文法如下: E->E+T|E-T|T T->T*F|T/F|F F->(E)|i 说明:优先关系矩阵的构造过程: (1) = 关系由产生式 F->(E) 知‘(’=‘)’ FIRSTVT集及LASTVT集 FIRSTVT(E)={ +,-,*,/,(,i } FIRSTVT(F)={ (,i } FIRSTVT(T)={ *,/,(,i } LASTVT(E)={ +,-,*,/,),i } LASTVT(F)={ ),i } LASTVT(T)={ *,/,),i } (2) < 关系 +T 则有:+ < FIRSTVT(T) -T 则有:- < FIRSTVT(T) *F 则有:* < FIRSTVT(F)

/F 则有:/ < FIRSTVT(F) (E 则有:( < FIRSTVT(E) (3) > 关系 E+ 则有: LASTVT(E) > + E- 则有: LASTVT(E) > - T* 则有: LASTVT(T) > * T/ 则有: LASTVT(T) > / E) 则有: LASTVT(E) > ) (4)请大家画出优先关系矩阵 终结符之间的优先关系是唯一的,所以该文法是算符优先文法。程序的功能描述:程序由文件读入字符串(以#结束),然后进行算符优先分析,分析过程中如有错误,则终止程序并报告错误位置,最终向屏幕输出移近——规约过程。

(5)依据文法和求出的相应FirstVT和 LastVT 集生成算符优先分析表。算法描述如下: for 每个形如 P->X1X2…Xn的产生式 do for i =1 to n-1 do begin if Xi和Xi+1都是终结符 then Xi = Xi+1 if i<= n-2, Xi和Xi+2 是终结符, 但Xi+1 为非终结符 then Xi = Xi+2 if Xi为终结符, Xi+1为非终结符 then for FirstVT 中的每个元素 a do Xi < a if Xi为非终结符, Xi+1为终结符 then for LastVT 中的每个元素 a do a > Xi+1 end (6)构造总控程序 算法描述如下: stack S; k = 1; //符号栈S的使用深度

编译原理 实验3 算符优先分析

编译原理实验3 算符优先分析 一、实验目的 通过设计编制调试构造FIRSTVT集、LASTVT集和构造算符优先表、对给定符号串进行分析的程序,了解构造算符优先分析表的步骤,对文法的要求,生成算符优先关系表的算法,对给定的符号串进行分析的方法。 二、实验内容 1. 给定一文法G,输出G的每个非终结符的FIRSTVT集和LASTVT集。 2. 构造算符优先表。 3. 对给定的符号串进行分析,包含符号栈,符号栈栈顶符号和输入串当前符号的优先级,最左素短语和使用的产生式和采取的动作。 三、程序思路 在文法框内输入待判断文法产生式,格式E->a|S,注意左部和右部之间是“->”,每个产生式一行,ENTER键换行。文法结束再输入一行G->#E# 1. 先做文法判断,即可判断文法情况。 2. 若是算符优先文法,则在优先表栏显示优先表。 3. 写入要分析的句子,按回车即可。 4. 在分析过程栏,可以看到整个归约过程情况 四、实验结果 FunctorFirst.h #include #include #include #include usingnamespace std;

#define rightlength 20 #define product_num 20 // 产生式最多个数 #define num_noterminal 26 // 非终结符最多个数 #define num_terminal 26 // 终结符最多个数 struct Production { char Left; char Right[rightlength]; int num; }; struct VT { bool vt[num_noterminal][num_terminal]; }; struct Stack { char P; char a; }; class CMyDlg { public:CMyDlg(); void InputRule(); CString showLastVT(); CString showFirstVT(); CString shownoTerminal(char G[]); CString showTerminal(char g[]); CString showLeftS(char S[], int j, int k); void InitAll(); CString showSentence(CString sen, int start); CString showStack(char S[], int n); void Initarry(char arry[], int n); CString ProdtoCStr(Production prod); int selectProd(int i, int j, char S[]); void preFunctor(CString sen); void insertFirstVT(Stack S[], int&sp, char P, char a); void insertLastVT(Stack S[], int&sp, char P, char a); void ShowPreTable(); void createPreTable();

算符优先分析程序

南华大学 实验名称:算符优先分析程序 学院:计算机学院 专业班级:本2010 电气信息类03班 学号:20104030342 姓名:谢志兴 指导教师:吴取劲 日期:2012 年 6 月12 日

实验二算符优先分析程序 一、实验目的 调试并完成一个算符优先分析程序,加深对算符优先分析原理的理解。 二、实验要求 算符优先分析程序的功能: 输入:所给文法的源程序字符串、待匹配字符串。 输出:转化后的文法、每个非终结符的FIRSTVT集和LASTVT集、算符优先分析表、规约过程。 三、源程序代码: #include "stdio.h" #include "stdlib.h" #include "iostream.h" char data[20][20]; //算符优先关系 char s[100]; //模拟符号栈s char lable[20]; //文法终极符集 char input[100]; //文法输入符号串 char string[20][10]; //用于输入串的分析 int k; char a; int j; char q; int r; //文法规则个数 int r1; //转化后文法规则个数 char st[10][30]; //用来存储文法规则 char first[10][10]; //文法非终结符FIRSTVT集 char last[10][10]; //文法非终结符LASTVT集 int fflag[10]={0}; //标志第i个非终结符的FIRSTVT集是否已求出

int lflag[10]={0}; //标志第i个非终结符的LASTVT集是否已求出 int deal(); //对输入串的分析 int zhongjie(char c); //判断字符c是否是终极符 int xiabiao(char c); //求字符c在算符优先关系表中的下标void out(int j,int k,char *s); //打印s栈 void firstvt(char c); //求非终结符c的FIRSTVT集 void lastvt(char c); //求非终结符c的LASTVT集 void table(); //创建文法优先关系表 void main() { int i,j,k=0; printf("请输入文法规则数:"); scanf("%d",&r); printf("请输入文法规则:\n"); for(i=0;i'Z') { printf("不是算符文法!\n"); exit(-1); } if(st[i][j]>='A'&&st[i][j]<='Z') {

算符优先报告及代码

实验任务: 对下述描述算符表达式的算符优先文法G[E],给出算符优先分析的实验结果。 E->E+T|E-T|T T->T*F|T/F|F F->(E)|i 说明: 优先关系矩阵的构造过程: (1)= 关系 由产生式F->(E) 知‘(’=‘)’ FIRSTVT集 FIRSTVT(E)={ +,-,*,/,(,i } FIRSTVT(F)={ (,i } FIRSTVT(T)={ *,/,(,i } LASTVT(E)={ +,-,*,/,),i } LASTVT(F)={ ),i } LASTVT(T)={ *,/,),i } (2) < 关系 +T 则有:+ < FIRSTVT(T) -T 则有:- < FIRSTVT(T) *F 则有:* < FIRSTVT(F) /F 则有:/ < FIRSTVT(F) (E 则有:( < FIRSTVT(E)

(3) > 关系 E+ 则有:LASTVT(E) > + E- 则有:LASTVT(E) > - T* 则有:LASTVT(T) > * T/ 则有:LASTVT(T) > / E) 则有:LASTVT(E) > ) (4)优先关系矩阵 + - * / ( ) i # + > > < < < > < > - > > < < < > < > * > > > > < > < > / > > > > < > < > ( < < < < < = < ) > > > > > > i > > > > > > # < < < < < < = 终结符之间的优先关系是唯一的,所以该文法是算符优先文法。 程序的功能描述: 程序由文件读入字符串(以#结束),然后进行算符优先分析,

算符优先文法

编译原理实验代码: 对于任意给定的文法,判断其是否是算符优先文法。 代码如下: #include #include #include #define row 50 #define col 50 #define SIZE 50 using namespace std; //两个重要结构体的定义 //FIRSTVT表或LASTVT表中一个表项(A,a)结构体的初始化typedef struct { char nonterm; //非终结符 char term; //终结符 }StackElement; //存放(A,a)的栈的初始化 typedef struct { StackElement *top; StackElement *bottom; int stacksize; }stack; //初始化(A,a)栈 void InitStack(stack &S) { S.bottom = new StackElement[SIZE]; if(!S.bottom) cout<<"存储空间分配失败!"<

//判断(A,a)栈是否为空 bool ifEmpty(stack S) { if(S.top==S.bottom) return true; //如果栈为空,则返回true else return false; //否则不为空,返回false } //插入栈顶(A,a)元素 void Insert(stack &S,StackElement e) { if(S.top-S.bottom>=S.stacksize) cout<<"栈已满,无法插入!"<nonterm=e.nonterm; S.top->term=e.term; S.top++; } } //弹出栈顶(A,a)元素 StackElement Pop(stack &S) { StackElement e; e.nonterm = '\0'; e.term = '\0'; if(S.top==S.bottom) { cout<<"栈为空,无法进行删除操作!"<nonterm; e.term=S.top->term; return e; } }

编译原理实验报告5-语法分析程序的设计(2)

实验5 语法分析程序的设计(2) 一、实验目的 通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析中算法优先分析方法。 二、实验内容 设计一个文法的算法优先分析程序,判断特定表达式的正确性。 三、实验要求 1、给出文法如下: G[E] E->T|E+T; T->F|T*F; F->i|(E); + * ( ) i + * ( ) i 2、计算机中表示上述优先关系,优先关系的机内存放方式有两种1)直接存放,2)为 优先关系建立优先函数,这里由学生自己选择一种方式; 1、给出算符优先分析算法如下: k:=1; S[k]:=‘#’; REPEAT 把下一个输入符号读进a中; IF S[k]∈V T THEN j:=k ELSE j:=k-1; WHILE S[j] a DO BEGIN REPEAT Q:=S[j]; IF S[j-1]∈V T THEN j:=j-1 ELSE j:=j-2 UNTIL S[j] Q 把S[j+1]…S[k]归约为某个N; k:=j+1;

S[k]:=N; END OF WHILE; IF S[j] a OR S[j] a THEN BEGIN k:=k+1;S[k]:=a END ELSE ERROR UNTIL a=‘#’ 1、 根据给出算法,利用适当的数据结构实现算符优先分析程序; 2、 利用算符优先分析程序完成下列功能: 1) 手工将测试的表达式写入文本文件,每个表达式写一行,用“;”表示结束; 2) 读入文本文件中的表达式; 3) 调用实验2中的词法分析程序搜索单词; 4) 把单词送入算法优先分析程序,判断表达式是否正确(是否是给出文法的语 言),若错误,应给出错误信息; 5) 完成上述功能,有余力的同学可以对正确的表达式计算出结果。 四、实验环境 PC 微机 DOS 操作系统或 Windows 操作系统 Turbo C 程序集成环境或 Visual C++ 程序集成环境 五、实验步骤 1、 分析文法中终结符号的优先关系; 2、 存放优先关系或构造优先函数; 3、利用算符优先分析的算法编写分析程序; 4、写测试程序,包括表达式的读入和结果的输出; 5、程序运行效果,测试数据可以参考下列给出的数据。 六、测试数据 输入数据: 编辑一个文本文文件expression.txt ,在文件中输入 如下内容: 正确 结果: (1)10; 输出:正确 (2)1+2; 输出:正确 (3)(1+2)*3+(5+6*7); 输出:正确 (4)((1+2)*3+4 10; 1+2; (1+2)*3+(5+6*7); ((1+2)*3+4; 1+2+3+(*4+5); (a+b)*(c+d); ((ab3+de4)**5)+1;

算符优先分析算法(c语言).(优选)

编译原理实验 一实验目的 设计、编制并调试一个算符优先分析算法,加深对此分析法的理解 二实验过程 先在算符栈置“$”,然后开始顺序扫描表达式,若读来的单词符号是操作数,这直接进操作数栈,然后继续读下一个单词符号。分析过程从头开始,并重复进行;若读来的是运算符θ2则将当前处于运算符栈顶的运算符θ1的入栈优先数f与θ2的比较优先函数g进行比较。 2.2 各种单词符号对应的种别码 2.3 算符优先程序的功能 完成一个交互式面向对象的算符优先分析程序,而一个交互式面向对象的算符优先分析程序基本功能是: (1)输入文法规则 (2)对文法进行转换 (3)生成每个非终结符的FirstVT和LastVT (4)生成算符优先分析表 (5)再输入文法符号 (6)生成移进规约步骤 三设计源码 算符优先分析器 #include "stdio.h"

#include "stdlib.h" #include "iostream.h" char data[20][20]; //算符优先关系 char s[100]; //模拟符号栈s char lable[20]; //文法终极符集 char input[100]; //文法输入符号串 char string[20][10]; //用于输入串的分析 int k; char a; int j; char q; int r; //文法规则个数 int r1; int m,n,N; //转化后文法规则个数 char st[10][30]; //用来存储文法规则 char first[10][10]; //文法非终结符FIRSTVT集 char last[10][10]; //文法非终结符LASTVT集 int fflag[10]={0}; //标志第i个非终结符的FIRSTVT集是否已求出int lflag[10]={0}; //标志第i个非终结符的LASTVT集是否已求出int deal(); //对输入串的分析 int zhongjie(char c); //判断字符c是否是终极符 int xiabiao(char c); //求字符c在算符优先关系表中的下标 void out(int j,int k,char *s); //打印s栈 void firstvt(char c); //求非终结符c的FIRSTVT集 void lastvt(char c); //求非终结符c的LASTVT集 void table(); //创建文法优先关系表 void main() { int i,j,k=0; printf("请输入文法规则数:"); scanf("%d",&r); printf("请输入文法规则:\n"); for(i=0;i

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

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

一、实验目的 通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。 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)都有

实验三算符优先分析算法设计与实现

实验三算符优先分析算法的设计与实现 (8学时) 一、实验目的 根据算符优先分析法,对表达式进行语法分析,使其能够判断一个表达式是否正确。通过算符优先分析方法的实现,加深对自下而上语法分析方法的理解。 二、实验要求 1、输入文法。可以是如下算术表达式的文法(你可以根据需要适当改变): E→E+T|E-T|T T→T*F|T/F|F F→(E)|i 2、对给定表达式进行分析,输出表达式正确与否的判断。 程序输入/输出示例: 输入:1+2; 输出:正确 输入:(1+2)/3+4-(5+6/7); 输出:正确 输入:((1-2)/3+4 输出:错误 输入:1+2-3+(*4/5) 输出:错误 三、实验步骤 1、参考数据结构 char *VN=0,*VT=0;//非终结符和终结符数组 char firstvt[N][N],lastvt[N][N],table[N][N]; typedef struct //符号对(P,a) { char Vn; char Vt; } VN_VT; typedef struct //栈 { VN_VT *top; VN_VT *bollow; int size; }stack; 2、根据文法求FIRSTVT集和LASTVT集 给定一个上下文无关文法,根据算法设计一个程序,求文法中每个非终结符的FirstVT 集和LastVT 集。

算符描述如下: /*求 FirstVT 集的算法*/ PROCEDURE insert(P,a); IF not F[P,a] then begin F[P,a] = true; //(P,a)进栈 end; Procedure FirstVT; Begin for 对每个非终结符 P和终结符 a do F[P,a] = false for 对每个形如 P a…或 P→Qa…的产生式 do Insert(P,a) while stack 非空 begin 栈顶项出栈,记为(Q,a) for 对每条形如 P→Q…的产生式 do insert(P,a) end; end. 同理,可构造计算LASTVT的算法。 3、构造算符优先分析表 依据文法和求出的相应FirstVT和 LastVT 集生成算符优先分析表。 算法描述如下: for 每个形如 P->X1X2…X n的产生式 do for i =1 to n-1 do begin if X i和X i+1都是终结符 then X i = X i+1 if i<= n-2, X i和X i+2 是终结符, 但X i+1 为非终结符 then X i = X i+2 if X i为终结符, X i+1为非终结符 then for FirstVT 中的每个元素 a do X i < a ; if X i为非终结符, X i+1为终结符 then for LastVT 中的每个元素 a do a > X i+1 ; end 4、构造总控程序 算法描述如下: stack S; k = 1; //符号栈S的使用深度 S[k] = ‘#’ REPEAT

编译原理_实验报告实验二__语法分析(算符优先) 2

华北水利水电学院编译原理实验报告 一、实验题目:语法分析(算符优先分析程序) (1)选择最有代表性的语法分析方法算符优先法; (2)选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。 二、实验内容 (1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件); (2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程) (3)给定表达式文法为: G(E’): E’→#E# E→E+T | T T→T*F |F F→(E)|i (4) 分析的句子为: (i+i)*i和i+i)*i 三、程序源代 #include #include #include #include #define SIZE 128 char priority[6][6]; //算符优先关系表数组 char input[SIZE]; //存放输入的要进行分析的句子 char remain[SIZE]; //存放剩余串 char AnalyseStack[SIZE]; //分析栈 void analyse(); int testchar(char x); //判断字符X在算符优先关系表中的位置 void remainString(); //移进时处理剩余字符串,即去掉剩余字符串第一个字符 int k; void init()//构造算符优先关系表,并将其存入数组中 {

c语言实现算符优先语法分析

#include char prog[100],zhongjian[100],shu[500]; char ch,zh; int syn,p,q,a,b,c,d; //p指向prog,q指向zhongjian int table[8][8]={ {1,1,-1,-1,-1,1,-1,1}, {1,1,-1,-1,-1,1,-1,1}, {1,1,1,1,-1,1,-1,1}, {1,1,1,1,-1,1,-1,1}, {-1,-1,-1,-1,-1,-1,-1,0}, {1,1,1,1,0,1,0,1}, {1,1,1,1,0,1,0,1}, {-1,-1,-1,-1,-1,0,-1,-1}}; //存储算符优先关系表,大于为1,小于或等于为-1,其它为0表示出错char zhan[100];//数组栈 int z,j;//z为栈顶指针,j为zhongjian数组指针 void push(char ch)//入栈 { zhan[z++]=ch; } void pop()//出栈 { z--; } void putzhan()//打印栈内字符 { for(int i=0;i

编译原理 六章 算符优先分析法

第六章算符优先分析法 课前索引 【课前思考】 ◇什么是自下而上语法分析的策略? ◇什么是移进-归约分析? ◇移进-归约过程和自顶向下最右推导有何关系? ◇自下而上语法分析成功的标志是什么? ◇什么是可归约串? ◇移进-归约过程的关键问题是什么? ◇如何确定可归约串? ◇如何决定什么时候移进,什么时候归约? ◇什么是算符文法?什么是算符优先文法? ◇算符优先分析是如何识别可归约串的? ◇算符优先分析法的优缺点和局限性有哪些? 【学习目标】 算符优先分析法是自下而上(自底向上)语法分析的一种,尤其适应于表达式的语法分析,由于它的算法简单直观易于理解,因此,也是学习其它自下而上语法分析的基础。通过本章学习学员应掌握: ◇对给定的文法能够判断该文法是否是算符文法 ◇对给定的算符文法能够判断该文法是否是算符优先文法 ◇对给定的算符文法能构造算符优先关系表,并能利用算符优先关系表判断该文法是否是算符优先文法。 ◇能应用算符优先分析算法对给定的输入串进行移进-归约分析,在分析的每一步能确定当前应移进还是归约,并能判断所给的输入串是否是该文法的句子。 ◇了解算符优先分析法的优缺点和实际应用中的局限性。 【学习指南】 算符优先分析法是自下而上语法分析的一种,它的算法简单、直观、易于理解,所以通常作为学习其它自下而上语法分析的基础。为学好本章内容,学员应复习有关语法分析的知识,如:什么是语言、文法、句子、句型、短语、简单短语、句柄、最右推导、规范归约基本概念。 【难重点】 ◇通过本章学习后,学员应该能知道算符文法的形式。 ◇对一个给定的算符文法能构造算符优先关系分析表,并能判别所给文法是否为算符优先文法。 ◇分清规范句型的句柄和最左素短语的区别,进而分清算符优先归约和规范归约的区别。 ◇算符优先分析的可归约串是句型的最左素短语,在分析过程中如何寻找可归约串是算符优先分析的关键问题。对一个给定的输入串能应用算符优先关系分析表给出分析(归约)步骤,并最终判断所给输入串是否为该文法的句子。 ◇深入理解算符优先分析法的优缺点和实际应用中的局限性。 【知识点】

编译原理算符优先算法语法分析实验报告

数学与计算机学院编译原理实验报告 年级专业学号姓名成绩 实验题目算符优先分析法分析器的设计实验日期 一、实验目的: 设计一个算符优先分析器,理解优先分析方法的原理。 二、实验要求: 设计一个算符优先分析器 三、实验内容: 使用算符优先分析算法分析下面的文法: E’→#E# E →E+T | T T →T*F | F F →P^F | P P →(E) | i 其中i可以看作是一个终结符,无需作词法分析。具体要求如下: 1、如果输入符号串为正确句子,显示分析步骤,包括分析栈中的内容、优先关系、输入符号串的变化情况; 2、如果输入符号串不是正确句子,则指示出错位置。 四、实验结果及主要代码: 1.主要代码 void operatorp()

{ char s[100]; char a,Q; int k,j,i,l; string input,temp; cin>>input; cout<<"步骤"<<'\t'<<"栈"<<'\t'<<"优先关系"<<'\t'<<"当前符号"<<'\t'<<"剩余输入串"<<'\t'<<"移进或归约"<') { cout<<'('<

for(l=1;l'<<'\t'<

算符优先分析算法

数学与计算机学院编译原理实验报告 年级09软工学号姓名成绩 专业软件工程实验地点主楼指导教师湛燕 实验项目算符优先关系算法实验日期2012.6.6 一、实验目的和要求 设计一个算符优先分析器,理解优先分析方法的原理。 重点和难点:本实验的重点是理解优先分析方法的原理;难点是如何构造算符优先关系。 二、实验内容 使用算符优先分析算法分析下面的文法: E’→ #E# E → E+T | T T → T*F | F F → P^F | P P → (E) | i 其中i可以看作是一个终结符,无需作词法分析。具体要求如下: 1、如果输入符号串为正确句子,显示分析步骤,包括分析栈中的内容、优先关系、输入符号串的变化情况; 2、如果输入符号串不是正确句子,则指示出错位置。 三、程序设计 全局变量有一下几个: static string input;//记录输入串 char s[20];//栈 int top=-1;//栈顶指针 有三个函数: int analyze(string input);//分析输入的串是否符合标准 void process();//进行归约的函数 int main() input是一个全局变量,记录输入串,用analyze(input)分析输入的是不是符合标准的字符串,(例如“i+i*i^(i+i)”)如果不符合标准,提示用户重新输入。 进行归约的函数主要思想是:先构造优先关系矩阵,有“<”,“>”,“=”和空格四种关系。Char a 记录栈中最高位的终结符,如果栈中是#E+E,则 a 的赋

值是“+”,如果形如“#E+”或“#E+i”则a 赋值“+”或“i”。charnowchar 记录当前的字符。a 与 nowchar 按照算符优先关系矩阵找出优先关系。如果优先关系是“<”,则进行移进;如果优先关系是“>”,则进行归约;如果是“=”,则去掉括号或分析成功。 五、代码和截图 自己编写代码如下: #include #include using namespace std; static string input;//输入串 char s[20];//栈 int top=-1;//栈顶指针 char VT[7]={'+','*','^','i','(',')','#'};//终结符 static char matrix[7][7]={ '>','<','<','<','<','>','>', '>','>','<','<','<','>','>', '>','>','<','<','<','>','>', '>','>','>',' ',' ','>','>', '<','<','<','<','<','=',' ', '>','>','>',' ',' ','>','>', '<','<','<','<','<',' ','='}; //优先关系矩阵,不存在优先关系时为空格 int analyze(string input);//分析输入的串是否符合标准 void process();//规约 int main() { //cout<<"输入一个符号串!"<>input; if(analyze(input)==0) flag=1; else flag=0; } cout<<"***********************************************************"<<

算符优先分析法课程设计报告

淮阴工学院 编译原理课程设计报告 选题名称:算符优先分析法 系(院):计算机工程学院 专业:计算机科学与技术 班级:计算机1075 姓名:学号: 指导教师: 学年学期:2009 ~ 2010 学年第 2 学期2010 年 5 月17 日

设计任务书 指导教师(签章): 年月日

摘要: 编译原理是计算机系统的基本组成部分之一,而且多数据计算机系统都配有不止一个高级语言的编译程序,对有些高级语言甚至配置了几个不同性能的编译程序。从功能上看,一个编译程序就是一个语言翻译程序。算符优先分析法是一种简单直观、广为使用的自下而上分析法。这种方法特别有利于表达式分析,宜于手工实现。算符优先分析过程是自下而上的归约过程,但这种归约未必是严格的最左归约。也就是说,算符优先分析法不是一种规范归约法。所谓算符优先分析就是定义算符之间(确切地说,终结符之间)的某种优先关系,借助于这种优先关系寻找“可归约串”和进行归约。 关键词:编译原理;归约;算法;算符优先;编译

目录 1需求分析 (1) 2 概要设计 (1) 2.1算符优先分析法的思想及其原理 (1) 2.2算符优先分析算法 (4) 2.3 构建算符优先关系表 (6) 2.4 出错处理 (7) 3 详细设计 (7) 3.1 程序流程图 (7) 3.2 构建算符优先关系表 (8) 3.3 进栈优先函数 (8) 3.4 算符优先规约函数 (10) 3.5 弹出窗体 (12) 4 程序运行、调试及操作说明 (12) 总结 (15) 致谢 (16) 参考文献 (17)

1需求分析 本次课程设计的题目是算符优先分析法。算符优先分析法是一种简单直观、特别方便于表达式分析,易于手式实现的方法。算符优先法只考虑算符(广义为终结符号)之间的优先关系,它是一种自底向上的归约过程,但这种归约未必严格按照句柄归约。它是一种不规范归约法。 根据已知文法: E->E+T|E-T|T T->T*F|T/F|F F->(E)|i(E)|i|d(其中d表示0-9的数字,i表示字母,大小写均包括) 根据算符优先分析法,将表达式进行语法分析,判断一个表达式是否正确 (1)可以使用任何语言来完成,例如:Java、C++。 (2)构造此文法的分析过程 (3)输入测试字符串,输出测试结果 给出关键类类图、整个应用程序的结构描述文档、关键模块流程图、较详细的接口文档、所有源代码。对应用程序进行测试,对测试结果进行分析研究,进而对应用程序进行改进,对关键算法进行尽可能的优化,最终得到一个在windows运行的可以根据算符优先分析法,将表达式进行语法分析,判断一个表达式是否正确,输入测试字符串,输出测试结果的完整应用程序。 2 概要设计 2.1算符优先分析法的思想及其原理 算符优先分析算法算法原理: (1)初始化栈:k=1; S[k]=‘#’; (2)依次从输入串中读入符号a: ①当前单词若为标识符,则a值为i,若为常数则a值为d; 其它a直接取单词值。 ②若a大于等于栈顶第一个终结符的优先级,则a进栈; ③若a小于栈顶第一个终结符的优先级,则重复做:

二语法分析程序(算符优先分析法)

实验二语法分析程序(算符优先分析法) 一、实验目的 通过设计调试算符优先分析程序,加深对课堂教学的理解,深刻理解自底向上语法分析方法的归约过程,提高语法分析方法的实践能力。 二、实验要求 (1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件); (2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程) (3)实验要求独立完成,不允许有抄袭现象。 (4)实验完成后,要求提交源程序和上交实验报告(包括源程序清单)。 (附:实验报告格式) 三、实验内容 (1)给定表达式文法为: G(E’): E’→#E# E→E+T | T T→T*F |F F→(E)|i (2)分析的句子为: (i+i)*i和i+i)*i (1)分析 1,判断为算符优先文法: 文法没有A->…BC…且BC均为非终结符,因此它为OG文法 文法没有同时存在①A->…ab…或A->….aBb…. ②A->…aB…且B=>b….或B=>Cb…. ③A->…Bb….且B=>…a或B=>…aC 文法为算符优先文法 2,求FirstVT集和LastVT集 FirstVT(E)={+, * , ( , i } LastVT(E)= {+, - , * , / , ) , i } FirstVT(T)={* , ( , i } LastVT(T)= {* , / , ( , i } FirstVT(F)={ ( , i } LastVT(F)={ ) , i } FirstVT(E’)={ #} LastVT(E’)={ #} 3,根据FirstVT和LastVT集构造算符优先表

相关主题
文本预览
相关文档 最新文档