Various usability improvements

This commit is contained in:
David Beazley 2018-11-18 06:42:22 -06:00
parent 0ac3c1a0a3
commit 503fae9e18
2 changed files with 31 additions and 9 deletions

21
CHANGES
View File

@ -1,5 +1,26 @@
Version 0.4 Version 0.4
----------- -----------
11/18/2018 Various usability fixes observed from last compilers course.
- Errors encountered during grammar construction are now
reported as part of the raised GrammarError exception
instead of via logging. This places them in the same
visual position as normal Python errors (at the end
of the traceback)
- Repeated warning messages about unused tokens have
been consolidated in a single warning message to make
the output less verbose.
- Grammar attributes (e.g., p.TOKEN) used during parsing
are now read-only.
- The error about "infinite recursion" is only checked
if there are no undefined grammar symbols. Sometimes
you'd get this message and be confused when the only
mistake was a bad token name or similar.
9/8/2018 Fixed Issue #14. YaccProduction index property causes 9/8/2018 Fixed Issue #14. YaccProduction index property causes
AttributeError if index is 0 AttributeError if index is 0

View File

@ -152,10 +152,10 @@ class YaccProduction:
raise AttributeError(f'No symbol {name}. Must be one of {nameset}.') raise AttributeError(f'No symbol {name}. Must be one of {nameset}.')
def __setattr__(self, name, value): def __setattr__(self, name, value):
if name[0:1] == '_' or name not in self._namemap: if name[:1] == '_':
super().__setattr__(name, value) super().__setattr__(name, value)
else: else:
self._slice[self._namemap[name]].value = value raise AttributeError(f"Can't reassign the value of attribute {name!r}")
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# === Grammar Representation === # === Grammar Representation ===
@ -1719,9 +1719,10 @@ class Parser(metaclass=ParserMeta):
for u in unreachable: for u in unreachable:
cls.log.warning('Symbol %r is unreachable', u) cls.log.warning('Symbol %r is unreachable', u)
infinite = grammar.infinite_cycles() if len(undefined_symbols) == 0:
for inf in infinite: infinite = grammar.infinite_cycles()
errors += 'Infinite recursion detected for symbol %r\n' % inf for inf in infinite:
errors += 'Infinite recursion detected for symbol %r\n' % inf
unused_prec = grammar.unused_precedence() unused_prec = grammar.unused_precedence()
for term, assoc in unused_prec: for term, assoc in unused_prec:
@ -1806,11 +1807,11 @@ 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(f'yacc: Syntax error at line {lineno}, token={token.type}\n') sys.stderr.write(f'sly: Syntax error at line {lineno}, token={token.type}\n')
else: else:
sys.stderr.write(f'yacc: Syntax error, token={token.type}') sys.stderr.write(f'sly: Syntax error, token={token.type}')
else: else:
sys.stderr.write('yacc: Parse error in input. EOF\n') sys.stderr.write('sly: Parse error in input. EOF\n')
def errok(self): def errok(self):
''' '''
@ -1995,4 +1996,4 @@ class Parser(metaclass=ParserMeta):
continue continue
# Call an error function here # Call an error function here
raise RuntimeError('yacc: internal parser error!!!\n') raise RuntimeError('sly: internal parser error!!!\n')