Switch to f-strings
This commit is contained in:
		| @@ -1,6 +1,6 @@ | |||||||
| SLY (Sly Lex-Yacc)                   Version 0.0 | SLY (Sly Lex-Yacc)                   Version 0.0 | ||||||
|  |  | ||||||
| Copyright (C) 2016 | Copyright (C) 2016-2017 | ||||||
| David M. Beazley (Dabeaz LLC) | David M. Beazley (Dabeaz LLC) | ||||||
| All rights reserved. | All rights reserved. | ||||||
|  |  | ||||||
| @@ -37,7 +37,7 @@ USE AT YOUR OWN RISK. | |||||||
| Requirements | Requirements | ||||||
| ============ | ============ | ||||||
|  |  | ||||||
| SLY requires the use of Python 3.5 or greater.  Older versions | SLY requires the use of Python 3.6 or greater.  Older versions | ||||||
| of Python are not supported. | of Python are not supported. | ||||||
|  |  | ||||||
| Introduction | Introduction | ||||||
|   | |||||||
| @@ -64,7 +64,7 @@ class CalcParser(Parser): | |||||||
|     def expr(self, p): |     def expr(self, p): | ||||||
|         return p.term |         return p.term | ||||||
|  |  | ||||||
|     @_('term TIMES factor1') |     @_('term TIMES factor') | ||||||
|     def term(self, p): |     def term(self, p): | ||||||
|         return p.term * p.factor |         return p.term * p.factor | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								sly/lex.py
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								sly/lex.py
									
									
									
									
									
								
							| @@ -66,7 +66,7 @@ class Token(object): | |||||||
