ll1语法分析器c语言e-%3ee t,LL1语法分析器_B12040921

《LL1语法分析器_B12040921》由会员分享,可在线阅读,更多相关《LL1语法分析器_B12040921(15页珍藏版)》请在人人文库网上搜索。

1、实 验 报 告(2014/2015学年 第二学期)课程名称编译原理实验名称语法分析器的构造实验时间2015年5月29日指导单位计算机学院软件工程系指导教师蒋凌云学生姓名Cjj班级学号B-学院(系)计算机学院专 业NIIT成 绩批阅人日期实 验 报 告实验名称语法分析器的构造指导教师蒋凌云实验类型上机实验学时4实验时间2015-5-14一、 实验目的和要求设计、编制、调试一个LL(1)语法分析程序,利用语法分析器对符号串进行识别,加深对语法分析原理的理解。要求设计并实现一个LL(1)语法分析器,实现对算数文法E-E+T|T T-T*F|F F-(E)|i 所定义的符号串进行识别。二、 实验环境(。

2、实验设备)Mac OS X + Python三、 实验原理及内容AnalyseMachine:Load( )方法 载入文法规则,自动求出First集,Follow集,分析表Judge( )方法 判断某一字符串是否为当前文法的句子程序代码#coding:utf-8#LL(1)分析法#By:Importcjj#由于仓促,代码有很多地方不是科学,但是基本功能已经实现#2015-6-15class AnalyseMachine(object):def __init__(self):passdef load(self, Grammers):载入文法规则参数Grammers: 文法的规则列表self.Gr。

3、ammers = Grammersself.noLeftRecursionGrammers = self.__NoLeftRecursion(self.Grammers)self.start = self.Grammers00self.nChars = self.__GetVn(self.noLeftRecursionGrammers)self.tChars = self.__GetVt(self.noLeftRecursionGrammers)self.firstSet = self.FirstSet(self.noLeftRecursionGrammers)self.followSet =。

4、 self.FollowSet(self.noLeftRecursionGrammers)self.analyseTable = self.AnalyseTable(self.noLeftRecursionGrammers, self.firstSet, self.followSet)def Judge(self, string):判断字符串是否为当前文法的句子isMatch = FalseanalyseStack = #, self.startStringStack = list(string) + #print u=*25,u判断字符串=%s%string,u=*25print %-30s。

5、%-12s%s%(u分析栈,u余留输入串,u所用生成式)try:while analyseStack:xm = analyseStack-1ai = StringStack0print %-20s%20s%10s%(.join(analyseStack),.join(StringStack), ),if xm in self.nChars:analyseStack.pop()expression = self.analyseTablexmaiif expression = ERROR:printraise ValueErrorprint expression,index = expressio。

6、n.find(:=) + 3if self.__Split(expressionindex:):-1 != :analyseStack += self.__Split(expressionindex:):-1 #逆序加入elif xm = ai and xm != #:analyseStack.pop()StringStack.pop(0)elif xm = ai and xm = #:analyseStack.pop()isMatch = Trueprintexcept Exception as e:passresult = u%s 为文法定义的句子 if isMatch else u%s 。

7、不是文法定义的句子print result%stringprint u=*25,u判断字符串=%s%string,=*25return isMatchdef FirstSet(self, Grammers):构造文法的First集speSymbol = :=Vn = self.nCharsVt = self.tCharsFirst = self.__SubExpressions(Grammers)#新建一个以所有非终结符作为键,以空列表作为值的字典FirstDict = for nChar in Vn:FirstDictnChar = lock = 1while First and lock=。

8、 0:char = expressionindexif char = nChar:breakelif char in Vt:breakelif char not in nilChar:followLink2char.append(nChar)# print 1 add %s to follow %s%(nChar, char)breakelse:followLink2char.append(nChar)# print 2 add %s to follow %s%(nChar, char)index -= 1# print followLink2hasFollowChar = notFollow。

9、Char = for nChar, links in followLink2.items():if not links:hasFollowChar.append(nChar)else:notFollowChar.append(nChar)# print hasFollowChar# print notFollowCharlock = 1while notFollowChar and lock 100:delChar = for nChar in notFollowChar:# print nChar is %s%nCharif set(followLink2nChar).issubset(se。

10、t(hasFollowChar):for link in followLink2nChar:FollowDictnChar += FollowDictlinkdelChar.append(nChar)# print delChar, delChar# print hasFollowChar, hasFollowChar# print notFollowChar, notFollowCharfor char in delChar:hasFollowChar.append(char)notFollowChar.remove(char)lock += 1if lock = 100:print War。

