Franck Pommereau

doc update

This diff is collapsed. Click to expand it.
"""A module to save and load objects in PNML.
Petri nets objects are saved in PNML, other Python objects are saved
in a readable format when possible and pickled as a last solution.
This should result in a complete PNML serialization of any object.
@todo: revise documentation
"""This module allows to save and load objects in PNML. The standard
is correctly handled for low-level nets, ie, nets with only `True`
guards and black tokens. However, module `snakes.pnml` was actually
created long before the PNML standard was extended to handle
high-level nets (in particular coloured variants) and so the standard
is not respected in this case. Consequently, in the following, we
abuse the term PNML for the XML produced and read by SNAKES.
@warning: this module will be replaced in a future version of SNAKES,
so its documentation will be kept minimal.
"""
import xml.dom.minidom
......@@ -160,6 +163,7 @@ class _set (object) :
"""
return len(self._data)
# apidoc skip
class Tree (object) :
"""Abstraction of a PNML tree
......@@ -911,7 +915,9 @@ class Tree (object) :
raise SnakesError("unsupported PNML tag '%s'" % self.name)
def dumps (obj) :
"""Dump an object to a PNML string
"""Dump an object to a PNML string, any Python object may be
serialised this way (resorting to pickling when the object does
not support serialisation to PNML).
>>> print(dumps(42))
<?xml version="1.0" encoding="utf-8"?>
......
......@@ -24,9 +24,9 @@ at SNAKES source code. However, let's note a few points:
* most Epydoc fields are supported: `@param`, `@type`, `@note`, ...
* directive `# apidoc skip` allow not to include the next object in
the generated documentation
* directive `apidoc stop` allow to stop the processing of current
* directive `# apidoc stop` allow to stop the processing of current
object (module or class)
* directive `apidoc include 'filename' lang='language'` allow to
* directive `# apidoc include 'filename' lang='language'` allow to
include the content of a file as a block of source code in the
specified language
* when statement `pass` is found in a doctest, the rest of the
......@@ -38,11 +38,12 @@ at SNAKES source code. However, let's note a few points:
options nor customisation, however, it is quite flexible already
by the way it handles documentation
@note: we do not build doc for the sub-modules of `snakes.lang`
because some of them are programmed for distinct versions of
Python with incompatible syntaxes. So `apidoc` will fail for sure
on one or another of these modules. Fortunately, most of the
documentation for `snakes.lang` is in the package itself.
@note: in the example above we do not build doc for the sub-modules of
`snakes.lang` because some of them are programmed for distinct
versions of Python with incompatible syntaxes. So `apidoc` will
fail for sure on one or another of these modules. Fortunately,
most of the documentation for `snakes.lang` is in the package
itself.
@note: for better rendering, `apidoc` uses [Python
Markdown](http://pythonhosted.org/Markdown), however, it will
handle situations when it is not installed
......@@ -578,10 +579,11 @@ class DocExtract (object) :
for exc, reason in sorted(info["raise"].items()) :
self.writelist("`%s`: %s" % (exc, reason))
self.newline()
def write_include (self, name, lang="python") :
def write_include (self, name, lang="python", first=1, last=-1) :
"""Write a block of source code included through directive
`apidoc include ...`
"""
first, last = int(first), int(last)
if os.path.exists(name) :
path = name
else :
......@@ -591,8 +593,9 @@ class DocExtract (object) :
with open(path) as infile :
self.newline()
self.writeline(" :::%s" % lang)
for line in infile :
self.writeline(" " + line.rstrip())
for i, line in enumerate(infile) :
if first <= i+1 and (last == -1 or i+1 <= last) :
self.writeline(" " + line.rstrip())
self.newline()
def main (finder, args, source=None) :
......
"""This module features a parser for CTL* formula. Function `build`
parses the formula (see _concrete syntax_ below) and expands
sub-formulas; then it returns an abstract syntax tree (see _abstract
syntax_) below.
>>> from snakes.utils.ctlstar.build import *
>>> spec = '''
... atom even (x : int) :
... return x % 2 == 0
... atom odd (x : int) :
... return x % 2 == 1
... prop evenplace (p : place) :
... exists tok in p (even(x=tok))
... prop oddplace (p : place) :
... exists tok in p (odd(x=tok))
... A (G (evenplace(p=@'some_place') => F oddplace(p=@'another_place')))
... '''
>>> tree = build(spec)
>>> print ast.dump(tree)
CtlUnary(op=All(), child=CtlUnary(op=Globally(), child=CtlBinary(op=Imply(), ...
In the example above, `atom` allows to define parameterised atomic
propositions and `prop` allows to define sub-formulas. In the returned
syntax tree, all these objects are inlined and fully instantiated.
## Concrete syntax ##
"""
@todo: revise (actually make) documentation
# apidoc include "../../lang/ctlstar/ctlstar.pgen" first=6 last=35 lang="text"
"""
## Abstract syntax ##
"""
# apidoc include "../../lang/ctlstar/ctlstar.asdl" first=3 last=59 lang="text"
pass
......
from snakes.lang.ctlstar.parser import parse
from snakes.lang.ctlstar import asdl as ast
from snakes.lang import getvars, bind
from snakes.lang import bind
import _ast
class SpecError (Exception) :
......@@ -53,7 +53,7 @@ class Builder (object) :
node.atomic = (isinstance(node.op, ast.Not)
and node.child.atomic)
else :
assert False, "how did we get there?"
raise SpecError(node, "not a CTL* formula")
return node
def _build_place (self, param, ctx) :
if isinstance(param, ast.Parameter) :
......@@ -144,9 +144,7 @@ class Builder (object) :
del new.params[:]
return new
def build (spec, main=None) :
b = Builder(spec)
if main is None :
return b.build(spec.main)
else :
return b.build(main)
def build (spec) :
if isinstance(spec, str) :
spec = parse(spec)
return Builder(spec).build(spec.main)
......