-=[ Mr. Bumblebee ]=-
_Indonesia_
ó
Ì\,Tc @ s} d d l Z d d l Z d d l Z d d l m Z d „ Z e e e e e e d d „ Z e e e e e e d d „ Z d S( iÿÿÿÿN( t _c # s | s
d St j t j ‰ i ‰ d ‰ d ‰ ‡ ‡ ‡ f d † } d „ | Dƒ ‰ ‡ f d † ‰ ‡ f d † ‰ ‡ f d † ‰ ‡ ‡ ‡ ‡ f d † } ˆ ƒ } xr| d
k rx | t j k rÌ ˆ ƒ } q± W| d k r d ˆ ˆ g f f Vˆ ‰ ˆ d
7‰ ˆ ƒ } q¢ | d k r}ˆ ˆ ƒ t j ƒ \ } } t | ƒ } xÑt d | ƒ D]* } d ˆ ˆ g f f Vˆ ‰ ˆ d
7‰ qLWq¢ | d k r4| d k r¡ˆ ƒ } n | | ƒ \ } } | g } x2 | d k rð| ˆ ƒ ƒ \ } } | j | ƒ q¿Wg | D] } | | ƒ ^ qø}
d ˆ |
f f Vˆ ‰ ˆ d
7‰ q¢ | d k rd| ˆ ƒ ƒ \ } } | | ƒ ‰ q¢ | d k r£| ˆ ƒ ƒ \ } } ˆ ˆ | <d ˆ | f f Vq¢ | d k rÒ| ˆ ƒ ƒ \ } } d | f Vq¢ | d k rVˆ ƒ } | d k r6d }
ˆ ƒ } x# | d k r'|
| 7}
ˆ ƒ } qWd |
f Vq| | ƒ \ } }
d |
f Vq¢ | d k rx« | d k r}ˆ ƒ } qeWq¢ | d k rŸd ‰ ˆ ƒ } q¢ | d
k r¯d Sd } d } x9 | d
k rö| d k rö| | 7} | d
7} ˆ ƒ } q¾Wt j t d ƒ | ƒ ‚ q¢ Wd S( só parses a DAG from a concise textual description; generates events
"+n" is a linear run of n nodes based on the current default parent
"." is a single node based on the current default parent
"$" resets the default parent to -1 (implied at the start);
otherwise the default parent is always the last node created
"<p" sets the default parent to the backref p
"*p" is a fork at parent p, where p is a backref
"*p1/p2/.../pn" is a merge of parents p1..pn, where the pi are backrefs
"/p2/.../pn" is a merge of the preceding node and p2..pn
":name" defines a label for the preceding node; labels can be redefined
"@text" emits an annotation event for text
"!command" emits an action event for the current node
"!!my command
" is like "!", but to the end of the line
"#...
" is a comment up to the end of the line
Whitespace between the above elements is ignored.
A backref is either
* a number n, which references the node curr-n, where curr is the current
node, or
* the name of a label you placed earlier using ":name", or
* empty to denote the default parent.
All string valued-elements are either strictly alphanumeric, or must
be enclosed in double quotes ("..."), with "" as escape character.
Generates sequence of
('n', (id, [parentids])) for node creation
('l', (id, labelname)) for labels on nodes
('a', text) for annotations
('c', command) for actions (!)
('C', command) for line actions (!!)
Examples
--------
Example of a complex graph (output not shown for brevity):
>>> len(list(parsedag("""
...
... +3 # 3 nodes in linear run
... :forkhere # a label for the last of the 3 nodes from above
... +5 # 5 more nodes on one branch
... :mergethis # label again
... <forkhere # set default parent to labeled fork node
... +10 # 10 more nodes on a parallel branch
... @stable # following nodes will be annotated as "stable"
... +5 # 5 nodes in stable
... !addfile # custom command; could trigger new file in next node
... +2 # two more nodes
... /mergethis # merge last node with labeled node
... +4 # 4 more nodes descending from merge node
...
... """)))
34
Empty list:
>>> list(parsedag(""))
[]
A simple linear run:
>>> list(parsedag("+3"))
[('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
Some non-standard ways to define such runs:
>>> list(parsedag("+1+2"))
[('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
>>> list(parsedag("+1*1*"))
[('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
>>> list(parsedag("*"))
[('n', (0, [-1]))]
>>> list(parsedag("..."))
[('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
A fork and a join, using numeric back references:
>>> list(parsedag("+2*2*/2"))
[('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])), ('n', (3, [2, 1]))]
>>> list(parsedag("+2<2+1/2"))
[('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])), ('n', (3, [2, 1]))]
Placing a label:
>>> list(parsedag("+1 :mylabel +1"))
[('n', (0, [-1])), ('l', (0, 'mylabel')), ('n', (1, [0]))]
An empty label (silly, really):
>>> list(parsedag("+1:+1"))
[('n', (0, [-1])), ('l', (0, '')), ('n', (1, [0]))]
Fork and join, but with labels instead of numeric back references:
>>> list(parsedag("+1:f +1:p2 *f */p2"))
[('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])), ('l', (1, 'p2')),
('n', (2, [0])), ('n', (3, [2, 1]))]
>>> list(parsedag("+1:f +1:p2 <f +1 /p2"))
[('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])), ('l', (1, 'p2')),
('n', (2, [0])), ('n', (3, [2, 1]))]
Restarting from the root:
>>> list(parsedag("+1 $ +1"))
[('n', (0, [-1])), ('n', (1, [-1]))]
Annotations, which are meant to introduce sticky state for subsequent nodes:
>>> list(parsedag("+1 @ann +1"))
[('n', (0, [-1])), ('a', 'ann'), ('n', (1, [0]))]
>>> list(parsedag('+1 @"my annotation" +1'))
[('n', (0, [-1])), ('a', 'my annotation'), ('n', (1, [0]))]
Commands, which are meant to operate on the most recently created node:
>>> list(parsedag("+1 !cmd +1"))
[('n', (0, [-1])), ('c', 'cmd'), ('n', (1, [0]))]
>>> list(parsedag('+1 !"my command" +1'))
[('n', (0, [-1])), ('c', 'my command'), ('n', (1, [0]))]
>>> list(parsedag('+1 !!my command line\n +1'))
[('n', (0, [-1])), ('C', 'my command line'), ('n', (1, [0]))]
Comments, which extend to the end of the line:
>>> list(parsedag('+1 # comment\n+1'))
[('n', (0, [-1])), ('n', (1, [0]))]
Error:
>>> try: list(parsedag('+1 bad'))
... except Exception, e: print e
invalid character in dag description: bad...
Niÿÿÿÿi c s7 | s
ˆ S| d t j k r+ ˆ t | ƒ Sˆ | Sd S( Ni ( t stringt digitst int( t ref( t labelst p1t r( s7 /usr/lib/python2.7/dist-packages/mercurial/dagparser.pyt resolve¨ s
c s s | ] } | Vq d S( N( ( t .0t c( ( s7 /usr/lib/python2.7/dist-packages/mercurial/dagparser.pys <genexpr>° s c s' y ˆ j ƒ SWn t k
r"