Changeset 552

Show
Ignore:
Timestamp:
06/15/08 05:17:05 (2 months ago)
Author:
athomas
Message:

Cleaned up the rather confusing user_context/with_context/with_user_context:

  • To pass user data into the parser use data=.... This will be available
    as the data member of the parse Context.
  • Specifying with_context=True to nodes will make the Context available to
    callbacks as the first argument.
Files:

Legend:

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

    r551 r552  
    235235            predicate = lambda node: True 
    236236 
    237         def walk(root): 
     237        def _walk(root): 
    238238            if not predicate(root): 
    239239                return 
    240240            yield root 
    241241            for node in root._children.itervalues(): 
    242                 for subnode in walk(node): 
     242                for subnode in _walk(node): 
    243243                    yield subnode 
    244244 
    245         for node in walk(self): 
     245        for node in _walk(self): 
    246246            yield node 
    247247 
     
    608608        if not self.condition(context): 
    609609            return [] 
    610         return Node.children(self, context
     610        return Node.children(self, context, follow=True
    611611 
    612612 
     
    615615    callable. 
    616616 
     617    :param callback: Callback to execute when the action is chosen. 
    617618    :attr with_context: If True, passes the current parse Context as the first 
    618619                        argument. 
     
    632633    pattern = '$' 
    633634    group = 9999 
    634     with_user_context = None 
    635635    with_context = None 
    636636 
     
    643643 
    644644    def terminal(self, context): 
    645         if self.with_user_context or \ 
    646                 (self.with_user_context is None and 
    647                  context.parser.with_user_context): 
    648             warnings.warn('with_user_context has been deprecated. Use ' 
    649                           'with_context and access the user_context attribute.', 
    650                           DeprecationWarning, stacklevel=2) 
    651             return self.callback(context.user_context, **context.vars) 
    652         elif self.with_context or \ 
    653                 (self.with_context is None and 
    654                  context.parser.with_context): 
     645        if self.with_context: 
    655646            return self.callback(context, **context.vars) 
    656647        else: 
     
    876867        if 'context' in locals: 
    877868            context = locals.pop('context') 
    878             user_context = context.user_context 
    879             if isinstance(user_context, dict): 
    880                 locals.update(user_context
     869            data = context.data 
     870            if isinstance(data, dict): 
     871                locals.update(data
    881872            vars = context.vars 
    882873        else: 
    883             user_context = {} 
     874            data = {} 
    884875            vars = {} 
    885876        locals.update(vars) 
     
    887878        locals['a'] = args 
    888879        locals['kw'] = kwargs 
    889         locals['c'] = user_context 
     880        locals['d'] = data 
    890881        locals['defined'] = lambda v: v in locals 
    891882        try: 
     
    933924 
    934925    Attributes that are methods on the Node will be evaluated as expressions. 
    935     All variables from the parse Context, user_context dictionary, and keyword 
     926    All variables from the parse Context, "data" dictionary, and keyword 
    936927    arguments (in that order) are available as locals to the evaluated 
    937928    expression, as well as some additional variables: 
     
    939930        v 
    940931            All variables from the parse Context. 
    941         c 
    942             The user_context dictionary. 
     932        d 
     933            The "data" dictionary. 
    943934        a 
    944935            Any positional arguments. 
     
    982973 
    983974      g = XMLGrammar('example.xml') 
    984       interact(g, user_context={'echo': echo}) 
     975      interact(g, data={'echo': echo}) 
    985976 
    986977    """ 
  • cly/trunk/cly/interactive.py

    r547 r552  
    190190        The prompt. 
    191191 
    192     :param user_context
     192    :param data
    193193        A user-specified object to pass to the parser. The parser builds each 
    194194        parse ``Context`` with this object, which in turn will deliver this 
     
    213213 
    214214    def __init__(self, grammar_or_parser, application='cly', prompt=None, 
    215                  user_context=None, with_user_context=None, with_context=None, 
    216                  history_file=None, history_length=500, 
     215                 data=None, history_file=None, history_length=500, 
    217216                 inhibit_exceptions=False, with_backtrace=False): 
    218217        if prompt is None: 
     
    221220            history_file = os.path.expanduser('~/.%s_history' % application) 
    222221        if isinstance(grammar_or_parser, Grammar): 
    223             parser = Parser(grammar_or_parser, 
    224                             user_context=user_context, 
    225                             with_user_context=with_user_context, 
    226                             with_context=with_context) 
     222            parser = Parser(grammar_or_parser, data=data) 
    227223        else: 
    228224            parser = grammar_or_parser 
    229225 
    230         if user_context is not None: 
    231             parser.user_context = user_context 
    232226        self.parser = parser 
    233         self.user_context = user_context 
     227        self.data = data 
    234228 
    235229        self.input_driver = InputDriver( 
  • cly/trunk/cly/parser.py

    r550 r552  
    104104 
    105105    """ 
    106     def __init__(self, parser, command, user_context=None): 
     106    def __init__(self, parser, command, data=None): 
    107107        self.parser = parser 
    108108        self.command = command 
    109109        self.cursor = 0 
    110         self.user_context = user_context 
     110        self.data = data 
    111111        self.vars = {} 
    112112        self._traversed = {} 
     
    243243class Parser(object): 
    244244    """Parse and execute CLY grammars. 
    245      
    246     A grammar is simply a data structure. To actually utilise it one needs to bind 
    247     it to a ``Parser`` object and parse some input with it. The parser takes care 
    248     of creating a ``Context`` for each parse run, parsing the input, and executing 
    249     any callbacks. 
    250   
    251     .. note:: 
    252        *parser* in this context refers to parsing user input, *not* parsing CLY 
    253        grammars. 
     245 
     246    A Parser object parses user input using a CLY grammar. For each parse, the 
     247    parser creates a ``Context`` containing the state for the run, parses the 
     248    input, and executes any callbacks. 
     249 
     250    :param grammar: Grammar to parse with. 
     251    :param data: User data to attach to Context. 
    254252    """ 
    255     def __init__(self, grammar, user_context=None, with_user_context=False, 
    256                  with_context=False): 
    257         """Construct a new Parser. 
    258  
    259         :param grammar: Grammar object. 
    260         :param user_context: A user-defined object. 
    261         :param with_context: If True, pass current Context as the first 
    262                              argument to all action callbacks. 
    263         """ 
     253    def __init__(self, grammar, data=None): 
     254        """Construct a new Parser.""" 
    264255        self.grammar = grammar 
    265         self.user_context = user_context 
    266         self.with_user_context = with_user_context 
    267         self.with_context = with_context 
     256        self.data = data 
    268257 
    269258    def _set_grammar(self, grammar): 
     
    290279            yield node 
    291280 
    292     def parse(self, command, user_context=None): 
     281    def parse(self, command, data=None): 
    293282        """Parse command using the current grammar. 
    294283 
     
    296285        of the parser. 
    297286 
    298         If a user_context is provided it will be passed on to any ``Action`` 
    299         node callbacks that have set ``with_context=True``. 
     287        :param command: String to parse. 
     288        :param data: The Context object has this as a data member, available to 
     289                     any ``Action`` node callbacks that have set 
     290                     ``with_context=True``. 
    300291 
    301292        >>> from cly.builder import Grammar, Node, Action 
     
    310301        <Context command:'two four' remaining:'four'> 
    311302        """ 
    312         context = Context(self, command, user_context or self.user_context) 
     303        if data is None: 
     304            data = self.data 
     305        context = Context(self, command, data) 
    313306 
    314307        def parse(node, match): 
     
    330323        return context 
    331324 
    332     def execute(self, command, user_context=None): 
     325    def execute(self, command, data=None): 
    333326        """Parse and execute the given command. 
    334327 
     
    339332        'foo bar' 
    340333        """ 
    341         return self.parse(command, user_context).execute() 
     334        return self.parse(command, data).execute() 
    342335 
    343336    def find(self, path): 
  • cly/trunk/cly/test.py

    r548 r552  
    3434 
    3535        grammar = XMLGrammar(xml) 
    36         parser = Parser(grammar, user_context={'echo': self._echo}) 
     36        parser = Parser(grammar, data={'echo': self._echo}) 
    3737        parser.execute('echo magic') 
    3838        self.assertEqual(self._output, (('magic',), {})) 
     
    7070 
    7171        grammar = XMLGrammar(xml) 
    72         parser = Parser(grammar, user_context={'echo': self._echo}) 
     72        parser = Parser(grammar, data={'echo': self._echo}) 
    7373        parser.execute('echo magic monkey') 
    7474        self.assertEqual(self._output, ((['magic', 'monkey'],), {})) 
     
    8989 
    9090        grammar = XMLGrammar(xml) 
    91         parser = Parser(grammar, user_context={'echo': self._echo}) 
     91        parser = Parser(grammar, data={'echo': self._echo}) 
    9292        context = parser.parse('echo ') 
    9393        self.assertEqual(list(context.candidates()), ['monkey', 'muppet']) 
     
    112112 
    113113        grammar = XMLGrammar(xml, extra_nodes=[ABC]) 
    114         parser = Parser(grammar, user_context={'echo': self._echo}) 
     114        parser = Parser(grammar, data={'echo': self._echo}) 
    115115        parser.execute('echo abaabbccc') 
    116116        self.assertEqual(self._output, (('abaabbccc',), {})) 
     
    134134 
    135135        grammar = XMLGrammar(xml) 
    136         parser = Parser(grammar, user_context={ 
     136        parser = Parser(grammar, data={ 
    137137            'echo': self._echo, 
    138138            'lazy': lazy, 
     
    155155 
    156156        grammar = XMLGrammar(xml) 
    157         parser = Parser(grammar, user_context={ 
     157        parser = Parser(grammar, data={ 
    158158            'echo': self._echo, 
    159159            'echo_allowed': True, 
  • cly/trunk/.todo

    r551 r552  
    1919        Figure out why rlext.py dies when the parser is used... 
    2020    </note> 
    21     <note priority="veryhigh" time="1213113286"
     21    <note priority="veryhigh" time="1213113286" done="1213465157"
    2222        Clarify/clean-up how with_context/with_user_context/user_context is used. 
    2323    </note>