|
| 1 | + |
| 2 | +# @ represents null |
| 3 | +# Reading grammar from grammar.txt file |
| 4 | + |
| 5 | +term_n=int(input("Enter the number of terminals: ")) |
| 6 | +print("Enter the terminals: ") |
| 7 | +term_set=[] |
| 8 | +foriinrange(term_n): |
| 9 | +term_set.append(input()) |
| 10 | + |
| 11 | +deflead(nonterm,gra,arr=[],leadset={}): |
| 12 | +lead_=set() |
| 13 | +forleft_vingra: |
| 14 | +ifleft_v==nonterm: |
| 15 | +forprodingra[left_v]: |
| 16 | +iflen(prod)==1: |
| 17 | +ifprodinterm_set: |
| 18 | +lead_=lead_|{prod} |
| 19 | +else: |
| 20 | +ifprod!=nontermandprodnotinarr: |
| 21 | +arr.append(prod) |
| 22 | +lead_=lead_|lead(prod,gra,arr,leadset) |
| 23 | +elifprod!=nontermandprodinleadset: |
| 24 | +lead_=lead_|leadset[prod] |
| 25 | +else: |
| 26 | +foriinprod: |
| 27 | +ifiinterm_set: |
| 28 | +lead_=lead_|{i} |
| 29 | +ifprod.index(i)!=0: |
| 30 | +ifprod[0]!=nontermandprod[0]notinarr: |
| 31 | +arr.append(prod[0]) |
| 32 | +lead_=lead_|lead(prod[0],gra,arr,leadset) |
| 33 | + |
| 34 | +elifprod[0]!=nontermandprod[0]inleadset: |
| 35 | +lead_=lead_|leadset[prod[0]] |
| 36 | +break |
| 37 | +leadset[nonterm]=lead_ |
| 38 | +returnlead_ |
| 39 | + |
| 40 | +deftrail(nonterm,gra,arr=[],trailset={}): |
| 41 | +trail_=set() |
| 42 | +forleft_vingra: |
| 43 | +ifleft_v==nonterm: |
| 44 | +forprodingra[left_v]: |
| 45 | +iflen(prod)==1: |
| 46 | +ifprodinterm_set: |
| 47 | +trail_=trail_|{prod} |
| 48 | +else: |
| 49 | +if (prod!=nonterm)and (prodnotinarr): |
| 50 | +arr.append(prod) |
| 51 | +trail_=trail_|trail(prod,gra,arr,trailset) |
| 52 | +elifprod!=nontermandprodintrailset: |
| 53 | +trail_=trail_|trailset[prod] |
| 54 | +else: |
| 55 | +foriinprod[::-1]: |
| 56 | +ifiinterm_set: |
| 57 | +trail_=trail_|{i} |
| 58 | +ifprod.index(i)!=len(prod)-1: |
| 59 | +if (prod[len(prod)-1]!=nonterm)and (prod[len(prod)-1]notinarr): |
| 60 | +arr.append(prod[len(prod)-1]) |
| 61 | +trail_=trail_|trail(prod[len(prod)-1],gra,arr,trailset) |
| 62 | +elifprod[len(prod)-1]!=nontermandprod[len(prod)-1]intrailset: |
| 63 | +trail_=trail_|trailset[prod[len(prod)-1]] |
| 64 | +break |
| 65 | +trailset[nonterm]=trail_ |
| 66 | +returntrail_ |
| 67 | + |
| 68 | +defread_gra(fname): |
| 69 | +f=open(fname,"r") |
| 70 | +raw_gra=f.read() |
| 71 | +lines=raw_gra.split('\n') |
| 72 | +gra=dict({}) |
| 73 | +foriinlines: |
| 74 | +words=i.split('->') |
| 75 | +foriinrange(len(words)): |
| 76 | +words[i]=words[i].strip() |
| 77 | +prod=words[1].split('/') |
| 78 | +gra[words[0]]=prod |
| 79 | +returngra |
| 80 | + |
| 81 | +defcheckgrammar(gra): |
| 82 | +isoperatorgra=True |
| 83 | +forleft_vingra: |
| 84 | +forprodingra[left_v]: |
| 85 | +j=1 |
| 86 | +iflen(prod)>1: |
| 87 | +foriinrange(len(prod)-1): |
| 88 | +if (prod[i]notinterm_set)and (prod[j]notinterm_set): |
| 89 | +isoperatorgra=False |
| 90 | +break |
| 91 | +j+=1 |
| 92 | + |
| 93 | +elifprod=='@': |
| 94 | +isoperatorgra=False |
| 95 | + |
| 96 | +ifisoperatorgra==False: |
| 97 | +break |
| 98 | +ifisoperatorgra==False: |
| 99 | +break |
| 100 | +returnisoperatorgra |
| 101 | + |
| 102 | +defprintLead(gra): |
| 103 | +foriingra: |
| 104 | +print("Leading of ",i,":",lead(i,gra)) |
| 105 | + |
| 106 | +defprintTrail(gra): |
| 107 | +foriingra: |
| 108 | +print("Trailing of ",i,":",trail(i,gra)) |
| 109 | + |
| 110 | +gra=read_gra('grammar.txt') |
| 111 | +print("Grammar: ",gra) |
| 112 | +print("Terminals: ",term_set) |
| 113 | +if(checkgrammar(gra)): |
| 114 | +print("Grammar is operator grammar") |
| 115 | +printLead(gra) |
| 116 | +printTrail(gra) |
| 117 | +else: |
| 118 | +print("Grammar is not a operator grammar") |
| 119 | + |