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

实验二--语法分析(算符优先)-(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-P->Qa…. 的产生式

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

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

void SearchQForLastVT(void); //搜索形如P->..生式

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

}

} }

//查找 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

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-n

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[

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-n

int nLocat = strProduce.GetLength(); if(IsNT(strProduce,nLocat-1)) { if(strProduce.GetAt(nLocat-1) == Q.m_strN

{ //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[

break;

} }

}

} }

}

}

}

}

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

//m_lbResult.AddString(_T("kjl"));

m_lst.SetExtendedStyle(LVS_EX_AUTOSIZECOLUMNS|LVS_EX_GRIDLI 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,_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

int nLocat = strProduce.GetLength(); for(int i=0;i

if(IsT(strProduce,i) && IsT(strProduce,i+1))

{ nItem = FindTLocat(strProduce.GetAt(i)); nColumn = FindTLocat(strProduce.GetAt(i+1

m_nPriSheet[nItem][nColumn] = 0;

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

}

if(i<=nLocat-2 && IsT(strProduce,i) && IsT(s IsNT(strProduce,i+1))

{ nItem = FindTLocat(strProduce.GetAt(i)); nColumn = FindTLocat(strProduce.GetAt(i+2

m_nPriSheet[nItem][nColumn] = 0;

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

} if(IsT(strProduce,i) && IsNT(strProduce,i+1))

{ nItem = FindTLocat(strProduce.GetAt(i));

int nNTLocat = FindNTLocat(strProduce.Get int nVTLen = m_strFristVT[nNTLocat].GetLe

for(int j=0;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.Get int nVTLen = m_strLastVT[nNTLocat].GetLen

for(int j=0;j

{ nItem = FindTLocat(m_strLastVT[nNTLo

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*&)s

int nFrist = 0;

int nLen = 0;

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

{

nFrist = nLen;

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

CString strProduce = str->Mid(nFrist+1,nL

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[nIt {

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

编译原理 语法分析实验二

华北水利水电学院编译原理实验报告 2010~2011学年第二学期xxxx 级计算机专业 班级:xxxxx 学号:xxxxx 姓名:xxx 一、实验目的 通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。 二、实验要求 ⑴选择最有代表性的语法分析方法,如LL(1)分析法、算符优先法或LR分析法 ⑵选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。 ⑶实习时间为6小时。 三、实验内容 选题1:使用预测分析法(LL(1)分析法)实现语法分析: (1)根据给定文法,先求出first集合、follow集合和select集合,构造预测分析表(要求预测分析表输出到屏幕或者输出到文件); (2)根据算法和预测分析表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程) (3)给定表达式文法为: G(E): S→TE E→+TE | ε T→FK K→*FK |ε F→(S)|i (4)分析的句子为: (i+i)*i和i+i)*i 四、程序源代码 #include "stdafx.h" #include "SyntaxAnalysis.h" #include "SyntaxAnalysisDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif /////////////////////////////////////////// // CAboutDlg dialog used for App About

编译原理-语法分析器-(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;

实验二-LL1语法分析器

实验二LL(1)分析法 一、实验目的 通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。有利于提高学生的专业素质,为培养适应社会多方面需要的能力。 二、实验内容 ◆根据某一文法编制调试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;

算符优先文法

编译原理实验代码: 对于任意给定的文法,判断其是否是算符优先文法。 代码如下: #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; } }

词法分析器的实现与设计

题目:词法分析器的设计与实现 一、引言................................ 错误!未定义书签。 二、词法分析器的设计 (3) 2.1词的内部定义 (3) 2.2词法分析器的任务及功能 (3) 3 2.2.2 功能: (4) 2.3单词符号对应的种别码: (4) 三、词法分析器的实现 (5) 3.1主程序示意图: (5) 3.2函数定义说明 (6) 3.3程序设计实现及功能说明 (6) 错误!未定义书签。 7 7 四、词法分析程序的C语言源代码: (7) 五、结果分析: (12) 摘要:词法分析是中文信息处理中的一项基础性工作。词法分析结果的好坏将直接影响中文信息处理上层应用的效果。通过权威的评测和实际应用表明,IRLAS是一个高精度、高质量的、高可靠性的词法分析系统。众所周知,切分歧义和未登录词识别是中文分词中的两大难点。理解词法分析在编译程序中的作用,加深对有穷自动机模型的理解,掌握词法分析程序的实

现方法和技术,用c语言对一个简单语言的子集编制一个一遍扫描的编译程序,以加深对编译原理的理解,掌握编译程序的实现方法和技术。Abstract:lexical analysis is a basic task in Chinese information processing. The results of lexical analysis will directly affect the effectiveness of the application of Chinese information processing. The evaluation and practical application show that IRLAS is a high precision, high quality and high reliability lexical analysis system. It is well known that segmentation ambiguity and unknown word recognition are the two major difficulties in Chinese word segmentation. The understanding of lexical analyse the program at compile, deepen of finite automata model for understanding, master lexical analysis program implementation method and technology, using C language subset of a simple language compilation of a scanned again compiler, to deepen to compile the principle solution, master compiler implementation method and technology. 关键词:词法分析器?扫描器?单词符号?预处理 Keywords: lexical analyzer word symbol pretreatment scanner 一、引言 运用C语言设计词法分析器,由指定文件读入预分析的源程序,经过词法分析器的分析,将结果写入指定文件。本程序是在Visual?Studio环境下,使用C语言作为开发工具。基于实验任务

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

编译原理程序设计实验报告 --- 表达式语法分析器的设计 班级:计算机1306班姓名:张涛学号:20133967实验目标:用LL(1)分析法设计实现表达式语法分析器实验内容: ⑴概要设计:通过对实验一的此法分析器的程序稍加改造, 使其能够输出正确的表达式的token序列。然后利用LL(1)分析法实现语法分析。 ⑵数据结构: int op=0; //当前判断进度 char ch; //当前字符 char nowword[10]=""; // 当前单词 char operate[4]={'+','-','*','/'}; // 运算符 char bound[2]={'(',')'}; // 界符 struct Token { int code; char ch[10];

}; //Token 定义 struct Token tokenlist[50]; //Token 数组 struct Token tokentemp; //临时Token 变量struct Stack //分析栈定义{ char *base; char *top; int stacksize; }; ⑶分析表及流程图 LL(1)分析表:

Begi n ⑷关键函数: int lsLetter(char ch) //判断ch 是否为字母 int IsDigit(char ch) 〃判断ch是否为数字 int lskey(char *string) 〃判断是否为关键字 int lsbound(char ch) //判断是否为界符 int lsboundnum(char ch) //给出界符所在token 值 int init(STack *s) // 栈初始化 int pop(STack *s,char *ch) // 弹栈操作 int push(STack *s,char ch) 〃压栈操作 void LL1(); //分析函数 源程序代码:(加入注释) #includevstdio.h> #includevstring.h> #includevctype.h> #includevwindows.h> #include vstdlib.h>

实验二--语法分析-

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

编译原理实验报告实验名称:语法分析器设计 专业:计算机科学与技术 姓名:田莉莉 学号:201117906

语法分析—算符优先分析程序 一.实验要求 ⑴ 选择最有代表性的语法分析方法,如算符优先法、递归子程序法或LR 分析法 ⑵ 选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。 ⑶ 实习时间为6 学时。 二.实验内容及要求 ( 1)根据给定文法,先求出 FirstVt 和 LastVt 集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件); ( 2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程) (3)给定表达式文法为: G(E ' ): E'T #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]; CString m_strLastVT[NT_LEN]; int m_nPriSheet[T_LEN+1][T_LEN+1]; // 终结符 //fristVT 集 //lastVT 集

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

编译原理程序设计实验报告 ——表达式语法分析器的设计班级:计算机1306班姓名:张涛学号:20133967 实验目标:用LL(1)分析法设计实现表达式语法分析器 实验内容: ⑴概要设计:通过对实验一的此法分析器的程序稍加改造,使其能够输出正确的表达式的token序列。然后利用LL(1)分析法实现语法分析。 ⑵数据结构: int op=0; //当前判断进度 char ch; //当前字符 char nowword[10]=""; //当前单词 char operate[4]={'+','-','*','/'}; //运算符 char bound[2]={'(',')'}; //界符 struct Token { int code; char ch[10]; }; //Token定义

struct Token tokenlist[50]; //Token数组 struct Token tokentemp; //临时Token变量struct Stack //分析栈定义 { char *base; char *top; int stacksize; }; ⑶分析表及流程图

Begin PUSH(#),PUSH(E) POP(x) x ∈VT x ∈VN x=w end W=#n y NEXT(w) y n err 查LL (1)分析表空? n PUSH (i )err n y 逆序压栈 ⑷关键函数: int IsLetter(char ch) //判断ch 是否为字母 int IsDigit(char ch) //判断ch 是否为数字 int Iskey(char *string) //判断是否为关键字 int Isbound(char ch) //判断是否为界符 int Isboundnum(char ch) //给出界符所在token 值 int init(STack *s) //栈初始化 int pop(STack *s,char *ch) //弹栈操作 int push(STack *s,char ch) //压栈操作 void LL1(); //分析函数 源程序代码:(加入注释)

编译原理实验二

实验二语法分析 一、实验目的: 设计MiniC的上下文无关文法,利用JavaCC生成调试递归下降分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。 二、语法分析器: 按照MiniC语言的语法规则检查词法分析输出的记号流是否符合这些规则,并根据这些规则所体现出的语言中的各种语法结构的层次性。把规则写入到JavaCC的.jjt文件中,可以生成树状的层次结构。 三、JavaCC: 在JavaCC的文法规范文件中,不仅可以描述语言的语法规范,而且可以描述词法规范,本次实习中,利用JavaCC以MiniC语言构造一个不含语义分析的编译器前端,包括词法分析、语法分析,并要考虑语法分析中的错误恢复问题。通过使用JavaCC, 可以体会LL(k)文法的编写特点,掌握编写JavaCC文法规范文件的方法。 内容:利用JavaCC生成一个MiniC的语法分析器; 要求: 1.用流的形式读入要分析的C语言程序,或者通过命令行输入源程序。 2.具有错误检查的能力,如果有能力可以输出错误所在的行号,并简单提示 3.如果输入的源程序符合MiniC的语法规范,输出该程序的层次结构的语法树本次实习仅完成以下语法范畴的语法分析: 1. 写出一个源程序中仅包含if…else, else语句的语法分析。要求能分析其自身 嵌套. 其他语句可简化处理 2. 写出一个源程序中仅包含for语句的语法分析。要求能分析其自身嵌套, 其他语句可简化处理 3. 写出一个源程序中仅包含while语句的语法分析。要求能分析其自身嵌套。 其他语句可简化处理 4. 写出一个源程序中包含上面的12或者13或者23或者123语句的语法分析。 要求能分析除其自身嵌套外,还包括相互嵌套。其他语句可简化处理 具体实施步骤如下: 1.把MiniC转换为文法如下 <程序〉→ main()〈语句块〉 〈语句块〉→{〈语句串〉}

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

实验三算符优先分析算法的设计与实现 (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) 二.设计要求 (2) 1. 词法分析器的定义 (2) 2. 设计要求 (2) 3. 本程序自行规定: (3) 三.设计作用与目的 (4) 1. 设计作用 (4) 2. 设计目的 (4) 四.运行环境及工具软件 (4) 五.系统设计 (5) 1. 系统总体设计 (5) (1)词法分析器的设计 (5) (2)总体设计框图 (6) (3)总程序流程图 (6) 2. 各子模块设计 (8) (1)字符的识别 (8) (2)关键字的识别 (8) (3)数字的识别 (8) (4)界符的识别 (10) (5)运算处理 (10) 3.相关函数分析 (11) 4. 源程序设计 (12) 六.实验调试结果 (29) 1. 调试工具 (29) 2. 调试步骤 (29) 3. 调试结果 (29) 七.设计中的问题及解决方法 (31) 八.设计心得 (32) 九.参考文献 (34)

词法分析器的设计与实现 一.设计题目 词法分析器的设计与实现 二.设计要求 1. 词法分析器的定义 词法分析顾名思义就是分词。它以程序设计语言编制的源程序作为输入,以单词序列作为输出。分词过程可以通过编制程序自动完成,我们通常称这个分词程序为词法分析器。词法分析器分析的源程序可以是现有的各类程序设计语言源程序也可以是人为给定的模型语言的源程序。本文中的源程序为后者。从词的角度来看,它涉及的内容较为简单,只包括几个较为常用的词类,词类的构成上也适当的作了一些简化。对词进行分析时,我们是按类型进行分析的。不同类型的词在后续的分析中所起的作用不同,相应的操作也各有不同,但同种类型中的词虽然单词的构成不同但从宏观上看它们的操作大体一致。模型语言中的单词可以分为“关键字”、“标识符”、“常数”、“分隔符”、“运算符”几类。一般,关键字在程序设计语言中人为给定 2. 设计要求 对给定的程序通过词法分析器能够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。另外,如果是算术表达式,则需要通过栈、运算符的优先级比较处理等从而计算出最终结果并显示。通过此次课程设计要求掌握从源程序文件中读取有效字符的方法,掌握词法分析的实现方法并上机调试编出的词法分析程序。 在处理表达式前,首先设置两个栈:一是运算符栈,用于在表达式处理过程中存放运算符。在开始时,运算符栈中先压入一个表达式结束符“#”。二是操作数栈,用于在表达式处理过程中存放操作数。然后从左到右依次读出表达式中的各个符号(运算符或操作数),每读出一个符号按以下原则进行处理:

编译原理实验二语法分析器LL(1)实现教学内容

编译原理实验二语法分析器L L(1)实现

编译原理程序设计实验报告 ——表达式语法分析器的设计班级:计算机1306班姓名:张涛学号:20133967 实验目标:用LL(1)分析法设计实现表达式语法分析器实验内容: ⑴概要设计:通过对实验一的此法分析器的程序稍加改造,使其能够输出正确的表达式的token序列。然后利用LL(1)分析法实现语法分析。 ⑵数据结构: int op=0; //当前判断进度 char ch; //当前字符 char nowword[10]=""; //当前单词 char operate[4]={'+','-','*','/'}; //运算符 char bound[2]={'(',')'}; //界符 struct Token { int code; char ch[10]; }; //Token定义

struct Token tokenlist[50]; //Token数组struct Token tokentemp; //临时Token变量struct Stack //分析栈定义 { char *base; char *top; int stacksize; }; ⑶分析表及流程图

逆序压栈 int IsLetter(char ch) //判断ch是否为字母 int IsDigit(char ch) //判断ch是否为数字 int Iskey(char *string) //判断是否为关键字 int Isbound(char ch) //判断是否为界符 int Isboundnum(char ch) //给出界符所在token值int init(STack *s) //栈初始化 int pop(STack *s,char *ch) //弹栈操作 int push(STack *s,char ch) //压栈操作 void LL1(); //分析函数 源程序代码:(加入注释)

编译原理_实验报告实验二__语法分析(算符优先) 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()//构造算符优先关系表,并将其存入数组中 {

编译原理实验报告《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);.Xn的FIRST集 string** create_table(string *P,string U,string u,int n,int t,int k,string* first);ppend(1,a) U=u=" ";mpty();n++) { U[n]=G[n][0]; }ength();j++) { if(G[i][j])==string::npos&&(G[i][j])==string::npos) if(G[i][j]!='|'&&G[i][j]!='^') ength();j++) { P[k][0]=U[i];P[k][1]=':';P[k][2]=':';P[k][3]='='; /* if(G[i][j]=='(') { j++;flag=1; for(temp=j;G[i][temp]!=')';temp++); C=G[i][temp+1]; ppend(1,U[i]);GG[m].append("::="); if('|')!=string::npos) GG[m].append("("+beta+")"); else GG[m].append(beta); while(C)!=string::npos){C++;} GG[m].append(1,C); m++; GG[m].append(1,C);GG[m].append("::="); if('|')!=string::npos) GG[m].append("("+arfa+")"); else GG[m].append(arfa); GG[m].append(1,C);GG[m].append("|^"); m++; C++; }ind('^')==string::npos) first[r].append(1,'^');ind(a)==string::npos)ppend(1,a); break;.Yk

实验二 语法分析程序设计与实现

实验二语法分析程序设计与实现 一、实验目的 任选一种有代表性的语法分析方法,如算符优先法、递归下降法、LL(1)、SLR(1)、LR(1)等,通过设计、编制、调试实现一个典型的语法分析程序,对实验一所得扫描器提供的单词序列进行语法检查和结构分析,实现并进一步掌握常用的语法分析方法。 二、基本实验内容与要求 选择对各种常见高级程序设计语言都较为通用的语法结构——算术表达式的一个简化子集——作为分析对象,根据如下描述其语法结构的BNF定义G2[<算术表达式>],任选一种学过的语法分析方法,针对运算对象为无符号常数和变量的四则运算,设计并实现一个语法分析程序。 G2[<算术表达式>]: <算术表达式> → <项> | <算术表达式>+<项> | <算术表达式>-<项> <项> → <因式> | <项>*<因式> | <项>/<因式> <因式> → <运算对象> | (<算术表达式>) 若将语法范畴<算术表达式>、<项>、<因式>和<运算对象>分别用E、T、F 和i代表,则G2可写成: G2[E]:E → T | E+T | E-T T → F | T*F | T/F F → i | (E) 输入:由实验一输出的单词串,例如:UCON,PL,UCON,MU,ID ······ 输出:若输入源程序中的符号串是给定文法的句子,则输出“RIGHT”,并且给出每一步分析过程;若不是句子,即输入串有错误,则输出“ERROR”,并且显示分析至此所得的中间结果,如分析栈、符号栈中的信息等,以及必要的出错说明信息。 要求: 1、确定语法分析程序的流程图,同时考虑相应的数据结构,编写一个语法分析源程序。 2、将词法、语法分析合在一起构成一个完整的程序,并调试成功。 3、供测试的例子应包括符合语法规则的语句,及分析程序能判别的若干错例。对于所输入的字符串,不论对错,都应有明确的信息输出。

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

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

编译原理课程设计报告C-语言词法与语法分析器的实现

编译原理课程设计报告 课题名称:编译原理课程设计 C-语言词法与语法分析器的实现 提交文档学生姓名: 提交文档学生学号: 同组成员名单: 指导教师姓名: 指导教师评阅成绩: 指导教师评阅意见: . . 提交报告时间:年月日

C-词法与语法分析器的实现 1.课程设计目标 (1)题目实用性 C-语言拥有一个完整语言的基本属性,通过编写C-语言的词法分析和语法分析,对于理解编译原理的相关理论和知识有很大的作用。通过编写C-语言词法和语法分析程序,能够对编译原理的相关知识:正则表达式、有限自动机、语法分析等有一个比较清晰的了解和掌握。(2)C-语言的词法说明 ①语言的关键字: else if int return void while 所有的关键字都是保留字,并且必须是小写。 ②专用符号: + - * / < <= > >= == != = ; , ( ) [ ] { } /* */ ③其他标记是ID和NUM,通过下列正则表达式定义: ID = letter letter* NUM = digit digit* letter = a|..|z|A|..|Z digit = 0|..|9 注:ID表示标识符,NUM表示数字,letter表示一个字母,digit表示一个数字。 小写和大写字母是有区别的。 ④空格由空白、换行符和制表符组成。空格通常被忽略。 ⑤注释用通常的c语言符号/ * . . . * /围起来。注释可以放在任何空白出现的位置(即注释不能放在标记内)上,且可以超过一行。注释不能嵌套。

(3)程序设计目标 能够对一个程序正确的进行词法及语法分析。 2.分析与设计 (1)设计思想 a.词法分析 词法分析的实现主要利用有穷自动机理论。有穷自动机可用作描述在输入串中识别模式的过程,因此也能用作构造扫描程序。通过有穷自动机理论能够容易的设计出词法分析器。b.语法分析 语法分析采用递归下降分析。递归下降法是语法分析中最易懂的一种方法。它的主要原理是,对每个非终结符按其产生式结构构造相应语法分析子程序,其中终结符产生匹配命令,而非终结符则产生过程调用命令。因为文法递归相应子程序也递归,所以称这种方法为递归子程序下降法或递归下降法。其中子程序的结构与产生式结构几乎是一致的。 (2)程序流程图 程序主流程图: 词法分析: 语法分析:

实验二语法分析

实验二、语法分析 一、实验目的: 设计MiniC的上下文无关文法,利用JavaCC生成调试递归下降分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。 二、语法分析器: 按照MiniC语言的语法规则检查词法分析输出的记号流是否符合这些规则,并根据这些规则所体现出的语言中的各种语法结构的层次性。把规则写入到JavaCC的.jjt文件中,可以生成树状的层次结构。 三、JavaCC: 在JavaCC的文法规范文件中,不仅可以描述语言的语法规范,而且可以描述词法规范,本次实习中,利用JavaCC以MiniC语言构造一个不含语义分析的编译器前端,包括词法分析、语法分析,并要考虑语法分析中的错误恢复问题。通过使用JavaCC, 可以体会LL(k)文法的编写特点,掌握编写JavaCC文法规范文件的方法。 内容:利用JavaCC生成一个MiniC的语法分析器; 要求: 1.用流的形式读入要分析的C语言程序,或者通过命令行输入源程序。 2.具有错误检查的能力,如果有能力可以输出错误所在的行号,并简单提示 3.如果输入的源程序符合MiniC的语法规范,输出该程序的层次结构的语法树 具体实施步骤如下: 1.把MiniC转换为文法如下 Procedure()→void main() {WhileStatement()} WhileStatement()→while(Condition()){(WhileStatement()|ass ign())} assign()→= ; expression()→term() (( + | - ) term()) term()→unary() (( * | / ) unary()) unary()→| | ( expression()) Condition()→expression()( < expression() | > expression() | >= expression() | <= expression() )

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