11、ning! The loop lock is walking.for nChar in Vn:FollowDictnChar = list(set(FollowDictnChar)return FollowDictdef AnalyseTable(self, Grammer, firstSet, followSet):建立文法的分析表Table = tChars = self.tCharsnChars = self.nCharsfor n_char in nChars:Tablen_char = for t_char in tChars:Tablen_chart_char = ERRORsub。

12、Rules = for rule in Grammer:left_char = rule.split(:=)0rightExpressions = rule.split(:=)1subRules += left_char +:=+right_expression for right_expression in rightExpressions.split(|)for sub_rule in subRules:left_char, meetChars = self.__ExpressionAnalyse(sub_rule, firstSet, followSet)for meet_char in。

13、 meetChars:Tableleft_charmeet_char=sub_rulereturn Tabledef __NoLeftRecursion(self, Grammers):消除文法规则的左递归RightFirstIndex = 4noLeftRecursionGrammers = for rule in Grammers:# print ruleindex = rule.find(:=) #左边终结符号的终止位置leftSymbol = rule:index #获取左边的非终结符rightFirstSymbol = ruleRightFirstIndex #获取右边的第一个符号i。

14、f rightFirstSymbol = leftSymbol: #如果左边的非终结符与右边第一个符号相等,则进行消除左递归resultOne = symbol for symbol in ruleRightFirstIndex:.split(|) if leftSymbol not in symbol #单独取出含左非终结符的子表达式resultTwo = symbol for symbol in ruleRightFirstIndex:.split(|) if leftSymbol in symbol #单独取出不含左非终结符的子表达式# print resultTwonewLeftSym。

15、bol = leftSymbol+ #引入一个新终结符resultOne = symbol + newLeftSymbol for symbol in resultOnerightExpressionOne = |.join(resultOne)expressionOne = rule0:RightFirstIndex+rightExpressionOne# print expressionOneresultTwo = symbol.replace(leftSymbol, )+newLeftSymbol for symbol in resultTworesultTwo.append()righ。

16、tExpressionTwo = |.join(resultTwo)expressionTwo = newLeftSymbol+rule1:RightFirstIndex+rightExpressionTwo# print expressionTwonoLeftRecursionGrammers += expressionOne,expressionTwo #返回经过改写法消除直接左递归后的文法规则# print ruleelse:noLeftRecursionGrammers += rule #如果不含直接左递归,则直接返回return noLeftRecursionGrammersdef 。

17、__GetVt(self, Grammer):获取文法中的终结符号Vt = speSymbol = :=Vn = self.__GetVn(self.noLeftRecursionGrammers)Vn.append(speSymbol)Vn.append()Vn.append(|)for grammer in Grammer:for symbol in Vn:grammer = grammer.replace(symbol,)for char in grammer:if char not in Vt:Vt.append(char)# for char in Vt:# print charre。

18、turn Vtdef __GetVn(self, Grammer):获取文法中的非终结符号Vn = for grammer in Grammer:index = grammer.find(:=) #左边终结符号的终止位置char = grammer:indexif char not in Vn:Vn.append(char)return Vndef __SubExpressions(self, Grammer):获取文法的子规则集形如左边非终结符: 对应的右边的所有文法子规则speSymbol = :=_Grammer = for grammer in Grammer:_grammer = g。

19、rammer.split(speSymbol)_Grammer_grammer0 = _grammer1#新建一个字典subExpressions 形如非终结符: 所有文法子规则subExpressions = for nChar, rightExpression in _Grammer.items():subExpressionsnChar = subExpression for subExpression in rightExpression.split(|)# print subExpressionsreturn subExpressionsdef __Split(self, Expre。

20、ssion):将一个文法规则按单个字符切分char_list = length = len(Expression)for _ in xrange(length):char = Expression_if char = :char_list_ - 1 += charelse:char_list.append(char)return char_listdef __ExpressionAnalyse(self, expression, firstSet, followSet):建立分析表时,判断某个表达式应该填入分析表的哪一个位置tChars = self.tCharsnChars = self.n。

21、Charsleft_char, rightChars = expression.split(:=)meetChars = for right_char in rightChars:if right_char = :meetChars += followSetleft_charbreakelif right_char in tChars:meetChars.append(right_char)breakelse:meetChars += firstSetright_charif not in firstSetright_char:breakelse:meetChars.remove()retur。

22、n left_char, meetCharsif __name__ = __main__:import pprint# grammer_list = A:=BCc|gDB, B:=|bCDE, C:=DaB|ca, D:=|dD, E:=gAf|cgrammer_list = E:=E+T|T, T:=T*F|F, F:=(E)|i# grammer_list = S:=iCtSS|a, S:=eS|, C:=bll1am = AnalyseMachine()ll1am.load(grammer_list)print u消除文法左递归print ll1am.noLeftRecursionGra。

23、mmersprint u非终极符print ll1am.nCharsprint u终结符print ll1am.tCharsprint uFirst集pprint.pprint(ll1am.firstSet)print uFollow集pprint.pprint(ll1am.followSet)print uLL(1)分析表pprint.pprint(ll1am.analyseTable)string1 = i+i*ill1am.Judge(string1)string2 = i*(i+i)ll1am.Judge(string2)string3 = i+i(i*i)ill1am.Judge(string3)实验结果:四、实验小结通过本次实验基本掌握了语法分析的原理和LL(1)语法分析方法,以及预测分析表的构造,了解了语法分析的过程。由于开始的时候不了解具体求法,感觉有点麻烦。但在仔细翻阅书本了解到了具体的分析方法后,就感觉手到擒来了。但是编写仓促,该程序虽然可以随意输入文法规则来分析,但是可能在一些小问题上还有待改进。如果有时间的话,还会好好改进一下的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值