Commenting spree no.2
This commit is contained in:
@@ -3,6 +3,73 @@ from textwrap import fill
|
||||
from filters import *
|
||||
|
||||
class ParseTree(object):
|
||||
"""
|
||||
The ParseTree class produces a semantic tree of C++ definitions given
|
||||
the output of the CppHeaderParser (from opencv/modules/python/src2/hdr_parser.py)
|
||||
|
||||
The full hierarchy is as follows:
|
||||
|
||||
Namespaces
|
||||
|
|
||||
|- name
|
||||
|- Classes
|
||||
|
|
||||
|- name
|
||||
|- Methods
|
||||
|- Constants
|
||||
|- Methods
|
||||
|
|
||||
|- name
|
||||
|- static (T/F)
|
||||
|- return type
|
||||
|- required Arguments
|
||||
|
|
||||
|- name
|
||||
|- const (T/F)
|
||||
|- reference ('&'/'*')
|
||||
|- type
|
||||
|- input
|
||||
|- output (pass return by reference)
|
||||
|- default value
|
||||
|- optional Arguments
|
||||
|- Constants
|
||||
|
|
||||
|- name
|
||||
|- const (T/F)
|
||||
|- reference ('&'/'*')
|
||||
|- type
|
||||
|- value
|
||||
|
||||
The semantic tree contains substantial information for easily introspecting
|
||||
information about objects. How many methods does the 'core' namespace have?
|
||||
Does the 'randn' method have any return by reference (output) arguments?
|
||||
How many required and optional arguments does the 'add' method have? Is the
|
||||
variable passed by reference or raw pointer?
|
||||
|
||||
Individual definitions from the parse tree (Classes, Functions, Constants)
|
||||
are passed to the Jinja2 template engine where they are manipulated to
|
||||
produce Matlab mex sources.
|
||||
|
||||
A common call tree for constructing and using a ParseTree object is:
|
||||
|
||||
# parse a set of definitions into a dictionary of namespaces
|
||||
parser = CppHeaderParser()
|
||||
ns['core'] = parser.parse('path/to/opencv/core.hpp')
|
||||
|
||||
# refactor into a semantic tree
|
||||
parse_tree = ParseTree()
|
||||
parse_tree.build(ns)
|
||||
|
||||
# iterate over the tree
|
||||
for namespace in parse_tree.namespaces:
|
||||
for clss in namespace.classes:
|
||||
# do stuff
|
||||
for method in namespace.methods:
|
||||
# do stuff
|
||||
|
||||
Calling 'print' on a ParseTree object will reconstruct the definitions
|
||||
to produce an output resembling the original C++ code.
|
||||
"""
|
||||
def __init__(self, namespaces=None):
|
||||
self.namespaces = namespaces if namespaces else []
|
||||
|
||||
@@ -48,6 +115,15 @@ class ParseTree(object):
|
||||
|
||||
|
||||
class Translator(object):
|
||||
"""
|
||||
The Translator class does the heavy lifting of translating the nested
|
||||
list representation of the hdr_parser into individual definitions that
|
||||
are inserted into the ParseTree.
|
||||
Translator consists of a top-level method: translate()
|
||||
along with a number of helper methods: translateClass(), translateMethod(),
|
||||
translateArgument(), translateConstant(), translateName(), and
|
||||
translateClassName()
|
||||
"""
|
||||
def translate(self, defn):
|
||||
# --- class ---
|
||||
# classes have 'class' prefixed on their name
|
||||
@@ -116,6 +192,14 @@ class Translator(object):
|
||||
|
||||
|
||||
class Namespace(object):
|
||||
"""
|
||||
Namespace
|
||||
|
|
||||
|- name
|
||||
|- Constants
|
||||
|- Methods
|
||||
|- Constants
|
||||
"""
|
||||
def __init__(self, name='', constants=None, classes=None, methods=None):
|
||||
self.name = name
|
||||
self.constants = constants if constants else []
|
||||
@@ -129,6 +213,13 @@ class Namespace(object):
|
||||
(join((o.__str__() for o in self.classes), '\n\n') if self.classes else '')+'\n};'
|
||||
|
||||
class Class(object):
|
||||
"""
|
||||
Class
|
||||
|
|
||||
|- name
|
||||
|- Methods
|
||||
|- Constants
|
||||
"""
|
||||
def __init__(self, name='', namespace='', constants=None, methods=None):
|
||||
self.name = name
|
||||
self.namespace = namespace
|
||||
@@ -141,6 +232,21 @@ class Class(object):
|
||||
(join((f.__str__() for f in self.methods), '\n\t') if self.methods else '')+'\n};'
|
||||
|
||||
class Method(object):
|
||||
"""
|
||||
Method
|
||||
int VideoWriter::read( cv::Mat& frame, const cv::Mat& mask=cv::Mat() );
|
||||
--- ----- ---- -------- ----------------
|
||||
rtp class name required optional
|
||||
|
||||
name the method name
|
||||
clss the class the method belongs to ('' if free)
|
||||
static static?
|
||||
namespace the namespace the method belongs to ('' if free)
|
||||
rtp the return type
|
||||
const const?
|
||||
req list of required arguments
|
||||
opt list of optional arguments
|
||||
"""
|
||||
def __init__(self, name='', clss='', static=False, namespace='', rtp='', const=False, req=None, opt=None):
|
||||
self.name = name
|
||||
self.clss = clss
|
||||
@@ -158,6 +264,20 @@ class Method(object):
|
||||
')'+(' const' if self.const else '')+';'
|
||||
|
||||
class Argument(object):
|
||||
"""
|
||||
Argument
|
||||
const cv::Mat& mask=cv::Mat()
|
||||
----- ---- --- ---- -------
|
||||
const tp ref name default
|
||||
|
||||
name the argument name
|
||||
tp the argument type
|
||||
const const?
|
||||
I is the argument treated as an input?
|
||||
O is the argument treated as an output (return by reference)
|
||||
ref is the argument passed by reference? ('*'/'&')
|
||||
default the default value of the argument ('' if required)
|
||||
"""
|
||||
def __init__(self, name='', tp='', const=False, I=True, O=False, ref='', default=''):
|
||||
self.name = name
|
||||
self.tp = tp
|
||||
@@ -172,6 +292,19 @@ class Argument(object):
|
||||
' '+self.name+('='+self.default if self.default else '')
|
||||
|
||||
class Constant(object):
|
||||
"""
|
||||
Constant
|
||||
DFT_COMPLEX_OUTPUT = 12;
|
||||
---- -------
|
||||
name default
|
||||
|
||||
name the name of the constant
|
||||
clss the class that the constant belongs to ('' if free)
|
||||
tp the type of the constant ('' if int)
|
||||
const const?
|
||||
ref is the constant a reference? ('*'/'&')
|
||||
default default value, required for constants
|
||||
"""
|
||||
def __init__(self, name='', clss='', tp='', const=False, ref='', default=''):
|
||||
self.name = name
|
||||
self.clss = clss
|
||||
@@ -185,6 +318,10 @@ class Constant(object):
|
||||
' '+self.name+('='+self.default if self.default else '')+';'
|
||||
|
||||
def constants(tree):
|
||||
"""
|
||||
recursive generator to strip all Constant objects from the ParseTree
|
||||
and place them into a flat dictionary of { name, value (default) }
|
||||
"""
|
||||
if isinstance(tree, dict) and 'constants' in tree and isinstance(tree['constants'], list):
|
||||
for node in tree['constants']:
|
||||
yield (node['name'], node['default'])
|
||||
@@ -198,6 +335,10 @@ def constants(tree):
|
||||
yield gen
|
||||
|
||||
def todict(obj, classkey=None):
|
||||
"""
|
||||
Convert the ParseTree to a dictionary, stripping all objects of their
|
||||
methods and converting class names to strings
|
||||
"""
|
||||
if isinstance(obj, dict):
|
||||
for k in obj.keys():
|
||||
obj[k] = todict(obj[k], classkey)
|
||||
|
Reference in New Issue
Block a user