Changeset 437

Show
Ignore:
Timestamp:
05/26/07 09:06:03 (2 years ago)
Author:
athomas
Message:

cly: Documentation updates, added anonymous method to builder.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • cly/trunk/cly/builder.py

    r434 r437  
    374374        return not self.traversals or context.traversed(self) < self.traversals 
    375375 
     376    def _get_anonymous(self): 
     377        """Is this node anonymous?""" 
     378        return self.name.startswith('__anonymous_') 
     379 
     380    anonymous = property(_get_anonymous, doc=_get_anonymous.__doc__) 
     381 
    376382    def __repr__(self): 
    377383        return '<%s:%s>' % (self.__class__.__name__, self.path() or '<root>') 
  • cly/trunk/doc/developers-guide.rst

    r419 r437  
    99 
    1010It offers a simple syntax for defining grammars and a powerful interactive 
    11 shell based on readline all with automatic full tab completion and contextual 
     11shell based on readline, all with automatic full tab completion and contextual 
    1212help. 
    1313 
     
    2727.. code-block:: python 
    2828 
    29     grammar = Grammar( 
    30         one=Node('Command 1')( 
    31             one_one=Node('Command 1.1'), 
    32             one_two=Node('Command 1.2'), 
    33         ), 
    34         two=Node('Command 2')( 
    35         ), 
    36    
     29  grammar = Grammar( 
     30      one=Node('Command 1')( 
     31          one_one=Node('Command 1.1'), 
     32          one_two=Node('Command 1.2'), 
     33      ), 
     34      two=Node('Command 2')( 
     35      ), 
     36 
    3737 
    3838This CLY grammar is equivalent to the following EBNF-style grammar:: 
    3939 
    40     ONE := 'one' (ONE_ONE | ONE_TWO) 
    41     TWO := 'two' 
    42     ONE_ONE := 'one_one' 
    43     ONE_TWO := 'one_two' 
     40  ONE := 'one' (ONE_ONE | ONE_TWO) 
     41  TWO := 'two' 
     42  ONE_ONE := 'one_one' 
     43  ONE_TWO := 'one_two' 
    4444 
    45 The first argument to every CLY grammar node must be a help string. This is 
    46 used to construct contextual help when a user presses ``?``. 
     45Help! 
     46~~~~~ 
     47The first argument to every CLY grammar node **must** be a help string. This is 
     48used to construct contextual help when a user presses `?`. 
    4749 
     50Context 
     51~~~~~~~ 
     52Each command is parsed in a new context. The context stores state like 
     53variables collected, number of traversals of nodes, etc. Mostly, it can be 
     54ignored but is mentioned here for reference. 
     55 
     56Types of Nodes 
     57~~~~~~~~~~~~~~ 
     58CLY includes a whole set of builtin node types, which can be broken down into 
     59the following groups: 
     60 
     61``Node`` 
     62    The base grammar node. These nodes in the grammar are purely for 
     63    routing the grammar to other nodes. They have no side-effects. 
     64 
     65``Grammar`` 
     66    The root of the grammar. Contains all other nodes. 
     67 
     68``Group`` 
     69    A convenience class used to group its child nodes together visually. 
     70    Equivalent to setting each nodes ``group`` attribute. 
     71 
     72``Alias`` 
     73    Allow branches of the grammar to be included in other locations. The only 
     74    argument to ``Alias`` is the relative or absolute path of the branch to be 
     75    included. This path can take the form of a glob in order to include 
     76    multiple nodes. Use this to create optional arguments. 
     77 
     78``Variable`` 
     79    Variable nodes insert their matching input into the ``vars`` of the 
     80    ``Context``, after being parsed by the ``parse()`` method. If the attribute 
     81    ``traversals != 1``, values are collected into a list rather than a scalar. 
     82    CLY includes a number of potentially useful ``Variable`` subclasses such as 
     83    ``URI``, ``Integer``, ``Float``, etc. 
     84 
     85``Action`` 
     86    An action matches the end of a line and is used to execute a callback. It 
     87    passes any ``vars`` parsed by previous ``Variable`` nodes through to the 
     88    callback as arguments. 
     89 
     90Node Attributes and Constructor Arguments 
     91~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     92Each node has a set of attributes that define its behaviour, from the regular 
     93expression used to match input, through to the number of times the node can 
     94be traversed in a parse context. 
     95 
     96These attributes can be set in three ways: 
     97 
     98  - As keyword arguments passed to the node constructor: 
     99 
     100    .. code-block:: python 
     101 
     102        Node('Help', pattern=r'.+') 
     103 
     104  - As keyword arguments passed to the node when it is "called": 
     105 
     106    .. code-block:: python 
     107 
     108        Node('Help')(pattern=r'.+') 
     109 
     110  - By subclassing the node and defining the attribute as a class attribute: 
     111 
     112    .. code-block:: python 
     113 
     114        class Any(Node): 
     115          pattern = r'.+' 
     116 
     117For details on what attributes are available for each node class, refer to the 
     118API documentation. 
     119 
     120Optional Branches 
     121~~~~~~~~~~~~~~~~~ 
     122As mentioned above, the ``Alias`` node allows inclusion of other parts of the 
     123grammar at the current location. This is useful in a couple of situations, the 
     124most common of which is simply allowing optional nodes: 
     125 
     126.. code-block:: python 
     127 
     128  def add_host(hostname, ip, comment=''): 
     129    ... 
     130 
     131  # add <hostname> <ip> [<comment>] 
     132  add=Node('Add a host')( 
     133      hostname=Variable('Host name')( 
     134          ip=IP('IP address')( 
     135              action=Action('Add host', add_host), 
     136              # Optional comment 
     137              comment=Variable('Comment', pattern=r'.+')( 
     138                  Alias('../../action'), 
     139              ) 
     140          ) 
     141      ), 
     142  ) 
     143 
     144A second useful situation is aliasing another entire block of the grammar at 
     145the current location: 
     146 
     147.. code-block:: python 
     148 
     149