|     ''' |     ''' | ||||||
|     __slots__ = ('type', 'value', 'lineno', 'index') |     __slots__ = ('type', 'value', 'lineno', 'index') | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|         return 'Token(type=%r, value=%r, lineno=%d, index=%d)' % (self.type, self.value, self.lineno, self.index) |         return f'Token(type={self.type!r}, value={self.value!r}, lineno={self.lineno}, index={self.index}' | ||||||
|  |  | ||||||
| class LexerMetaDict(OrderedDict): | class LexerMetaDict(OrderedDict): | ||||||
|     ''' |     ''' | ||||||
| @@ -78,7 +78,7 @@ class LexerMetaDict(OrderedDict): | |||||||
|                 if callable(value): |                 if callable(value): | ||||||
|                     value.pattern = self[key] |                     value.pattern = self[key] | ||||||
|                 else: |                 else: | ||||||
|                     raise AttributeError('Name %s redefined' % (key)) |                     raise AttributeError(f'Name {key} redefined') | ||||||
|              |              | ||||||
|         super().__setitem__(key, value) |         super().__setitem__(key, value) | ||||||
|  |  | ||||||
| @@ -92,7 +92,7 @@ class LexerMeta(type): | |||||||
|         def _(pattern, *extra): |         def _(pattern, *extra): | ||||||
|             patterns = [pattern, *extra] |             patterns = [pattern, *extra] | ||||||
|             def decorate(func): |             def decorate(func): | ||||||
|                 pattern = '|'.join('(%s)' % pat for pat in patterns ) |                 pattern = '|'.join(f'({pat})' for pat in patterns ) | ||||||
|                 if hasattr(func, 'pattern'): |                 if hasattr(func, 'pattern'): | ||||||
|                     func.pattern = pattern + '|' + func.pattern |                     func.pattern = pattern + '|' + func.pattern | ||||||
|                 else: |                 else: | ||||||
| @@ -140,7 +140,7 @@ class Lexer(metaclass=LexerMeta): | |||||||
|         Validate the rules to make sure they look sane. |         Validate the rules to make sure they look sane. | ||||||
|         ''' |         ''' | ||||||
|         if 'tokens' not in vars(cls): |         if 'tokens' not in vars(cls): | ||||||
|             raise LexerBuildError('%s class does not define a tokens attribute' % cls.__qualname__) |             raise LexerBuildError(f'{cls.__qualname__} class does not define a tokens attribute') | ||||||
|  |  | ||||||
|         cls._token_names = cls._token_names | set(cls.tokens) |         cls._token_names = cls._token_names | set(cls.tokens) | ||||||
|         cls._literals = cls._literals | set(cls.literals) |         cls._literals = cls._literals | set(cls.literals) | ||||||
| @@ -161,17 +161,17 @@ class Lexer(metaclass=LexerMeta): | |||||||
|                 cls._token_funcs[tokname] = value |                 cls._token_funcs[tokname] = value | ||||||
|  |  | ||||||
|             # Form the regular expression component  |             # Form the regular expression component  | ||||||
|             part = '(?P<%s>%s)' % (tokname, pattern) |             part = f'(?P<{tokname}>{pattern})' | ||||||
|  |  | ||||||
|             # Make sure the individual regex compiles properly |             # Make sure the individual regex compiles properly | ||||||
|             try: |             try: | ||||||
|                 cpat = re.compile(part, cls.reflags) |                 cpat = re.compile(part, cls.reflags) | ||||||
|             except Exception as e: |             except Exception as e: | ||||||
|                 raise PatternError('Invalid regex for token %s' % tokname) from e |                 raise PatternError(f'Invalid regex for token {tokname}') from e | ||||||
|  |  | ||||||
|             # Verify that the pattern doesn't match the empty string |             # Verify that the pattern doesn't match the empty string | ||||||
|             if cpat.match(''): |             if cpat.match(''): | ||||||
|                 raise PatternError('Regex for token %s matches empty input' % tokname) |                 raise PatternError(f'Regex for token {tokname} matches empty input') | ||||||
|  |  | ||||||
|             parts.append(part) |             parts.append(part) | ||||||
|  |  | ||||||
| @@ -187,7 +187,7 @@ class Lexer(metaclass=LexerMeta): | |||||||
|             raise LexerBuildError('ignore specifier must be a string') |             raise LexerBuildError('ignore specifier must be a string') | ||||||
|          |          | ||||||
|         if not all(isinstance(lit, str) for lit in cls.literals): |         if not all(isinstance(lit, str) for lit in cls.literals): | ||||||
|             raise LexerBuildError("literals must be specified as strings") |             raise LexerBuildError('literals must be specified as strings') | ||||||
|  |  | ||||||
|     def tokenize(self, text, lineno=1, index=0): |     def tokenize(self, text, lineno=1, index=0): | ||||||
|         # Local copies of frequently used values |         # Local copies of frequently used values | ||||||
| @@ -252,4 +252,4 @@ class Lexer(metaclass=LexerMeta): | |||||||
|  |  | ||||||
|     # Default implementations of the error handler. May be changed in subclasses |     # Default implementations of the error handler. May be changed in subclasses | ||||||
|     def error(self, value): |     def error(self, value): | ||||||
|         raise LexError("Illegal character %r at index %d" % (value[0], self.index), value) |         raise LexError(f'Illegal character {value[0]!r} at index {self.index}', value) | ||||||
|   | |||||||
							
								
								
									
										80
									
								
								sly/yacc.py
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								sly/yacc.py
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | |||||||
| # ----------------------------------------------------------------------------- | # ----------------------------------------------------------------------------- | ||||||
| # sly: yacc.py | # sly: yacc.py | ||||||
| # | # | ||||||
| # Copyright (C) 2016 | # Copyright (C) 2016-2017 | ||||||
| # David M. Beazley (Dabeaz LLC) | # David M. Beazley (Dabeaz LLC) | ||||||
| # All rights reserved. | # All rights reserved. | ||||||
| # | # | ||||||
| @@ -224,7 +224,7 @@ class Production(object): | |||||||
|         if self.prod: |         if self.prod: | ||||||
|             s = '%s -> %s' % (self.name, ' '.join(self.prod)) |             s = '%s -> %s' % (self.name, ' '.join(self.prod)) | ||||||
|         else: |         else: | ||||||
|             s = '%s -> <empty>' % self.name |             s = f'{self.name} -> <empty>' | ||||||
|  |  | ||||||
|         if self.prec[1]: |         if self.prec[1]: | ||||||
|             s += '  [precedence=%s, level=%d]' % self.prec |             s += '  [precedence=%s, level=%d]' % self.prec | ||||||
| @@ -232,7 +232,7 @@ class Production(object): | |||||||
|         return s |         return s | ||||||
|  |  | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|         return 'Production(' + str(self) + ')' |         return f'Production({self})' | ||||||
|  |  | ||||||
|     def __len__(self): |     def __len__(self): | ||||||
|         return len(self.prod) |         return len(self.prod) | ||||||
| @@ -300,11 +300,11 @@ class LRItem(object): | |||||||
|         if self.prod: |         if self.prod: | ||||||
|             s = '%s -> %s' % (self.name, ' '.join(self.prod)) |             s = '%s -> %s' % (self.name, ' '.join(self.prod)) | ||||||
|         else: |         else: | ||||||
|             s = '%s -> <empty>' % self.name |             s = f'{self.name} -> <empty>' | ||||||
|         return s |         return s | ||||||
|  |  | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|         return 'LRItem(' + str(self) + ')' |         return f'LRItem({self})' | ||||||
|  |  | ||||||
| # ----------------------------------------------------------------------------- | # ----------------------------------------------------------------------------- | ||||||
| # rightmost_terminal() | # rightmost_terminal() | ||||||
| @@ -384,7 +384,7 @@ class Grammar(object): | |||||||
|     def set_precedence(self, term, assoc, level): |     def set_precedence(self, term, assoc, level): | ||||||
|         assert self.Productions == [None], 'Must call set_precedence() before add_production()' |         assert self.Productions == [None], 'Must call set_precedence() before add_production()' | ||||||
|         if term in self.Precedence: |         if term in self.Precedence: | ||||||
|             raise GrammarError('Precedence already specified for terminal %r' % term) |             raise GrammarError(f'Precedence already specified for terminal {term!r}') | ||||||
|         if assoc not in ['left', 'right', 'nonassoc']: |         if assoc not in ['left', 'right', 'nonassoc']: | ||||||
|             raise GrammarError("Associativity must be one of 'left','right', or 'nonassoc'") |             raise GrammarError("Associativity must be one of 'left','right', or 'nonassoc'") | ||||||
|         self.Precedence[term] = (assoc, level) |         self.Precedence[term] = (assoc, level) | ||||||
| @@ -409,17 +409,16 @@ class Grammar(object): | |||||||
|     def add_production(self, prodname, syms, func=None, file='', line=0): |     def add_production(self, prodname, syms, func=None, file='', line=0): | ||||||
|  |  | ||||||
|         if prodname in self.Terminals: |         if prodname in self.Terminals: | ||||||
|             raise GrammarError('%s:%d: Illegal rule name %r. Already defined as a token' % (file, line, prodname)) |             raise GrammarError(f'{file}:{line}: Illegal rule name {prodname!r}. Already defined as a token') | ||||||
|         if prodname == 'error': |         if prodname == 'error': | ||||||
|             raise GrammarError('%s:%d: Illegal rule name %r. error is a reserved word' % (file, line, prodname)) |             raise GrammarError(f'{file}:{line}: Illegal rule name {prodname!r}. error is a reserved word') | ||||||
|  |  | ||||||
|         # Look for literal tokens |         # Look for literal tokens | ||||||
|         for n, s in enumerate(syms): |         for n, s in enumerate(syms): | ||||||
|             if s[0] in "'\"" and s[0] == s[-1]: |             if s[0] in "'\"" and s[0] == s[-1]: | ||||||
|                 c = s[1:-1] |                 c = s[1:-1] | ||||||
|                 if (len(c) != 1): |                 if (len(c) != 1): | ||||||
|                     raise GrammarError('%s:%d: Literal token %s in rule %r may only be a single character' % |                     raise GrammarError(f'{file}:{line}: Literal token {s} in rule {prodname!r} may only be a single character') | ||||||
|                                        (file, line, s, prodname)) |  | ||||||
|                 if c not in self.Terminals: |                 if c not in self.Terminals: | ||||||
|                     self.Terminals[c] = [] |                     self.Terminals[c] = [] | ||||||
|                 syms[n] = c |                 syms[n] = c | ||||||
| @@ -428,14 +427,13 @@ class Grammar(object): | |||||||
|         # Determine the precedence level |         # Determine the precedence level | ||||||
|         if '%prec' in syms: |         if '%prec' in syms: | ||||||
|             if syms[-1] == '%prec': |             if syms[-1] == '%prec': | ||||||
|                 raise GrammarError('%s:%d: Syntax error. Nothing follows %%prec' % (file, line)) |                 raise GrammarError(f'{file}:{line}: Syntax error. Nothing follows %%prec') | ||||||
|             if syms[-2] != '%prec': |             if syms[-2] != '%prec': | ||||||
|                 raise GrammarError('%s:%d: Syntax error. %%prec can only appear at the end of a grammar rule' % |                 raise GrammarError(f'{file}:{line}: Syntax error. %prec can only appear at the end of a grammar rule') | ||||||
|                                    (file, line)) |  | ||||||
|             precname = syms[-1] |             precname = syms[-1] | ||||||
|             prodprec = self.Precedence.get(precname) |             prodprec = self.Precedence.get(precname) | ||||||
|             if not prodprec: |             if not prodprec: | ||||||
|                 raise GrammarError('%s:%d: Nothing known about the precedence of %r' % (file, line, precname)) |                 raise GrammarError(f'{file}:{line}: Nothing known about the precedence of {precname!r}') | ||||||
|             else: |             else: | ||||||
|                 self.UsedPrecedence.add(precname) |                 self.UsedPrecedence.add(precname) | ||||||
|             del syms[-2:]     # Drop %prec from the rule |             del syms[-2:]     # Drop %prec from the rule | ||||||
| @@ -448,8 +446,8 @@ class Grammar(object): | |||||||
|         map = '%s -> %s' % (prodname, syms) |         map = '%s -> %s' % (prodname, syms) | ||||||
|         if map in self.Prodmap: |         if map in self.Prodmap: | ||||||
|             m = self.Prodmap[map] |             m = self.Prodmap[map] | ||||||
|             raise GrammarError('%s:%d: Duplicate rule %s. ' % (file, line, m) + |             raise GrammarError(f'{file}:{line}: Duplicate rule {m}. ' + | ||||||
|                                'Previous definition at %s:%d' % (m.file, m.line)) |                                f'Previous definition at {m.file}:{m.line}') | ||||||
|  |  | ||||||
|         # From this point on, everything is valid.  Create a new Production instance |         # From this point on, everything is valid.  Create a new Production instance | ||||||
|         pnumber  = len(self.Productions) |         pnumber  = len(self.Productions) | ||||||
| @@ -488,7 +486,7 @@ class Grammar(object): | |||||||
|             start = self.Productions[1].name |             start = self.Productions[1].name | ||||||
|  |  | ||||||
|         if start not in self.Nonterminals: |         if start not in self.Nonterminals: | ||||||
|             raise GrammarError('start symbol %s undefined' % start) |             raise GrammarError(f'start symbol {start} undefined') | ||||||
|         self.Productions[0] = Production(0, "S'", [start]) |         self.Productions[0] = Production(0, "S'", [start]) | ||||||
|         self.Nonterminals[start].append(0) |         self.Nonterminals[start].append(0) | ||||||
|         self.Start = start |         self.Start = start | ||||||
| @@ -820,13 +818,13 @@ class Grammar(object): | |||||||
|         out = [] |         out = [] | ||||||
|         out.append('Grammar:\n') |         out.append('Grammar:\n') | ||||||
|         for n, p in enumerate(self.Productions): |         for n, p in enumerate(self.Productions): | ||||||
|             out.append('Rule %-5d %s' % (n, p)) |             out.append(f'Rule {n:<5d} {p}') | ||||||
|          |          | ||||||
|         unused_terminals = self.unused_terminals() |         unused_terminals = self.unused_terminals() | ||||||
|         if unused_terminals: |         if unused_terminals: | ||||||
|             out.append('\nUnused terminals:\n') |             out.append('\nUnused terminals:\n') | ||||||
|             for term in unused_terminals: |             for term in unused_terminals: | ||||||
|                 out.append('    %s' % term) |                 out.append(f'    {term}') | ||||||
|  |  | ||||||
|         out.append('\nTerminals, with rules where they appear:\n') |         out.append('\nTerminals, with rules where they appear:\n') | ||||||
|         for term in sorted(self.Terminals): |         for term in sorted(self.Terminals): | ||||||
| @@ -1368,9 +1366,9 @@ class LRTable(object): | |||||||
|             st_actionp = {} |             st_actionp = {} | ||||||
|             st_goto    = {} |             st_goto    = {} | ||||||
|  |  | ||||||
|             descrip.append('\nstate %d\n' % st) |             descrip.append(f'\nstate {st}\n') | ||||||
|             for p in I: |             for p in I: | ||||||
|                 descrip.append('    (%d) %s' % (p.number, p)) |                 descrip.append(f'    ({p.number}) {p}') | ||||||
|  |  | ||||||
|             for p in I: |             for p in I: | ||||||
|                     if p.len == p.lr_index + 1: |                     if p.len == p.lr_index + 1: | ||||||
| @@ -1382,7 +1380,7 @@ class LRTable(object): | |||||||
|                             # We are at the end of a production.  Reduce! |                             # We are at the end of a production.  Reduce! | ||||||
|                             laheads = p.lookaheads[st] |                             laheads = p.lookaheads[st] | ||||||
|                             for a in laheads: |                             for a in laheads: | ||||||
|                                 actlist.append((a, p, 'reduce using rule %d (%s)' % (p.number, p))) |                                 actlist.append((a, p, f'reduce using rule {p.number} ({p})')) | ||||||
|                                 r = st_action.get(a) |                                 r = st_action.get(a) | ||||||
|                                 if r is not None: |                                 if r is not None: | ||||||
|                                     # Have a shift/reduce or reduce/reduce conflict |                                     # Have a shift/reduce or reduce/reduce conflict | ||||||
| @@ -1402,7 +1400,7 @@ class LRTable(object): | |||||||
|                                             st_action[a] = -p.number |                                             st_action[a] = -p.number | ||||||
|                                             st_actionp[a] = p |                                             st_actionp[a] = p | ||||||
|                                             if not slevel and not rlevel: |                                             if not slevel and not rlevel: | ||||||
|                                                 descrip.append('  ! shift/reduce conflict for %s resolved as reduce' % a) |                                                 descrip.append(f'  ! shift/reduce conflict for {a} resolved as reduce') | ||||||
|                                                 self.sr_conflicts.append((st, a, 'reduce')) |                                                 self.sr_conflicts.append((st, a, 'reduce')) | ||||||
|                                             Productions[p.number].reduced += 1 |                                             Productions[p.number].reduced += 1 | ||||||
|                                         elif (slevel == rlevel) and (rprec == 'nonassoc'): |                                         elif (slevel == rlevel) and (rprec == 'nonassoc'): | ||||||
| @@ -1410,7 +1408,7 @@ class LRTable(object): | |||||||
|                                         else: |                                         else: | ||||||
|                                             # Hmmm. Guess we'll keep the shift |                                             # Hmmm. Guess we'll keep the shift | ||||||
|                                             if not rlevel: |                                             if not rlevel: | ||||||
|                                                 descrip.append('  ! shift/reduce conflict for %s resolved as shift' % a) |                                                 descrip.append(f'  ! shift/reduce conflict for {a} resolved as shift') | ||||||
|                                                 self.sr_conflicts.append((st, a, 'shift')) |                                                 self.sr_conflicts.append((st, a, 'shift')) | ||||||
|                                     elif r < 0: |                                     elif r < 0: | ||||||
|                                         # Reduce/reduce conflict.   In this case, we favor the rule |                                         # Reduce/reduce conflict.   In this case, we favor the rule | ||||||
| @@ -1429,7 +1427,7 @@ class LRTable(object): | |||||||
|                                         descrip.append('  ! reduce/reduce conflict for %s resolved using rule %d (%s)' %  |                                         descrip.append('  ! reduce/reduce conflict for %s resolved using rule %d (%s)' %  | ||||||
|                                                        (a, st_actionp[a].number, st_actionp[a])) |                                                        (a, st_actionp[a].number, st_actionp[a])) | ||||||
|                                     else: |                                     else: | ||||||
|                                         raise LALRError('Unknown conflict in state %d' % st) |                                         raise LALRError(f'Unknown conflict in state {st}') | ||||||
|                                 else: |                                 else: | ||||||
|                                     st_action[a] = -p.number |                                     st_action[a] = -p.number | ||||||
|                                     st_actionp[a] = p |                                     st_actionp[a] = p | ||||||
| @@ -1442,13 +1440,13 @@ class LRTable(object): | |||||||
|                             j = self.lr0_cidhash.get(id(g), -1) |                             j = self.lr0_cidhash.get(id(g), -1) | ||||||
|                             if j >= 0: |                             if j >= 0: | ||||||
|                                 # We are in a shift state |                                 # We are in a shift state | ||||||
|                                 actlist.append((a, p, 'shift and go to state %d' % j)) |                                 actlist.append((a, p, f'shift and go to state {j}')) | ||||||
|                                 r = st_action.get(a) |                                 r = st_action.get(a) | ||||||
|                                 if r is not None: |                                 if r is not None: | ||||||
|                                     # Whoa have a shift/reduce or shift/shift conflict |                                     # Whoa have a shift/reduce or shift/shift conflict | ||||||
|                                     if r > 0: |                                     if r > 0: | ||||||
|                                         if r != j: |                                         if r != j: | ||||||
|                                             raise LALRError('Shift/shift conflict in state %d' % st) |                                             raise LALRError(f'Shift/shift conflict in state {st}') | ||||||
|                                     elif r < 0: |                                     elif r < 0: | ||||||
|                                         # Do a precedence check. |                                         # Do a precedence check. | ||||||
|                                         #   -  if precedence of reduce rule is higher, we reduce. |                                         #   -  if precedence of reduce rule is higher, we reduce. | ||||||
| @@ -1462,18 +1460,18 @@ class LRTable(object): | |||||||
|                                             st_action[a] = j |                                             st_action[a] = j | ||||||
|                                             st_actionp[a] = p |                                             st_actionp[a] = p | ||||||
|                                             if not rlevel: |                                             if not rlevel: | ||||||
|                                                 descrip.append('  ! shift/reduce conflict for %s resolved as shift' % a) |                                                 descrip.append(f'  ! shift/reduce conflict for {a} resolved as shift') | ||||||
|                                                 self.sr_conflicts.append((st, a, 'shift')) |                                                 self.sr_conflicts.append((st, a, 'shift')) | ||||||
|                                         elif (slevel == rlevel) and (rprec == 'nonassoc'): |                                         elif (slevel == rlevel) and (rprec == 'nonassoc'): | ||||||
|                                             st_action[a] = None |                                             st_action[a] = None | ||||||
|                                         else: |                                         else: | ||||||
|                                             # Hmmm. Guess we'll keep the reduce |                                             # Hmmm. Guess we'll keep the reduce | ||||||
|                                             if not slevel and not rlevel: |                                             if not slevel and not rlevel: | ||||||
|                                                 descrip.append('  ! shift/reduce conflict for %s resolved as reduce' % a) |                                                 descrip.append(f'  ! shift/reduce conflict for {a} resolved as reduce') | ||||||
|                                                 self.sr_conflicts.append((st, a, 'reduce')) |                                                 self.sr_conflicts.append((st, a, 'reduce')) | ||||||
|  |  | ||||||
|                                     else: |                                     else: | ||||||
|                                         raise LALRError('Unknown conflict in state %d' % st) |                                         raise LALRError(f'Unknown conflict in state {st}') | ||||||
|                                 else: |                                 else: | ||||||
|                                     st_action[a] = j |                                     st_action[a] = j | ||||||
|                                     st_actionp[a] = p |                                     st_actionp[a] = p | ||||||
| @@ -1483,7 +1481,7 @@ class LRTable(object): | |||||||
|             for a, p, m in actlist: |             for a, p, m in actlist: | ||||||
|                 if a in st_action: |                 if a in st_action: | ||||||
|                     if p is st_actionp[a]: |                     if p is st_actionp[a]: | ||||||
|                         descrip.append('    %-15s %s' % (a, m)) |                         descrip.append(f'    {a:<15s} {m}') | ||||||
|                         _actprint[(a, m)] = 1 |                         _actprint[(a, m)] = 1 | ||||||
|             descrip.append('') |             descrip.append('') | ||||||
|  |  | ||||||
| @@ -1498,7 +1496,7 @@ class LRTable(object): | |||||||
|                 j = self.lr0_cidhash.get(id(g), -1) |                 j = self.lr0_cidhash.get(id(g), -1) | ||||||
|                 if j >= 0: |                 if j >= 0: | ||||||
|                     st_goto[n] = j |                     st_goto[n] = j | ||||||
|                     descrip.append('    %-30s shift and go to state %d' % (n, j)) |                     descrip.append(f'    {n:<30s} shift and go to state {j}') | ||||||
|  |  | ||||||
|             action[st] = st_action |             action[st] = st_action | ||||||
|             actionp[st] = st_actionp |             actionp[st] = st_actionp | ||||||
| @@ -1518,20 +1516,20 @@ class LRTable(object): | |||||||
|             out.append('\nConflicts:\n') |             out.append('\nConflicts:\n') | ||||||
|  |  | ||||||
|             for state, tok, resolution in self.sr_conflicts: |             for state, tok, resolution in self.sr_conflicts: | ||||||
|                 out.append('shift/reduce conflict for %s in state %d resolved as %s' % (tok, state, resolution)) |                 out.append(f'shift/reduce conflict for {tok} in state {state} resolved as {resolution}') | ||||||
|  |  | ||||||
|             already_reported = set() |             already_reported = set() | ||||||
|             for state, rule, rejected in self.rr_conflicts: |             for state, rule, rejected in self.rr_conflicts: | ||||||
|                 if (state, id(rule), id(rejected)) in already_reported: |                 if (state, id(rule), id(rejected)) in already_reported: | ||||||
|                     continue |                     continue | ||||||
|                 out.append('reduce/reduce conflict in state %d resolved using rule (%s)' % (state, rule)) |                 out.append(f'reduce/reduce conflict in state {state} resolved using rule {rule}') | ||||||
|                 out.append('rejected rule (%s) in state %d' % (rejected, state)) |                 out.append(f'rejected rule ({rejected}) in state {state}') | ||||||
|                 already_reported.add((state, id(rule), id(rejected))) |                 already_reported.add((state, id(rule), id(rejected))) | ||||||
|  |  | ||||||
|             warned_never = set() |             warned_never = set() | ||||||
|             for state, rule, rejected in self.rr_conflicts: |             for state, rule, rejected in self.rr_conflicts: | ||||||
|                 if not rejected.reduced and (rejected not in warned_never): |                 if not rejected.reduced and (rejected not in warned_never): | ||||||
|                     out.append('Rule (%s) is never reduced' % rejected) |                     out.append(f'Rule ({rejected}) is never reduced') | ||||||
|                     warned_never.add(rejected) |                     warned_never.add(rejected) | ||||||
|  |  | ||||||
|         return '\n'.join(out) |         return '\n'.join(out) | ||||||
| @@ -1618,11 +1616,11 @@ class Parser(metaclass=ParserMeta): | |||||||
|  |  | ||||||
|         for level, p in enumerate(cls.precedence, start=1): |         for level, p in enumerate(cls.precedence, start=1): | ||||||
|             if not isinstance(p, (list, tuple)): |             if not isinstance(p, (list, tuple)): | ||||||
|                 cls.log.error('Bad precedence table entry %r. Must be a list or tuple', p) |                 cls.log.error(f'Bad precedence table entry {p!r}. Must be a list or tuple') | ||||||
|                 return False |                 return False | ||||||
|  |  | ||||||
|             if len(p) < 2: |             if len(p) < 2: | ||||||
|                 cls.log.error('Malformed precedence entry %s. Must be (assoc, term, ..., term)', p) |                 cls.log.error(f'Malformed precedence entry {p!r}. Must be (assoc, term, ..., term)') | ||||||
|                 return False |                 return False | ||||||
|  |  | ||||||
|             if not all(isinstance(term, str) for term in p): |             if not all(isinstance(term, str) for term in p): | ||||||
| @@ -1688,7 +1686,7 @@ class Parser(metaclass=ParserMeta): | |||||||
|  |  | ||||||
|         undefined_symbols = grammar.undefined_symbols() |         undefined_symbols = grammar.undefined_symbols() | ||||||
|         for sym, prod in undefined_symbols: |         for sym, prod in undefined_symbols: | ||||||
|             cls.log.error('%s:%d: Symbol %r used, but not defined as a token or a rule', prod.file, prod.line, sym) |             cls.log.error(f'%s:%d: Symbol %r used, but not defined as a token or a rule', prod.file, prod.line, sym) | ||||||
|             fail = True |             fail = True | ||||||
|  |  | ||||||
|         unused_terminals = grammar.unused_terminals() |         unused_terminals = grammar.unused_terminals() | ||||||
| @@ -1802,9 +1800,9 @@ class Parser(metaclass=ParserMeta): | |||||||
|         if token: |         if token: | ||||||
|             lineno = getattr(token, 'lineno', 0) |             lineno = getattr(token, 'lineno', 0) | ||||||
|             if lineno: |             if lineno: | ||||||
|                 sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, token.type)) |                 sys.stderr.write(f'yacc: Syntax error at line {lineno}, token={token.type}\n') | ||||||
|             else: |             else: | ||||||
|                 sys.stderr.write('yacc: Syntax error, token=%s' % token.type) |                 sys.stderr.write(f'yacc: Syntax error, token={token.type}') | ||||||
|         else: |         else: | ||||||
|             sys.stderr.write('yacc: Parse error in input. EOF\n') |             sys.stderr.write('yacc: Parse error in input. EOF\n') | ||||||
|   |   | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 David Beazley
					David Beazley