diff options
author | David Beazley <dave@dabeaz.com> | 2016-08-30 15:48:18 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-30 15:48:18 -0500 |
commit | 481413e07356a2f9b7cabd2e6fc34b43c1e791c7 (patch) | |
tree | 3f1ea52f0a4beac2b189ca6eb6c6f712fe460a43 | |
parent | b427e007362be3f749da875e570b7a5767e88d5a (diff) | |
parent | 5ab820632b54a330ceed4d0284e43221348a5b10 (diff) | |
download | ply-481413e07356a2f9b7cabd2e6fc34b43c1e791c7.tar.gz |
Merge pull request #87 from bionikspoon/patch-1
Allow decorating production functions.
-rw-r--r-- | doc/ply.html | 36 | ||||
-rw-r--r-- | ply/yacc.py | 2 |
2 files changed, 37 insertions, 1 deletions
diff --git a/doc/ply.html b/doc/ply.html index 808ed1d..dacde5c 100644 --- a/doc/ply.html +++ b/doc/ply.html @@ -3167,6 +3167,42 @@ in the same source file. </li> </p> +<p> +<li>Decorators of production rules have to update the wrapped function's line number. <tt>wrapper.co_firstlineno = func.__code__.co_firstlineno</tt>: + +<blockquote> +<pre> +from functools import wraps +from nodes import Collection + + +def strict(*types): + def decorate(func): + @wraps(func) + def wrapper(p): + func(p) + if not isinstance(p[0], types): + raise TypeError + + wrapper.co_firstlineno = func.__code__.co_firstlineno + return wrapper + + return decorate + +@strict(Collection) +def p_collection(p): + """ + collection : sequence + | map + """ + p[0] = p[1] +</pre> +</blockquote> + +</li> +</p> + + </ul> </p> diff --git a/ply/yacc.py b/ply/yacc.py index 41f4795..c1bea17 100644 --- a/ply/yacc.py +++ b/ply/yacc.py @@ -3119,7 +3119,7 @@ class ParserReflect(object): if not name.startswith('p_') or name == 'p_error': continue if isinstance(item, (types.FunctionType, types.MethodType)): - line = item.__code__.co_firstlineno + line = getattr(item, 'co_firstlineno', item.__code__.co_firstlineno) module = inspect.getmodule(item) p_functions.append((line, module, name, item.__doc__)) |