logo资料库

语法分析器实验报告.doc

第1页 / 共23页
第2页 / 共23页
第3页 / 共23页
第4页 / 共23页
第5页 / 共23页
第6页 / 共23页
第7页 / 共23页
第8页 / 共23页
资料共23页,剩余部分请下载后查看
1概述
1.1.实验目标
1.2.实验描述
1.3.实验要求
2技术分析
2.1实验流程图
2.2.状态转换图
3实验内容
3.1实验代码
KeySimple=['*','-','/','=','>','<','>=','==','<=',
KeyAmbit=['(',')',',',';','.','{','}','<','>','"',
KeyWord=[ 'bool','char' ,'char[','class','define',
'private','public','put','read','return'
'unsigned','void']
TypeKeyWord=['int','long','unsign','double','float
FunctionKeyWord=['getchar','open','printf','put','
#-------------------------------------------------
SourceProgram=[]
DeleteNote_SourceProgram=[]
Reader_SourceProgram=[]
WordPositionList=[]
#-------------------------------------------------
ErrorList={}
WordType={}
WordPosition={}
#-------------------------------------------------
Filepath=''
#-------------------------------------------------
LeftNoteFlag=0
RightNoteFlag=0
LeftBracketNumber=0
RighBracketNumber=0
NumberInString=0
NumberinList=0
#-------------------------------------------------
class Assembly():
def IsLetter(self,Char):
if((Char<='z' and Char>='a') or( Char<='Z
return True
else:
return False
def IsNote(self,String):
global LeftNoteFlag
global RightNoteFlag
NumberInString=0
for Char in String:
if(NumberInString
NumberInString+=1
if(Char=='/'):
if(String[NumberInString]=='/'):
return 2
elif(String[NumberInString]=='*'):
if(LeftNoteFlag==0):
LeftNoteFlag+=1
return 1
elif(Char=='*'):
if(String[NumberInString]=='/'):
if(RightNoteFlag==0):
RightNoteFlag+=1
return 3
if(len(String)==NumberInString+1):
return False
def IsDigit(self,Char):
if(Char<='9' and Char>='0'):
return True
else:
return False
def IsSpace(self,Char):
if(Char==' '):
return True
else:
return False
def PassSpace(self,List):
NumberinList=0
for String in List:
List[NumberinList]=String.strip()
NumberinList+=1
return List
def DeleteNote(self,List):
global LeftNoteFlag
global RightNoteFlag
RemoveList=[]
ResultList=List
FirstLeftNoteNumber=0
NumberinList=0
LeftNoteNumber=0
for String in ResultList:
Flag=self.IsNote(String)
NumberInString=0
FirstLeftNoteNumber=0
if(Flag):
for Char in String:
if(NumberInString
NumberInString+=1
if(Flag==1):
if(Char=='/' and String[Nu
if(NumberInString!=1):
LeftNoteNumber=Num
else:
LeftNoteNumber=Num
if(FirstLeftNoteNumber
FirstLeftNoteNumbe
LeftNoteFlag=1
else:
pass
if(Char=='*' and String[Nu
if(NumberInString!=len
String=String[0:Fi
else:
String=String[0:Fi
LeftNoteFlag=0
break
if(NumberInString+1==len(S
if(FirstLeftNoteNumber
RemoveList.append(S
else:
String=String[0:Fi
break
elif(Flag==2):
if(Char=='/' and String[Nu
String=String[0:Number
break
elif(Flag==3):
if(Char=='*' and String[Nu
if(LeftNoteFlag!=0 and
String=String[Numb
elif(LeftNoteFlag==0 a
String=String[0:Nu
elif(LeftNoteFlag!=0 a
RemoveList.append(
RightNoteFlag=0
LeftNoteFlag=0
break
else:
if(LeftNoteFlag!=0 and RightNoteFl
RemoveList.append(String)
elif(LeftNoteFlag!=0 and RightNote
LeftNoteFlag=0
RightNoteFlag=0
else:
pass
ResultList[NumberinList]=String
if(NumberinList
NumberinList+=1
for ListString in RemoveList:
ResultList.remove(ListString)
return ResultList
def Reader(self,List):
ResultList=[]
for String in List:
Letter=''
Digit=''
ElseLetter=''
NumberInString=0
CharNumber=0
for Char in String:
if(NumberInString
NumberInString+=1
if(self.IsLetter(Char)):
if( (self.IsLetter(String[Numb
Letter+=Char
elif(self.IsSpace(String[Numbe
Letter+=Char
ResultList.append(Letter)
Letter=''
else:
if(self.IsDigit(Char) or Char=
if(String[NumberInString]=
Digit+=Char
elif (self.IsSpace(String[
Digit+=Char
ResultList.append(Digi
Digit=''
else:
if(Char=='#'):
ResultList.append('#')
else:
if(Char in KeyAmbit ):
if(Char=='.' and s
pass
else:
ResultList.app
else:
if(Char in KeySimp
ElseLetter+=Ch
if(String[Numb
ElseLetter
ResultList
ElseLetter
else:
ResultList
ElseLetter
else:
if(self.IsSpac
pass
CharNumber+=1
return ResultList
def JugeMent(self,List):
global WordType
FormatFlag=0
NumberinList=0
for String in List:
if(NumberinList
NumberinList+=1
if(len(String)==1):
if(String=='#'):
WordType.setdefault('宏定义符号',[]).
elif(String in KeyAmbit):
if(String=='<' ):
if(List[NumberinList] in K
WordType.setdefault('分
elif(String=='>'):
if(List[NumberinList-3] in
WordType.setdefault('分
elif(String=='.'):
if(List[NumberinList].isdi
WordType.setdefault('运
else:
WordType.setdefault('分界符',
elif(String in KeySimple):
if(String=='%'):
if(not(List[NumberinList].
WordType.setdefault('格
FormatFlag=1
continue
WordType.setdefault('运算符',[]).
else:
if(String.isdigit()):
WordType.setdefault('数字',[
elif(String.isalnum()):
if(FormatFlag==0):
WordType.setdefault('变
else:
WordType.setdefault('格
FormatFlag=0
else:
if(String in KeyWord):
WordType.setdefault('关键字',[]).
elif(String in KeySimple):
WordType.setdefault('运算符',[]).
else:
if(String.isdigit()):
WordType.setdefault('数字',[
elif(String.isalnum()):
if(FormatFlag==0):
WordType.setdefault('变
else:
WordType.setdefault('格
FormatFlag=0
def KeyWordPosition(self,HandleList,DivisionLi
global WordPosition
for ListIdex in range(len(HandleList)):
SameFlag=-1
Word=''
for StringIndex in range(len(HandleLis
if(HandleList[ListIdex][String
pass
else:
Word+=HandleList[ListIdex]
if(Word in DivisionList):
if(SameFlag!=StringIndex):
WordPosition.setdefaul
SameFlag=StringIndex
Word=''
else:
Word=''
continue
def DefineError(self,HandleList,DivisionList):
global WordType
global WordPosition
SlineNumber=0
LineNumber=0
WellNumber=-1
LoopFlag=0
for Line in HandleList:
LineNumber+=1
if(Line[0]=='#'):
SlineNumber+=1
if(LoopFlag==0):
for Index in range(len(Divisio
if(DivisionList[Index]=='#
if(WellNumber
WellNumber+=1
if(DivisionList[Index+
print('宏定义错误!错
if(LineNumber-SlineNumber!=0):
print('宏定义不能出现在代码段中!错误位置为:
LoopFlag+=1
def BracketError(self,DivisionList):
global WordType
global WordPosition
lLeftBracketNumber=0
lRighBracketNumber=0
bLeftBracketNumber=0
bRighBracketNumber=0
sLeftBracketNumber=0
sRighBracketNumber=0
for String in DivisionList:
if(String=='('):
lLeftBracketNumber+=1
elif(String==')'):
lRighBracketNumber+=1
elif(String=='['):
bLeftBracketNumber+=1
elif(String==']'):
bRighBracketNumber+=1
elif(String=='{'):
sLeftBracketNumber+=1
elif(String=='}'):
sRighBracketNumber+=1
if(lLeftBracketNumber!=lRighBracketNumber)
if(lLeftBracketNumber>lRighBracketNumb
print('括号不匹配,缺少右小括号,尝试匹配此处括号:'+str
else:
print('括号不匹配,缺少左小括号,尝试匹配此处括号或者删除:'
elif(bLeftBracketNumber!=bRighBracketNumbe
if(bLeftBracketNumber>bRighBracketNumb
print('括号不匹配,缺少右中括号,尝试匹配此处括号:'+str
else:
print('括号不匹配,缺少左中括号,尝试匹配此处括号或者删除:'
elif(sLeftBracketNumber!=sRighBracketNumbe
if(sLeftBracketNumber>sRighBracketNumb
print('括号不匹配,缺少右大括号,尝试匹配此处括号:'+str
else:
print('括号不匹配,缺少左大括号,尝试匹配此处括号或者删除:'
def TypeClassError(self,DivisionList):
global WordType
global WordPosition
IntNumber=-1
ShortNumber=-1
LongNumber=-1
StringNumber=-1
FloatNumber=-1
DoubleNumber=-1
StringFlag=0
for Index in range(len(DivisionList)):
if(DivisionList[Index] in TypeKeyWord)
if(DivisionList[Index]=='int'):
IntNumber+=1
if(DivisionList[Index+1] not i
if(DivisionList[Index+1]==
continue
print('定义无变量,错误位置:'+str(Wo
else:
if(DivisionList[Index+2]!=
print('Int缺省定义,错误位置:'+
elif(DivisionList[Index+2]
continue
else:
for Number in Division
if(not self.IsDigi
print('Int类型数据
break
elif(DivisionList[Index]=='short')
ShortNumber+=1
if(DivisionList[Index+1] not i
if(DivisionList[Index+1]==
continue
print('定义无变量,错误位置:'+str(Wo
else:
if(DivisionList[Index+2]!=
print('Short缺省定义,错误位置:
elif(DivisionList[Index+2]
continue
else:
for Number in Division
if(not self.IsDigi
print('Short类型
break
elif(DivisionList[Index]=='long'):
LongNumber+=1
if(DivisionList[Index+1] not i
if(DivisionList[Index+1]==
continue
print('定义无变量,错误位置:'+str(Wo
else:
if(DivisionList[Index+2]!=
print('Long缺省定义,错误位置:'
continue
elif(DivisionList[Index+2]
continue
else:
for Number in Division
if(not self.IsDigi
print('Long类型数
break
elif(DivisionList[Index]=='float')
FloatNumber+=1
if(DivisionList[Index+1] not i
if(DivisionList[Index+1]==
print('定义无变量,错误位置:'+st
continue
else:
if(DivisionList[Index+2]!=
print('Float缺省定义,错误位置:
continue
elif(DivisionList[Index+2]
continue
else:
for Number in Division
if(not self.IsDigi
print('Float类型
break
elif(DivisionList[Index]=='double'
DoubleNumber+=1
if(DivisionList[Index+1] not i
if(DivisionList[Index+1]==
print('定义无变量,错误位置:'+st
continue
else:
if(DivisionList[Index+2]!=
print('Double缺省定义,错误位置
continue
elif(DivisionList[Index+2]
continue
else:
for Number in Division
if(not self.IsDigi
print('Double类
break
elif(DivisionList[Index]=='string'
StringNumber+=1
if(DivisionList[Index+1] not i
print('定义无变量,错误位置:'+str(Wo
continue
else:
if(DivisionList[Index+2]!=
print('String缺省定义,错误位置
continue
elif(DivisionList[Index+2]
continue
else:
for Char in DivisionLi
if(Char=='"'):
StringFlag+=1
if(DivisionList[Index+
print('String类型数据定
break
def NameClassError(self,DivisionList):
global WordType
global WordPosition
WordNumber={}
WordNumbers=0
for Number in range(len(WordType.get('变量')
if(WordType.get('变量')[Number] not in W
WordNumber.setdefault(WordType.get
else:
WordNumbers=WordNumber.get(WordTyp
WordNumbers+=1
WordNumber[WordType.get('变量')[Numb
for String in WordNumber.keys():
if(not self.IsLetter(String[0])):
for Index in WordPosition.values()
print(String+'变量名定义错误,错误位置:'+s
else:
for Char in String[1:]:
if(not(self.IsDigit(Char)) and
for Index in WordPosition.
print(String+'变量中含有非法字
def SemicolonError(self,HandleList,DivisionLis
global WordType
global WordPosition
global WordPositionList
LineNumber=0
LineFlag=0
for key,value in WordPosition.items():
WordPositionList.append([key,value])
for Line in HandleList:
LineNumber+=1
LineFlag=0
SameFlag=0
TypeWordNumber=0
TenporaryList=[]
if(Line[0]=='#' or 'main' in Line):
continue
else:
for TypeWord in TypeKeyWord:
if(TypeWord in Line):
for xyposition in WordPosi
if(LineNumber-1 ==xypo
SameFlag+=1
if(LineFlag==0 and SameFla
if(';' not in Line):
print('缺少分号,错误位置为'
LineFlag=1
else:
for Block in WordP
for Position i
for LinePo
if(Lin
if
for Char in Line:
if(Char==';'):
TypeWordNu
if(len(TenporaryLi
print('缺少分号,错误
LineFlag=1
for Function in FunctionKeyWord:
if(Function in Line):
if(LineFlag==0):
if(';' not in Line):
print('缺少分号,错误位置为'
LineFlag=1
else:
for Block in WordP
for Position i
for LinePo
if(Lin
if
for Char in Line:
if(Char==';'):
TypeWordNu
if(len(TenporaryLi
print(Tenporar
print('缺少分号,错误
LineFlag=1
for Variable in WordType.get('变量')
if(Variable in Line):
if(LineFlag==0):
if(';' not in Line):
print('缺少分号,错误位置为'
LineFlag=1
else:
pass
def AllKindOfError(self,HandleList,DivisionLis
global WordType
global WordPosition
self.DefineError(HandleList,DivisionList)
self.BracketError(DivisionList)
self.TypeClassError(DivisionList)
self.NameClassError(DivisionList)
self.SemicolonError(HandleList,DivisionLis
pass
def main():
global Reader_SourceProgram
global DeleteNote_SourceProgram
global SourceProgram
global Filepath
global WordPosition
global WordType
AsseMbly=Assembly()
Filepath=input("请输入文件路径:")
for line in open(Filepath,'r',encoding='GB2312
line=line.replace('\n','')
SourceProgram.append(line)
print("源程序:")
for line in SourceProgram:
print(line)
DeleteNote_SourceProgram=AsseMbly.DeleteNote(S
DeleteNote_SourceProgram=AsseMbly.PassSpace(De
Reader_SourceProgram=AsseMbly.Reader(DeleteNot
AsseMbly.JugeMent(Reader_SourceProgram)
AsseMbly.KeyWordPosition(DeleteNote_SourceProg
print("\n处理后程序:")
for line in DeleteNote_SourceProgram:
print(line)
print("\n错误信息:")
#print(DeleteNote_SourceProgram)
#print(Reader_SourceProgram)
#print(WordPosition)
#print(WordType)
AsseMbly.AllKindOfError(DeleteNote_SourceProgr
#print(WordPositionList)
if __name__ == "__main__":
main()
3.2测试结果
4自我总结
5参考文献
《编译原理》实验报告 实验一:语法分析器 系 专 学 名 计算机科学与技术系 业 计算机科学与技术 号 ___________ 学生姓名 ______ 2018 年 12 月 10 日
目 录 目 录.............................................................................................2 1 概述.................................................................................................1 1.1. 实验目标......................................................................................1 1.2. 实验描述......................................................................................1 1.3. 实验要求......................................................................................1 2 技术分析.........................................................................................1 2.1 实验流程图..................................................................................2 2.2. 状态转换图................................................................................3 3 实验内容.........................................................................................3 3.1 实验代码......................................................................................3 3.2 测试结果....................................................................................20 4 自我总结.......................................................................................20 5 参考文献.......................................................................................21
1 概述 本次实验通过用 python 语言,设计,编制,调试一个词法分析子程序,识 别单词,实现一个 python 语法分析器,经过此过程可以加深对编译器解释的过 程。 1.1. 实验目标 理解并掌握语法分析的原理与方法,能够使用某种语言实现语法分析程序。 1.2. 实验描述 本实验中将 C 语言单词符号分为三类:关键字,运算符,界符,将关键字初 始 在 KeyWord 列 表 中 , 将 界 符 初 始 在 KeyAmbit 列 表 中 , 将 运 算 符 初 始 在 KeySimple 列表中。因此,从原文件字符串中识别出关键字,界符,运算符只能 从中选取,其他的可以归类为变量,数字,格式变量,格式符,存放到列表中, 字典存放这些变量的位置,方便确认报错位置。 1.3. 实验要求 1.输入词法分析输出的单词序列,判断单词序列构成的程序是否符合语法语法 规则。 2.记录语法错误信息,统一输出错误信息。 2 技术分析 1
2.1 实验流程图 2
2.2. 状态转换图 3 实验内容 3.1 实验代码 KeySimple=['*','-','/','=','>','<','>=','==','<=','%','+','+=','-=','*=','/='] #词法分析器中分别运算符 KeyAmbit=['(',')',',',';','.','{','}','<','>','"','[',']'] #词法分析器中分别界符 KeyWord=[ 'bool','char' ,'char[','class','define','double','false','float','getchar','include','i nt','iostream','long','main','null','open','printf', 'private','public','put','read','return','short','scanf','signed','static','stdio','string','struct','tru e', 'unsigned','void'] TypeKeyWord=['int','long','unsign','double','float','string','struct','char','void','bool','clas s','short'] #语法分析定义类型 3
FunctionKeyWord=['getchar','open','printf','put','read','return','scanf'] #语法分析功能类型 #------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------ SourceProgram=[] #存放源程序代码 DeleteNote_SourceProgram=[] #存放去除注释源程序代码 Reader_SourceProgram=[] #存放类型判断后源程序 WordPositionList=[] #存放单词位置信息 #------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------ ErrorList={} #语法分析器错误储存报表(存储报错位置和类型) WordType={} #词法类型字典 WordPosition={} #定位关键字位置 #------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------ Filepath='' #存放文件路径 #------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------ LeftNoteFlag=0 #/*注释清除标记 RightNoteFlag=0 #*/注释清除标记 LeftBracketNumber=0 #成对界符的左标记 RighBracketNumber=0 #成对界符的右标记 NumberInString=0 #String 中的下标 NumberinList=0 #List 中的下标 #------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------ class #封装成编译器 4 Assembly():
if((Char<='z' and Char>='a') or( Char<='Z' and Char>='A') or Char=='_'): return False IsNote(self,String): def IsLetter(self,Char): return True else: def #判断注释类型 global LeftNoteFlag global RightNoteFlag NumberInString=0 for Char in String: if(NumberInString='0'): else: return True return False def IsSpace(self,Char): if(Char==' '): return True else: return False def #清除字符串中前后的空格 NumberinList=0 PassSpace(self,List): 5
def #删除列表中的注释『'//'或者'/* */'』 DeleteNote(self,List): for String in List: List[NumberinList]=String.strip() NumberinList+=1 return List global LeftNoteFlag global RightNoteFlag RemoveList=[] ResultList=List FirstLeftNoteNumber=0 NumberinList=0 LeftNoteNumber=0 for String in ResultList: Flag=self.IsNote(String) NumberInString=0 FirstLeftNoteNumber=0 if(Flag): for Char in String: if(NumberInString
分享到:
收藏