summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Beazley <dave@dabeaz.com>2016-08-30 15:48:18 -0500
committerGitHub <noreply@github.com>2016-08-30 15:48:18 -0500
commit481413e07356a2f9b7cabd2e6fc34b43c1e791c7 (patch)
tree3f1ea52f0a4beac2b189ca6eb6c6f712fe460a43
parentb427e007362be3f749da875e570b7a5767e88d5a (diff)
parent5ab820632b54a330ceed4d0284e43221348a5b10 (diff)
downloadply-481413e07356a2f9b7cabd2e6fc34b43c1e791c7.tar.gz
Merge pull request #87 from bionikspoon/patch-1
Allow decorating production functions.
-rw-r--r--doc/ply.html36
-rw-r--r--ply/yacc.py2
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__))