Skip to content

Commit f451091

Browse files
committed
more optimizations
1 parent 2add1cb commit f451091

File tree

1 file changed

+19
-21
lines changed

1 file changed

+19
-21
lines changed

sly/yacc.py

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def end(self):
150150

151151
def __getattr__(self, name):
152152
if name in self._namemap:
153-
return self._namemap[name](self._slice)
153+
return self._slice[self._namemap[name]].value
154154
else:
155155
nameset = '{' + ', '.join(self._namemap) + '}'
156156
raise AttributeError(f'No symbol {name}. Must be one of {nameset}.')
@@ -233,15 +233,16 @@ def __init__(self, number, name, prod, precedence=('right', 0), func=None, file=
233233
nameuse[key] += 1
234234
else:
235235
k = key
236-
namemap[k] = lambda s,i=index: s[i].value
236+
namemap[k] = index
237237
if key in _name_aliases:
238238
for n, alias in enumerate(_name_aliases[key]):
239239
if namecount[alias] > 1:
240240
k = f'{alias}{nameuse[alias]}'
241241
nameuse[alias] += 1
242242
else:
243243
k = alias
244-
# The value is either a list (for repetition) or a tuple for optional
244+
# The value is either a list (for repetition) or a tuple for optional
245+
raise RuntimeError('Refactor the line below') # this code is not called
245246
namemap[k] = lambda s,i=index,n=n: ([x[n] for x in s[i].value]) if isinstance(s[i].value, list) else s[i].value[n]
246247

247248
self.namemap = namemap
@@ -686,7 +687,7 @@ def unused_precedence(self):
686687
def _first(self, beta):
687688

688689
# We are computing First(x1,x2,x3,...,xn)
689-
result = []
690+
result = set()
690691
for x in beta:
691692
x_produces_empty = False
692693

@@ -695,8 +696,7 @@ def _first(self, beta):
695696
if f == '<empty>':
696697
x_produces_empty = True
697698
else:
698-
if f not in result:
699-
result.append(f)
699+
result.add(f)
700700

701701
if x_produces_empty:
702702
# We have to consider the next x in beta,
@@ -709,7 +709,7 @@ def _first(self, beta):
709709
# There was no 'break' from the loop,
710710
# so x_produces_empty was true for all x in beta,
711711
# so beta produces empty as well.
712-
result.append('<empty>')
712+
result.add('<empty>')
713713

714714
return result
715715

@@ -724,25 +724,24 @@ def compute_first(self):
724724

725725
# Terminals:
726726
for t in self.Terminals:
727-
self.First[t] = [t]
727+
self.First[t] = {t}
728728

729-
self.First['$end'] = ['$end']
729+
self.First['$end'] = {'$end'}
730730

731731
# Nonterminals:
732732

733733
# Initialize to the empty set:
734734
for n in self.Nonterminals:
735-
self.First[n] = []
735+
self.First[n] = set()
736736

737737
# Then propagate symbols until no change:
738738
while True:
739739
some_change = False
740740
for n in self.Nonterminals:
741741
for p in self.Prodnames[n]:
742-
for f in self._first(p.prod):
743-
if f not in self.First[n]:
744-
self.First[n].append(f)
745-
some_change = True
742+
length = len(self.First[n])
743+
self.First[n].update(self._first(p.prod))
744+
some_change = length != len(self.First[n])
746745
if not some_change:
747746
break
748747

@@ -766,12 +765,12 @@ def compute_follow(self, start=None):
766765

767766
# Add '$end' to the follow list of the start symbol
768767
for k in self.Nonterminals:
769-
self.Follow[k] = []
768+
self.Follow[k] = set()
770769

771770
if not start:
772771
start = self.Productions[1].name
773772

774-
self.Follow[start] = ['$end']
773+
self.Follow[start] = {'$end'}
775774

776775
while True:
777776
didadd = False
@@ -784,16 +783,15 @@ def compute_follow(self, start=None):
784783
hasempty = False
785784
for f in fst:
786785
if f != '<empty>' and f not in self.Follow[B]:
787-
self.Follow[B].append(f)
786+
self.Follow[B].add(f)
788787
didadd = True
789788
if f == '<empty>':
790789
hasempty = True
791790
if hasempty or i == (len(p.prod)-1):
792791
# Add elements of follow(a) to follow(b)
793-
for f in self.Follow[p.name]:
794-
if f not in self.Follow[B]:
795-
self.Follow[B].append(f)
796-
didadd = True
792+
length = len(self.Follow[B])
793+
self.Follow[B].update(self.Follow[p.name])
794+
didadd = len(self.Follow[B]) != length
797795
if not didadd:
798796
break
799797
return self.Follow

0 commit comments

Comments
 (0)