LL1语法分析器B1921Word下载.docx
- 文档编号:19411860
- 上传时间:2023-01-06
- 格式:DOCX
- 页数:17
- 大小:79.93KB
LL1语法分析器B1921Word下载.docx
《LL1语法分析器B1921Word下载.docx》由会员分享,可在线阅读,更多相关《LL1语法分析器B1921Word下载.docx(17页珍藏版)》请在冰豆网上搜索。
T*F|FF->
(E)|i所定义的符号串进行识别。
二、实验环境(实验设备)
MacOSX+Python
三、实验原理及内容
AnalyseMachine:
Load()方法载入文法规则,自动求出First集,Follow集,分析表
Judge()方法判断某一字符串是否为当前文法的句子
程序代码
#coding:
utf-8
#LL
(1)分析法
#By:
Importcjj
#由于仓促,代码有很多地方不是科学,但是基本功能已经实现
#2015-6-15
classAnalyseMachine(object):
def__init__(self):
pass
defload(self,Grammers):
"
"
载入文法规则
参数
Grammers:
文法的规则列表
self.Grammers=Grammers
self.noLeftRecursionGrammers=self.__NoLeftRecursion(self.Grammers)
self.start=self.Grammers[0][0]
self.nChars=self.__GetVn(self.noLeftRecursionGrammers)
self.tChars=self.__GetVt(self.noLeftRecursionGrammers)
self.firstSet=self.FirstSet(self.noLeftRecursionGrammers)
self.followSet=self.FollowSet(self.noLeftRecursionGrammers)
self.analyseTable=self.AnalyseTable(self.noLeftRecursionGrammers,self.firstSet,self.followSet)
defJudge(self,string):
判断字符串是否为当前文法的句子
isMatch=False
analyseStack=["
#"
self.start]
StringStack=list(string)+["
]
printu"
="
*25,u"
判断字符串=%s"
%string,u"
*25
print"
%-30s%-12s%s"
%(u"
分析栈"
u"
余留输入串"
所用生成式"
)
try:
whileanalyseStack:
xm=analyseStack[-1]
ai=StringStack[0]
print"
%-20s%20s%10s"
%("
.join(analyseStack),"
.join(StringStack),"
),
ifxminself.nChars:
analyseStack.pop()
expression=self.analyseTable[xm][ai]
ifexpression=="
ERROR"
:
raiseValueError
printexpression,
index=expression.find("
)+3
ifself.__Split(expression[index:
])[:
-1]!
=["
~"
]:
analyseStack+=self.__Split(expression[index:
-1]#逆序加入
elifxm==aiandxm!
="
StringStack.pop(0)
elifxm==aiandxm=="
isMatch=True
exceptExceptionase:
pass
result=u"
%s为文法定义的句子"
ifisMatchelseu"
%s不是文法定义的句子"
printresult%string
%string,"
returnisMatch
defFirstSet(self,Grammers):
构造文法的First集
speSymbol="
Vn=self.nChars
Vt=self.tChars
First=self.__SubExpressions(Grammers)
#新建一个以所有非终结符作为键,以空列表作为值的字典
FirstDict={}
fornCharinVn:
FirstDict[nChar]=[]
lock=1
whileFirstandlock<
100:
fornCharinVn:
ifFirst.has_key(nChar):
#如果nChar的First还没求完毕
first=First[nChar]
forcharsinfirst:
char=chars[0]
ifcharinVt:
#如果子规则的第一个符号是终结符,直接加入First集
FirstDict[nChar].append(char)
First[nChar].remove(chars)
else:
#isinVn
ifcharnotinFirst:
#char是非终结符而且他的First集已经求解完毕
FirstDict[nChar]+=FirstDict[char]#把该非终结符的First集(除”~“外加入nChar的First集中)
First[nChar].remove(chars)
if"
inFirstDict[char]:
FirstDict[nChar].remove("
First[nChar].append(chars[1:
])#如果该终结符的First中含有”~“,那么他的下一个符号的First集也需要被继续计算
else:
pass
ifnotFirst[nChar]:
#如果子规则全部检查计算完毕,那么删去First中以nChar作为键的键值对
First.pop(nChar)
lock+=1
iflock==100:
print"
Warning!
thelooplockisworking.."
returnFirstDict
defFollowSet(self,Grammers):
构造文法的Follow集
Follow=self.__SubExpressions(Grammers)
FollowDict={}
FollowDict[nChar]=[]
#rule1----------------”#加入文法的开始符号的Follow集“
FollowDict[Vn[0]].append("
#rule2----------------
firstSet=self.firstSet
followLink={}
followLink[nChar]=[]
fornChar,expressioninFollow.items():
forsubExpressioninexpression:
subExpression=self.__Split(subExpression)
forcharinsubExpression[:
-1]:
ifcharinVn:
index=subExpression.index(char)+1
string=subExpression[index:
followLink[char].append('
'
.join(string))
#printfollowLink
fornChar,stringListinfollowLink.items():
forstringinstringList:
string=self.__Split(string)
forcharinstring:
#print"
string"
string
ifcharinVt:
FollowDict[nChar].append(char)
break
else:
firstSetOfChar=firstSet[char]
#print"
nchar=%schar=%sfirstSetOfChar=%s"
%(nChar,char,firstSetOfChar)
FollowDict[nChar]+=firstSetOfChar
if"
infirstSetOfChar:
FollowDict[nChar].remove("
break
#rule3----------------
#先求出能推倒出”~“的非终结符
nilChar=[]
fornChar,subExpressionsinFollow.items():
if"
insubExpressions:
nilChar.append(nChar)
nilChar.append('
followLink2={}
followLink2[nChar]=[]
#print"
ncahr=%s,subExpressions="
%nChar,subExpressions
forexpressioninsubExpressions:
expression=self.__Split(expression)
index=len(expression)-1
whileindex>
=0:
char=expression[index]
ifchar==nChar:
elifcharinVt:
elifcharnotinnilChar:
followLink2[char].append(nChar)
1add%stofollow%s"
%(nChar,char)
2add%stofollow%s"
index-=1
#printfollowLink2
hasFollowChar=[]
notFollowChar=[]
fornChar,linksinfollowLink2.items():
ifnotlinks:
hasFollowChar.append(nChar)
else:
notFollowChar.append(nChar)
#printhasFollowChar
#printnotFollowChar
whilenotFollowCharandlock<
delChar=[]
fornCharinnotFollowChar:
#print"
nCharis%s"
%nChar
ifset(followLink2[nChar]).issubset(set(hasFollowChar)):
forlinkinfollowLink2[nChar]:
FollowDict[nChar]+=FollowDict[link]
delChar.append(nChar)
delChar"
delChar
hasFollowChar"
hasFollowChar
notFollowChar"
notFollowChar
forcharindelChar:
hasFollowChar.append(char)
notFollowChar.remove(char)
lock+=1
iflock==100:
Warning!
Thelooplockiswalking.."
FollowDict[nChar]=list(set(FollowDict[nChar]))
returnFollowDict
defAnalyseTable(self,Grammer,firstSet,followSet):
建立文法的分析表
Table={}
tChars=self.tChars
nChars=self.nChars
forn_charinnChars:
Table[n_char]={}
fort_charintChars:
Table[n_char][t_char]="
subRules=[]
forruleinGrammer:
left_char=rule.split("
)[0]
rightExpressions=rule.split("
)[1]
subRules+=[left_char+"
+right_expressionforright_expressioninrightExpressions.split("
|"
)]
forsub_ruleinsubRules:
left_char,meetChars=self.__ExpressionAnalyse(sub_rule,firstSet,followSet)
formeet_charinmeetChars:
Table[left_char][meet_char]=sub_rule
returnTable
def__NoLeftRecursion(self,Grammers):
消除文法规则的左递归
RightFirstIndex=4
noLeftRecursionGrammers=[]
forruleinGrammers:
#printrule
index=rule.find('
='
)#左边终结符号的终止位置
leftSymbol=rule[:
index]#获取左边的非终结符
rightFirstSymbol=rule[RightFirstIndex]#获取右边的第一个符号
ifrightFirstSymbol==leftSymbol:
#如果左边的非终结符与右边第一个符号相等,则进行消除左递归
resultOne=[symbolforsymbolinrule[RightFirstIndex:
].split('
|'
)ifleftSymbolnotinsymbol]#单独取出含左非终结符的子表达式
resultTwo=[symbolforsymbolinrule[RightFirstIndex:
)ifleftSymbolinsymbol]#单独取出不含左非终结符的子表达式
#printresultTwo
newLeftSymbol=leftSymbol+"
#引入一个新终结符
resultOne=[symbol+newLeftSymbolforsymbolinresultOne]
rightExpressionOne="
.join(resultOne)
expressionOne=rule[0:
RightFirstIndex]+rightExpressionOne
#printexpressionOne
resultTwo=[symbol.replace(leftSymbol,"
)+newLeftSymbolforsymbolinresultTwo]
resultTwo.append('
~'
rightExpressionTwo="
.join(resultTwo)
expressionTwo=newLeftSymbol+rule[1:
RightFirstIndex]+rightExpressionTwo
#printexpressionTwo
noLeftRecursionGrammers+=[expressionOne,expressionTwo]#返回经过改写法消除直接左递归后的文法规则
noLeftRecursionGrammers+=[rule]#如果不含直接左递归,则直接返回
returnnoLeftRecursionGrammers
def__GetVt(self,Grammer):
获取文法中的终结符号
Vt=[]
Vn=self.__GetVn(self.noLeftRecursionGrammers)
Vn.append(speSymbol)
Vn.append("
forgrammerinGrammer:
forsymbolinVn:
grammer=grammer.replace(symbol,'
forcharingrammer:
ifcharnotinVt:
Vt.append(char)
#forcharinVt:
#printchar
returnVt
def__GetVn(self,Grammer):
获取文法中的非终结符号
Vn=[]
index=grammer.find('
char=grammer[:
index]
ifcharnotinVn:
Vn.append(char)
returnVn
def__SubExpressions(self,Grammer):
获取文法的子规则集
形如{左边非终结符:
[对应的右边的所有文法子规则]}
_Grammer={}
_grammer=grammer.split(speSymbol)
_Grammer[_grammer[0]]=_grammer[1]
#新建一个字典subExpressions形如{非终结符:
[所有文法子规则]}
subExpressions={}
fornChar,rightExpressionin_Grammer.items():
subExpressions[nChar]=[subExpressionforsubExpressioninrightExpression.split("
#printsubExpressions
returnsubExpressions
def__Split(self,Expression):
将一个文法规则按单个字符切分
char_list=[]
length=len(Expression)
for_inxrange(length):
char=Expression[_]
ifchar=="
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LL1 语法 分析器 B1921