The synopsis framework provides a function process
that lets you declare and expose processors as commands so they can be
used per command line:
#
# Copyright (C) 2006 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#
from Synopsis.process import process
from Synopsis.Processor import Processor, Parameter, Composite
from Synopsis.Parsers import Cxx
from Synopsis.Parsers import Python
from Synopsis.Processors import Linker
from Synopsis.Processors import Comments
from Synopsis.Formatters import HTML
from Synopsis.Formatters import Dot
from Synopsis.Formatters import Dump
class Joker(Processor):
parameter = Parameter(':-)', 'a friendly parameter')
def process(self, ir, **keywords):
# override default parameter values
self.set_parameters(keywords)
# merge in IR from 'input' parameter if given
self.ir = self.merge_input(ir)
print 'this processor is harmless...', self.parameter
# write to output (if given) and return IR
return self.output_and_return_ir()
cxx = Cxx.Parser(base_path='../src')
ss = Comments.Translator(filter = Comments.SSFilter(),
processor = Comments.Grouper())
ssd_prev = Comments.Translator(filter = Comments.SSDFilter(),
processor = Composite(Comments.Previous(),
Comments.Grouper()))
javadoc = Comments.Translator(markup='javadoc',
filter = Comments.JavaFilter(),
processor = Comments.Grouper())
rst = Comments.Translator(markup='rst',
filter = Comments.SSDFilter(),
processor = Comments.Grouper())
process(cxx_ss = Composite(cxx, ss),
cxx_ssd_prev = Composite(cxx, ssd_prev),
cxx_javadoc = Composite(cxx, javadoc),
cxx_rst = Composite(cxx, rst),
link = Linker(),
html = HTML.Formatter(),
dot = Dot.Formatter(),
joker = Joker(parameter = '(-;'))
With such a script synopsis.py it is possible
to call
python synopsis.py cxx_ssd --output=Bezier.syn Bezier.h
to do the same as in Chapter 2, Using the synopsis tool, but with much more flexibility. Let's have a closer look at how this script works:
As every conventional python script, the first thing to do is
to pull in all the definitions that are used later on, in our case
the definition of the process function, together
with a number of predefined processors.
As outlined in the section called “Composing A Pipeline”, processors can be composed into pipelines, which are themselfs new (composite) processors. Synopsis provides a Composite type for convenient pipeline construction. Its constructor takes a list of processors that the process method will iterate over.
New processors can be defined by deriving from Processor
or any of its subclasses. As outlined in the section called “The Processor class”,
it has only to respect the semantics of the process
method.
With all these new processrs defined, they need to be made accessible
to be called per command line. That is done with the process
function. It sets up a dictionary of named processors, with which the script
can be invoked as
python synopsis.py joker
which will invoke the joker's process method with
any argument that was provided passed as a named value (keyword).