From 15d33bed9c475f927abfa0f4bd9eedddcc82a936 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Mon, 19 Nov 2012 08:19:29 -0500 Subject: [PATCH 01/34] Add a prototyping code watcher --- code_watcher.py | 217 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 code_watcher.py diff --git a/code_watcher.py b/code_watcher.py new file mode 100644 index 00000000..42506848 --- /dev/null +++ b/code_watcher.py @@ -0,0 +1,217 @@ +import types +from enaml.core.byteplay import ( + Code, LOAD_ATTR, LOAD_CONST, ROT_TWO, DUP_TOP, CALL_FUNCTION, POP_TOP, + LOAD_FAST, STORE_FAST, BUILD_TUPLE, ROT_THREE, UNPACK_SEQUENCE, DUP_TOPX, + BINARY_SUBSCR, GET_ITER, LOAD_NAME, LOAD_GLOBAL, DELETE_NAME, DELETE_GLOBAL +) + + +class Watcher(object): + + def load_name(self, name): + print 'load name', name + + def call_function(self, func, args, kwargs): + print 'call function', args, kwargs + + def get_item(self, obj, index): + print 'get item', obj, index + + def get_attr(self, obj, attr): + print 'get attr', obj, attr + + +def translate_code(code, f_globals): + bp_code = Code.from_code(code) + code_list = list(bp_code.code) + + # Make a first pass over the code list and replace LOAD_GLOBAL with + # LOAD_NAME. This enables dynamic scoping using a custom locals map. + for idx, (op, op_arg) in enumerate(code_list): + if op == LOAD_GLOBAL: + code_list[idx] = (LOAD_NAME, op_arg) + if op == DELETE_GLOBAL: + code_list[idx] = (DELETE_NAME, op_arg) + + # The list of code segments that will be inserted into the + # new bytecode for the expression. + inserts = [] + for idx, (op, op_arg) in enumerate(code_list): + # This bit of code is injected between the object on TOS + # and its pending attribute access. The TOS obj is duped, + # the rotated above the binder code. The attr is loaded, + # and the binder is called with the object and attr. The + # return value of the binder is discarded. This leaves the + # original TOS and pending attribute access to continue on + # as normal + if op == LOAD_ATTR: + code = [ # obj + (DUP_TOP, None), # obj -> obj + (LOAD_FAST, '_[tracer]'), # obj -> obj -> tracer + (LOAD_ATTR, 'load_attr'), # obj -> obj -> tracefunc + (ROT_TWO, None), # obj -> tracefunc -> obj + (LOAD_CONST, op_arg), # obj -> tracefunc -> obj -> attr + (CALL_FUNCTION, 0x0002), # obj -> retval + (POP_TOP, None), # obj + ] + inserts.append((idx, code)) + elif op == CALL_FUNCTION: + # This computes the number of objects on the stack + # between TOS and the object being called. Only the + # last 16bits of the op_arg are signifcant. The lowest + # 8 are the number of positional args on the stack, + # the upper 8 is the number of kwargs. For kwargs, the + # number of items on the stack is twice this number + # since the values on the stack alternate name, value. + n_stack_args = (op_arg & 0xFF) + 2 * ((op_arg >> 8) & 0xFF) + code = [ # func -> arg(0) -> arg(1) -> ... -> arg(n-1) + (BUILD_TUPLE, n_stack_args), # func -> argtuple + (DUP_TOPX, 2), # func -> argtuple -> func -> argtuple + (LOAD_FAST, '_[tracer]'), # func -> argtuple -> func -> argtuple -> tracer + (LOAD_ATTR, 'call_function'), # func -> argtuple -> func -> argtuple -> tracefunc + (ROT_THREE, None), # func -> argtuple -> tracefunc -> func -> argtuple + (LOAD_CONST, op_arg), # func -> argtuple -> tracefunc -> func -> argtuple -> argspec + (CALL_FUNCTION, 0x0003), # func -> argtuple -> retval + (POP_TOP, None), # func -> argtuple + (UNPACK_SEQUENCE, n_stack_args), # func -> arg(n-1) -> arg(n-2) -> ... -> arg(0) + (BUILD_TUPLE, n_stack_args), # func -> reversedargtuple + (UNPACK_SEQUENCE, n_stack_args), # func -> arg(0) -> arg(1) -> ... -> arg(n-1) + ] + inserts.append((idx, code)) + elif op == BINARY_SUBSCR: + code = [ # obj -> idx + (DUP_TOPX, 2), # obj -> idx -> obj -> idx -> tracer + (LOAD_FAST, '_[tracer]'), # obj -> idx -> obj -> idx -> tracer + (LOAD_ATTR, 'binary_subscr'), # obj -> idx -> obj -> idx -> tracefunc + (ROT_THREE, None), # obj -> idx -> tracefunc -> obj -> idx + (CALL_FUNCTION, 0x0002), # obj -> idx -> retval + (POP_TOP, None), # obj -> idx + ] + inserts.append((idx, code)) + elif op == GET_ITER: + code = [ # obj + (DUP_TOP, None), # obj -> obj + (LOAD_FAST, '_[tracer]'), # obj -> obj -> tracer + (LOAD_ATTR, 'get_iter'), # obj -> obj -> tracefunc + (ROT_TWO, None), # obj -> tracefunc -> obj + (CALL_FUNCTION, 0x0001), # obj -> retval + (POP_TOP, None), # obj + ] + inserts.append((idx, code)) + elif op == LOAD_NAME: + code = [ # + (LOAD_FAST, '_[tracer]'), # tracer + (LOAD_ATTR, 'load_name'), # tracefunc + (LOAD_CONST, op_arg), # tracefunc -> name + (CALL_FUNCTION, 0x0001), # retval + (POP_TOP, None), # + ] + inserts.append((idx, code)) + + insertions = {} + for idx, code in inserts: + insertions[idx] = code + + # Create a new code list which interleaves the code generated + # by the monitors at the appropriate location in the expression. + new_code = [] + for idx, code_op in enumerate(code_list): + if idx in insertions: + new_code.extend(insertions[idx]) + new_code.append(code_op) + + bp_code.code = new_code + bp_code.newlocals = False + bp_code.args = ('_[tracer]',) + bp_code.args + eval_code = bp_code.to_code() + + return types.FunctionType(eval_code, f_globals) + + +class CustomScope(dict): + + def __init__(self, f_globals): + self._f_globals = f_globals + + def __getitem__(self, name): + print + print '############# getitem', name + print + try: + r = self._f_globals[name] + except KeyError: + r = getattr(__builtins__, name) + return r + + def __setitem__(self, name, value): + print + print '############ setitem', name, value + print + self._f_globals[name] = value + + def __delitem__(self, name): + print + print '############ delitem', name + print + del self._f_globals[name] + + +class CodeTracer(object): + + def __init__(self, code, f_globals): + self._s = CustomScope(f_globals) + self._watchers = [] + self._func = translate_code(code, self._s) + + def __call__(self, watcher, *args, **kwargs): + self._watchers.append(watcher) + try: + self._func(self, *args, **kwargs) + finally: + self._watchers.pop() + + def load_name(self, name): + print 'load_name', name + + def load_attr(self, obj, attr): + print 'load attr', obj, attr + + def call_function(self, func, arg_tuple, nargs): + print 'call function', func, arg_tuple + + def binary_subscr(self, obj, idx): + print 'binary subscr', type(obj), idx + + def get_iter(self, obj): + print 'get iter', obj + + +class Foo(object): + def __init__(self, *args, **kwargs): pass + a = 1 + b = 2 + c = 3 + + +foobar = 12 + +def tester(): + f = Foo() + Bar = Foo + c = (f.a, f.b, f.c, f) + c[-1].a + fs = [Bar(1, 2, w=12) for i in range(10)] + d = [f.b for f in fs] + del f + del c + #global foobar + del foobar + + + +if __name__ == '__main__': + t = CodeTracer(tester.func_code, tester.func_globals) + import dis + print dis.dis(t._func) + t(None) + print foobar From 10648f9d5023935944ea8a323393386b6d7dc2f5 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Tue, 20 Nov 2012 19:03:28 -0500 Subject: [PATCH 02/34] WIP commit --- code_watcher.py | 33 +-- enaml/__init__.py | 6 +- enaml/core/abstract_expressions.py | 66 +++++ enaml/core/code_tracing.py | 314 ++++++++++++++++++++++++ enaml/core/declarative.py | 74 +++--- enaml/core/dynamic_scope.py | 285 ++++++++++++++++++++++ enaml/core/funchelper.cpp | 110 +++++++++ enaml/core/new_expressions.py | 377 +++++++++++++++++++++++++++++ enaml/core/new_operators.py | 87 +++++++ enaml/core/nonlocals.py | 148 +++++++++++ enaml/core/trait_types.py | 70 +++--- setup.py | 9 + 12 files changed, 1480 insertions(+), 99 deletions(-) create mode 100644 enaml/core/abstract_expressions.py create mode 100644 enaml/core/code_tracing.py create mode 100644 enaml/core/dynamic_scope.py create mode 100644 enaml/core/funchelper.cpp create mode 100644 enaml/core/new_expressions.py create mode 100644 enaml/core/new_operators.py create mode 100644 enaml/core/nonlocals.py diff --git a/code_watcher.py b/code_watcher.py index 42506848..264cd761 100644 --- a/code_watcher.py +++ b/code_watcher.py @@ -5,6 +5,8 @@ BINARY_SUBSCR, GET_ITER, LOAD_NAME, LOAD_GLOBAL, DELETE_NAME, DELETE_GLOBAL ) +from enaml.core._funchelper import call_func + class Watcher(object): @@ -30,8 +32,6 @@ def translate_code(code, f_globals): for idx, (op, op_arg) in enumerate(code_list): if op == LOAD_GLOBAL: code_list[idx] = (LOAD_NAME, op_arg) - if op == DELETE_GLOBAL: - code_list[idx] = (DELETE_NAME, op_arg) # The list of code segments that will be inserted into the # new bytecode for the expression. @@ -130,43 +130,37 @@ def translate_code(code, f_globals): class CustomScope(dict): - def __init__(self, f_globals): - self._f_globals = f_globals - def __getitem__(self, name): print print '############# getitem', name print - try: - r = self._f_globals[name] - except KeyError: - r = getattr(__builtins__, name) - return r + raise KeyError def __setitem__(self, name, value): print print '############ setitem', name, value print - self._f_globals[name] = value + raise KeyError def __delitem__(self, name): print print '############ delitem', name print - del self._f_globals[name] + raise KeyError class CodeTracer(object): def __init__(self, code, f_globals): - self._s = CustomScope(f_globals) + self._s = CustomScope() self._watchers = [] - self._func = translate_code(code, self._s) + self._func = translate_code(code, f_globals) def __call__(self, watcher, *args, **kwargs): self._watchers.append(watcher) try: - self._func(self, *args, **kwargs) + a = (self,) + args + call_func(self._func, a, kwargs, self._s) finally: self._watchers.pop() @@ -202,16 +196,9 @@ def tester(): c[-1].a fs = [Bar(1, 2, w=12) for i in range(10)] d = [f.b for f in fs] - del f - del c - #global foobar - del foobar - if __name__ == '__main__': t = CodeTracer(tester.func_code, tester.func_globals) - import dis - print dis.dis(t._func) t(None) - print foobar + diff --git a/enaml/__init__.py b/enaml/__init__.py index 4cfb3089..f462ca35 100644 --- a/enaml/__init__.py +++ b/enaml/__init__.py @@ -40,7 +40,7 @@ def imports(): #------------------------------------------------------------------------------ # Operator Context Functions #------------------------------------------------------------------------------ -#: The private storage for the optional default operator context function +#: The private storage for the optional default operator context function #: which overrides that which is provided by default. _default_operator_context_func = None @@ -53,7 +53,7 @@ def set_default_operator_context_func(func): func : callable A callable object which takes no arguments and returns an instance of OperatorContext. - + """ global _default_operator_context_func _default_operator_context_func = func @@ -79,7 +79,7 @@ def default_operator_context(): if ctxt_func is not None: return ctxt_func() from enaml.core.operator_context import OperatorContext - from enaml.core.operators import OPERATORS + from enaml.core.new_operators import OPERATORS return OperatorContext(OPERATORS) diff --git a/enaml/core/abstract_expressions.py b/enaml/core/abstract_expressions.py new file mode 100644 index 00000000..6950bb8b --- /dev/null +++ b/enaml/core/abstract_expressions.py @@ -0,0 +1,66 @@ +#------------------------------------------------------------------------------ +# Copyright (c) 2012, Enthought, Inc. +# All rights reserved. +#------------------------------------------------------------------------------ +from abc import ABCMeta, abstractmethod + + +class AbstractListener(object): + """ An interface definition for creating attribute listeners. + + Listeners can be regisitered with `Declarative` instances in order + to track changes to their attributes. + + """ + __metaclass__ = ABCMeta + + @abstractmethod + def value_changed(self, obj, name, old, new): + """ Called when the attribute on the object has changed. + + Parameters + ---------- + obj : Declarative + The Declarative object which owns the attribute. + + name : str + The name of the attribute which changed. + + old : object + The old value of the attribute. + + new : object + The new value of the attribute. + + """ + raise NotImplementedError + + +class AbstractExpression(object): + """ An abstract interface definition for creating expressions. + + Expressions can be registered with `Declarative` instances in order + to provide dynamically computed values at runtime. + + """ + __metaclass__ = ABCMeta + + #: An Enaml Signal which should be emitted by the expression when + #: the the expression is invalidated. If an expression does not + #: support invalidation, this may be None. + invalidated = None + + @abstractmethod + def eval(self, obj): + """ Evaluate and return the results of the expression. + + Parameters + ---------- + obj : Declarative + The declarative object which owns the expression. + + + + """ + raise NotImplementedError + diff --git a/enaml/core/code_tracing.py b/enaml/core/code_tracing.py new file mode 100644 index 00000000..30ea47f2 --- /dev/null +++ b/enaml/core/code_tracing.py @@ -0,0 +1,314 @@ +#------------------------------------------------------------------------------ +# Copyright (c) 2012, Enthought, Inc. +# All rights reserved. +#------------------------------------------------------------------------------ +from .byteplay import ( + Code, LOAD_ATTR, LOAD_CONST, ROT_TWO, DUP_TOP, CALL_FUNCTION, POP_TOP, + LOAD_FAST, BUILD_TUPLE, ROT_THREE, UNPACK_SEQUENCE, DUP_TOPX, + BINARY_SUBSCR, GET_ITER, LOAD_NAME, LOAD_GLOBAL +) + + +class CodeTracer(object): + """ A base class for implementing code tracers. + + This class defines the interface for a code tracer object, which is + an object which can be passed as the first argument to a code object + which has been transformed to enable tracing. Methods on the tracer + are called with relevant arguments from the Python stack, when that + particular code segment is executing. The return values of a tracer + method is ignored; exceptions are propagated. + + """ + def load_attr(self, obj, attr): + """ Called before the LOAD_ATTR opcode is executed. + + Parameters + ---------- + obj : object + The object which owns the attribute. + + attr : str + The attribute being loaded. + + """ + pass + + def call_function(self, func, argtuple, argspec): + """ Called before the CALL_FUNCTION opcode is executed. + + Parameters + ---------- + func : object + The object being called. + + argtuple : tuple + The argument tuple from the stack (see notes). + + argspec : int + The argument tuple specification. + + Notes + ----- + The `argstuple` contains both positional and keyword argument + information. `argspec` is an int which specifies how to parse + the information. The lower 16bits of `argspec` are significant. + The lowest 8 bits are the number of positional arguments which + are the first n items in `argtuple`. The second 8 bits are the + number of keyword arguments which follow the positional args in + `argtuple` and alternate name -> value. `argtuple` can be parsed + into a conventional tuple and dict with the following: + + nargs = argspec & 0xFF + args = argtuple[:nargs] + kwargs = dict(zip(argtuple[nargs::2], argtuple[nargs+1::2])) + + """ + pass + + def binary_subscr(self, obj, idx): + """ Called before the BINARY_SUBSCR opcode is executed. + + Parameters + ---------- + obj : object + The object being indexed. + + idx : object + The index. + + """ + pass + + def get_iter(self, obj): + """ Called before the GET_ITER opcode is executed. + + Parameters + ---------- + obj : object + The object which should return an iterator. + + """ + pass + + +class CodeInverter(object): + """ A base class for implementing code inverters. + + This class defines the interface for a code inverter object, which is + an object which can be passed as the first argument to a code object + which has been transformed to enable inversion. The methods on the + inverter are called with relevant arguments from the Python stack, + when that particular code segment is executing. The return values of + a tracer method is ignored; exceptions are propagated. + + The default behavior of an inverter is to raise. Implementations + must provide their own code. + + """ + def fail(self): + """ Called by the modified code to raise an inversion exception. + + """ + raise RuntimeError('Cannot assign to the given expression') + + def load_name(self, name, value): + """ Called before the LOAD_NAME opcode is executed. + + This method should perform a STORE_NAME operation. + + Parameters + ---------- + name : str + The name being loaded. + + value : object + The value to store. + + """ + self.fail() + + def load_attr(self, obj, attr, value): + """ Called before the LOAD_ATTR opcode is executed. + + This method should perform a STORE_ATTR operation. + + Parameters + ---------- + obj : object + The object which owns the attribute. + + attr : str + The attribute being loaded. + + value : object + The value to store + + """ + self.fail() + + def call_function(self, func, argtuple, argspec, value): + """ Called before the CALL_FUNCTION opcode is executed. + + This method should perform an appropriate store operation. + + Parameters + ---------- + func : object + The object being called. + + argtuple : tuple + The argument tuple from the stack (see Notes). + + argspec : int + The argument tuple specification. + + value : object + The value to store. + + Notes + ----- + The semantics of the arguments is identical to the method + `call_function` on the `CodeTracer` type. + + """ + self.fail() + + def binary_subscr(self, obj, idx, value): + """ Called before the BINARY_SUBSCR opcode is executed. + + This method should perform a STORE_SUBSCR operation. + + Parameters + ---------- + obj : object + The object being indexed. + + idx : object + The index. + + value : object + The value to store. + + """ + self.fail() + + +def transform_code(code, trace): + """ Transform a code object into a Python function. + + This will disassemble the given code object and rewrite it to enable + Enaml's dynamic scoping and tracing features. + + Parameters + ---------- + code : types.CodeType + The Python code object which should transformed. + + trace : bool + Whether or not to add tracing code to the function. If this is + True, the arguments of the returned function are extended so + that the first argument to the function is a `CodeTracer` + instance. + + Returns + ------- + result : types.CodeType + A Python code object which implements the desired functionality. + + """ + bp_code = Code.from_code(code) + code_list = list(bp_code.code) + + # Replacing LOAD_GLOBAL with LOAD_NAME enables dynamic scoping by + # way of a custom locals mapping. There is a C extension module + # with a function `call_func` which allows a Python function to + # be called with a locals mapping, which is normally not possible. + for idx, (op, op_arg) in enumerate(code_list): + if op == LOAD_GLOBAL: + code_list[idx] = (LOAD_NAME, op_arg) + + # If tracing code is not required, the transformation is complete. + if not trace: + bp_code.code = code_list + bp_code.newlocals = False + return bp_code.to_code() + + # This builds a mapping of code idx to a list of ops, which are the + # tracing bytecode instructions which will be inserted into the code + # object being transformed. The ops assume that a tracer object is + # available in the fast locals using a non-clashable name. All of + # the ops have a net-zero effect on the execution stack. Provided + # that the tracer has no visible side effects, the tracing is + # transparent. + inserts = {} + for idx, (op, op_arg) in enumerate(code_list): + if op == LOAD_ATTR: + code = [ # obj + (DUP_TOP, None), # obj -> obj + (LOAD_FAST, '_[tracer]'), # obj -> obj -> tracer + (LOAD_ATTR, 'load_attr'), # obj -> obj -> tracefunc + (ROT_TWO, None), # obj -> tracefunc -> obj + (LOAD_CONST, op_arg), # obj -> tracefunc -> obj -> attr + (CALL_FUNCTION, 0x0002), # obj -> retval + (POP_TOP, None), # obj + ] + inserts[idx] = code + elif op == CALL_FUNCTION: + # This computes the number of objects on the stack between + # TOS and the object being called. Only the last 16bits of + # the op_arg are signifcant. The lowest 8 are the number of + # positional args on the stack, the upper 8 is the number of + # kwargs. For kwargs, the number of items on the stack is + # twice this number since the values on the stack alternate + # name, value. + n_stack_args = (op_arg & 0xFF) + 2 * ((op_arg >> 8) & 0xFF) + code = [ # func -> arg(0) -> arg(1) -> ... -> arg(n-1) + (BUILD_TUPLE, n_stack_args), # func -> argtuple + (DUP_TOPX, 2), # func -> argtuple -> func -> argtuple + (LOAD_FAST, '_[tracer]'), # func -> argtuple -> func -> argtuple -> tracer + (LOAD_ATTR, 'call_function'), # func -> argtuple -> func -> argtuple -> tracefunc + (ROT_THREE, None), # func -> argtuple -> tracefunc -> func -> argtuple + (LOAD_CONST, op_arg), # func -> argtuple -> tracefunc -> func -> argtuple -> argspec + (CALL_FUNCTION, 0x0003), # func -> argtuple -> retval + (POP_TOP, None), # func -> argtuple + (UNPACK_SEQUENCE, n_stack_args), # func -> arg(n-1) -> arg(n-2) -> ... -> arg(0) + (BUILD_TUPLE, n_stack_args), # func -> reversedargtuple + (UNPACK_SEQUENCE, n_stack_args), # func -> arg(0) -> arg(1) -> ... -> arg(n-1) + ] + inserts[idx] = code + elif op == BINARY_SUBSCR: + code = [ # obj -> idx + (DUP_TOPX, 2), # obj -> idx -> obj -> idx + (LOAD_FAST, '_[tracer]'), # obj -> idx -> obj -> idx -> tracer + (LOAD_ATTR, 'binary_subscr'), # obj -> idx -> obj -> idx -> tracefunc + (ROT_THREE, None), # obj -> idx -> tracefunc -> obj -> idx + (CALL_FUNCTION, 0x0002), # obj -> idx -> retval + (POP_TOP, None), # obj -> idx + ] + inserts[idx] = code + elif op == GET_ITER: + code = [ # obj + (DUP_TOP, None), # obj -> obj + (LOAD_FAST, '_[tracer]'), # obj -> obj -> tracer + (LOAD_ATTR, 'get_iter'), # obj -> obj -> tracefunc + (ROT_TWO, None), # obj -> tracefunc -> obj + (CALL_FUNCTION, 0x0001), # obj -> retval + (POP_TOP, None), # obj + ] + inserts[idx] = code + + # Create a new code list which interleaves the generated code with + # the original code at the appropriate location. + new_code = [] + for idx, code_op in enumerate(code_list): + if idx in inserts: + new_code.extend(inserts[idx]) + new_code.append(code_op) + + # Create the new code object which takes a tracer as the first arg. + bp_code.code = new_code + bp_code.newlocals = False + bp_code.args = ('_[tracer]',) + bp_code.args + return bp_code.to_code() + diff --git a/enaml/core/declarative.py b/enaml/core/declarative.py index ea3ac05d..bb03831a 100644 --- a/enaml/core/declarative.py +++ b/enaml/core/declarative.py @@ -2,9 +2,9 @@ # Copyright (c) 2012, Enthought, Inc. # All rights reserved. #------------------------------------------------------------------------------ -from traits.api import Instance, List, Property, Str, Dict, Disallow +from traits.api import Instance, List, Property, Str, Dict, Disallow, ReadOnly -from .expressions import AbstractExpression +from .abstract_expressions import AbstractExpression, AbstractListener from .object import Object from .operator_context import OperatorContext from .trait_types import ExpressionTrait, UserAttribute, UserEvent @@ -29,12 +29,17 @@ class Declarative(Object): #: 'self' according to Enaml's dynamic scoping rules. self = Property(fget=lambda self: self) + #: The operator context used to build out this instance. + operators = ReadOnly + #: The private dictionary of expression objects that are bound to #: attributes on this component. It should not be manipulated by #: user code. Rather, expressions should be bound by the operators #: by calling the '_bind_expression' method. _expressions = Dict(Str, List(Instance(AbstractExpression))) + _listeners = Dict(Str, List(Instance(AbstractListener))) + #: A class attribute used by the Enaml compiler machinery to store #: the builder functions on the class. The functions are called #: when a component is instantiated and are the mechanism by which @@ -64,9 +69,9 @@ def __init__(self, parent=None, **kwargs): # Builders that come later can then override these bindings. # Each component gets it's own identifier namespace and current # operator context. + operators = self.operators = OperatorContext.active_context() if self._builders: identifiers = {} - operators = OperatorContext.active_context() for builder in self._builders: builder(self, identifiers, operators) @@ -133,7 +138,7 @@ def _add_user_attribute(cls, name, attr_type, is_event): cls.__base_traits__[name] = ctrait cls.__class_traits__[name] = ctrait - def _bind_expression(self, name, expression, notify_only=False): + def _bind_expression(self, name, expression): """ A private method used by the Enaml execution engine. This method is called by the Enaml operators to bind the given @@ -160,33 +165,13 @@ def _bind_expression(self, name, expression, notify_only=False): msg = "Cannot bind expression. %s object has no attribute '%s'" raise AttributeError(msg % (self, name)) - # If this is the first time an expression is being bound to the - # given attribute, then we hook up a change handler. This ensures - # that we only get one notification event per bound attribute. - # We also create the notification entry in the dict, which is - # a list with at least one item. The first item will always be - # the left associative expression (or None) and all following - # items will be the notify_only expressions. expressions = self._expressions - if name not in expressions: - self.on_trait_change(self._on_bound_attr_changed, name) - expressions[name] = [None] - - # There can be multiple notify_only expressions bound to a - # single attribute, so they just get appended to the end of - # the list. Otherwise, the left associative expression gets - # placed at the zero position of the list, overriding any - # existing expression. - if notify_only: - expressions[name].append(expression) - else: - handler = self._on_expression_changed + handler = self._on_expression_changed + if name in expressions: old = expressions[name][0] - if old is not None: - old.expression_changed.disconnect(handler) - expression.expression_changed.connect(handler) - expressions[name][0] = expression - + if old.invalidated is not None: + old.invalidated.disconnect(handler) + else: # Hookup support for default value computation. We only need # to add an ExpressionTrait once, since it will reach back # into the _expressions dict as needed and retrieve the most @@ -194,13 +179,26 @@ def _bind_expression(self, name, expression, notify_only=False): if not isinstance(curr.trait_type, ExpressionTrait): self.add_trait(name, ExpressionTrait(curr)) - def _on_expression_changed(self, expression, name, value): - """ A private signal callback for the expression_changed signal - of the bound expressions. It updates the value of the attribute - with the new value from the expression. + if expression.invalidated is not None: + expression.invalidated.connect(handler) + expressions[name] = [expression] - """ - setattr(self, name, value) + def _bind_listener(self, name, listener): + curr = self.trait(name) + if curr is None or curr.trait_type is Disallow: + msg = "Cannot bind expression. %s object has no attribute '%s'" + raise AttributeError(msg % (self, name)) + listeners = self._listeners + if name not in listeners: + self.on_trait_change(self._on_bound_attr_changed, name) + listeners[name] = [] + listeners[name].append(listener) + + def _on_expression_changed(self, name): + expressions = self._expressions + if name in expressions: + expr = expressions[name][0] + setattr(self, name, expr.eval(self, name)) def _on_bound_attr_changed(self, obj, name, old, new): """ A private handler which is called when any attribute which @@ -212,9 +210,9 @@ def _on_bound_attr_changed(self, obj, name, old, new): # The check for None is for the case where there are no left # associative expressions bound to the attribute, so the first # entry in the list is still None. - for expr in self._expressions[name]: - if expr is not None: - expr.notify(old, new) + for expr in self._listeners[name]: + #expr.notify(old, new) + expr.value_changed(self, name, old, new) #-------------------------------------------------------------------------- # Public API diff --git a/enaml/core/dynamic_scope.py b/enaml/core/dynamic_scope.py new file mode 100644 index 00000000..ce524070 --- /dev/null +++ b/enaml/core/dynamic_scope.py @@ -0,0 +1,285 @@ +#------------------------------------------------------------------------------ +# Copyright (c) 2012, Enthought, Inc. +# All rights reserved. +#------------------------------------------------------------------------------ +from abc import ABCMeta, abstractmethod +from .trait_types import UninitializedAttributeError + + +class AbstractScopeListener(object): + """ An abstract interface definition for scope listeners. + + A scope listener will be notified when an attribute is accessed via + dynamic scoping. + + """ + __metaclass__ = ABCMeta + + @abstractmethod + def dynamic_load(self, obj, name, value): + """ Called after the scope dynamically loads an attribute. + + Parameters + ---------- + obj : object + The object which owns the attribute. + + name : str + The name of the attribute loaded. + + value : object + The value of the loaded attribute. + + """ + raise NotImplementedError + + +class DynamicScope(object): + """ A custom mapping object that implements Enaml's dynamic scope. + + The __getitem__ method of this object is called when LOAD_NAME + opcode is encountered in a code object which has been transformed + by the Enaml compiler chain. + + Notes + ----- + Strong references are kept to all objects passed to the constructor, + so these scope objects should be created as needed and discarded in + order to avoid unnecessary reference cycles. + + """ + def __init__(self, obj, identifiers, overrides, listener): + """ Initialize a DynamicScope. + + Parameters + ---------- + obj : Declarative + The Declarative object which owns the executing code. + + identifiers : dict + The identifiers available to the executing code. + + overrides : dict + A dict of objects which should have higher precedence than + the identifiers. + + listener : DynamicScopeListener or None + A listener which should be notified when a name is loaded + via dynamic scoping. + + """ + self._obj = obj + self._identifiers = identifiers + self._overrides = overrides + self._listener = listener + + def __getitem__(self, name): + """ Lookup and return an item from the scope. + + Parameters + ---------- + name : str + The name of the item to retrieve from the scope. + + Raises + ------ + KeyError + The named item is not contained in the scope. + + """ + dct = self._overrides + if name in dct: + return dct[name] + dct = self._identifiers + if name in dct: + return dct[name] + parent = self._obj + while parent is not None: + try: + value = getattr(parent, name) + except AttributeError: + parent = parent.parent + else: + listener = self._listener + if listener is not None: + listener.dynamic_load(parent, name, value) + return value + raise KeyError(name) + + def __contains__(self, name): + """ Return True if the name is in scope, False otherwise. + + """ + if isinstance(name, basestring): + try: + self.__getitem__(name) + except KeyError: + res = False + else: + res = True + else: + res = False + return res + + +class Nonlocals(object): + """ An object which implements userland dynamic scoping. + + An instance of this object is made available with the `nonlocals` + magic name in the scope of an expression. + + """ + def __init__(self, obj, listener): + """ Initialize a nonlocal scope. + + Parameters + ---------- + obj : Declarative + The Declarative object which owns the executing code. + + listener : DynamicScopeListener or None + A listener which should be notified when a name is loaded + via dynamic scoping. + + """ + self._nls_obj = obj + self._nls_listener = listener + + def __repr__(self): + """ A pretty representation of the NonlocalScope. + + """ + return 'Nonlocals[%s]' % self._obj + + def __call__(self, level=0): + """ Get a new nonlocals object for the given offset. + + Parameters + ---------- + level : int, optional + The number of levels up the tree to offset. The default is + zero and indicates no offset. The level must be >= 0. + + """ + if not isinstance(level, int) or level < 0: + msg = ('The nonlocal scope level must be an int >= 0. ' + 'Got %r instead.') + raise ValueError(msg % level) + offset = 0 + target = self._nls_obj + while target is not None and offset != level: + target = target.parent + offset += 1 + if offset != level: + msg = 'Scope level %s is out of range' + raise ValueError(msg % level) + return Nonlocals(target, self._nls_listener) + + def __getattr__(self, name): + """ A convenience method which allows accessing items in the + scope via getattr instead of getitem. + + """ + try: + return self.__getitem__(name) + except KeyError: + msg = "%s has no attribute '%s'" % (self, name) + raise AttributeError(msg) + + def __setattr__(self, name, value): + """ A convenience method which allows setting items in the + scope via setattr instead of setitem. + + """ + if name in ('_nls_obj', '_nls_listener'): + super(Nonlocals, self).__setattr__(name, value) + else: + try: + self.__setitem__(name, value) + except KeyError: + msg = "%s has no attribute '%s'" % (self, name) + raise AttributeError(msg) + + def __getitem__(self, name): + """ Lookup and return an item from the nonlocals. + + Parameters + ---------- + name : str + The name of the item to retrieve from the nonlocals. + + Raises + ------ + KeyError + The named item is not contained in the nonlocals. + + """ + parent = self._nls_obj + while parent is not None: + try: + value = getattr(parent, name) + except AttributeError: + parent = parent.parent + else: + listener = self._nls_listener + if listener is not None: + listener.dynamic_load(parent, name, value) + return value + raise KeyError(name) + + def __setitem__(self, name, value): + """ Sets the value of the nonlocal. + + Parameters + ---------- + name : str + The name of the item to set in the nonlocals. + + value : object + The value to set in the nonlocals. + + Raises + ------ + KeyError + The named item is not contained in the nonlocals. + + """ + parent = self._nls_obj + while parent is not None: + # It's not sufficient to try to do setattr(...) here and + # catch the AttributeError, because HasStrictTraits raises + # a TraitError in these cases and it becomes impossible + # to distinguish that error from a trait typing error + # without checking the message of the exception. + try: + getattr(parent, name) + except UninitializedAttributeError: + pass + except AttributeError: + parent = parent.parent + continue + setattr(parent, name, value) + return + raise KeyError(name) + + def __contains__(self, name): + """ True if the name is in the nonlocals, False otherwise. + + """ + if isinstance(name, basestring): + # Temporarily disable the listener to prevent property + # bindings due to scope testing. + listener = self._nls_listener + self._nls_listener = None + try: + self.__getitem__(name) + except KeyError: + res = False + else: + res = True + finally: + self._nls_listener = listener + else: + res = False + return res + diff --git a/enaml/core/funchelper.cpp b/enaml/core/funchelper.cpp new file mode 100644 index 00000000..b25ea26b --- /dev/null +++ b/enaml/core/funchelper.cpp @@ -0,0 +1,110 @@ +#include + + +/* Call a function with an optional locals mapping. + +This allows Enaml to generate bytecode with the LOAD_GLOBAL opcode +replace with LOAD_NAME and use a custom locals mapping to implement +dynamic scoping. The code below is a slightly tweaked `function_call` +from Python's funcobject.c + +*/ +extern "C" { static PyObject* call_trace_func( PyObject*, PyObject* ); } +static PyObject* +call_func( PyObject* mod, PyObject* args ) +{ + PyObject* func; + PyObject* func_args; + PyObject* func_kwargs; + PyObject* func_locals = Py_None; + + if( !PyArg_UnpackTuple( args, "call_func", 3, 4, &func, &func_args, &func_kwargs, &func_locals ) ) + { + return 0; + } + + if( !PyFunction_Check( func ) ) + { + PyErr_SetString( PyExc_TypeError, "function must be a Python function" ); + return 0; + } + + if( !PyTuple_Check( func_args ) ) + { + PyErr_SetString( PyExc_TypeError, "arguments must be a tuple" ); + return 0; + } + + if( !PyDict_Check( func_kwargs ) ) + { + PyErr_SetString( PyExc_TypeError, "keywords must be a dict" ); + return 0; + } + + if( func_locals != Py_None && !PyMapping_Check( func_locals ) ) + { + PyErr_SetString( PyExc_TypeError, "locals must be a mapping" ); + return 0; + } + if( func_locals == Py_None ) + func_locals = 0; + + PyObject** defaults = 0; + Py_ssize_t num_defaults = 0; + PyObject* argdefs = PyFunction_GET_DEFAULTS( func ); + if( ( argdefs ) && PyTuple_Check( argdefs ) ) + { + defaults = &PyTuple_GET_ITEM( reinterpret_cast( argdefs ), 0 ); + num_defaults = PyTuple_Size( argdefs ); + } + + PyObject** keywords = 0; + Py_ssize_t num_keywords = PyDict_Size( func_kwargs ); + if( num_keywords > 0 ) + { + keywords = PyMem_NEW( PyObject*, 2 * num_keywords ); + if( !keywords ) + { + PyErr_NoMemory(); + return 0; + } + Py_ssize_t i = 0; + Py_ssize_t pos = 0; + while( PyDict_Next( func_kwargs, &pos, &keywords[ i ], &keywords[ i + 1 ] ) ) + i += 2; + num_keywords = i / 2; + /* XXX This is broken if the caller deletes dict items! */ + } + + PyObject* result = PyEval_EvalCodeEx( + reinterpret_cast( PyFunction_GET_CODE( func ) ), + PyFunction_GET_GLOBALS( func ), + func_locals, + &PyTuple_GET_ITEM( func_args, 0 ), + PyTuple_Size( func_args ), + keywords, num_keywords, defaults, num_defaults, + PyFunction_GET_CLOSURE( func ) + ); + + if( keywords ) + PyMem_DEL( keywords ); + + return result; + } + + +static PyMethodDef +funchelper_methods[] = { + { "call_func", ( PyCFunction )call_func, METH_VARARGS, + "call_func(func, args, kwargs[, locals])" }, + { 0 } // sentinel +}; + + +PyMODINIT_FUNC +initfunchelper( void ) +{ + PyObject* mod = Py_InitModule( "funchelper", funchelper_methods ); + if( !mod ) + return; +} \ No newline at end of file diff --git a/enaml/core/new_expressions.py b/enaml/core/new_expressions.py new file mode 100644 index 00000000..82a533af --- /dev/null +++ b/enaml/core/new_expressions.py @@ -0,0 +1,377 @@ +#------------------------------------------------------------------------------ +# Copyright (c) 2012, Enthought, Inc. +# All rights reserved. +#------------------------------------------------------------------------------ +from collections import namedtuple + +from traits.api import HasTraits, Disallow, TraitListObject, TraitDictObject + +from enaml.signaling import Signal + +from .abstract_expressions import AbstractExpression, AbstractListener +from .code_tracing import CodeTracer, CodeInverter +from .dynamic_scope import DynamicScope, AbstractScopeListener, Nonlocals +from .funchelper import call_func + + +#------------------------------------------------------------------------------ +# Traits Code Tracer +#------------------------------------------------------------------------------ +class TraitsTracer(CodeTracer): + """ A CodeTracer for tracing expressions using Traits. + + """ + def __init__(self, notifier): + """ Initialize a TraitsTracer. + + Parameters + ---------- + notifier : AbstractNotifier + The notifier to use as a handler for traits dependencies. + + """ + self._notifier = notifier + self._bound = set() + + #-------------------------------------------------------------------------- + # Private API + #-------------------------------------------------------------------------- + def _bind_trait(self, obj, name): + """ Bind the a handler for the named trait on the object. + + Parameters + ---------- + obj : HasTraits + The traits object owning the attribute. + + name : str + The trait name to for which to bind a handler. + + """ + trait = obj.trait(name) + if trait is not None and trait is not Disallow: + key = (obj, name) + bound = self._bound + if key not in bound: + obj.on_trait_change(self._notifier.notify, name) + bound.add(key) + + #-------------------------------------------------------------------------- + # AbstractScopeListener Interface + #-------------------------------------------------------------------------- + def dynamic_load(self, obj, attr): + """ Called when an object attribute is dynamically loaded. + + This will attach a listener to the object if it is a HasTraits + instance. See also: `AbstractScopeListener.dynamic_load`. + + """ + if isinstance(obj, HasTraits): + self._bind_trait(obj, attr) + + #-------------------------------------------------------------------------- + # CodeTracer Interface + #-------------------------------------------------------------------------- + def load_attr(self, obj, attr): + """ Called before the LOAD_ATTR opcode is executed. + + This will attach a listener to the object if it is a HasTraits + instance. See also: `CodeTracer.dynamic_load`. + + """ + if isinstance(obj, HasTraits): + self._bind_trait(obj, attr) + + def call_function(self, func, argtuple, argspec): + """ Called before the CALL_FUNCTION opcode is executed. + + This will attach a listener if the func is the builtin `getattr` + and the object is a HasTraits instance. + See also: `CodeTracer.call_function` + + """ + nargs = argspec & 0xFF + nkwargs = (argspec >> 8) & 0xFF + if (func is getattr and (nargs == 2 or nargs == 3) and nkwargs == 0): + obj, attr = argtuple[0], argtuple[1] + if isinstance(obj, HasTraits) and isinstance(attr, basestring): + self._bind_trait(obj, attr) + + def binary_subscr(self, obj, idx): + """ Called before the BINARY_SUBSCR opcode is executed. + + This will attach a trait if the object is a `TraitListObject` + or a `TraitDictObject`. See also: `CodeTracer.get_iter`. + + """ + if isinstance(obj, (TraitListObject, TraitDictObject)): + o = obj.object() + if o is not None: + if obj.name_items: + self._bind_trait(o, obj.name_items) + + def get_iter(self, obj): + """ Called before the GET_ITER opcode is executed. + + This will attach a trait if the object is a `TraitListObject`. + See also: `CodeTracer.get_iter`. + + """ + if isinstance(obj, TraitListObject): + o = obj.object() + if o is not None: + if obj.name_items: + self._bind_trait(o, obj.name_items) + + +AbstractScopeListener.register(TraitsTracer) + + +#------------------------------------------------------------------------------ +# Standard Code Inverter +#------------------------------------------------------------------------------ +class StandardInverter(CodeInverter): + """ The standard code inverter for Enaml expressions. + + """ + def __init__(self, nonlocals): + """ Initialize a StandardInverter. + + Parameters + ---------- + nonlocals : Nonlocals + The nonlocal scope for the executing expression. + + """ + self._nonlocals = nonlocals + + #-------------------------------------------------------------------------- + # CodeInverter Interface + #-------------------------------------------------------------------------- + def load_name(self, name, value): + """ Called before the LOAD_NAME opcode is executed. + + This method performs STORE_NAME by storing to the nonlocals. + See also: `CodeInverter.load_name`. + + """ + self._nonlocals[name] = value + + def load_attr(self, obj, attr, value): + """ Called before the LOAD_ATTR opcode is executed. + + This method performs STORE_ATTR via the builting `setattr`. + See also: `CodeInverter.load_attr`. + + """ + setattr(obj, attr, value) + + def call_function(self, func, argtuple, argspec, value): + """ Called before the CALL_FUNCTION opcode is executed. + + This method inverts a call to the builtin `getattr` into a call + to the builtin `setattr`, and allows the builtin `setattr` to + execute unmodified. All other calls will raise. + See also: `CodeInverter.call_function`. + + """ + nargs = argspec & 0xFF + nkwargs = (argspec >> 8) & 0xFF + if (func is getattr and (nargs == 2 or nargs == 3) and nkwargs == 0): + obj, attr = argtuple[0], argtuple[1] + setattr(obj, attr, value) + elif (func is setattr and nargs == 3 and nkwargs == 0): + obj, attr = argtuple[0], argtuple[1] + setattr(obj, attr, value) + else: + self.fail() + + def binary_subscr(self, obj, idx, value): + """ Called before the BINARY_SUBSCR opcode is executed. + + This method performs a STORE_SUBSCR operation through standard + setitem semantics. See also: `CodeInverter.binary_subscr`. + + """ + obj[idx] = value + + +#------------------------------------------------------------------------------ +# Notifier +#------------------------------------------------------------------------------ +class Notifier(object): + """ A simple object used to attach notification handlers. + + """ + __slots__ = ('_expr', '_name', '__weakref__') + + def __init__(self, expr, name): + """ Initialize a TraitNotifier. + + Parameters + ---------- + expr : AbstractExpression + The expression whose `invalidated` signal should be emitted + when the notifier is triggered. + + name : str + The name to which the expression is bound. + + """ + self._expr = expr + self._name = name + + def notify(self): + """ Notify that the expression is invalid. + + """ + self._expr.invalidated.emit(self._name) + +#------------------------------------------------------------------------------ +# Base Expression +#------------------------------------------------------------------------------ +class BaseExpression(object): + """ The base class of the standard Enaml expression classes. + + """ + __slots__ = ('_func', '_identifiers') + + def __init__(self, func, identifiers): + """ Initialize a BaseExpression. + + Parameters + ---------- + func : types.FunctionType + A function whose bytecode has been patch support dynamic + scoping but not tracing. + + identifiers : dict + The dictionary of identifiers available to the function. + + """ + self._func = func + self._identifiers = identifiers + + +#------------------------------------------------------------------------------ +# Simple Expression +#------------------------------------------------------------------------------ +class SimpleExpression(BaseExpression): + """ An implementation of AbstractExpression for the `=` operator. + + """ + __slots__ = () + + # SimpleExpression does not support invalidation. + invalidated = None + + #-------------------------------------------------------------------------- + # AbstractExpression Interface + #-------------------------------------------------------------------------- + def eval(self, obj, name): + """ Evaluate and return the expression value. + + """ + overrides = {'nonlocals': Nonlocals(obj, None)} + scope = DynamicScope(obj, self._identifiers, overrides, None) + with obj.operators: + return call_func(self._func, (), {}, scope) + + +AbstractExpression.register(SimpleExpression) + + +#------------------------------------------------------------------------------ +# Notification Expression +#------------------------------------------------------------------------------ +class NotificationExpression(BaseExpression): + """ An implementation of AbstractListener for the `::` operator. + + """ + __slots__ = () + + #: A namedtuple which is used to pass arguments to the expression. + event = namedtuple('event', 'obj name old new') + + #-------------------------------------------------------------------------- + # AbstractListener Interface + #-------------------------------------------------------------------------- + def value_changed(self, obj, name, old, new): + """ Called when the attribute on the object has changed. + + """ + overrides = { + 'event': self.event(obj, name, old, new), + 'nonlocals': Nonlocals(obj, None), + } + scope = DynamicScope(obj, self._identifiers, overrides, None) + with obj.operators: + call_func(self._func, (), {}, scope) + + +AbstractListener.register(NotificationExpression) + + +#------------------------------------------------------------------------------ +# Update Expression +#------------------------------------------------------------------------------ +class UpdateExpression(BaseExpression): + """ An implementation of AbstractListener for the `>>` operator. + + """ + __slots__ = () + + #-------------------------------------------------------------------------- + # AbstractListener Interface + #-------------------------------------------------------------------------- + def value_changed(self, obj, name, old, new): + """ Called when the attribute on the object has changed. + + """ + nonlocals = Nonlocals(obj, None) + inverter = StandardInverter(nonlocals) + overrides = {'nonlocals': nonlocals} + scope = DynamicScope(obj, self._identifiers, overrides, None) + with obj.operators: + call_func(self._func, (inverter, new), {}, scope) + + +AbstractListener.register(UpdateExpression) + + +#------------------------------------------------------------------------------ +# Subcsription Expression +#------------------------------------------------------------------------------ +class SubscriptionExpression(BaseExpression): + """ An implementation of AbstractExpression for the `<<` operator. + + """ + # Slots not declared because Signal requires a __dict__ + invalidated = Signal() + + # Internal storage for the notifier + _notifier = None + + #-------------------------------------------------------------------------- + # AbstractExpression Interface + #-------------------------------------------------------------------------- + def eval(self, obj, name): + """ Evaluate and return the expression value. + + """ + notifier = self._notifier + if notifier is not None: + notifier._expr = None # break the ref cycle + notifier = self._notifier = Notifier(self, name) + tracer = TraitsTracer(notifier) + overrides = {'nonlocals': Nonlocals(obj, None)} + scope = DynamicScope(obj, self._identifiers, overrides, None) + with obj.operators: + try: + return call_func(self._func, (tracer,), {}, scope) + except Exception, e: + print e + return '' + +AbstractExpression.register(SubscriptionExpression) + diff --git a/enaml/core/new_operators.py b/enaml/core/new_operators.py new file mode 100644 index 00000000..9462650f --- /dev/null +++ b/enaml/core/new_operators.py @@ -0,0 +1,87 @@ +#------------------------------------------------------------------------------ +# Copyright (c) 2012, Enthought, Inc. +# All rights reserved. +#------------------------------------------------------------------------------ +import types +from .code_tracing import transform_code +from .new_expressions import ( + SimpleExpression, NotificationExpression, SubscriptionExpression, + UpdateExpression, +) + + +_cached_code = {} + + +def op_simple(cmpnt, attr, code, identifiers, f_globals, operators): + """ The default Enaml operator for '=' expressions. It binds an + instance of SimpleExpression to the component. + + """ + if code in _cached_code: + func = _cached_code[code] + else: + c = transform_code(code, False) + func = _cached_code[code] = types.FunctionType(c, f_globals) + expr = SimpleExpression(func, identifiers) + cmpnt._bind_expression(attr, expr) + + +def op_notify(cmpnt, attr, code, identifiers, f_globals, operators): + """ The default Enaml operator for '::' expressions. It binds an + instance of NotificationExpression to the component. + + """ + if code in _cached_code: + func = _cached_code[code] + else: + c = transform_code(code, False) + func = _cached_code[code] = types.FunctionType(c, f_globals) + expr = NotificationExpression(func, identifiers) + cmpnt._bind_listener(attr, expr) + + +def op_update(cmpnt, attr, code, identifiers, f_globals, operators): + """ The default Enaml operator for '>>' expressions. It binds an + instance of UpdateExpression to the component. + + """ + return + + +def op_subscribe(cmpnt, attr, code, identifiers, f_globals, operators): + """ The default Enaml operator for '<<' expressions. It binds an + instance of SubscriptionExpression to the component using monitors + which understand traits attribute access via dotted notation and + the builtin getattr function. + + """ + if code in _cached_code: + func = _cached_code[code] + else: + c = transform_code(code, True) + func = _cached_code[code] = types.FunctionType(c, f_globals) + expr = SubscriptionExpression(func, identifiers) + cmpnt._bind_expression(attr, expr) + + +def op_delegate(cmpnt, attr, code, identifiers, f_globals, operators): + """ The default Enaml operator for ':=' expressions. It binds an + instance of DelegationExpression to the component using monitors + which understand traits attribute access via dotted notation and + the builtin getattr function, and inverters which understand the + dotted attribute access, implicit attribute access, and also the + builtin getattr function. + + """ + return + + +OPERATORS = { + '__operator_Equal__': op_simple, + '__operator_LessLess__': op_subscribe, + '__operator_ColonEqual__': op_delegate, + '__operator_ColonColon__': op_notify, + '__operator_GreaterGreater__': op_update, +} + diff --git a/enaml/core/nonlocals.py b/enaml/core/nonlocals.py new file mode 100644 index 00000000..2914aae7 --- /dev/null +++ b/enaml/core/nonlocals.py @@ -0,0 +1,148 @@ +#------------------------------------------------------------------------------ +# Copyright (c) 2012, Enthought, Inc. +# All rights reserved. +#------------------------------------------------------------------------------ +class Nonlocals(object): + """ An object which implements implicit attribute scoping starting + at a given object in the tree. It is used in conjuction with a + nonlocals() instance to allow for explicit referencing of values + which would otherwise be implicitly scoped. + + """ + def __init__(self, obj, attr_cb): + """ Initialize a nonlocal scope. + + Parameters + ---------- + obj : Declarative + The Declarative instance which forms the first level of + the scope. + + attr_cb : callable or None + A callable which is called when an implicit attribute is + found and accessed on the object. The arguments passed are + the object and the attribute name. + + """ + self._nls_obj = obj + self._nls_attr_cb = attr_cb + + def __repr__(self): + """ A pretty representation of the NonlocalScope. + + """ + templ = 'NonlocalScope[%s]' + return templ % self._nls_obj + + def __call__(self, level=0): + """ Returns a new nonlocal scope object offset the given number + of levels in the hierarchy. + + Parameters + ---------- + level : int, optional + The number of levels up the tree to offset. The default is + zero and indicates no offset. The level must be >= 0. + + """ + if not isinstance(level, int) or level < 0: + msg = ('The nonlocal scope level must be an int >= 0. ' + 'Got %r instead.') + raise ValueError(msg % level) + + offset = 0 + target = self._nls_obj + while target is not None and offset != level: + target = target.parent + offset += 1 + + if offset != level: + msg = 'Scope level %s is out of range' + raise ValueError(msg % level) + + return NonlocalScope(target, self._nls_attr_cb) + + def __getattr__(self, name): + """ A convenience method which allows accessing items in the + scope via getattr instead of getitem. + + """ + try: + return self.__getitem__(name) + except KeyError: + msg = "%s has no attribute '%s'" % (self, name) + raise AttributeError(msg) + + def __setattr__(self, name, value): + """ A convenience method which allows setting items in the + scope via setattr instead of setitem. + + """ + if name in ('_nls_obj', '_nls_attr_cb'): + super(NonlocalScope, self).__setattr__(name, value) + else: + try: + self.__setitem__(name, value) + except KeyError: + msg = "%s has no attribute '%s'" % (self, name) + raise AttributeError(msg) + + def __getitem__(self, name): + """ Returns the named item beginning at the current scope object + and progressing up the tree until the named attribute is found. + A KeyError is raised if the attribute is not found. + + """ + parent = self._nls_obj + while parent is not None: + try: + res = getattr(parent, name) + except AttributeError: + parent = parent.parent + else: + cb = self._nls_attr_cb + if cb is not None: + cb(parent, name) + return res + raise KeyError(name) + + def __setitem__(self, name, value): + """ Sets the value of the scope by beginning at the current scope + object and progressing up the tree until the named attribute is + found. A KeyError is raise in the attribute is not found. + + """ + parent = self._nls_obj + while parent is not None: + # It's not sufficient to try to do setattr(...) here and + # catch the AttributeError, because HasStrictTraits raises + # a TraitError in these cases and it becomes impossible + # to distinguish that error from a trait typing error + # without checking the message of the exception. + try: + getattr(parent, name) + except UninitializedAttributeError: + pass + except AttributeError: + parent = parent.parent + continue + setattr(parent, name, value) + return + raise KeyError(name) + + def __contains__(self, name): + """ Return True if the name is found in the scope, False + otherwise. + + """ + with swap_attribute(self, '_nls_attr_cb', None): + if isinstance(name, basestring): + try: + self.__getitem__(name) + except KeyError: + res = False + else: + res = True + else: + res = False + return res diff --git a/enaml/core/trait_types.py b/enaml/core/trait_types.py index 091ede30..7bc5a038 100644 --- a/enaml/core/trait_types.py +++ b/enaml/core/trait_types.py @@ -58,8 +58,8 @@ def __init__(self, base_type=object): self.base_type = base_type def validate(self, obj, name, value): - """ The validation handler for an EnamlInstace. It performs a - simple isinstance(...) check using the attribute type provided + """ The validation handler for an EnamlInstace. It performs a + simple isinstance(...) check using the attribute type provided to the constructor. """ @@ -82,7 +82,7 @@ class EnamlEventDispatcher(object): """ A thin object which is used to dispatch a notification for an EnamlEvent. Instances of this class are callable with at most one argument, which will be the payload of the event. Instances of this - dispatcher should not be held onto, since they maintain a strong + dispatcher should not be held onto, since they maintain a strong reference to the underlying object. """ @@ -94,28 +94,28 @@ def __init__(self, trait, obj, name): trait : Instance(TraitType) The trait type instance on which validate will be called with the event payload. - + obj : Instance(HasTraits) The HasTraits object on which the event is being emitted. - + name : string The name of the event being emitted. - + """ self._trait = trait self._obj = obj self._name = name - + def __call__(self, payload=None): """ Dispatches the event with the given payload. Paramters --------- payload : object, optional - The payload argument of the event. This object will be + The payload argument of the event. This object will be validated against the type declared for the event. The default payload is None. - + """ obj = self._obj name = self._name @@ -159,7 +159,7 @@ class ExpressionInitializationError(Exception): of an expression. """ - # XXX - We can't inherit from AttributeError because the local + # XXX - We can't inherit from AttributeError because the local # scope object used by expressions captures an AttributeError # and converts it into in a KeyError in order to implement # dynamic attribute scoping. We actually want this exception @@ -168,7 +168,7 @@ class ExpressionInitializationError(Exception): class ExpressionTrait(TraitType): - """ A custom trait type which is used to help implement expression + """ A custom trait type which is used to help implement expression binding. Instances of this trait are added to an object, but swap themselves out and replace the old trait the first time they are accessed. This allows bound expressions to be initialized in the @@ -182,14 +182,14 @@ def __init__(self, old_trait): ---------- old_trait : ctrait The trait object that the expression trait is temporarily - replacing. When a 'get' or 'set' is triggered on this + replacing. When a 'get' or 'set' is triggered on this trait, the old trait will be restored and then the default value of the expression will be applied. - + """ super(ExpressionTrait, self).__init__() self.old_trait = old_trait - + def swapout(self, obj, name): """ Restore the old trait onto the object. This method takes care to make sure that listeners are copied over properly. @@ -221,7 +221,7 @@ def compute_default(self, obj, name): expr = obj._expressions[name][0] if expr is not None: try: - res = expr.eval() + res = expr.eval(obj, name) except Exception as e: # Reraise a propagating initialization error. if isinstance(e, ExpressionInitializationError): @@ -230,16 +230,16 @@ def compute_default(self, obj, name): 'Orignal exception was:\n%s') import traceback tb = traceback.format_exc() - filename = expr.code.co_filename - lineno = expr.code.co_firstlineno + filename = expr._func.func_code.co_filename + lineno = expr._func.func_code.co_firstlineno args = (filename, lineno, tb) raise ExpressionInitializationError(msg % args) return res def get(self, obj, name): - """ Handle computing the initial value for the expression trait. - This method first restores the old trait, then evaluates the - expression and sets the value on the trait quietly. It then + """ Handle computing the initial value for the expression trait. + This method first restores the old trait, then evaluates the + expression and sets the value on the trait quietly. It then performs a getattr to return the new value of the trait. """ @@ -264,11 +264,11 @@ def set(self, obj, name, val): # User Attribute and Event #------------------------------------------------------------------------------ class UninitializedAttributeError(Exception): - """ A custom Exception used by UserAttribute to signal the access + """ A custom Exception used by UserAttribute to signal the access of an uninitialized attribute. """ - # XXX - We can't inherit from AttributeError because the local + # XXX - We can't inherit from AttributeError because the local # scope object used by expressions captures an AttributeError # and converts it into in a KeyError in order to implement # dynamic attribute scoping. We actually want this exception @@ -277,8 +277,8 @@ class UninitializedAttributeError(Exception): class UserAttribute(EnamlInstance): - """ An EnamlInstance subclass that is used to implement optional - attribute typing when adding a new user attribute to an Enaml + """ An EnamlInstance subclass that is used to implement optional + attribute typing when adding a new user attribute to an Enaml component. """ @@ -293,7 +293,7 @@ def get(self, obj, name): return dct[name] def set(self, obj, name, value): - """ The trait setter method. Sets the value in the object's + """ The trait setter method. Sets the value in the object's dict if it is valid, and emits a change notification if the value has changed. The first time the value is set the change notification will carry None as the old value. @@ -374,7 +374,7 @@ def __init__(self, value=None, low=None, high=None, **metadata): if isinstance(value, basestring): self.default_value_type = 8 self.default_value = self._get_default_value - + def _get_default_value(self, obj): """ Handles computing the default value for the Bounded trait. @@ -405,7 +405,7 @@ def validate_bounds(self, obj, name, value): low = value if high is None: high = value - + is_inside_bounds = False try: is_inside_bounds = (low <= value <= high) @@ -416,7 +416,7 @@ def validate_bounds(self, obj, name, value): msg = ('Bound checking of {0} caused a the following Python ' 'Exception: {1}'.format(value, raised_exception)) raise TraitError(msg) - + if not is_inside_bounds: msg = ('The assigned value must be bounded between {0} ' ' and {1}. Got {2} instead.'.format(low, high, value)) @@ -431,7 +431,7 @@ def get_bounds(self, obj): low = self._low if isinstance(low, basestring): low = reduce(getattr, low.split('.'), obj) - + high = self._high if isinstance(high, basestring): high = reduce(getattr, high.split('.'), obj) @@ -457,13 +457,13 @@ def __init__(self, trait=None, depends_on=''): ---------- trait : TraitType, optional An optional trait type for the values returned by the - property. List is required if using extending trait + property. List is required if using extending trait name syntax for e.g. list listeners. - + depends_on : string, optional The traits notification string for the dependencies of the filter. - + """ super(LazyProperty, self).__init__() self.dependency = depends_on @@ -472,7 +472,7 @@ def __init__(self, trait=None, depends_on=''): self.default_value_type = trait.default_value_type def get(self, obj, name): - """ Returns the (possibly cached) value of the filter. The + """ Returns the (possibly cached) value of the filter. The notification handlers will be attached the first time the value is accessed. @@ -487,7 +487,7 @@ def get(self, obj, name): else: val = dct[cache_name] return val - + def bind(self, obj, name): """ Binds the dependency notification handlers for the object. @@ -512,7 +512,7 @@ def notify(): # Coercing Instance #------------------------------------------------------------------------------ class CoercingInstance(BaseInstance): - """ A BaseInstance subclass which attempts to coerce a value by + """ A BaseInstance subclass which attempts to coerce a value by calling the class constructor and passing the new value into the original validate method. diff --git a/setup.py b/setup.py index 5eb017d1..4877c789 100644 --- a/setup.py +++ b/setup.py @@ -28,6 +28,15 @@ ext_modules = [] +ext_modules.append( + Extension( + 'enaml.core.funchelper', + ['enaml/core/funchelper.cpp'], + language='c++', + ) +) + + setup( name='enaml', version='0.5.0', From bc4acd0b1c9b485896488e5538629df1602cec85 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 11:10:53 -0500 Subject: [PATCH 03/34] Shuffle some code around for better locality. --- enaml/core/declarative.py | 295 ++++++++++++++++++++++++++++++------ enaml/core/dynamic_scope.py | 29 +++- enaml/core/trait_types.py | 252 +----------------------------- 3 files changed, 274 insertions(+), 302 deletions(-) diff --git a/enaml/core/declarative.py b/enaml/core/declarative.py index bb03831a..234a5e30 100644 --- a/enaml/core/declarative.py +++ b/enaml/core/declarative.py @@ -2,19 +2,166 @@ # Copyright (c) 2012, Enthought, Inc. # All rights reserved. #------------------------------------------------------------------------------ -from traits.api import Instance, List, Property, Str, Dict, Disallow, ReadOnly +from traits.api import ( + Instance, List, Property, Str, Dict, Disallow, ReadOnly, TraitType, +) from .abstract_expressions import AbstractExpression, AbstractListener +from .dynamic_scope import DynamicAttributeError from .object import Object from .operator_context import OperatorContext -from .trait_types import ExpressionTrait, UserAttribute, UserEvent +from .trait_types import EnamlInstance, EnamlEvent -#: The traits types on an Declarative instance which can be overridden -#: by the user in an enamldef declaration. -_OVERRIDE_ALLOWED = (UserAttribute, UserEvent) +#------------------------------------------------------------------------------ +# Expression Trait +#------------------------------------------------------------------------------ +class ExpressionTrait(TraitType): + """ A custom trait type which is used to help implement expression + binding. Instances of this trait are added to an object, but swap + themselves out and replace the old trait the first time they are + accessed. This allows bound expressions to be initialized in the + proper order without requiring an explicit initialization graph. + + """ + def __init__(self, old_trait): + """ Initialize an expression trait. + + Parameters + ---------- + old_trait : ctrait + The trait object that the expression trait is temporarily + replacing. When a 'get' or 'set' is triggered on this + trait, the old trait will be restored and then the default + value of the expression will be applied. + + """ + super(ExpressionTrait, self).__init__() + self.old_trait = old_trait + + def swapout(self, obj, name): + """ Restore the old trait onto the object. This method takes + care to make sure that listeners are copied over properly. + """ + # The default behavior of add_trait does *almost* the right + # thing when it copies over notifiers when replacing the + # existing trait. What it fails to do is update the owner + # attribute of TraitChangeNotifyWrappers which are managing + # a bound method notifier. This means that if said notifier + # ever dies, it removes itself from the incorrect owner list + # and it will be (erroneously) called on the next dispatch + # cycle. The logic here makes sure that the owner attribute + # of such a notifier is properly updated with its new owner. + obj.add_trait(name, self.old_trait) + notifiers = obj.trait(name)._notifiers(0) + if notifiers is not None: + for notifier in notifiers: + if hasattr(notifier, 'owner'): + notifier.owner = notifiers + + def compute_default(self, obj, name): + """ Returns the default value as computed by the most recently + bound expression. If a value cannot be provided, NotImplemented + is returned. + + """ + try: + res = obj.eval_expression(name) + except DynamicAttributeError: + raise # Reraise a propagating initialization error. + except Exception: + # XXX hack! I'd rather not dig into Declarative's private api. + import traceback + expr = obj._expressions[name] + filename = expr._func.func_code.co_filename + lineno = expr._func.func_code.co_firstlineno + args = (filename, lineno, traceback.format_exc()) + msg = ('Error initializing expression (%r line %s). Orignal ' + 'exception was:\n%s') + raise DynamicAttributeError(msg % args) + return res + + def get(self, obj, name): + """ Handle computing the initial value for the expression trait. + This method first restores the old trait, then evaluates the + expression and sets the value on the trait quietly. It then + performs a getattr to return the new value of the trait. + + """ + self.swapout(obj, name) + val = self.compute_default(obj, name) + if val is not NotImplemented: + obj.trait_setq(**{name: val}) + return getattr(obj, name, val) + + def set(self, obj, name, val): + """ Handle the setting of an initial value for the expression + trait. This method first restores the old trait, then sets + the value on that trait. In this case, the expression object + is not needed. + + """ + self.swapout(obj, name) + setattr(obj, name, val) + +#------------------------------------------------------------------------------ +# User Attribute and User Event +#------------------------------------------------------------------------------ +class UserAttribute(EnamlInstance): + """ An EnamlInstance subclass that is used to implement optional + attribute typing when adding a new user attribute to an Enaml + component. + + """ + def get(self, obj, name): + """ The trait getter method. Returns the value from the object's + dict, or raises an uninitialized error if the value doesn't exist. + + """ + dct = obj.__dict__ + if name not in dct: + self.uninitialized_error(obj, name) + return dct[name] + + def set(self, obj, name, value): + """ The trait setter method. Sets the value in the object's + dict if it is valid, and emits a change notification if the + value has changed. The first time the value is set the change + notification will carry None as the old value. + + """ + value = self.validate(obj, name, value) + dct = obj.__dict__ + if name not in dct: + old = None + else: + old = dct[name] + dct[name] = value + if old != value: + obj.trait_property_changed(name, old, value) + + def uninitialized_error(self, obj, name): + """ A method which raises a DynamicAttributeError for the given + object and attribute name. + + """ + msg = "Cannot access the uninitialized '%s' attribute of the %s object" + raise DynamicAttributeError(msg % (name, obj)) + + +class UserEvent(EnamlEvent): + """ A simple EnamlEvent subclass used to distinguish between events + declared by the framework, and events declared by the user. + + """ + pass + + +#------------------------------------------------------------------------------ +# Declarative +#------------------------------------------------------------------------------ class Declarative(Object): """ The most base class of the Enaml declarative objects. @@ -29,15 +176,21 @@ class Declarative(Object): #: 'self' according to Enaml's dynamic scoping rules. self = Property(fget=lambda self: self) - #: The operator context used to build out this instance. + #: The operator context used to build out this instance. This is + #: assigned during object instantiation. It should not be edited + #: by user code. operators = ReadOnly #: The private dictionary of expression objects that are bound to #: attributes on this component. It should not be manipulated by #: user code. Rather, expressions should be bound by the operators #: by calling the '_bind_expression' method. - _expressions = Dict(Str, List(Instance(AbstractExpression))) + _expressions = Dict(Str, Instance(AbstractExpression)) + #: The private dictionary of listener objects that are bound to + #: attributes on this component. It should not be manipulated by + #: user code. Rather, expressions should be bound by the operators + #: by calling the '_bind_listener' method. _listeners = Dict(Str, List(Instance(AbstractListener))) #: A class attribute used by the Enaml compiler machinery to store @@ -63,7 +216,7 @@ def __init__(self, parent=None, **kwargs): super(Declarative, self).__init__(parent) # If any builders are present, they need to be invoked before # applying any other keyword arguments so that bound expressions - # do not override the keywords. The builders appear and are run + # do not override the keywords. The builders in the list exist # in the reverse order of a typical mro. The most base builder # gets to add its children and bind its expressions first. # Builders that come later can then override these bindings. @@ -109,7 +262,7 @@ def _add_user_attribute(cls, name, attr_type, is_event): base_traits = cls.__base_traits__ if name in base_traits: ttype = base_traits[name].trait_type - if not isinstance(ttype, _OVERRIDE_ALLOWED): + if not isinstance(ttype, (UserAttribute, UserEvent)): msg = ("can't add '%s' attribute. The '%s' attribute on " "enamldef '%s.%s' already exists.") items = (name, name, cls.__module__, cls.__name__) @@ -154,71 +307,113 @@ def _bind_expression(self, name, expression): expression : AbstractExpression A concrete implementation of AbstractExpression. - notify_only : bool, optional - If True, the expression is only a notifier, in which case - multiple binding is allowed, otherwise the new expression - overrides any old non-notify expression. Defaults to False. - """ curr = self.trait(name) if curr is None or curr.trait_type is Disallow: msg = "Cannot bind expression. %s object has no attribute '%s'" raise AttributeError(msg % (self, name)) - expressions = self._expressions - handler = self._on_expression_changed - if name in expressions: - old = expressions[name][0] + exprs = self._expressions + handler = self._on_expr_invalidated + if name in exprs: + old = exprs[name] if old.invalidated is not None: old.invalidated.disconnect(handler) else: - # Hookup support for default value computation. We only need - # to add an ExpressionTrait once, since it will reach back - # into the _expressions dict as needed and retrieve the most - # current bound expression. + # Add support for default value computation. ExpressionTrait + # must only be added once; it will call `eval_expression` + # as needed and retrieve the most current expression value. if not isinstance(curr.trait_type, ExpressionTrait): self.add_trait(name, ExpressionTrait(curr)) if expression.invalidated is not None: expression.invalidated.connect(handler) - expressions[name] = [expression] + exprs[name] = expression def _bind_listener(self, name, listener): + """ A private method used by the Enaml execution engine. + + This method is called by the Enaml operators to bind the given + listener object to the given attribute name. If the attribute + does not exist, an exception is raised. A strong reference to + the listener object is kept internally. + + Parameters + ---------- + name : string + The name of the attribute on which to bind the listener. + + listener : AbstractListener + A concrete implementation of AbstractListener. + + """ curr = self.trait(name) if curr is None or curr.trait_type is Disallow: - msg = "Cannot bind expression. %s object has no attribute '%s'" + msg = "Cannot bind listener. %s object has no attribute '%s'" raise AttributeError(msg % (self, name)) - listeners = self._listeners - if name not in listeners: - self.on_trait_change(self._on_bound_attr_changed, name) - listeners[name] = [] - listeners[name].append(listener) - - def _on_expression_changed(self, name): - expressions = self._expressions - if name in expressions: - expr = expressions[name][0] - setattr(self, name, expr.eval(self, name)) - - def _on_bound_attr_changed(self, obj, name, old, new): - """ A private handler which is called when any attribute which - has a bound signal changes. It calls the notify method on each - of the expressions bound to that attribute, but if the component - is marked as live. - - """ - # The check for None is for the case where there are no left - # associative expressions bound to the attribute, so the first - # entry in the list is still None. - for expr in self._listeners[name]: - #expr.notify(old, new) - expr.value_changed(self, name, old, new) + lsnrs = self._listeners + if name not in lsnrs: + lsnrs[name] = [] + lsnrs[name].append(listener) + + def _on_expr_invalidated(self, name): + """ A signal handler invoked when an expression is invalidated. + + This handler is connected to the `invalidated` signal on bound + expressions which support dynamic notification. When a given + expression is invalidated, it is recomputed and the value of + its attribute is updated. + + Parameters + ---------- + name : str + The attribute name to which the invalid expression is bound. + + """ + value = self.eval_expression(name) + if value is not NotImplemented: + setattr(self, name, value) + + def _anytrait_changed(self, name, old, new): + """ An any trait changed handler for listener notification. + + This handler will notify any bound listeners when their attribute + of interest has changed. Using an `anytrait` handler reduces the + number of notifier objects which must be created. + + """ + lsnrs = self._listeners + if name in lsnrs: + for listener in lsnrs[name]: + listener.value_changed(self, name, old, new) #-------------------------------------------------------------------------- # Public API #-------------------------------------------------------------------------- + def eval_expression(self, name): + """ Evaluate a bound expression with the given name. + + This will not update the value of the bound attribute. + + Parameters + ---------- + name : str + The name of the attribute to which the expression is bound. + + Returns + ------- + result : object or NotImplemented + The results of the expression, or NotImplemented if there + is no expression bound to the given name. + + """ + exprs = self._expressions + if name in exprs: + return exprs[name].eval(self, name) + return NotImplemented + def destroy(self): - """ A reimplement parent class destructor method. + """ A reimplemented parent class destructor method. This method clears the dictionary of bound expression objects before proceeding with the standard destruction. diff --git a/enaml/core/dynamic_scope.py b/enaml/core/dynamic_scope.py index ce524070..813a5333 100644 --- a/enaml/core/dynamic_scope.py +++ b/enaml/core/dynamic_scope.py @@ -3,9 +3,11 @@ # All rights reserved. #------------------------------------------------------------------------------ from abc import ABCMeta, abstractmethod -from .trait_types import UninitializedAttributeError +#------------------------------------------------------------------------------ +# Abstract Scope Listener +#------------------------------------------------------------------------------ class AbstractScopeListener(object): """ An abstract interface definition for scope listeners. @@ -34,6 +36,20 @@ def dynamic_load(self, obj, name, value): raise NotImplementedError +#------------------------------------------------------------------------------ +# Dynamic Scope +#------------------------------------------------------------------------------ +class DynamicAttributeError(AttributeError): + """ A custom Attribute error for use with dynamic scoping. + + DynamicScope operates by catching AttributeError and converting it + into a key error. This DynamicAttributeError can be raised by user + code in order to escape the trapping and bubble up. + + """ + pass + + class DynamicScope(object): """ A custom mapping object that implements Enaml's dynamic scope. @@ -97,6 +113,8 @@ def __getitem__(self, name): while parent is not None: try: value = getattr(parent, name) + except DynamicAttributeError: + raise except AttributeError: parent = parent.parent else: @@ -122,6 +140,9 @@ def __contains__(self, name): return res +#------------------------------------------------------------------------------ +# Nonlocals +#------------------------------------------------------------------------------ class Nonlocals(object): """ An object which implements userland dynamic scoping. @@ -218,6 +239,8 @@ def __getitem__(self, name): while parent is not None: try: value = getattr(parent, name) + except DynamicAttributeError: + raise except AttributeError: parent = parent.parent else: @@ -253,8 +276,8 @@ def __setitem__(self, name, value): # without checking the message of the exception. try: getattr(parent, name) - except UninitializedAttributeError: - pass + except DynamicAttributeError: + pass # ignore uninitialized attribute errors except AttributeError: parent = parent.parent continue diff --git a/enaml/core/trait_types.py b/enaml/core/trait_types.py index 7bc5a038..c0bb1c56 100644 --- a/enaml/core/trait_types.py +++ b/enaml/core/trait_types.py @@ -2,10 +2,8 @@ # Copyright (c) 2011, Enthought, Inc. # All rights reserved. #------------------------------------------------------------------------------ -from weakref import WeakKeyDictionary, ref - from traits.api import TraitType, TraitError, BaseInstance -from traits.traits import CTrait, trait_from +from traits.traits import CTrait #------------------------------------------------------------------------------ @@ -14,7 +12,7 @@ class EnamlInstance(TraitType): """ A custom TraitType which serves as a simple isinstance(...) validator. This class serves as the base class for other custom - trait types such as EnamlEvent and UserAttribute. + trait types such as EnamlEvent. """ @staticmethod @@ -39,7 +37,7 @@ def is_valid_type(obj): return isinstance(obj, type) or hasattr(obj, '__instancecheck__') def __init__(self, base_type=object): - """ Initialize a UserAttribute instance. + """ Initialize an EnamlInstance. Parameters ---------- @@ -151,181 +149,6 @@ def full_info(self, obj, name, value): return 'emitted with an object of %s' % self.base_type -#------------------------------------------------------------------------------ -# Expression Trait -#------------------------------------------------------------------------------ -class ExpressionInitializationError(Exception): - """ An exception used to indicate an error during initialization - of an expression. - - """ - # XXX - We can't inherit from AttributeError because the local - # scope object used by expressions captures an AttributeError - # and converts it into in a KeyError in order to implement - # dynamic attribute scoping. We actually want this exception - # to propagate. - pass - - -class ExpressionTrait(TraitType): - """ A custom trait type which is used to help implement expression - binding. Instances of this trait are added to an object, but swap - themselves out and replace the old trait the first time they are - accessed. This allows bound expressions to be initialized in the - proper order without requiring an explicit initialization graph. - - """ - def __init__(self, old_trait): - """ Initialize an expression trait. - - Parameters - ---------- - old_trait : ctrait - The trait object that the expression trait is temporarily - replacing. When a 'get' or 'set' is triggered on this - trait, the old trait will be restored and then the default - value of the expression will be applied. - - """ - super(ExpressionTrait, self).__init__() - self.old_trait = old_trait - - def swapout(self, obj, name): - """ Restore the old trait onto the object. This method takes - care to make sure that listeners are copied over properly. - - """ - # The default behavior of add_trait does *almost* the right - # thing when it copies over notifiers when replacing the - # existing trait. What it fails to do is update the owner - # attribute of TraitChangeNotifyWrappers which are managing - # a bound method notifier. This means that if said notifier - # ever dies, it removes itself from the incorrect owner list - # and it will be (erroneously) called on the next dispatch - # cycle. The logic here makes sure that the owner attribute - # of such a notifier is properly updated with its new owner. - obj.add_trait(name, self.old_trait) - notifiers = obj.trait(name)._notifiers(0) - if notifiers is not None: - for notifier in notifiers: - if hasattr(notifier, 'owner'): - notifier.owner = notifiers - - def compute_default(self, obj, name): - """ Returns the default value as computed by the most recently - bound expression. If a value cannot be provided, NotImplemented - is returned. - - """ - res = NotImplemented - expr = obj._expressions[name][0] - if expr is not None: - try: - res = expr.eval(obj, name) - except Exception as e: - # Reraise a propagating initialization error. - if isinstance(e, ExpressionInitializationError): - raise - msg = ('Error initializing expression (%r line %s). ' - 'Orignal exception was:\n%s') - import traceback - tb = traceback.format_exc() - filename = expr._func.func_code.co_filename - lineno = expr._func.func_code.co_firstlineno - args = (filename, lineno, tb) - raise ExpressionInitializationError(msg % args) - return res - - def get(self, obj, name): - """ Handle computing the initial value for the expression trait. - This method first restores the old trait, then evaluates the - expression and sets the value on the trait quietly. It then - performs a getattr to return the new value of the trait. - - """ - self.swapout(obj, name) - val = self.compute_default(obj, name) - if val is not NotImplemented: - obj.trait_setq(**{name: val}) - return getattr(obj, name, val) - - def set(self, obj, name, val): - """ Handle the setting of an initial value for the expression - trait. This method first restores the old trait, then sets - the value on that trait. In this case, the expression object - is not needed. - - """ - self.swapout(obj, name) - setattr(obj, name, val) - - -#------------------------------------------------------------------------------ -# User Attribute and Event -#------------------------------------------------------------------------------ -class UninitializedAttributeError(Exception): - """ A custom Exception used by UserAttribute to signal the access - of an uninitialized attribute. - - """ - # XXX - We can't inherit from AttributeError because the local - # scope object used by expressions captures an AttributeError - # and converts it into in a KeyError in order to implement - # dynamic attribute scoping. We actually want this exception - # to propagate. - pass - - -class UserAttribute(EnamlInstance): - """ An EnamlInstance subclass that is used to implement optional - attribute typing when adding a new user attribute to an Enaml - component. - - """ - def get(self, obj, name): - """ The trait getter method. Returns the value from the object's - dict, or raises an uninitialized error if the value doesn't exist. - - """ - dct = obj.__dict__ - if name not in dct: - self.uninitialized_error(obj, name) - return dct[name] - - def set(self, obj, name, value): - """ The trait setter method. Sets the value in the object's - dict if it is valid, and emits a change notification if the - value has changed. The first time the value is set the change - notification will carry None as the old value. - - """ - value = self.validate(obj, name, value) - dct = obj.__dict__ - if name not in dct: - old = None - else: - old = dct[name] - dct[name] = value - if old != value: - obj.trait_property_changed(name, old, value) - - def uninitialized_error(self, obj, name): - """ A method which raises an UninitializedAttributeError for - the given object and attribute name - - """ - msg = "Cannot access the uninitialized '%s' attribute of the %s object" - raise UninitializedAttributeError(msg % (name, obj)) - - -class UserEvent(EnamlEvent): - """ A simple EnamlEvent subclass used to distinguish between events - declared by the framework, and events declared by the user. - - """ - pass - - #------------------------------------------------------------------------------ # Bounded #------------------------------------------------------------------------------ @@ -439,75 +262,6 @@ def get_bounds(self, obj): return (low, high) -#------------------------------------------------------------------------------ -# Lazy Property -#------------------------------------------------------------------------------ -class LazyProperty(TraitType): - """ A trait which behaves like a read-only cached property, but - which lazily defers binding the dependency notifiers until the - first time the value is retrieved. It is used to avoid situations - where a property dependency is prematurely evaluated during - component instantiation. - - """ - def __init__(self, trait=None, depends_on=''): - """ Initialize a LazyProperty. - - Parameters - ---------- - trait : TraitType, optional - An optional trait type for the values returned by the - property. List is required if using extending trait - name syntax for e.g. list listeners. - - depends_on : string, optional - The traits notification string for the dependencies of - the filter. - - """ - super(LazyProperty, self).__init__() - self.dependency = depends_on - self.handlers = WeakKeyDictionary() - if trait is not None: - self.default_value_type = trait.default_value_type - - def get(self, obj, name): - """ Returns the (possibly cached) value of the filter. The - notification handlers will be attached the first time the - value is accessed. - - """ - cache_name = '_%s_lazy_property_cache' % name - dct = obj.__dict__ - if cache_name not in dct: - method_name = '_get_%s' % name - val = getattr(obj, method_name)() - dct[cache_name] = val - self.bind(obj, name) - else: - val = dct[cache_name] - return val - - def bind(self, obj, name): - """ Binds the dependency notification handlers for the object. - - """ - wr_obj = ref(obj) - def notify(): - obj = wr_obj() - if obj is not None: - cache_name = '_%s_lazy_property_cache' % name - old = obj.__dict__.pop(cache_name, None) - obj.trait_property_changed(name, old) - - handlers = self.handlers - dependency = self.dependency - if obj in handlers: - obj.on_trait_change(handlers[obj], dependency, remove=True) - handlers[obj] = notify - obj.on_trait_change(notify, dependency) - - #------------------------------------------------------------------------------ # Coercing Instance #------------------------------------------------------------------------------ From da73011230fefdb3fdefd8176cb92fec6e392837 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 12:04:32 -0500 Subject: [PATCH 04/34] Move cpp funchelper to /extensions; add a ctypes version to /core --- enaml/core/funchelper.py | 100 ++++++++++++++++++++++ enaml/{core => extensions}/funchelper.cpp | 7 +- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 enaml/core/funchelper.py rename enaml/{core => extensions}/funchelper.cpp (92%) diff --git a/enaml/core/funchelper.py b/enaml/core/funchelper.py new file mode 100644 index 00000000..d67d6638 --- /dev/null +++ b/enaml/core/funchelper.py @@ -0,0 +1,100 @@ +#------------------------------------------------------------------------------ +# Copyright (c) 2012, Enthought, Inc. +# All rights reserved. +#------------------------------------------------------------------------------ +from ctypes import pythonapi, py_object, POINTER, c_int, byref +from types import FunctionType + + +PyEval_EvalCodeEx = pythonapi.PyEval_EvalCodeEx +PyEval_EvalCodeEx.restype = py_object +PyEval_EvalCodeEx.argtypes = [ + py_object, # code object + py_object, # globals dict + py_object, # locals mapping + POINTER(py_object), # args array + c_int, # num args + POINTER(py_object), # keywords array + c_int, # num keywords + POINTER(py_object), # defaults array + c_int, # num defaults + py_object, # closure +] + + +def call_func(func, args, kwargs, f_locals=None): + """ Call a function which has been modified by the Enaml compiler + to support tracing and dynamic scoping. + + Parameters + ---------- + func : types.FunctionType + The Python function to call. + + args : tuple + The tuple of arguments to pass to the function. + + kwargs : dict + The dictionary of keywords to pass to the function. + + f_locals : mapping, optional + An optional locals mapping to use with the function. + + Returns + ------- + result : object + The result of calling the function. + + """ + if not isinstance(func, FunctionType): + raise TypeError('function must be a Python function') + + if not isinstance(args, tuple): + raise TypeError('arguments must be a tuple') + + if not isinstance(kwargs, dict): + raise TypeError('keywords must be a dict') + + if f_locals is not None and not hasattr(f_locals, '__getitem__'): + raise TypeError('locals must be a mapping') + + defaults = func.func_defaults + num_defaults = len(defaults) if defaults else 0 + + if kwargs: + keywords = [] + for key, value in kwargs.iteritems: + keywords.append(key) + keywords.append(value) + keywords = tuple(keywords) + num_keywords = len(keywords) / 2 + else: + keywords = None + num_keywords = 0 + + args_ptr = byref(py_object(args[0])) if args else None + defaults_ptr = byref(py_object(defaults[0])) if defaults else None + keywords_ptr = byref(py_object(keywords[0])) if keywords else None + + result = PyEval_EvalCodeEx( + func.func_code, + func.func_globals, + f_locals, + args_ptr, + len(args), + keywords_ptr, + num_keywords, + defaults_ptr, + num_defaults, + func.func_closure + ) + + return result + + +# Use the faster version of `call_func` if it's available. +try: + from enaml.extensions.funchelper import call_func +except ImportError: + pass + diff --git a/enaml/core/funchelper.cpp b/enaml/extensions/funchelper.cpp similarity index 92% rename from enaml/core/funchelper.cpp rename to enaml/extensions/funchelper.cpp index b25ea26b..fd7340e3 100644 --- a/enaml/core/funchelper.cpp +++ b/enaml/extensions/funchelper.cpp @@ -1,3 +1,7 @@ +/*----------------------------------------------------------------------------- +| Copyright (c) 2012, Enthought, Inc. +| All rights reserved. +|----------------------------------------------------------------------------*/ #include @@ -107,4 +111,5 @@ initfunchelper( void ) PyObject* mod = Py_InitModule( "funchelper", funchelper_methods ); if( !mod ) return; -} \ No newline at end of file +} + From 4db76684abb8617bdebc7c69a7e51b9277cb5869 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 12:05:10 -0500 Subject: [PATCH 05/34] whitespace commit --- enaml/core/new_expressions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/enaml/core/new_expressions.py b/enaml/core/new_expressions.py index 82a533af..dd58356b 100644 --- a/enaml/core/new_expressions.py +++ b/enaml/core/new_expressions.py @@ -227,6 +227,7 @@ def notify(self): """ self._expr.invalidated.emit(self._name) + #------------------------------------------------------------------------------ # Base Expression #------------------------------------------------------------------------------ From 1da0aaf39a4b7ee7c5c39786d68cd0d0aaa8715b Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 19:55:37 -0500 Subject: [PATCH 06/34] Move the funchelper extension module to the optional build --- setup.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/setup.py b/setup.py index 4877c789..ed2876a7 100644 --- a/setup.py +++ b/setup.py @@ -23,20 +23,16 @@ ['enaml/extensions/signaling.cpp'], language='c++', ), + Extension( + 'enaml.extensions.funchelper', + ['enaml/extensions/funchelper.cpp'], + language='c++', + ), ] else: ext_modules = [] -ext_modules.append( - Extension( - 'enaml.core.funchelper', - ['enaml/core/funchelper.cpp'], - language='c++', - ) -) - - setup( name='enaml', version='0.5.0', From 5ab94f12884b3da5e81997a37a842b8ae22b1312 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 19:56:19 -0500 Subject: [PATCH 07/34] Use an anytrait changed handler to publish most messages. This cuts down on the number of notifiers required. --- enaml/core/object.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/enaml/core/object.py b/enaml/core/object.py index 9da70b17..a9a2206f 100644 --- a/enaml/core/object.py +++ b/enaml/core/object.py @@ -189,6 +189,11 @@ class Object(HasStrictTraits): #: cycle when setting attributes from within an action handler. loopback_guard = Instance(LoopbackGuard, ()) + #: The internal set of published attributes. Publishing is performed + #: through an anytrait handler to reduce the number of notifier + #: objects which must be created. + _published_attrs = Instance(set, ()) + #: Class level storage for Object instances. Objects are added to #: this dict as they are created. The instances are stored weakly. _objects = WeakValueDictionary() @@ -688,7 +693,7 @@ def publish_attributes(self, *attrs): the changed attribute. This method is suitable for most cases of simple attribute publishing. More complex cases will need to implement their own dispatching handlers. The handler for - the changes will only emit the `action` signal if the attribute + the changes will only send the action message if the attribute name is not held by the loopback guard. Parameters @@ -699,10 +704,7 @@ def publish_attributes(self, *attrs): More complex values should use their own dispatch handlers. """ - otc = self.on_trait_change - handler = self._publish_attr_handler - for attr in attrs: - otc(handler, attr) + self._published_attrs.update(attrs) def set_guarded(self, **attrs): """ A convenience method provided for subclasses to set a @@ -746,9 +748,8 @@ def child_event(self, event): content['added'] = [c.snapshot() for c in added if c.snappable] self.send_action('children_changed', content) - def _publish_attr_handler(self, name, new): - """ A private handler which will emit the `action` signal in - response to a trait change event. + def _anytrait_changed(self, name, old, new): + """ An `anytrait` change handler which publishes action messages. The action will be created by prefixing the attribute name with 'set_'. The value of the attribute should be JSON serializable. @@ -758,7 +759,7 @@ def _publish_attr_handler(self, name, new): helping to avoid potential loopbacks. """ - if name not in self.loopback_guard: + if name in self._published_attrs and name not in self.loopback_guard: action = 'set_' + name content = {name: new} self.send_action(action, content) From 30d0903e17fd9bd8e506aa4d1b3da280bbeb22a2 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 19:57:24 -0500 Subject: [PATCH 08/34] Update Declarative to propogate the anytrait change handlers. Call super on the handler to run Object's handler. --- enaml/core/declarative.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/enaml/core/declarative.py b/enaml/core/declarative.py index 234a5e30..9a0631ad 100644 --- a/enaml/core/declarative.py +++ b/enaml/core/declarative.py @@ -288,6 +288,9 @@ def _add_user_attribute(cls, name, attr_type, is_event): # needed in this case, since this method will only be called by # the compiler machinery for brand new subclasses. ctrait = user_trait.as_ctrait() + anytrait_handler = cls.__prefix_traits__.get('@') + if anytrait_handler is not None: + ctrait._notifiers(1).append(anytrait_handler) cls.__base_traits__[name] = ctrait cls.__class_traits__[name] = ctrait @@ -382,6 +385,7 @@ def _anytrait_changed(self, name, old, new): number of notifier objects which must be created. """ + super(Declarative, self)._anytrait_changed(name, old, new) lsnrs = self._listeners if name in lsnrs: for listener in lsnrs[name]: From 199eaaa54b859fe4f5923e86cc9b1bb0ca16dee0 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 19:59:36 -0500 Subject: [PATCH 09/34] Update the AST and parser to using string names instead of ast nodes when loading simple names. --- enaml/core/enaml_ast.py | 48 +- enaml/core/parse_tab/parsetab.py | 870 +++++++++++++++---------------- enaml/core/parser.py | 75 ++- 3 files changed, 509 insertions(+), 484 deletions(-) diff --git a/enaml/core/enaml_ast.py b/enaml/core/enaml_ast.py index a86499aa..284f910e 100644 --- a/enaml/core/enaml_ast.py +++ b/enaml/core/enaml_ast.py @@ -9,7 +9,7 @@ class ASTNode(object): ---------- lineno : int The line number in the source code that created this node. - + """ def __init__(self, lineno): self.lineno = lineno @@ -19,7 +19,7 @@ def __repr__(self): def __str__(self): return repr(self) - + class Module(ASTNode): """ An AST node representing an Enaml module. @@ -28,10 +28,10 @@ class Module(ASTNode): ---------- doc : str The module's documentation string. - + body : list A list of ast nodes comprising the body of the module. - + """ def __init__(self, body, lineno): super(Module, self).__init__(lineno) @@ -45,7 +45,7 @@ class Python(ASTNode): ---------- py_ast : ast.AST A Python ast node. - + """ def __init__(self, py_ast, lineno): super(Python, self).__init__(lineno) @@ -59,19 +59,19 @@ class Declaration(ASTNode): ---------- name : str The name of the declaration. - - base : Python - A Python node which represents the base type of the declaration. - + + base : str + The name of the base type. + identifier : str The local identifier to use for instances of the declaration. - + doc : str The documentation string for the declaration. - + body : list A list of AST nodes that comprise the body of the declaration. - + """ def __init__(self, name, base, identifier, doc, body, lineno): super(Declaration, self).__init__(lineno) @@ -89,13 +89,13 @@ class Instantiation(ASTNode): ---------- name : str The name of declaration being instantiated. - + identifier : str The local identifier to use for the new instance. - + body : list A list of AST nodes which comprise the instantiation body. - + """ def __init__(self, name, identifier, body, lineno): super(Instantiation, self).__init__(lineno) @@ -112,14 +112,14 @@ class AttributeDeclaration(ASTNode): name : str The name of the attribute being declared. - type : Python or None - A Python node representing the type of the attribute, or None - if no type was given. If None the attribute can be of any type. + type : str + A string representing the type of the attribute, or None if no + type was given. If None the attribute can be of any type. default : AttributeBinding or None - The default binding of the attribute, or None if no default + The default binding of the attribute, or None if no default is provided. - + is_event : boolean Whether or not this declaration represents an event. i.e. was declared with 'event' instead of 'attr'. @@ -140,10 +140,10 @@ class AttributeBinding(ASTNode): ---------- name : str The name of the attribute being bound. - + binding : BoundExpression The BoundExpression ast node which represents the binding. - + """ def __init__(self, name, binding, lineno): super(AttributeBinding, self).__init__(lineno) @@ -158,10 +158,10 @@ class BoundExpression(ASTNode): ---------- op : str The name of the operator that will perform the binding. - + expr : Python A Python ast node that reprents the bound expression. - + """ def __init__(self, op, expr, lineno): super(BoundExpression, self).__init__(lineno) diff --git a/enaml/core/parse_tab/parsetab.py b/enaml/core/parse_tab/parsetab.py index 3de29338..840a72c6 100644 --- a/enaml/core/parse_tab/parsetab.py +++ b/enaml/core/parse_tab/parsetab.py @@ -5,9 +5,9 @@ _lr_method = 'LALR' -_lr_signature = 'A\xedm\xb9\xa4<\xec-\xb3\xabt<\xd4\x9c\xd2\xb9' +_lr_signature = '\x7f\xdd\xc1Pb\x9c\xa9\xeb\xac\xc9\xad\xb5=\x06\x80j' -_lr_action_items = {'LPAR':([0,1,6,7,9,13,14,16,18,24,28,29,30,31,33,35,39,42,43,44,47,49,52,54,55,57,61,63,64,65,67,72,73,74,82,83,85,86,89,90,95,96,97,102,103,104,106,109,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,137,138,140,144,147,148,150,155,157,160,161,163,165,166,168,169,170,171,177,183,185,186,187,188,189,191,193,194,195,196,199,201,202,205,210,211,213,215,216,218,219,220,228,233,234,244,246,248,251,253,256,258,260,262,263,265,270,271,272,274,277,278,279,281,282,291,292,293,296,299,300,301,303,306,307,308,309,310,312,314,315,316,318,319,321,324,328,330,333,341,343,346,347,350,353,354,355,356,360,364,365,367,368,370,374,375,377,378,379,383,391,394,401,404,410,414,417,418,420,428,429,430,432,435,437,440,442,444,447,450,453,459,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,512,518,523,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[1,1,-140,1,1,1,-55,-143,-139,-137,-141,1,-297,1,1,-298,1,-56,1,-9,-7,1,165,171,1,1,1,-8,-142,1,-295,-296,1,1,1,1,-144,1,-138,-288,-57,1,-58,1,1,1,1,-215,1,1,-125,-116,-120,-115,1,-118,-122,-117,-121,-124,-126,-123,-119,1,1,-181,-180,242,1,-299,1,1,251,1,1,1,-293,1,1,1,165,1,1,-286,171,1,-291,-241,1,-237,-236,-244,-239,-242,-240,-238,-6,1,1,314,316,-290,1,1,-289,1,1,1,1,-216,1,1,1,1,1,171,1,1,-51,1,-294,1,1,1,-314,1,1,1,-287,-317,1,1,1,171,1,1,1,-292,1,1,-245,1,-243,1,1,1,1,1,1,1,408,411,1,-168,1,-217,1,1,1,1,1,1,-163,-158,1,1,-315,1,1,1,-371,1,1,1,-316,171,171,-153,1,-177,-145,483,1,-169,-218,1,-174,1,1,-162,1,1,1,1,-372,1,1,171,171,1,1,1,1,-150,1,-146,-147,-155,-52,1,1,-164,1,1,1,-157,1,1,1,1,1,171,1,171,-178,1,1,-149,-148,1,-10,-159,-160,-165,1,-371,1,-154,1,1,1,-179,1,-152,-11,1,1,1,1,1,-372,1,1,-151,-12,-156,1,-166,-167,1,-14,-15,1,1,1,1,1,-13,-161,-16,-17,-18,-19,]),'ENDMARKER':([0,6,8,14,16,18,24,28,41,42,44,47,63,64,73,85,89,95,97,135,136,153,196,258,328,354,355,391,401,404,417,428,432,472,475,476,488,490,493,497,524,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[2,-140,100,-55,-143,-139,-137,-141,152,-56,-9,-7,-8,-142,-5,-144,-138,-57,-58,-181,-180,255,-6,-51,-168,-163,-158,-153,-177,-145,-169,-174,-162,-150,-146,-147,-155,-52,-164,-157,-178,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'NOTEQUAL':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,185,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,185,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'AMPEREQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,120,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'CIRCUMFLEX':([10,12,23,30,35,37,38,51,52,67,72,90,101,105,107,113,131,132,140,149,151,160,162,164,166,170,181,183,210,215,222,223,224,225,226,232,239,240,241,254,262,267,268,269,271,278,279,280,300,336,351,364,371,378,],[-270,112,-264,-297,-298,-278,-254,-258,-282,-295,-296,-288,-279,-272,-271,233,-265,-266,-299,-255,-280,-293,-260,-259,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-253,-257,-315,-285,-316,]),'WITH':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,97,135,136,196,258,328,353,354,355,391,401,404,417,428,430,432,472,475,476,488,490,493,497,524,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[7,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,7,-144,-138,-57,-58,-181,-180,-6,-51,-168,7,-163,-158,-153,-177,-145,-169,-174,7,-162,-150,-146,-147,-155,-52,-164,-157,-178,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'MINUS':([0,1,6,7,9,10,13,14,16,18,23,24,28,29,30,31,33,35,37,39,42,43,44,47,49,52,55,57,61,63,64,65,67,72,73,74,82,83,85,86,89,90,95,96,97,101,102,103,104,105,106,107,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,131,132,133,134,135,136,138,140,144,147,150,151,155,157,160,161,163,165,166,168,169,170,177,181,183,185,186,187,188,189,191,193,194,195,196,199,201,210,211,213,215,216,218,219,220,222,223,224,225,226,233,234,239,240,241,244,246,248,253,256,258,260,262,263,265,270,271,272,274,277,278,279,280,281,282,291,293,296,299,300,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,364,365,367,368,370,371,374,375,377,378,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[39,39,-140,39,39,-270,39,-55,-143,-139,134,-137,-141,39,-297,39,39,-298,-278,39,-56,39,-9,-7,39,-282,39,39,39,-8,-142,39,-295,-296,39,39,39,39,-144,39,-138,-288,-57,39,-58,-279,39,39,39,-272,39,-271,39,39,-125,-116,-120,-115,39,-118,-122,-117,-121,-124,-126,-123,-119,134,-266,39,39,-181,-180,39,-299,39,39,39,-280,39,39,-293,39,39,39,-284,39,39,-286,39,-281,-291,-241,39,-237,-236,-244,-239,-242,-240,-238,-6,39,39,-290,39,39,-289,39,39,39,39,-274,-276,-277,-275,-273,39,39,-267,-268,-269,39,39,39,39,39,-51,39,-294,39,39,39,-314,39,39,39,-287,-317,-283,39,39,39,39,39,39,-292,39,39,-245,39,-243,39,39,39,39,39,39,39,39,-168,39,39,39,39,39,39,39,-163,-158,39,39,-315,39,39,39,-371,-285,39,39,39,-316,-153,39,-177,-145,39,-169,39,-174,39,39,-162,39,39,39,39,-372,39,39,39,39,39,39,-150,39,-146,-147,-155,-52,39,39,-164,39,39,39,-157,39,39,39,39,39,39,-178,39,39,-149,-148,39,-10,-159,-160,-165,39,-371,39,-154,39,39,39,-179,39,-152,-11,39,39,39,39,39,-372,39,39,-151,-12,-156,39,-166,-167,39,-14,-15,39,39,39,39,39,-13,-161,-16,-17,-18,-19,]),'LESS':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,188,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,188,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'EXCEPT':([95,97,258,259,354,490,493,549,617,618,],[-57,-58,-51,356,356,-52,-164,-165,-166,-167,]),'PLUS':([0,1,6,7,9,10,13,14,16,18,23,24,28,29,30,31,33,35,37,39,42,43,44,47,49,52,55,57,61,63,64,65,67,72,73,74,82,83,85,86,89,90,95,96,97,101,102,103,104,105,106,107,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,131,132,133,134,135,136,138,140,144,147,150,151,155,157,160,161,163,165,166,168,169,170,177,181,183,185,186,187,188,189,191,193,194,195,196,199,201,210,211,213,215,216,218,219,220,222,223,224,225,226,233,234,239,240,241,244,246,248,253,256,258,260,262,263,265,270,271,272,274,277,278,279,280,281,282,291,293,296,299,300,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,364,365,367,368,370,371,374,375,377,378,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[9,9,-140,9,9,-270,9,-55,-143,-139,133,-137,-141,9,-297,9,9,-298,-278,9,-56,9,-9,-7,9,-282,9,9,9,-8,-142,9,-295,-296,9,9,9,9,-144,9,-138,-288,-57,9,-58,-279,9,9,9,-272,9,-271,9,9,-125,-116,-120,-115,9,-118,-122,-117,-121,-124,-126,-123,-119,133,-266,9,9,-181,-180,9,-299,9,9,9,-280,9,9,-293,9,9,9,-284,9,9,-286,9,-281,-291,-241,9,-237,-236,-244,-239,-242,-240,-238,-6,9,9,-290,9,9,-289,9,9,9,9,-274,-276,-277,-275,-273,9,9,-267,-268,-269,9,9,9,9,9,-51,9,-294,9,9,9,-314,9,9,9,-287,-317,-283,9,9,9,9,9,9,-292,9,9,-245,9,-243,9,9,9,9,9,9,9,9,-168,9,9,9,9,9,9,9,-163,-158,9,9,-315,9,9,9,-371,-285,9,9,9,-316,-153,9,-177,-145,9,-169,9,-174,9,9,-162,9,9,9,9,-372,9,9,9,9,9,9,-150,9,-146,-147,-155,-52,9,9,-164,9,9,9,-157,9,9,9,9,9,9,-178,9,9,-149,-148,9,-10,-159,-160,-165,9,-371,9,-154,9,9,9,-179,9,-152,-11,9,9,9,9,9,-372,9,9,-151,-12,-156,9,-166,-167,9,-14,-15,9,9,9,9,9,-13,-161,-16,-17,-18,-19,]),'PERCENTEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,125,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'IMPORT':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,109,135,136,155,196,207,208,209,216,219,228,258,299,315,318,320,322,328,330,333,350,353,354,355,391,401,404,417,418,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[11,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,11,-144,-138,-57,11,-58,-215,-181,-180,11,-6,319,321,-199,11,11,-216,-51,11,11,11,410,-200,-168,11,-217,11,11,-163,-158,-153,-177,-145,-169,-218,-174,11,11,-162,11,11,11,-150,-146,-147,-155,-52,11,11,-164,11,-157,11,-178,11,11,-149,-148,-10,-159,-160,-165,-154,-179,11,-152,-11,11,11,11,-151,-12,-156,11,-166,-167,-14,-15,11,-13,-161,-16,-17,-18,-19,]),'EQEQUAL':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,195,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,195,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'RBRACE':([10,12,19,23,27,30,32,35,37,38,46,48,49,51,52,67,68,72,75,90,101,105,107,113,131,132,140,143,149,151,156,158,160,162,164,166,170,181,183,190,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,263,264,266,267,268,269,271,278,279,280,295,300,305,311,336,344,351,358,359,360,361,364,371,378,388,395,397,422,438,439,440,441,485,498,521,522,537,538,539,579,588,601,603,619,627,],[-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,160,-258,-282,-295,-232,-296,-226,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,262,-293,-260,-259,-284,-286,-281,-291,-233,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-350,-351,-349,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-253,-249,-257,-225,-355,-352,-345,-315,-285,-316,-398,-235,-229,-220,-356,-347,-346,-344,-382,-348,-394,-393,-385,-384,-383,-386,-353,-395,-387,-354,-396,]),'EXEC':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[13,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,13,-144,-138,-57,13,-58,-181,-180,13,-6,13,13,-51,13,13,13,-168,13,13,13,-163,-158,-153,-177,-145,-169,-174,13,13,-162,13,13,13,-150,-146,-147,-155,-52,13,13,-164,13,-157,13,-178,13,13,-149,-148,-10,-159,-160,-165,-154,-179,13,-152,-11,13,13,13,-151,-12,-156,13,-166,-167,-14,-15,13,-13,-161,-16,-17,-18,-19,]),'SLASH':([10,30,35,37,52,67,72,90,101,105,107,140,151,160,166,170,181,183,210,215,222,223,224,225,226,262,271,278,279,280,300,364,371,378,],[106,-297,-298,-278,-282,-295,-296,-288,-279,-272,106,-299,-280,-293,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-294,-314,-287,-317,-283,-292,-315,-285,-316,]),'PASS':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,487,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,580,581,582,583,585,586,602,604,606,607,608,609,611,613,615,616,617,618,628,629,631,632,633,634,638,641,642,643,644,648,649,650,651,653,654,661,663,664,666,667,668,670,672,673,674,675,676,677,678,679,680,681,683,685,686,687,689,690,692,693,694,696,697,698,699,700,],[20,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,20,-144,-138,-57,20,-58,-181,-180,20,-6,20,20,-51,20,20,20,-168,20,20,20,-163,-158,-153,-177,-145,-169,-174,20,20,-162,20,20,20,-150,-146,-147,544,-155,-52,20,20,-164,20,-157,20,-178,20,20,-149,-148,-10,-159,-160,-165,-154,-179,20,-152,610,614,-11,20,20,20,-151,-24,-22,-20,-23,610,610,-12,-156,20,-166,-167,610,-14,-21,-25,-15,610,-45,662,20,-13,-161,610,610,662,-16,-26,-28,-32,-31,-50,-17,-18,610,-49,-47,-46,-48,-30,684,691,-33,-19,-27,-29,-35,-34,-42,691,-40,-43,691,-36,-37,-41,-44,-38,691,-39,]),'NAME':([0,1,6,7,9,11,13,14,16,18,24,26,28,29,31,33,34,39,42,43,44,47,49,54,55,56,57,61,63,64,65,73,74,80,82,83,84,85,86,87,89,95,96,97,102,103,104,106,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,138,144,147,150,155,157,161,163,165,167,168,169,171,172,176,177,185,186,187,188,189,191,193,194,195,196,199,201,208,209,211,213,216,218,219,220,227,229,230,233,234,242,244,246,248,251,253,256,258,260,263,265,270,272,274,277,281,282,291,292,293,296,298,299,301,303,306,307,308,309,310,312,314,315,316,318,319,321,322,324,328,330,332,335,341,343,346,347,350,353,354,355,356,360,365,367,368,370,374,375,377,379,383,385,387,391,394,401,404,408,410,411,414,417,420,428,429,430,432,435,437,440,442,444,447,450,453,454,455,457,459,461,463,466,468,472,473,475,476,477,479,483,487,488,490,491,492,493,494,495,496,497,498,501,502,505,510,512,513,514,518,523,524,525,528,529,530,532,540,543,546,547,549,552,553,556,560,561,564,565,569,570,573,574,575,576,580,582,583,585,586,587,589,590,592,599,600,602,604,606,607,608,609,611,612,613,615,616,617,618,621,624,628,629,630,631,632,633,634,635,637,638,639,640,641,642,643,644,646,648,649,650,651,653,654,655,661,663,664,666,667,668,670,672,673,674,675,676,677,678,679,680,681,683,685,686,687,689,690,692,693,694,696,697,698,699,700,],[67,67,-140,67,67,109,67,-55,-143,-139,-137,137,-141,67,67,67,148,67,-56,67,-9,-7,67,173,67,179,67,67,-8,-142,67,67,67,202,67,67,109,-144,67,109,-138,-57,67,-58,67,67,67,67,67,67,-125,-116,-120,-115,67,-118,-122,-117,-121,-124,-126,-123,-119,67,67,-181,-180,67,67,67,67,67,67,67,67,67,279,67,67,173,289,294,67,-241,67,-237,-236,-244,-239,-242,-240,-238,-6,67,67,109,-199,67,67,67,67,67,67,331,333,109,67,67,340,67,67,67,173,67,67,-51,67,67,67,67,67,67,67,67,67,67,173,67,67,390,67,67,67,-245,67,-243,67,67,67,67,67,67,67,407,407,-200,67,-168,67,418,109,67,67,67,67,67,67,-163,-158,67,67,67,67,67,-371,67,67,67,173,173,460,462,-153,67,-177,-145,407,407,407,67,-169,67,-174,67,67,-162,67,67,67,67,-372,67,67,173,508,509,511,173,67,67,67,67,-150,67,-146,-147,407,533,407,542,-155,-52,67,67,-164,67,67,67,-157,67,67,67,67,67,173,562,563,67,173,-178,67,67,-149,-148,407,67,-10,-159,-160,-165,67,-371,67,593,594,596,-154,67,67,67,-179,67,-152,612,-11,67,67,67,67,67,-372,622,67,67,-151,-24,-22,-20,-23,630,630,636,-12,-156,67,-166,-167,67,647,612,-14,636,-21,-25,-15,630,67,67,-45,67,67,659,67,-13,-161,665,630,630,669,-16,-26,-28,671,-32,-31,-50,-17,-18,630,-49,-47,-46,-48,-30,682,688,-33,-19,-27,-29,-35,-34,-42,695,-40,-43,695,-36,-37,-41,-44,-38,695,-39,]),'INDENT':([257,541,660,],[353,580,677,]),'MINUSEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,119,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'ENAMLDEF':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,97,135,136,196,258,328,354,355,391,401,404,417,428,432,472,475,476,488,490,493,497,524,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[26,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,26,-144,-138,-57,-58,-181,-180,-6,-51,-168,-163,-158,-153,-177,-145,-169,-174,-162,-150,-146,-147,-155,-52,-164,-157,-178,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'DEDENT':([6,14,16,18,24,28,42,64,85,89,95,97,135,136,258,328,354,355,391,401,404,417,428,430,431,432,472,475,476,488,489,490,493,497,524,529,530,546,547,549,565,574,576,602,604,606,607,608,609,611,615,617,618,631,632,634,638,644,648,649,653,654,661,663,664,668,670,672,673,674,675,678,680,681,683,685,686,687,689,690,692,693,694,696,697,698,699,700,],[-140,-55,-143,-139,-137,-141,-56,-142,-144,-138,-57,-58,-181,-180,-51,-168,-163,-158,-153,-177,-145,-169,-174,-54,490,-162,-150,-146,-147,-155,-53,-52,-164,-157,-178,-149,-148,-159,-160,-165,-154,-179,-152,-151,-24,-22,-20,-23,629,633,-156,-166,-167,-21,-25,651,-45,-161,666,667,-26,-28,-32,-31,-50,679,-49,-47,-46,-48,-30,-33,-27,-29,-35,-34,-42,694,-40,-43,698,-36,-37,-41,-44,-38,700,-39,]),'RETURN':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[29,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,29,-144,-138,-57,29,-58,-181,-180,29,-6,29,29,-51,29,29,29,-168,29,29,29,-163,-158,-153,-177,-145,-169,-174,29,29,-162,29,29,29,-150,-146,-147,-155,-52,29,29,-164,29,-157,29,-178,29,29,-149,-148,-10,-159,-160,-165,-154,-179,29,-152,-11,29,29,29,-151,-12,-156,29,-166,-167,-14,-15,29,-13,-161,-16,-17,-18,-19,]),'DEL':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[31,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,31,-144,-138,-57,31,-58,-181,-180,31,-6,31,31,-51,31,31,31,-168,31,31,31,-163,-158,-153,-177,-145,-169,-174,31,31,-162,31,31,31,-150,-146,-147,-155,-52,31,31,-164,31,-157,31,-178,31,31,-149,-148,-10,-159,-160,-165,-154,-179,31,-152,-11,31,31,31,-151,-12,-156,31,-166,-167,-14,-15,31,-13,-161,-16,-17,-18,-19,]),'PRINT':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[33,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,33,-144,-138,-57,33,-58,-181,-180,33,-6,33,33,-51,33,33,33,-168,33,33,33,-163,-158,-153,-177,-145,-169,-174,33,33,-162,33,33,33,-150,-146,-147,-155,-52,33,33,-164,33,-157,33,-178,33,33,-149,-148,-10,-159,-160,-165,-154,-179,33,-152,-11,33,33,33,-151,-12,-156,33,-166,-167,-14,-15,33,-13,-161,-16,-17,-18,-19,]),'DOUBLESTAR':([30,35,52,54,67,72,90,140,160,165,166,170,183,210,215,251,262,271,274,278,279,292,300,316,364,370,378,382,383,442,444,459,503,512,515,523,553,558,590,595,623,],[-297,-298,168,176,-295,-296,-288,-299,-293,272,277,-286,-291,-290,-289,176,-294,-314,367,-287,-317,387,-292,272,-315,-371,-316,454,457,501,-372,514,556,561,564,176,589,592,621,624,646,]),'DEF':([0,6,14,16,18,22,24,25,28,42,44,47,63,64,73,85,89,95,97,130,135,136,196,258,317,328,353,354,355,391,401,404,417,428,430,432,470,472,475,476,488,490,493,497,524,526,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[34,-140,-55,-143,-139,-183,-137,34,-141,-56,-9,-7,-8,-142,34,-144,-138,-57,-58,-182,-181,-180,-6,-51,-184,-168,34,-163,-158,-153,-177,-145,-169,-174,34,-162,-185,-150,-146,-147,-155,-52,-164,-157,-178,-186,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'CIRCUMFLEXEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,118,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'COLON':([10,12,19,23,27,30,32,35,37,38,45,46,48,51,52,54,67,68,72,75,77,90,98,99,101,105,107,113,131,132,140,143,149,151,156,159,160,162,164,166,169,170,173,174,175,180,181,183,190,198,200,201,202,204,206,210,215,221,222,223,224,225,226,232,239,240,241,247,252,254,261,262,267,268,269,271,278,279,280,283,289,290,292,294,295,300,305,311,312,313,327,329,336,344,348,351,352,356,357,358,364,371,372,377,378,381,383,384,386,388,395,397,398,399,416,421,422,427,433,434,436,448,450,456,458,459,460,462,465,469,474,499,508,509,511,512,516,523,527,542,545,548,550,551,559,562,563,572,584,593,594,596,612,622,630,636,647,659,665,669,688,695,],[-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,155,-222,-230,-258,-282,177,-295,-232,-296,-226,-131,-288,-170,219,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,265,-293,-260,-259,-284,281,-286,-426,-402,293,299,-281,-291,-233,-227,-133,-132,315,-231,318,-290,-289,330,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,350,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,374,-419,-407,-403,-421,-397,-292,-234,-228,-134,-135,-171,-173,-253,-249,-175,-257,429,435,437,-225,-315,-285,447,281,-316,-427,-408,-412,-422,-398,-235,-229,-136,468,-172,487,-220,-176,491,492,495,505,281,-424,-417,-413,-399,-401,518,525,528,552,-420,-404,-406,-418,-423,573,575,581,583,585,586,587,-425,-409,-411,600,616,-414,-416,-400,641,-405,650,655,-410,676,-415,676,641,650,]),'DOUBLECOLON':([10,12,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,169,170,181,183,190,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,283,295,300,305,311,336,344,351,358,364,371,377,378,388,395,397,422,450,612,630,636,659,669,671,682,688,695,],[-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,282,-286,-281,-291,-233,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,375,-397,-292,-234,-228,-253,-249,-257,-225,-315,-285,282,-316,-398,-235,-229,-220,282,642,642,642,642,642,642,642,642,642,]),'$end':([2,71,100,152,255,],[-4,0,-3,-2,-1,]),'FOR':([0,6,10,12,14,16,18,19,23,24,27,28,30,32,35,37,38,42,44,46,47,48,51,52,63,64,67,68,72,73,75,85,89,90,92,95,97,101,105,107,113,131,132,135,136,140,143,149,151,156,159,160,162,164,166,170,181,183,184,190,196,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,258,261,262,267,268,269,271,275,278,279,280,295,300,305,311,328,336,344,351,353,354,355,358,361,364,371,378,388,391,395,397,401,404,417,422,428,430,432,472,475,476,485,488,490,493,497,519,520,521,522,524,529,530,543,546,547,549,565,571,574,576,579,582,597,598,599,601,602,613,615,617,618,626,627,629,633,643,644,651,666,667,679,],[43,-140,-270,-250,-55,-143,-139,-221,-264,-137,-219,-141,-297,-246,-298,-278,-254,-56,-9,-222,-7,-230,-258,-282,-8,-142,-295,-232,-296,43,-226,-144,-138,-288,211,-57,-58,-279,-272,-271,-251,-265,-266,-181,-180,-299,-247,-255,-280,-223,211,-293,-260,-259,-284,-286,-281,-291,301,-233,-6,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-51,-224,-294,-262,-263,-261,-314,211,-287,-317,-283,-397,-292,-234,-228,-168,-253,-249,-257,43,-163,-158,-225,211,-315,-285,-316,-398,-153,-235,-229,-177,-145,-169,-220,-174,43,-162,-150,-146,-147,211,-155,-52,-164,-157,301,-388,-394,-393,-178,-149,-148,-10,-159,-160,-165,-154,-389,-179,-152,211,-11,301,-391,-390,-395,-151,-12,-156,-166,-167,-392,-396,-14,-15,-13,-161,-16,-17,-18,-19,]),'DOUBLESTAREQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,122,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'ELSE':([10,12,23,30,32,35,37,38,46,48,51,52,67,68,72,75,90,95,97,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,204,210,215,222,223,224,225,226,232,239,240,241,243,247,254,258,261,262,267,268,269,271,278,279,280,300,305,311,336,344,351,354,355,358,364,371,378,391,395,397,404,432,472,475,488,490,493,529,549,602,617,618,],[-270,-250,-264,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-288,-57,-58,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,341,-248,-256,-51,-224,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-228,-253,-249,-257,-163,433,-225,-315,-285,-316,465,-235,-229,474,-162,-150,474,545,-52,-164,-149,-165,-151,-166,-167,]),'TRY':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,97,135,136,196,258,328,353,354,355,391,401,404,417,428,430,432,472,475,476,488,490,493,497,524,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[45,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,45,-144,-138,-57,-58,-181,-180,-6,-51,-168,45,-163,-158,-153,-177,-145,-169,-174,45,-162,-150,-146,-147,-155,-52,-164,-157,-178,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'AND':([10,12,23,30,32,35,37,38,48,51,52,67,68,72,75,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,311,336,344,351,364,371,378,395,397,],[-270,-250,-264,-297,-246,-298,-278,-254,-230,-258,-282,-295,-232,-296,199,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,-233,310,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-228,-253,-249,-257,-315,-285,-316,-235,-229,]),'LBRACE':([0,1,6,7,9,13,14,16,18,24,28,29,31,33,39,42,43,44,47,49,55,57,61,63,64,65,73,74,82,83,85,86,89,95,96,97,102,103,104,106,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,138,144,147,150,155,157,161,163,165,168,169,177,185,186,187,188,189,191,193,194,195,196,199,201,211,213,216,218,219,220,233,234,244,246,248,253,256,258,260,263,265,270,272,274,277,281,282,291,293,296,299,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,365,367,368,370,374,375,377,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[49,49,-140,49,49,49,-55,-143,-139,-137,-141,49,49,49,49,-56,49,-9,-7,49,49,49,49,-8,-142,49,49,49,49,49,-144,49,-138,-57,49,-58,49,49,49,49,49,49,-125,-116,-120,-115,49,-118,-122,-117,-121,-124,-126,-123,-119,49,49,-181,-180,49,49,49,49,49,49,49,49,49,49,49,49,-241,49,-237,-236,-244,-239,-242,-240,-238,-6,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,-51,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,-245,49,-243,49,49,49,49,49,49,49,49,-168,49,49,49,49,49,49,49,-163,-158,49,49,49,49,49,-371,49,49,49,-153,49,-177,-145,49,-169,49,-174,49,49,-162,49,49,49,49,-372,49,49,49,49,49,49,-150,49,-146,-147,-155,-52,49,49,-164,49,49,49,-157,49,49,49,49,49,49,-178,49,49,-149,-148,49,-10,-159,-160,-165,49,-371,49,-154,49,49,49,-179,49,-152,-11,49,49,49,49,49,-372,49,49,-151,-12,-156,49,-166,-167,49,-14,-15,49,49,49,49,49,-13,-161,-16,-17,-18,-19,]),'AS':([10,12,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,90,98,101,105,107,108,109,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,204,210,215,222,223,224,225,226,228,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,333,336,344,351,358,364,371,378,388,395,397,407,418,422,436,],[-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-288,218,-279,-272,-271,227,-215,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-231,-290,-289,-274,-276,-277,-275,-273,-216,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-217,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,479,-218,-220,494,]),'OR':([10,12,23,30,32,35,37,38,46,48,51,52,67,68,72,75,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,300,305,311,336,344,351,358,364,371,378,395,397,],[-270,-250,-264,-297,-246,-298,-278,-254,157,-230,-258,-282,-295,-232,-296,-226,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,260,-293,-260,-259,-284,-286,-281,-291,-233,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-228,-253,-249,-257,-225,-315,-285,-316,-235,-229,]),'LEFTSHIFT':([10,23,30,35,37,51,52,67,72,90,101,105,107,131,132,140,151,160,162,164,166,170,181,183,210,215,222,223,224,225,226,239,240,241,262,267,268,269,271,278,279,280,300,364,371,378,612,630,636,659,669,671,682,688,695,],[-270,-264,-297,-298,-278,161,-282,-295,-296,-288,-279,-272,-271,-265,-266,-299,-280,-293,-260,161,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-267,-268,-269,-294,-262,-263,-261,-314,-287,-317,-283,-292,-315,-285,-316,640,640,640,640,640,640,640,640,640,]),'CONTINUE':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[53,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,53,-144,-138,-57,53,-58,-181,-180,53,-6,53,53,-51,53,53,53,-168,53,53,53,-163,-158,-153,-177,-145,-169,-174,53,53,-162,53,53,53,-150,-146,-147,-155,-52,53,53,-164,53,-157,53,-178,53,53,-149,-148,-10,-159,-160,-165,-154,-179,53,-152,-11,53,53,53,-151,-12,-156,53,-166,-167,-14,-15,53,-13,-161,-16,-17,-18,-19,]),'NOT':([0,1,6,7,10,12,14,16,18,23,24,28,29,30,32,33,35,37,38,42,44,47,49,51,52,55,57,63,64,65,67,68,72,73,74,82,83,85,86,89,90,95,96,97,101,105,107,113,116,117,118,119,120,121,122,123,124,125,126,127,128,129,131,132,135,136,138,140,143,147,149,151,155,157,160,162,164,165,166,169,170,177,181,183,189,190,196,199,201,210,213,215,216,219,220,222,223,224,225,226,232,234,239,240,241,247,248,254,256,258,260,262,263,265,267,268,269,270,271,272,274,278,279,280,281,282,291,293,296,299,300,303,305,309,310,312,314,315,316,318,324,328,330,336,341,344,346,347,350,351,353,354,355,356,360,364,365,367,368,370,371,374,375,377,378,391,394,395,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[83,83,-140,83,-270,-250,-55,-143,-139,-264,-137,-141,83,-297,-246,83,-298,-278,-254,-56,-9,-7,83,-258,-282,83,83,-8,-142,83,-295,192,-296,83,83,83,83,-144,83,-138,-288,-57,83,-58,-279,-272,-271,-251,83,-125,-116,-120,-115,83,-118,-122,-117,-121,-124,-126,-123,-119,-265,-266,-181,-180,83,-299,-247,83,-255,-280,83,83,-293,-260,-259,83,-284,83,-286,83,-281,-291,306,192,-6,83,83,-290,83,-289,83,83,83,-274,-276,-277,-275,-273,-252,83,-267,-268,-269,-248,83,-256,83,-51,83,-294,83,83,-262,-263,-261,83,-314,83,83,-287,-317,-283,83,83,83,83,83,83,-292,83,-234,83,83,83,83,83,83,83,83,-168,83,-253,83,-249,83,83,83,-257,83,-163,-158,83,83,-315,83,83,83,-371,-285,83,83,83,-316,-153,83,-235,-177,-145,83,-169,83,-174,83,83,-162,83,83,83,83,-372,83,83,83,83,83,83,-150,83,-146,-147,-155,-52,83,83,-164,83,83,83,-157,83,83,83,83,83,83,-178,83,83,-149,-148,83,-10,-159,-160,-165,83,-371,83,-154,83,83,83,-179,83,-152,-11,83,83,83,83,83,-372,83,83,-151,-12,-156,83,-166,-167,83,-14,-15,83,83,83,83,83,-13,-161,-16,-17,-18,-19,]),'LAMBDA':([0,1,6,7,14,16,18,24,28,29,33,42,44,47,49,55,57,63,64,65,73,74,82,85,86,89,95,96,97,116,117,118,119,120,121,122,123,124,125,126,127,128,129,135,136,147,155,165,169,177,196,201,213,216,219,220,234,248,256,258,263,265,270,272,274,281,282,291,293,296,299,303,309,312,314,315,316,318,324,328,330,341,346,347,350,353,354,355,356,360,365,367,368,370,374,375,377,391,394,401,404,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[54,54,-140,54,-55,-143,-139,-137,-141,54,54,-56,-9,-7,54,54,54,-8,-142,54,54,54,54,-144,54,-138,-57,54,-58,54,-125,-116,-120,-115,54,-118,-122,-117,-121,-124,-126,-123,-119,-181,-180,54,54,54,54,54,-6,54,54,54,54,54,54,54,54,-51,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,-168,54,54,54,54,54,54,-163,-158,54,54,54,54,54,-371,54,54,54,-153,54,-177,-145,-169,54,-174,54,54,-162,54,54,54,54,-372,54,54,54,54,523,54,-150,54,-146,-147,-155,-52,54,54,-164,54,54,54,-157,54,54,54,54,54,54,-178,54,54,-149,-148,523,-10,-159,-160,-165,54,-371,54,-154,523,523,523,-179,54,-152,-11,54,54,54,54,54,-372,523,523,-151,-12,-156,54,-166,-167,54,-14,-15,54,54,54,54,54,-13,-161,-16,-17,-18,-19,]),'NEWLINE':([0,3,4,5,6,10,12,14,15,16,17,18,19,20,21,23,24,27,28,29,30,32,33,35,36,37,38,40,41,42,44,46,47,48,50,51,52,53,55,58,59,60,62,63,64,66,67,68,69,70,72,73,75,76,77,78,79,81,82,85,88,89,90,94,95,96,97,101,105,107,108,109,110,111,113,114,115,131,132,135,136,139,140,141,142,143,145,146,149,151,155,156,160,162,164,166,170,178,179,181,183,190,196,197,198,200,201,203,204,205,210,215,216,217,219,222,223,224,225,226,228,231,232,235,236,237,238,239,240,241,244,245,247,248,249,250,254,258,261,262,267,268,269,271,278,279,280,295,297,299,300,305,311,312,313,315,318,326,328,330,331,333,334,336,337,338,339,342,343,344,345,346,350,351,354,355,358,364,371,378,388,389,390,391,395,396,397,398,401,402,404,405,406,407,409,412,413,417,418,419,422,423,424,425,426,428,429,432,435,437,464,468,471,472,475,476,477,478,481,482,486,487,488,490,491,492,493,495,497,517,518,524,525,528,529,530,531,532,533,534,536,543,544,546,547,549,565,574,575,576,577,578,581,582,583,585,586,602,605,610,613,614,615,616,617,618,629,633,636,641,642,643,644,650,651,652,656,657,658,659,662,666,667,671,676,679,684,691,],[8,95,-188,97,-140,-270,-250,-55,-111,-143,-72,-139,-221,-85,-64,-264,-137,-219,-141,-93,-297,-246,-73,-298,-68,-278,-254,-71,153,-56,-9,-222,-7,-230,-67,-258,-282,-92,-95,-88,-69,-87,-65,-8,-142,-89,-295,-232,-91,-90,-296,-5,-226,-86,-131,-70,-187,-99,-100,-144,-66,-138,-288,-60,-57,-59,-58,-279,-272,-271,-203,-215,-189,-211,-251,-106,-114,-265,-266,-181,-180,-94,-299,-84,-338,-247,-75,-74,-255,-280,257,-223,-293,-260,-259,-284,-286,-96,-102,-281,-291,-233,-6,-109,-227,-133,-132,-101,-231,317,-290,-289,-61,-62,257,-274,-276,-277,-275,-273,-216,-212,-252,-113,-112,-128,-127,-267,-268,-269,-339,-340,-248,-79,-80,-76,-256,-51,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-103,257,-292,-234,-228,-134,-135,257,257,-63,-168,257,-204,-217,-213,-253,-107,-130,-129,-342,-341,-249,-82,-81,257,-257,-163,-158,-225,-315,-285,-316,-398,-97,-105,-153,-235,-110,-229,-136,-177,470,-145,-205,-190,-201,-191,-196,-197,-169,-218,-214,-220,-343,-83,-78,-77,-174,257,-162,257,257,-104,257,526,-150,-146,-147,-206,-207,-194,-193,-108,541,-155,-52,257,257,-164,257,-157,-98,257,-178,257,257,-149,-148,-209,-208,-202,-192,-198,-10,582,-159,-160,-165,-154,-179,257,-152,-210,-195,541,-11,257,257,257,-151,628,632,-12,643,-156,257,-166,-167,-14,-15,653,660,257,-13,-161,660,-16,670,672,673,674,675,678,-17,-18,680,660,-19,693,697,]),'RAISE':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[55,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,55,-144,-138,-57,55,-58,-181,-180,55,-6,55,55,-51,55,55,55,-168,55,55,55,-163,-158,-153,-177,-145,-169,-174,55,55,-162,55,55,55,-150,-146,-147,-155,-52,55,55,-164,55,-157,55,-178,55,55,-149,-148,-10,-159,-160,-165,-154,-179,55,-152,-11,55,55,55,-151,-12,-156,55,-166,-167,-14,-15,55,-13,-161,-16,-17,-18,-19,]),'GLOBAL':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[56,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,56,-144,-138,-57,56,-58,-181,-180,56,-6,56,56,-51,56,56,56,-168,56,56,56,-163,-158,-153,-177,-145,-169,-174,56,56,-162,56,56,56,-150,-146,-147,-155,-52,56,56,-164,56,-157,56,-178,56,56,-149,-148,-10,-159,-160,-165,-154,-179,56,-152,-11,56,56,56,-151,-12,-156,56,-166,-167,-14,-15,56,-13,-161,-16,-17,-18,-19,]),'WHILE':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,97,135,136,196,258,328,353,354,355,391,401,404,417,428,430,432,472,475,476,488,490,493,497,524,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[57,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,57,-144,-138,-57,-58,-181,-180,-6,-51,-168,57,-163,-158,-153,-177,-145,-169,-174,57,-162,-150,-146,-147,-155,-52,-164,-157,-178,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'VBAR':([10,12,23,30,32,35,37,38,51,52,67,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,336,344,351,364,371,378,],[-270,-250,-264,-297,144,-298,-278,-254,-258,-282,-295,-296,-288,-279,-272,-271,-251,-265,-266,-299,246,-255,-280,-293,-260,-259,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-253,-249,-257,-315,-285,-316,]),'STAR':([10,30,35,37,52,54,67,72,90,101,105,107,140,151,160,165,166,170,181,183,210,215,222,223,224,225,226,251,262,271,274,278,279,280,292,300,316,319,321,364,370,371,378,383,410,444,459,512,523,],[102,-297,-298,-278,-282,172,-295,-296,-288,-279,-272,102,-299,-280,-293,270,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,172,-294,-314,365,-287,-317,-283,385,-292,270,406,412,-315,-371,-285,-316,455,482,-372,513,560,172,]),'DOT':([30,35,52,67,72,87,90,109,140,160,166,170,183,208,209,210,215,228,262,271,278,279,300,322,333,364,378,418,],[-297,-298,167,-295,-296,209,-288,229,-299,-293,167,-286,-291,322,-199,-290,-289,332,-294,-314,-287,-317,-292,-200,-217,-315,-316,-218,]),'LEFTSHIFTEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,129,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'TILDE':([0,1,6,7,9,13,14,16,18,24,28,29,31,33,39,42,43,44,47,49,55,57,61,63,64,65,73,74,82,83,85,86,89,95,96,97,102,103,104,106,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,138,144,147,150,155,157,161,163,165,168,169,177,185,186,187,188,189,191,193,194,195,196,199,201,211,213,216,218,219,220,233,234,244,246,248,253,256,258,260,263,265,270,272,274,277,281,282,291,293,296,299,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,365,367,368,370,374,375,377,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[61,61,-140,61,61,61,-55,-143,-139,-137,-141,61,61,61,61,-56,61,-9,-7,61,61,61,61,-8,-142,61,61,61,61,61,-144,61,-138,-57,61,-58,61,61,61,61,61,61,-125,-116,-120,-115,61,-118,-122,-117,-121,-124,-126,-123,-119,61,61,-181,-180,61,61,61,61,61,61,61,61,61,61,61,61,-241,61,-237,-236,-244,-239,-242,-240,-238,-6,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,-51,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,-245,61,-243,61,61,61,61,61,61,61,61,-168,61,61,61,61,61,61,61,-163,-158,61,61,61,61,61,-371,61,61,61,-153,61,-177,-145,61,-169,61,-174,61,61,-162,61,61,61,61,-372,61,61,61,61,61,61,-150,61,-146,-147,-155,-52,61,61,-164,61,61,61,-157,61,61,61,61,61,61,-178,61,61,-149,-148,61,-10,-159,-160,-165,61,-371,61,-154,61,61,61,-179,61,-152,-11,61,61,61,61,61,-372,61,61,-151,-12,-156,61,-166,-167,61,-14,-15,61,61,61,61,61,-13,-161,-16,-17,-18,-19,]),'RSQB':([10,12,19,23,27,30,32,35,37,38,46,48,51,52,65,67,68,72,75,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,182,183,184,190,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,281,282,283,284,285,286,295,300,302,303,304,305,311,336,344,351,358,364,371,372,373,374,375,376,377,378,388,393,394,395,397,422,447,448,449,450,451,467,504,505,506,519,520,521,522,557,566,567,568,571,597,598,599,601,625,626,627,],[-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,183,-295,-232,-296,-226,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,300,-291,-301,-233,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-326,-327,-325,-318,378,-324,-397,-292,-300,-302,-303,-234,-228,-253,-249,-257,-225,-315,-285,-330,-332,-328,-329,-320,-319,-316,-398,-305,-304,-235,-229,-220,-331,-333,-337,-321,-322,-306,-335,-334,-323,-376,-388,-394,-393,-336,-377,-379,-378,-389,-380,-391,-390,-395,-381,-392,-396,]),'PERCENT':([10,30,35,37,52,67,72,90,101,105,107,140,151,160,166,170,181,183,210,215,222,223,224,225,226,262,271,278,279,280,300,364,371,378,],[103,-297,-298,-278,-282,-295,-296,-288,-279,-272,103,-299,-280,-293,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-294,-314,-287,-317,-283,-292,-315,-285,-316,]),'DOUBLESLASH':([10,30,35,37,52,67,72,90,101,105,107,140,151,160,166,170,181,183,210,215,222,223,224,225,226,262,271,278,279,280,300,364,371,378,],[104,-297,-298,-278,-282,-295,-296,-288,-279,-272,104,-299,-280,-293,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-294,-314,-287,-317,-283,-292,-315,-285,-316,]),'EQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,82,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,173,174,181,183,190,198,200,201,203,204,210,215,222,223,224,225,226,232,237,238,239,240,241,247,254,261,262,267,268,269,271,275,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,381,386,388,395,397,398,422,456,612,630,636,659,669,671,682,688,695,],[-270,-250,121,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-100,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-426,291,-281,-291,-233,-227,-133,-132,-101,-231,-290,-289,-274,-276,-277,-275,-273,-252,121,121,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,368,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-427,461,-398,-235,-229,-136,-220,510,639,639,639,639,639,639,639,639,639,]),'PLUSEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,123,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'ELLIPSIS':([169,377,450,],[286,286,286,]),'LESSEQUAL':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,194,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,194,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'LSQB':([0,1,6,7,9,13,14,16,18,24,28,29,30,31,33,35,39,42,43,44,47,49,52,55,57,61,63,64,65,67,72,73,74,82,83,85,86,89,90,95,96,97,102,103,104,106,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,138,140,144,147,150,155,157,160,161,163,165,166,168,169,170,177,183,185,186,187,188,189,191,193,194,195,196,199,201,210,211,213,215,216,218,219,220,233,234,244,246,248,253,256,258,260,262,263,265,270,271,272,274,277,278,279,281,282,291,293,296,299,300,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,364,365,367,368,370,374,375,377,378,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[65,65,-140,65,65,65,-55,-143,-139,-137,-141,65,-297,65,65,-298,65,-56,65,-9,-7,65,169,65,65,65,-8,-142,65,-295,-296,65,65,65,65,-144,65,-138,-288,-57,65,-58,65,65,65,65,65,65,-125,-116,-120,-115,65,-118,-122,-117,-121,-124,-126,-123,-119,65,65,-181,-180,65,-299,65,65,65,65,65,-293,65,65,65,169,65,65,-286,65,-291,-241,65,-237,-236,-244,-239,-242,-240,-238,-6,65,65,-290,65,65,-289,65,65,65,65,65,65,65,65,65,65,65,-51,65,-294,65,65,65,-314,65,65,65,-287,-317,65,65,65,65,65,65,-292,65,65,-245,65,-243,65,65,65,65,65,65,65,65,-168,65,65,65,65,65,65,65,-163,-158,65,65,-315,65,65,65,-371,65,65,65,-316,-153,65,-177,-145,65,-169,65,-174,65,65,-162,65,65,65,65,-372,65,65,65,65,65,65,-150,65,-146,-147,-155,-52,65,65,-164,65,65,65,-157,65,65,65,65,65,65,-178,65,65,-149,-148,65,-10,-159,-160,-165,65,-371,65,-154,65,65,65,-179,65,-152,-11,65,65,65,65,65,-372,65,65,-151,-12,-156,65,-166,-167,65,-14,-15,65,65,65,65,65,-13,-161,-16,-17,-18,-19,]),'GREATER':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,187,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,187,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'VBAREQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,127,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'BREAK':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[69,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,69,-144,-138,-57,69,-58,-181,-180,69,-6,69,69,-51,69,69,69,-168,69,69,69,-163,-158,-153,-177,-145,-169,-174,69,69,-162,69,69,69,-150,-146,-147,-155,-52,69,69,-164,69,-157,69,-178,69,69,-149,-148,-10,-159,-160,-165,-154,-179,69,-152,-11,69,69,69,-151,-12,-156,69,-166,-167,-14,-15,69,-13,-161,-16,-17,-18,-19,]),'STAREQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,117,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'ELIF':([95,97,258,404,472,475,490,529,602,],[-57,-58,-51,473,-150,473,-52,-149,-151,]),'SLASHEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,126,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'NUMBER':([0,1,6,7,9,13,14,16,18,24,28,29,31,33,39,42,43,44,47,49,55,57,61,63,64,65,73,74,82,83,85,86,89,95,96,97,102,103,104,106,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,138,144,147,150,155,157,161,163,165,168,169,177,185,186,187,188,189,191,193,194,195,196,199,201,211,213,216,218,219,220,233,234,244,246,248,253,256,258,260,263,265,270,272,274,277,281,282,291,293,296,299,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,365,367,368,370,374,375,377,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[72,72,-140,72,72,72,-55,-143,-139,-137,-141,72,72,72,72,-56,72,-9,-7,72,72,72,72,-8,-142,72,72,72,72,72,-144,72,-138,-57,72,-58,72,72,72,72,72,72,-125,-116,-120,-115,72,-118,-122,-117,-121,-124,-126,-123,-119,72,72,-181,-180,72,72,72,72,72,72,72,72,72,72,72,72,-241,72,-237,-236,-244,-239,-242,-240,-238,-6,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-51,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-245,72,-243,72,72,72,72,72,72,72,72,-168,72,72,72,72,72,72,72,-163,-158,72,72,72,72,72,-371,72,72,72,-153,72,-177,-145,72,-169,72,-174,72,72,-162,72,72,72,72,-372,72,72,72,72,72,72,-150,72,-146,-147,-155,-52,72,72,-164,72,72,72,-157,72,72,72,72,72,72,-178,72,72,-149,-148,72,-10,-159,-160,-165,72,-371,72,-154,72,72,72,-179,72,-152,-11,72,72,72,72,72,-372,72,72,-151,-12,-156,72,-166,-167,72,-14,-15,72,72,72,72,72,-13,-161,-16,-17,-18,-19,]),'RPAR':([1,10,12,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,82,90,91,92,93,101,105,107,113,131,132,140,143,149,151,156,160,162,164,165,166,170,173,174,181,183,190,198,200,201,203,204,210,212,213,214,215,222,223,224,225,226,232,239,240,241,247,251,254,261,262,267,268,269,271,273,275,276,278,279,280,287,288,289,290,292,294,295,300,305,311,312,313,314,316,324,325,336,340,344,349,351,358,362,363,364,366,369,370,371,378,379,380,381,383,384,386,388,395,397,398,400,403,405,407,415,422,443,444,445,446,452,453,456,458,459,460,462,477,478,480,484,485,500,507,508,509,511,512,516,521,522,531,532,533,535,537,538,539,554,555,559,562,563,577,579,591,593,594,596,601,603,620,622,627,645,647,665,],[90,-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-100,-288,210,-308,215,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,271,-284,-286,-426,-402,-281,-291,-233,-227,-133,-132,-101,-231,-290,-310,-309,-307,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,348,-256,-224,-294,-262,-263,-261,-314,364,-373,-357,-287,-317,-283,-428,381,-419,-407,-403,-421,-397,-292,-234,-228,-134,-135,399,402,-311,-312,-253,421,-249,427,-257,-225,-359,-361,-315,-362,-374,-358,-285,-316,-429,-430,-427,-408,-412,-422,-398,-235,-229,-136,469,471,-205,-201,-313,-220,-364,-363,-366,-375,-432,-431,-424,-417,-413,-399,-401,-206,-207,534,536,-382,-367,-433,-420,-404,-406,-418,-423,-394,-393,-209,-208,-202,578,-385,-384,-383,-360,-369,-425,-409,-411,-210,-386,-365,-414,-416,-400,-395,-387,-368,-405,-396,-370,-410,-415,]),'ASSERT':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[74,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,74,-144,-138,-57,74,-58,-181,-180,74,-6,74,74,-51,74,74,74,-168,74,74,74,-163,-158,-153,-177,-145,-169,-174,74,74,-162,74,74,74,-150,-146,-147,-155,-52,74,74,-164,74,-157,74,-178,74,74,-149,-148,-10,-159,-160,-165,-154,-179,74,-152,-11,74,74,74,-151,-12,-156,74,-166,-167,-14,-15,74,-13,-161,-16,-17,-18,-19,]),'RIGHTSHIFTEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,128,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'GREATEREQUAL':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,191,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,191,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'SEMI':([3,4,10,12,15,17,19,20,21,23,27,29,30,32,33,35,36,37,38,40,46,48,50,51,52,53,55,58,59,60,62,66,67,68,69,70,72,75,76,77,78,79,81,82,88,90,94,101,105,107,108,109,110,111,113,114,115,131,132,139,140,141,142,143,145,146,149,151,156,160,162,164,166,170,178,179,181,183,190,197,198,200,201,203,204,210,215,217,222,223,224,225,226,228,231,232,235,236,237,238,239,240,241,244,245,247,248,249,250,254,261,262,267,268,269,271,278,279,280,295,297,300,305,311,312,313,326,331,333,334,336,337,338,339,342,343,344,345,346,351,358,364,371,378,388,389,390,395,396,397,398,405,406,407,409,412,413,418,419,422,423,424,425,426,464,477,478,481,482,486,517,531,532,533,534,536,577,578,],[96,-188,-270,-250,-111,-72,-221,-85,-64,-264,-219,-93,-297,-246,-73,-298,-68,-278,-254,-71,-222,-230,-67,-258,-282,-92,-95,-88,-69,-87,-65,-89,-295,-232,-91,-90,-296,-226,-86,-131,-70,-187,-99,-100,-66,-288,216,-279,-272,-271,-203,-215,-189,-211,-251,-106,-114,-265,-266,-94,-299,-84,-338,-247,-75,-74,-255,-280,-223,-293,-260,-259,-284,-286,-96,-102,-281,-291,-233,-109,-227,-133,-132,-101,-231,-290,-289,-62,-274,-276,-277,-275,-273,-216,-212,-252,-113,-112,-128,-127,-267,-268,-269,-339,-340,-248,-79,-80,-76,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-103,-292,-234,-228,-134,-135,-63,-204,-217,-213,-253,-107,-130,-129,-342,-341,-249,-82,-81,-257,-225,-315,-285,-316,-398,-97,-105,-235,-110,-229,-136,-205,-190,-201,-191,-196,-197,-218,-214,-220,-343,-83,-78,-77,-104,-206,-207,-194,-193,-108,-98,-209,-208,-202,-192,-198,-210,-195,]),'DOUBLESLASHEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,124,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'COMMA':([10,12,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,92,98,99,101,105,107,108,109,111,113,131,132,140,142,143,146,149,151,156,159,160,162,164,166,170,173,174,178,179,181,183,184,190,197,198,200,204,210,212,215,222,223,224,225,226,228,231,232,239,240,241,245,247,249,250,254,261,262,264,267,268,269,271,275,276,278,279,280,281,282,283,284,286,287,289,290,295,300,304,305,311,313,325,327,329,331,333,334,336,337,342,344,345,351,358,359,361,362,364,366,369,371,372,373,374,375,376,378,380,381,384,386,388,389,390,393,395,397,398,405,407,415,418,419,422,423,424,426,436,438,439,443,446,447,448,449,451,452,456,458,460,467,478,485,500,504,505,506,507,509,516,520,521,522,531,533,537,538,539,555,557,559,562,571,577,579,588,593,598,601,603,619,626,627,],[-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,201,-288,213,-170,220,-279,-272,-271,-203,-215,230,-251,-265,-266,-299,244,-247,248,-255,-280,-223,263,-293,-260,-259,-284,-286,-426,292,296,298,-281,-291,303,-233,309,-227,312,-231,-290,324,-289,-274,-276,-277,-275,-273,-216,335,-252,-267,-268,-269,343,-248,346,347,-256,-224,-294,360,-262,-263,-261,-314,-373,370,-287,-317,-283,-326,-327,-325,377,-324,379,382,383,-397,-292,394,-234,-228,-135,-312,-171,220,-204,-217,-213,-253,420,-342,-249,-82,-257,-225,-355,440,442,-315,444,-374,-285,-330,-332,-328,-329,450,-316,453,-427,459,-422,-398,463,298,-305,-235,-229,-136,477,-201,-313,-218,-214,-220,-343,-83,248,496,-356,498,503,-375,-331,-333,-337,-322,-432,-424,512,515,-306,532,-382,553,-335,-334,-323,-433,558,-423,570,-394,-393,-209,-202,-385,-384,-383,590,-336,-425,595,599,-210,-386,-353,623,-391,-395,-387,-354,-392,-396,]),'CLASS':([0,6,14,16,18,22,24,25,28,42,44,47,63,64,73,85,89,95,97,130,135,136,196,258,317,328,353,354,355,391,401,404,417,428,430,432,470,472,475,476,488,490,493,497,524,526,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[80,-140,-55,-143,-139,-183,-137,80,-141,-56,-9,-7,-8,-142,80,-144,-138,-57,-58,-182,-181,-180,-6,-51,-184,-168,80,-163,-158,-153,-177,-145,-169,-174,80,-162,-185,-150,-146,-147,-155,-52,-164,-157,-178,-186,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'RIGHTSHIFT':([10,23,30,33,35,37,51,52,67,72,90,101,105,107,131,132,140,151,160,162,164,166,170,181,183,210,215,222,223,224,225,226,239,240,241,262,267,268,269,271,278,279,280,300,364,371,378,612,630,636,659,669,671,682,688,695,],[-270,-264,-297,147,-298,-278,163,-282,-295,-296,-288,-279,-272,-271,-265,-266,-299,-280,-293,-260,163,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-267,-268,-269,-294,-262,-263,-261,-314,-287,-317,-283,-292,-315,-285,-316,635,635,635,635,635,635,635,635,635,]),'STRING':([0,1,6,7,9,13,14,16,18,24,28,29,30,31,33,35,39,42,43,44,47,49,55,57,61,63,64,65,73,74,82,83,85,86,89,95,96,97,102,103,104,106,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,138,140,144,147,150,155,157,161,163,165,168,169,177,185,186,187,188,189,191,193,194,195,196,199,201,211,213,216,218,219,220,233,234,244,246,248,253,256,258,260,263,265,270,272,274,277,281,282,291,293,296,299,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,365,367,368,370,374,375,377,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,580,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[35,35,-140,35,35,35,-55,-143,-139,-137,-141,35,140,35,35,-298,35,-56,35,-9,-7,35,35,35,35,-8,-142,35,35,35,35,35,-144,35,-138,-57,35,-58,35,35,35,35,35,35,-125,-116,-120,-115,35,-118,-122,-117,-121,-124,-126,-123,-119,35,35,-181,-180,35,-299,35,35,35,35,35,35,35,35,35,35,35,-241,35,-237,-236,-244,-239,-242,-240,-238,-6,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,-51,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,-245,35,-243,35,35,35,35,35,35,35,35,-168,35,35,35,35,35,35,35,-163,-158,35,35,35,35,35,-371,35,35,35,-153,35,-177,-145,35,-169,35,-174,35,35,-162,35,35,35,35,-372,35,35,35,35,35,35,-150,35,-146,-147,-155,-52,35,35,-164,35,35,35,-157,35,35,35,35,35,35,-178,35,35,-149,-148,35,-10,-159,-160,-165,35,-371,35,-154,35,35,35,-179,35,-152,605,-11,35,35,35,35,35,-372,35,35,-151,-12,-156,35,-166,-167,35,-14,-15,35,35,35,35,35,-13,-161,-16,-17,-18,-19,]),'COLONEQUAL':([612,630,636,659,669,671,682,688,695,],[637,637,637,637,637,637,637,637,637,]),'IS':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,189,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,189,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'YIELD':([0,1,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,116,117,118,119,120,121,122,123,124,125,126,127,128,129,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[82,82,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,82,-144,-138,-57,82,-58,82,-125,-116,-120,-115,82,-118,-122,-117,-121,-124,-126,-123,-119,-181,-180,82,-6,82,82,-51,82,82,82,-168,82,82,82,-163,-158,-153,-177,-145,-169,-174,82,82,-162,82,82,82,-150,-146,-147,-155,-52,82,82,-164,82,-157,82,-178,82,82,-149,-148,-10,-159,-160,-165,-154,-179,82,-152,-11,82,82,82,-151,-12,-156,82,-166,-167,-14,-15,82,-13,-161,-16,-17,-18,-19,]),'FINALLY':([95,97,258,259,354,355,432,490,493,546,549,617,618,],[-57,-58,-51,357,-163,434,-162,-52,-164,584,-165,-166,-167,]),'AT':([0,6,14,16,18,22,24,28,42,44,47,63,64,73,85,89,95,97,135,136,196,258,317,328,353,354,355,391,401,404,417,428,430,432,470,472,475,476,488,490,493,497,524,526,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[84,-140,-55,-143,-139,84,-137,-141,-56,-9,-7,-8,-142,84,-144,-138,-57,-58,-181,-180,-6,-51,-184,-168,84,-163,-158,-153,-177,-145,-169,-174,84,-162,-185,-150,-146,-147,-155,-52,-164,-157,-178,-186,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'AMPER':([10,23,30,35,37,38,51,52,67,72,90,101,105,107,131,132,140,149,151,160,162,164,166,170,181,183,210,215,222,223,224,225,226,239,240,241,254,262,267,268,269,271,278,279,280,300,351,364,371,378,],[-270,-264,-297,-298,-278,150,-258,-282,-295,-296,-288,-279,-272,-271,-265,-266,-299,253,-280,-293,-260,-259,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-267,-268,-269,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-257,-315,-285,-316,]),'IN':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,114,131,132,140,142,143,149,151,154,160,162,164,166,170,181,183,190,192,210,215,222,223,224,225,226,232,239,240,241,244,245,247,254,262,267,268,269,271,278,279,280,300,305,323,336,342,343,344,351,364,371,378,392,395,423,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,193,-296,-288,-279,-272,-271,-251,234,-265,-266,-299,-338,-247,-255,-280,256,-293,-260,-259,-284,-286,-281,-291,193,308,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-339,-340,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,414,-253,-342,-341,-249,-257,-315,-285,-316,466,-235,-343,]),'IF':([0,6,10,12,14,16,18,23,24,27,28,30,32,35,37,38,42,44,46,47,48,51,52,63,64,67,68,72,73,75,85,89,90,95,97,101,105,107,113,131,132,135,136,140,143,149,151,156,160,162,164,166,170,181,183,190,196,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,258,261,262,267,268,269,271,278,279,280,300,305,311,328,336,344,351,353,354,355,358,364,371,378,391,395,397,401,404,417,428,430,432,472,475,476,485,488,490,493,497,519,520,521,522,524,529,530,543,546,547,549,565,571,574,576,579,582,597,598,599,601,602,613,615,617,618,626,627,629,633,643,644,651,666,667,679,],[86,-140,-270,-250,-55,-143,-139,-264,-137,138,-141,-297,-246,-298,-278,-254,-56,-9,-222,-7,-230,-258,-282,-8,-142,-295,-232,-296,86,-226,-144,-138,-288,-57,-58,-279,-272,-271,-251,-265,-266,-181,-180,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-6,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-51,-224,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-228,-168,-253,-249,-257,86,-163,-158,-225,-315,-285,-316,-153,-235,-229,-177,-145,-169,-174,86,-162,-150,-146,-147,540,-155,-52,-164,-157,569,-388,-394,-393,-178,-149,-148,-10,-159,-160,-165,-154,-389,-179,-152,540,-11,569,-391,-390,-395,-151,-12,-156,-166,-167,-392,-396,-14,-15,-13,-161,-16,-17,-18,-19,]),'FROM':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[87,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,87,-144,-138,-57,87,-58,-181,-180,87,-6,87,87,-51,87,87,87,-168,87,87,87,-163,-158,-153,-177,-145,-169,-174,87,87,-162,87,87,87,-150,-146,-147,-155,-52,87,87,-164,87,-157,87,-178,87,87,-149,-148,-10,-159,-160,-165,-154,-179,87,-152,-11,87,87,87,-151,-12,-156,87,-166,-167,-14,-15,87,-13,-161,-16,-17,-18,-19,]),} +_lr_action_items = {'LPAR':([0,1,6,7,9,13,14,16,18,24,28,29,30,31,33,35,39,42,43,44,47,49,52,54,55,57,61,63,64,65,67,72,73,74,82,83,85,86,89,90,95,96,97,102,103,104,106,109,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,137,138,140,144,147,148,150,155,157,160,161,163,165,166,168,169,170,171,177,183,185,186,187,188,189,191,193,194,195,196,199,201,202,205,210,211,213,215,216,218,219,220,228,233,234,244,246,248,251,253,256,258,260,262,263,265,270,271,272,274,277,278,279,281,282,291,292,293,296,299,300,301,303,306,307,308,309,310,312,314,315,316,318,319,321,324,328,330,333,341,343,346,347,350,353,354,355,356,360,364,365,367,368,370,374,375,377,378,379,383,391,394,401,404,410,414,417,418,420,428,429,430,432,435,437,440,442,444,447,450,453,459,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,512,518,523,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[1,1,-140,1,1,1,-55,-143,-139,-137,-141,1,-297,1,1,-298,1,-56,1,-9,-7,1,165,171,1,1,1,-8,-142,1,-295,-296,1,1,1,1,-144,1,-138,-288,-57,1,-58,1,1,1,1,-215,1,1,-125,-116,-120,-115,1,-118,-122,-117,-121,-124,-126,-123,-119,1,1,-181,-180,242,1,-299,1,1,251,1,1,1,-293,1,1,1,165,1,1,-286,171,1,-291,-241,1,-237,-236,-244,-239,-242,-240,-238,-6,1,1,314,316,-290,1,1,-289,1,1,1,1,-216,1,1,1,1,1,171,1,1,-51,1,-294,1,1,1,-314,1,1,1,-287,-317,1,1,1,171,1,1,1,-292,1,1,-245,1,-243,1,1,1,1,1,1,1,408,411,1,-168,1,-217,1,1,1,1,1,1,-163,-158,1,1,-315,1,1,1,-371,1,1,1,-316,171,171,-153,1,-177,-145,483,1,-169,-218,1,-174,1,1,-162,1,1,1,1,-372,1,1,171,171,1,1,1,1,-150,1,-146,-147,-155,-52,1,1,-164,1,1,1,-157,1,1,1,1,1,171,1,171,-178,1,1,-149,-148,1,-10,-159,-160,-165,1,-371,1,-154,1,1,1,-179,1,-152,-11,1,1,1,1,1,-372,1,1,-151,-12,-156,1,-166,-167,1,-14,-15,1,1,1,1,1,-13,-161,-16,-17,-18,-19,]),'ENDMARKER':([0,6,8,14,16,18,24,28,41,42,44,47,63,64,73,85,89,95,97,135,136,153,196,258,328,354,355,391,401,404,417,428,432,472,475,476,488,490,493,497,524,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[2,-140,100,-55,-143,-139,-137,-141,152,-56,-9,-7,-8,-142,-5,-144,-138,-57,-58,-181,-180,255,-6,-51,-168,-163,-158,-153,-177,-145,-169,-174,-162,-150,-146,-147,-155,-52,-164,-157,-178,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'NOTEQUAL':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,185,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,185,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'AMPEREQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,120,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'CIRCUMFLEX':([10,12,23,30,35,37,38,51,52,67,72,90,101,105,107,113,131,132,140,149,151,160,162,164,166,170,181,183,210,215,222,223,224,225,226,232,239,240,241,254,262,267,268,269,271,278,279,280,300,336,351,364,371,378,],[-270,112,-264,-297,-298,-278,-254,-258,-282,-295,-296,-288,-279,-272,-271,233,-265,-266,-299,-255,-280,-293,-260,-259,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-253,-257,-315,-285,-316,]),'WITH':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,97,135,136,196,258,328,353,354,355,391,401,404,417,428,430,432,472,475,476,488,490,493,497,524,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[7,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,7,-144,-138,-57,-58,-181,-180,-6,-51,-168,7,-163,-158,-153,-177,-145,-169,-174,7,-162,-150,-146,-147,-155,-52,-164,-157,-178,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'MINUS':([0,1,6,7,9,10,13,14,16,18,23,24,28,29,30,31,33,35,37,39,42,43,44,47,49,52,55,57,61,63,64,65,67,72,73,74,82,83,85,86,89,90,95,96,97,101,102,103,104,105,106,107,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,131,132,133,134,135,136,138,140,144,147,150,151,155,157,160,161,163,165,166,168,169,170,177,181,183,185,186,187,188,189,191,193,194,195,196,199,201,210,211,213,215,216,218,219,220,222,223,224,225,226,233,234,239,240,241,244,246,248,253,256,258,260,262,263,265,270,271,272,274,277,278,279,280,281,282,291,293,296,299,300,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,364,365,367,368,370,371,374,375,377,378,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[39,39,-140,39,39,-270,39,-55,-143,-139,134,-137,-141,39,-297,39,39,-298,-278,39,-56,39,-9,-7,39,-282,39,39,39,-8,-142,39,-295,-296,39,39,39,39,-144,39,-138,-288,-57,39,-58,-279,39,39,39,-272,39,-271,39,39,-125,-116,-120,-115,39,-118,-122,-117,-121,-124,-126,-123,-119,134,-266,39,39,-181,-180,39,-299,39,39,39,-280,39,39,-293,39,39,39,-284,39,39,-286,39,-281,-291,-241,39,-237,-236,-244,-239,-242,-240,-238,-6,39,39,-290,39,39,-289,39,39,39,39,-274,-276,-277,-275,-273,39,39,-267,-268,-269,39,39,39,39,39,-51,39,-294,39,39,39,-314,39,39,39,-287,-317,-283,39,39,39,39,39,39,-292,39,39,-245,39,-243,39,39,39,39,39,39,39,39,-168,39,39,39,39,39,39,39,-163,-158,39,39,-315,39,39,39,-371,-285,39,39,39,-316,-153,39,-177,-145,39,-169,39,-174,39,39,-162,39,39,39,39,-372,39,39,39,39,39,39,-150,39,-146,-147,-155,-52,39,39,-164,39,39,39,-157,39,39,39,39,39,39,-178,39,39,-149,-148,39,-10,-159,-160,-165,39,-371,39,-154,39,39,39,-179,39,-152,-11,39,39,39,39,39,-372,39,39,-151,-12,-156,39,-166,-167,39,-14,-15,39,39,39,39,39,-13,-161,-16,-17,-18,-19,]),'LESS':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,188,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,188,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'EXCEPT':([95,97,258,259,354,490,493,549,617,618,],[-57,-58,-51,356,356,-52,-164,-165,-166,-167,]),'PLUS':([0,1,6,7,9,10,13,14,16,18,23,24,28,29,30,31,33,35,37,39,42,43,44,47,49,52,55,57,61,63,64,65,67,72,73,74,82,83,85,86,89,90,95,96,97,101,102,103,104,105,106,107,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,131,132,133,134,135,136,138,140,144,147,150,151,155,157,160,161,163,165,166,168,169,170,177,181,183,185,186,187,188,189,191,193,194,195,196,199,201,210,211,213,215,216,218,219,220,222,223,224,225,226,233,234,239,240,241,244,246,248,253,256,258,260,262,263,265,270,271,272,274,277,278,279,280,281,282,291,293,296,299,300,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,364,365,367,368,370,371,374,375,377,378,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[9,9,-140,9,9,-270,9,-55,-143,-139,133,-137,-141,9,-297,9,9,-298,-278,9,-56,9,-9,-7,9,-282,9,9,9,-8,-142,9,-295,-296,9,9,9,9,-144,9,-138,-288,-57,9,-58,-279,9,9,9,-272,9,-271,9,9,-125,-116,-120,-115,9,-118,-122,-117,-121,-124,-126,-123,-119,133,-266,9,9,-181,-180,9,-299,9,9,9,-280,9,9,-293,9,9,9,-284,9,9,-286,9,-281,-291,-241,9,-237,-236,-244,-239,-242,-240,-238,-6,9,9,-290,9,9,-289,9,9,9,9,-274,-276,-277,-275,-273,9,9,-267,-268,-269,9,9,9,9,9,-51,9,-294,9,9,9,-314,9,9,9,-287,-317,-283,9,9,9,9,9,9,-292,9,9,-245,9,-243,9,9,9,9,9,9,9,9,-168,9,9,9,9,9,9,9,-163,-158,9,9,-315,9,9,9,-371,-285,9,9,9,-316,-153,9,-177,-145,9,-169,9,-174,9,9,-162,9,9,9,9,-372,9,9,9,9,9,9,-150,9,-146,-147,-155,-52,9,9,-164,9,9,9,-157,9,9,9,9,9,9,-178,9,9,-149,-148,9,-10,-159,-160,-165,9,-371,9,-154,9,9,9,-179,9,-152,-11,9,9,9,9,9,-372,9,9,-151,-12,-156,9,-166,-167,9,-14,-15,9,9,9,9,9,-13,-161,-16,-17,-18,-19,]),'PERCENTEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,125,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'IMPORT':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,109,135,136,155,196,207,208,209,216,219,228,258,299,315,318,320,322,328,330,333,350,353,354,355,391,401,404,417,418,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[11,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,11,-144,-138,-57,11,-58,-215,-181,-180,11,-6,319,321,-199,11,11,-216,-51,11,11,11,410,-200,-168,11,-217,11,11,-163,-158,-153,-177,-145,-169,-218,-174,11,11,-162,11,11,11,-150,-146,-147,-155,-52,11,11,-164,11,-157,11,-178,11,11,-149,-148,-10,-159,-160,-165,-154,-179,11,-152,-11,11,11,11,-151,-12,-156,11,-166,-167,-14,-15,11,-13,-161,-16,-17,-18,-19,]),'EQEQUAL':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,195,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,195,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'RBRACE':([10,12,19,23,27,30,32,35,37,38,46,48,49,51,52,67,68,72,75,90,101,105,107,113,131,132,140,143,149,151,156,158,160,162,164,166,170,181,183,190,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,263,264,266,267,268,269,271,278,279,280,295,300,305,311,336,344,351,358,359,360,361,364,371,378,388,395,397,422,438,439,440,441,485,498,521,522,537,538,539,579,588,601,603,619,627,],[-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,160,-258,-282,-295,-232,-296,-226,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,262,-293,-260,-259,-284,-286,-281,-291,-233,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-350,-351,-349,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-253,-249,-257,-225,-355,-352,-345,-315,-285,-316,-398,-235,-229,-220,-356,-347,-346,-344,-382,-348,-394,-393,-385,-384,-383,-386,-353,-395,-387,-354,-396,]),'EXEC':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[13,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,13,-144,-138,-57,13,-58,-181,-180,13,-6,13,13,-51,13,13,13,-168,13,13,13,-163,-158,-153,-177,-145,-169,-174,13,13,-162,13,13,13,-150,-146,-147,-155,-52,13,13,-164,13,-157,13,-178,13,13,-149,-148,-10,-159,-160,-165,-154,-179,13,-152,-11,13,13,13,-151,-12,-156,13,-166,-167,-14,-15,13,-13,-161,-16,-17,-18,-19,]),'SLASH':([10,30,35,37,52,67,72,90,101,105,107,140,151,160,166,170,181,183,210,215,222,223,224,225,226,262,271,278,279,280,300,364,371,378,],[106,-297,-298,-278,-282,-295,-296,-288,-279,-272,106,-299,-280,-293,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-294,-314,-287,-317,-283,-292,-315,-285,-316,]),'PASS':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,487,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,580,581,582,583,585,586,602,604,606,607,608,609,611,613,615,616,617,618,628,629,631,632,633,634,638,641,642,643,644,648,649,650,651,653,654,661,663,664,666,667,668,670,672,673,674,675,676,677,678,679,680,681,683,685,686,687,689,690,692,693,694,696,697,698,699,700,],[20,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,20,-144,-138,-57,20,-58,-181,-180,20,-6,20,20,-51,20,20,20,-168,20,20,20,-163,-158,-153,-177,-145,-169,-174,20,20,-162,20,20,20,-150,-146,-147,544,-155,-52,20,20,-164,20,-157,20,-178,20,20,-149,-148,-10,-159,-160,-165,-154,-179,20,-152,610,614,-11,20,20,20,-151,-24,-22,-20,-23,610,610,-12,-156,20,-166,-167,610,-14,-21,-25,-15,610,-45,662,20,-13,-161,610,610,662,-16,-26,-28,-32,-31,-50,-17,-18,610,-49,-48,-46,-47,-30,684,691,-33,-19,-27,-29,-35,-34,-42,691,-40,-43,691,-36,-37,-41,-44,-38,691,-39,]),'NAME':([0,1,6,7,9,11,13,14,16,18,24,26,28,29,31,33,34,39,42,43,44,47,49,54,55,56,57,61,63,64,65,73,74,80,82,83,84,85,86,87,89,95,96,97,102,103,104,106,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,138,144,147,150,155,157,161,163,165,167,168,169,171,172,176,177,185,186,187,188,189,191,193,194,195,196,199,201,208,209,211,213,216,218,219,220,227,229,230,233,234,242,244,246,248,251,253,256,258,260,263,265,270,272,274,277,281,282,291,292,293,296,298,299,301,303,306,307,308,309,310,312,314,315,316,318,319,321,322,324,328,330,332,335,341,343,346,347,350,353,354,355,356,360,365,367,368,370,374,375,377,379,383,385,387,391,394,401,404,408,410,411,414,417,420,428,429,430,432,435,437,440,442,444,447,450,453,454,455,457,459,461,463,466,468,472,473,475,476,477,479,483,487,488,490,491,492,493,494,495,496,497,498,501,502,505,510,512,513,514,518,523,524,525,528,529,530,532,540,543,546,547,549,552,553,556,560,561,564,565,569,570,573,574,575,576,580,582,583,585,586,587,589,590,592,599,600,602,604,606,607,608,609,611,612,613,615,616,617,618,621,624,628,629,630,631,632,633,634,635,637,638,639,640,641,642,643,644,646,648,649,650,651,653,654,655,661,663,664,666,667,668,670,672,673,674,675,676,677,678,679,680,681,683,685,686,687,689,690,692,693,694,696,697,698,699,700,],[67,67,-140,67,67,109,67,-55,-143,-139,-137,137,-141,67,67,67,148,67,-56,67,-9,-7,67,173,67,179,67,67,-8,-142,67,67,67,202,67,67,109,-144,67,109,-138,-57,67,-58,67,67,67,67,67,67,-125,-116,-120,-115,67,-118,-122,-117,-121,-124,-126,-123,-119,67,67,-181,-180,67,67,67,67,67,67,67,67,67,279,67,67,173,289,294,67,-241,67,-237,-236,-244,-239,-242,-240,-238,-6,67,67,109,-199,67,67,67,67,67,67,331,333,109,67,67,340,67,67,67,173,67,67,-51,67,67,67,67,67,67,67,67,67,67,173,67,67,390,67,67,67,-245,67,-243,67,67,67,67,67,67,67,407,407,-200,67,-168,67,418,109,67,67,67,67,67,67,-163,-158,67,67,67,67,67,-371,67,67,67,173,173,460,462,-153,67,-177,-145,407,407,407,67,-169,67,-174,67,67,-162,67,67,67,67,-372,67,67,173,508,509,511,173,67,67,67,67,-150,67,-146,-147,407,533,407,542,-155,-52,67,67,-164,67,67,67,-157,67,67,67,67,67,173,562,563,67,173,-178,67,67,-149,-148,407,67,-10,-159,-160,-165,67,-371,67,593,594,596,-154,67,67,67,-179,67,-152,612,-11,67,67,67,67,67,-372,622,67,67,-151,-24,-22,-20,-23,630,630,636,-12,-156,67,-166,-167,67,647,612,-14,636,-21,-25,-15,630,67,67,-45,67,67,659,67,-13,-161,665,630,630,669,-16,-26,-28,671,-32,-31,-50,-17,-18,630,-49,-48,-46,-47,-30,682,688,-33,-19,-27,-29,-35,-34,-42,695,-40,-43,695,-36,-37,-41,-44,-38,695,-39,]),'INDENT':([257,541,660,],[353,580,677,]),'MINUSEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,119,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'ENAMLDEF':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,97,135,136,196,258,328,354,355,391,401,404,417,428,432,472,475,476,488,490,493,497,524,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[26,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,26,-144,-138,-57,-58,-181,-180,-6,-51,-168,-163,-158,-153,-177,-145,-169,-174,-162,-150,-146,-147,-155,-52,-164,-157,-178,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'DEDENT':([6,14,16,18,24,28,42,64,85,89,95,97,135,136,258,328,354,355,391,401,404,417,428,430,431,432,472,475,476,488,489,490,493,497,524,529,530,546,547,549,565,574,576,602,604,606,607,608,609,611,615,617,618,631,632,634,638,644,648,649,653,654,661,663,664,668,670,672,673,674,675,678,680,681,683,685,686,687,689,690,692,693,694,696,697,698,699,700,],[-140,-55,-143,-139,-137,-141,-56,-142,-144,-138,-57,-58,-181,-180,-51,-168,-163,-158,-153,-177,-145,-169,-174,-54,490,-162,-150,-146,-147,-155,-53,-52,-164,-157,-178,-149,-148,-159,-160,-165,-154,-179,-152,-151,-24,-22,-20,-23,629,633,-156,-166,-167,-21,-25,651,-45,-161,666,667,-26,-28,-32,-31,-50,679,-49,-48,-46,-47,-30,-33,-27,-29,-35,-34,-42,694,-40,-43,698,-36,-37,-41,-44,-38,700,-39,]),'RETURN':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[29,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,29,-144,-138,-57,29,-58,-181,-180,29,-6,29,29,-51,29,29,29,-168,29,29,29,-163,-158,-153,-177,-145,-169,-174,29,29,-162,29,29,29,-150,-146,-147,-155,-52,29,29,-164,29,-157,29,-178,29,29,-149,-148,-10,-159,-160,-165,-154,-179,29,-152,-11,29,29,29,-151,-12,-156,29,-166,-167,-14,-15,29,-13,-161,-16,-17,-18,-19,]),'DEL':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[31,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,31,-144,-138,-57,31,-58,-181,-180,31,-6,31,31,-51,31,31,31,-168,31,31,31,-163,-158,-153,-177,-145,-169,-174,31,31,-162,31,31,31,-150,-146,-147,-155,-52,31,31,-164,31,-157,31,-178,31,31,-149,-148,-10,-159,-160,-165,-154,-179,31,-152,-11,31,31,31,-151,-12,-156,31,-166,-167,-14,-15,31,-13,-161,-16,-17,-18,-19,]),'PRINT':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[33,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,33,-144,-138,-57,33,-58,-181,-180,33,-6,33,33,-51,33,33,33,-168,33,33,33,-163,-158,-153,-177,-145,-169,-174,33,33,-162,33,33,33,-150,-146,-147,-155,-52,33,33,-164,33,-157,33,-178,33,33,-149,-148,-10,-159,-160,-165,-154,-179,33,-152,-11,33,33,33,-151,-12,-156,33,-166,-167,-14,-15,33,-13,-161,-16,-17,-18,-19,]),'DOUBLESTAR':([30,35,52,54,67,72,90,140,160,165,166,170,183,210,215,251,262,271,274,278,279,292,300,316,364,370,378,382,383,442,444,459,503,512,515,523,553,558,590,595,623,],[-297,-298,168,176,-295,-296,-288,-299,-293,272,277,-286,-291,-290,-289,176,-294,-314,367,-287,-317,387,-292,272,-315,-371,-316,454,457,501,-372,514,556,561,564,176,589,592,621,624,646,]),'DEF':([0,6,14,16,18,22,24,25,28,42,44,47,63,64,73,85,89,95,97,130,135,136,196,258,317,328,353,354,355,391,401,404,417,428,430,432,470,472,475,476,488,490,493,497,524,526,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[34,-140,-55,-143,-139,-183,-137,34,-141,-56,-9,-7,-8,-142,34,-144,-138,-57,-58,-182,-181,-180,-6,-51,-184,-168,34,-163,-158,-153,-177,-145,-169,-174,34,-162,-185,-150,-146,-147,-155,-52,-164,-157,-178,-186,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'CIRCUMFLEXEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,118,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'COLON':([10,12,19,23,27,30,32,35,37,38,45,46,48,51,52,54,67,68,72,75,77,90,98,99,101,105,107,113,131,132,140,143,149,151,156,159,160,162,164,166,169,170,173,174,175,180,181,183,190,198,200,201,202,204,206,210,215,221,222,223,224,225,226,232,239,240,241,247,252,254,261,262,267,268,269,271,278,279,280,283,289,290,292,294,295,300,305,311,312,313,327,329,336,344,348,351,352,356,357,358,364,371,372,377,378,381,383,384,386,388,395,397,398,399,416,421,422,427,433,434,436,448,450,456,458,459,460,462,465,469,474,499,508,509,511,512,516,523,527,542,545,548,550,551,559,562,563,572,584,593,594,596,612,622,630,636,647,659,665,669,688,695,],[-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,155,-222,-230,-258,-282,177,-295,-232,-296,-226,-131,-288,-170,219,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,265,-293,-260,-259,-284,281,-286,-426,-402,293,299,-281,-291,-233,-227,-133,-132,315,-231,318,-290,-289,330,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,350,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,374,-419,-407,-403,-421,-397,-292,-234,-228,-134,-135,-171,-173,-253,-249,-175,-257,429,435,437,-225,-315,-285,447,281,-316,-427,-408,-412,-422,-398,-235,-229,-136,468,-172,487,-220,-176,491,492,495,505,281,-424,-417,-413,-399,-401,518,525,528,552,-420,-404,-406,-418,-423,573,575,581,583,585,586,587,-425,-409,-411,600,616,-414,-416,-400,641,-405,650,655,-410,676,-415,676,641,650,]),'DOUBLECOLON':([10,12,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,169,170,181,183,190,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,283,295,300,305,311,336,344,351,358,364,371,377,378,388,395,397,422,450,612,630,636,659,669,671,682,688,695,],[-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,282,-286,-281,-291,-233,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,375,-397,-292,-234,-228,-253,-249,-257,-225,-315,-285,282,-316,-398,-235,-229,-220,282,642,642,642,642,642,642,642,642,642,]),'$end':([2,71,100,152,255,],[-4,0,-3,-2,-1,]),'FOR':([0,6,10,12,14,16,18,19,23,24,27,28,30,32,35,37,38,42,44,46,47,48,51,52,63,64,67,68,72,73,75,85,89,90,92,95,97,101,105,107,113,131,132,135,136,140,143,149,151,156,159,160,162,164,166,170,181,183,184,190,196,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,258,261,262,267,268,269,271,275,278,279,280,295,300,305,311,328,336,344,351,353,354,355,358,361,364,371,378,388,391,395,397,401,404,417,422,428,430,432,472,475,476,485,488,490,493,497,519,520,521,522,524,529,530,543,546,547,549,565,571,574,576,579,582,597,598,599,601,602,613,615,617,618,626,627,629,633,643,644,651,666,667,679,],[43,-140,-270,-250,-55,-143,-139,-221,-264,-137,-219,-141,-297,-246,-298,-278,-254,-56,-9,-222,-7,-230,-258,-282,-8,-142,-295,-232,-296,43,-226,-144,-138,-288,211,-57,-58,-279,-272,-271,-251,-265,-266,-181,-180,-299,-247,-255,-280,-223,211,-293,-260,-259,-284,-286,-281,-291,301,-233,-6,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-51,-224,-294,-262,-263,-261,-314,211,-287,-317,-283,-397,-292,-234,-228,-168,-253,-249,-257,43,-163,-158,-225,211,-315,-285,-316,-398,-153,-235,-229,-177,-145,-169,-220,-174,43,-162,-150,-146,-147,211,-155,-52,-164,-157,301,-388,-394,-393,-178,-149,-148,-10,-159,-160,-165,-154,-389,-179,-152,211,-11,301,-391,-390,-395,-151,-12,-156,-166,-167,-392,-396,-14,-15,-13,-161,-16,-17,-18,-19,]),'DOUBLESTAREQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,122,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'ELSE':([10,12,23,30,32,35,37,38,46,48,51,52,67,68,72,75,90,95,97,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,204,210,215,222,223,224,225,226,232,239,240,241,243,247,254,258,261,262,267,268,269,271,278,279,280,300,305,311,336,344,351,354,355,358,364,371,378,391,395,397,404,432,472,475,488,490,493,529,549,602,617,618,],[-270,-250,-264,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-288,-57,-58,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,341,-248,-256,-51,-224,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-228,-253,-249,-257,-163,433,-225,-315,-285,-316,465,-235,-229,474,-162,-150,474,545,-52,-164,-149,-165,-151,-166,-167,]),'TRY':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,97,135,136,196,258,328,353,354,355,391,401,404,417,428,430,432,472,475,476,488,490,493,497,524,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[45,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,45,-144,-138,-57,-58,-181,-180,-6,-51,-168,45,-163,-158,-153,-177,-145,-169,-174,45,-162,-150,-146,-147,-155,-52,-164,-157,-178,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'AND':([10,12,23,30,32,35,37,38,48,51,52,67,68,72,75,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,311,336,344,351,364,371,378,395,397,],[-270,-250,-264,-297,-246,-298,-278,-254,-230,-258,-282,-295,-232,-296,199,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,-233,310,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-228,-253,-249,-257,-315,-285,-316,-235,-229,]),'LBRACE':([0,1,6,7,9,13,14,16,18,24,28,29,31,33,39,42,43,44,47,49,55,57,61,63,64,65,73,74,82,83,85,86,89,95,96,97,102,103,104,106,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,138,144,147,150,155,157,161,163,165,168,169,177,185,186,187,188,189,191,193,194,195,196,199,201,211,213,216,218,219,220,233,234,244,246,248,253,256,258,260,263,265,270,272,274,277,281,282,291,293,296,299,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,365,367,368,370,374,375,377,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[49,49,-140,49,49,49,-55,-143,-139,-137,-141,49,49,49,49,-56,49,-9,-7,49,49,49,49,-8,-142,49,49,49,49,49,-144,49,-138,-57,49,-58,49,49,49,49,49,49,-125,-116,-120,-115,49,-118,-122,-117,-121,-124,-126,-123,-119,49,49,-181,-180,49,49,49,49,49,49,49,49,49,49,49,49,-241,49,-237,-236,-244,-239,-242,-240,-238,-6,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,-51,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,-245,49,-243,49,49,49,49,49,49,49,49,-168,49,49,49,49,49,49,49,-163,-158,49,49,49,49,49,-371,49,49,49,-153,49,-177,-145,49,-169,49,-174,49,49,-162,49,49,49,49,-372,49,49,49,49,49,49,-150,49,-146,-147,-155,-52,49,49,-164,49,49,49,-157,49,49,49,49,49,49,-178,49,49,-149,-148,49,-10,-159,-160,-165,49,-371,49,-154,49,49,49,-179,49,-152,-11,49,49,49,49,49,-372,49,49,-151,-12,-156,49,-166,-167,49,-14,-15,49,49,49,49,49,-13,-161,-16,-17,-18,-19,]),'AS':([10,12,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,90,98,101,105,107,108,109,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,204,210,215,222,223,224,225,226,228,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,333,336,344,351,358,364,371,378,388,395,397,407,418,422,436,],[-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-288,218,-279,-272,-271,227,-215,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-231,-290,-289,-274,-276,-277,-275,-273,-216,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-217,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,479,-218,-220,494,]),'OR':([10,12,23,30,32,35,37,38,46,48,51,52,67,68,72,75,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,300,305,311,336,344,351,358,364,371,378,395,397,],[-270,-250,-264,-297,-246,-298,-278,-254,157,-230,-258,-282,-295,-232,-296,-226,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,260,-293,-260,-259,-284,-286,-281,-291,-233,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-228,-253,-249,-257,-225,-315,-285,-316,-235,-229,]),'LEFTSHIFT':([10,23,30,35,37,51,52,67,72,90,101,105,107,131,132,140,151,160,162,164,166,170,181,183,210,215,222,223,224,225,226,239,240,241,262,267,268,269,271,278,279,280,300,364,371,378,612,630,636,659,669,671,682,688,695,],[-270,-264,-297,-298,-278,161,-282,-295,-296,-288,-279,-272,-271,-265,-266,-299,-280,-293,-260,161,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-267,-268,-269,-294,-262,-263,-261,-314,-287,-317,-283,-292,-315,-285,-316,640,640,640,640,640,640,640,640,640,]),'CONTINUE':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[53,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,53,-144,-138,-57,53,-58,-181,-180,53,-6,53,53,-51,53,53,53,-168,53,53,53,-163,-158,-153,-177,-145,-169,-174,53,53,-162,53,53,53,-150,-146,-147,-155,-52,53,53,-164,53,-157,53,-178,53,53,-149,-148,-10,-159,-160,-165,-154,-179,53,-152,-11,53,53,53,-151,-12,-156,53,-166,-167,-14,-15,53,-13,-161,-16,-17,-18,-19,]),'NOT':([0,1,6,7,10,12,14,16,18,23,24,28,29,30,32,33,35,37,38,42,44,47,49,51,52,55,57,63,64,65,67,68,72,73,74,82,83,85,86,89,90,95,96,97,101,105,107,113,116,117,118,119,120,121,122,123,124,125,126,127,128,129,131,132,135,136,138,140,143,147,149,151,155,157,160,162,164,165,166,169,170,177,181,183,189,190,196,199,201,210,213,215,216,219,220,222,223,224,225,226,232,234,239,240,241,247,248,254,256,258,260,262,263,265,267,268,269,270,271,272,274,278,279,280,281,282,291,293,296,299,300,303,305,309,310,312,314,315,316,318,324,328,330,336,341,344,346,347,350,351,353,354,355,356,360,364,365,367,368,370,371,374,375,377,378,391,394,395,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[83,83,-140,83,-270,-250,-55,-143,-139,-264,-137,-141,83,-297,-246,83,-298,-278,-254,-56,-9,-7,83,-258,-282,83,83,-8,-142,83,-295,192,-296,83,83,83,83,-144,83,-138,-288,-57,83,-58,-279,-272,-271,-251,83,-125,-116,-120,-115,83,-118,-122,-117,-121,-124,-126,-123,-119,-265,-266,-181,-180,83,-299,-247,83,-255,-280,83,83,-293,-260,-259,83,-284,83,-286,83,-281,-291,306,192,-6,83,83,-290,83,-289,83,83,83,-274,-276,-277,-275,-273,-252,83,-267,-268,-269,-248,83,-256,83,-51,83,-294,83,83,-262,-263,-261,83,-314,83,83,-287,-317,-283,83,83,83,83,83,83,-292,83,-234,83,83,83,83,83,83,83,83,-168,83,-253,83,-249,83,83,83,-257,83,-163,-158,83,83,-315,83,83,83,-371,-285,83,83,83,-316,-153,83,-235,-177,-145,83,-169,83,-174,83,83,-162,83,83,83,83,-372,83,83,83,83,83,83,-150,83,-146,-147,-155,-52,83,83,-164,83,83,83,-157,83,83,83,83,83,83,-178,83,83,-149,-148,83,-10,-159,-160,-165,83,-371,83,-154,83,83,83,-179,83,-152,-11,83,83,83,83,83,-372,83,83,-151,-12,-156,83,-166,-167,83,-14,-15,83,83,83,83,83,-13,-161,-16,-17,-18,-19,]),'LAMBDA':([0,1,6,7,14,16,18,24,28,29,33,42,44,47,49,55,57,63,64,65,73,74,82,85,86,89,95,96,97,116,117,118,119,120,121,122,123,124,125,126,127,128,129,135,136,147,155,165,169,177,196,201,213,216,219,220,234,248,256,258,263,265,270,272,274,281,282,291,293,296,299,303,309,312,314,315,316,318,324,328,330,341,346,347,350,353,354,355,356,360,365,367,368,370,374,375,377,391,394,401,404,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[54,54,-140,54,-55,-143,-139,-137,-141,54,54,-56,-9,-7,54,54,54,-8,-142,54,54,54,54,-144,54,-138,-57,54,-58,54,-125,-116,-120,-115,54,-118,-122,-117,-121,-124,-126,-123,-119,-181,-180,54,54,54,54,54,-6,54,54,54,54,54,54,54,54,-51,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,-168,54,54,54,54,54,54,-163,-158,54,54,54,54,54,-371,54,54,54,-153,54,-177,-145,-169,54,-174,54,54,-162,54,54,54,54,-372,54,54,54,54,523,54,-150,54,-146,-147,-155,-52,54,54,-164,54,54,54,-157,54,54,54,54,54,54,-178,54,54,-149,-148,523,-10,-159,-160,-165,54,-371,54,-154,523,523,523,-179,54,-152,-11,54,54,54,54,54,-372,523,523,-151,-12,-156,54,-166,-167,54,-14,-15,54,54,54,54,54,-13,-161,-16,-17,-18,-19,]),'NEWLINE':([0,3,4,5,6,10,12,14,15,16,17,18,19,20,21,23,24,27,28,29,30,32,33,35,36,37,38,40,41,42,44,46,47,48,50,51,52,53,55,58,59,60,62,63,64,66,67,68,69,70,72,73,75,76,77,78,79,81,82,85,88,89,90,94,95,96,97,101,105,107,108,109,110,111,113,114,115,131,132,135,136,139,140,141,142,143,145,146,149,151,155,156,160,162,164,166,170,178,179,181,183,190,196,197,198,200,201,203,204,205,210,215,216,217,219,222,223,224,225,226,228,231,232,235,236,237,238,239,240,241,244,245,247,248,249,250,254,258,261,262,267,268,269,271,278,279,280,295,297,299,300,305,311,312,313,315,318,326,328,330,331,333,334,336,337,338,339,342,343,344,345,346,350,351,354,355,358,364,371,378,388,389,390,391,395,396,397,398,401,402,404,405,406,407,409,412,413,417,418,419,422,423,424,425,426,428,429,432,435,437,464,468,471,472,475,476,477,478,481,482,486,487,488,490,491,492,493,495,497,517,518,524,525,528,529,530,531,532,533,534,536,543,544,546,547,549,565,574,575,576,577,578,581,582,583,585,586,602,605,610,613,614,615,616,617,618,629,633,636,641,642,643,644,650,651,652,656,657,658,659,662,666,667,671,676,679,684,691,],[8,95,-188,97,-140,-270,-250,-55,-111,-143,-72,-139,-221,-85,-64,-264,-137,-219,-141,-93,-297,-246,-73,-298,-68,-278,-254,-71,153,-56,-9,-222,-7,-230,-67,-258,-282,-92,-95,-88,-69,-87,-65,-8,-142,-89,-295,-232,-91,-90,-296,-5,-226,-86,-131,-70,-187,-99,-100,-144,-66,-138,-288,-60,-57,-59,-58,-279,-272,-271,-203,-215,-189,-211,-251,-106,-114,-265,-266,-181,-180,-94,-299,-84,-338,-247,-75,-74,-255,-280,257,-223,-293,-260,-259,-284,-286,-96,-102,-281,-291,-233,-6,-109,-227,-133,-132,-101,-231,317,-290,-289,-61,-62,257,-274,-276,-277,-275,-273,-216,-212,-252,-113,-112,-128,-127,-267,-268,-269,-339,-340,-248,-79,-80,-76,-256,-51,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-103,257,-292,-234,-228,-134,-135,257,257,-63,-168,257,-204,-217,-213,-253,-107,-130,-129,-342,-341,-249,-82,-81,257,-257,-163,-158,-225,-315,-285,-316,-398,-97,-105,-153,-235,-110,-229,-136,-177,470,-145,-205,-190,-201,-191,-196,-197,-169,-218,-214,-220,-343,-83,-78,-77,-174,257,-162,257,257,-104,257,526,-150,-146,-147,-206,-207,-194,-193,-108,541,-155,-52,257,257,-164,257,-157,-98,257,-178,257,257,-149,-148,-209,-208,-202,-192,-198,-10,582,-159,-160,-165,-154,-179,257,-152,-210,-195,541,-11,257,257,257,-151,628,632,-12,643,-156,257,-166,-167,-14,-15,653,660,257,-13,-161,660,-16,670,672,673,674,675,678,-17,-18,680,660,-19,693,697,]),'RAISE':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[55,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,55,-144,-138,-57,55,-58,-181,-180,55,-6,55,55,-51,55,55,55,-168,55,55,55,-163,-158,-153,-177,-145,-169,-174,55,55,-162,55,55,55,-150,-146,-147,-155,-52,55,55,-164,55,-157,55,-178,55,55,-149,-148,-10,-159,-160,-165,-154,-179,55,-152,-11,55,55,55,-151,-12,-156,55,-166,-167,-14,-15,55,-13,-161,-16,-17,-18,-19,]),'GLOBAL':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[56,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,56,-144,-138,-57,56,-58,-181,-180,56,-6,56,56,-51,56,56,56,-168,56,56,56,-163,-158,-153,-177,-145,-169,-174,56,56,-162,56,56,56,-150,-146,-147,-155,-52,56,56,-164,56,-157,56,-178,56,56,-149,-148,-10,-159,-160,-165,-154,-179,56,-152,-11,56,56,56,-151,-12,-156,56,-166,-167,-14,-15,56,-13,-161,-16,-17,-18,-19,]),'WHILE':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,97,135,136,196,258,328,353,354,355,391,401,404,417,428,430,432,472,475,476,488,490,493,497,524,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[57,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,57,-144,-138,-57,-58,-181,-180,-6,-51,-168,57,-163,-158,-153,-177,-145,-169,-174,57,-162,-150,-146,-147,-155,-52,-164,-157,-178,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'VBAR':([10,12,23,30,32,35,37,38,51,52,67,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,336,344,351,364,371,378,],[-270,-250,-264,-297,144,-298,-278,-254,-258,-282,-295,-296,-288,-279,-272,-271,-251,-265,-266,-299,246,-255,-280,-293,-260,-259,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-253,-249,-257,-315,-285,-316,]),'STAR':([10,30,35,37,52,54,67,72,90,101,105,107,140,151,160,165,166,170,181,183,210,215,222,223,224,225,226,251,262,271,274,278,279,280,292,300,316,319,321,364,370,371,378,383,410,444,459,512,523,],[102,-297,-298,-278,-282,172,-295,-296,-288,-279,-272,102,-299,-280,-293,270,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,172,-294,-314,365,-287,-317,-283,385,-292,270,406,412,-315,-371,-285,-316,455,482,-372,513,560,172,]),'DOT':([30,35,52,67,72,87,90,109,140,160,166,170,183,208,209,210,215,228,262,271,278,279,300,322,333,364,378,418,],[-297,-298,167,-295,-296,209,-288,229,-299,-293,167,-286,-291,322,-199,-290,-289,332,-294,-314,-287,-317,-292,-200,-217,-315,-316,-218,]),'LEFTSHIFTEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,129,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'TILDE':([0,1,6,7,9,13,14,16,18,24,28,29,31,33,39,42,43,44,47,49,55,57,61,63,64,65,73,74,82,83,85,86,89,95,96,97,102,103,104,106,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,138,144,147,150,155,157,161,163,165,168,169,177,185,186,187,188,189,191,193,194,195,196,199,201,211,213,216,218,219,220,233,234,244,246,248,253,256,258,260,263,265,270,272,274,277,281,282,291,293,296,299,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,365,367,368,370,374,375,377,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[61,61,-140,61,61,61,-55,-143,-139,-137,-141,61,61,61,61,-56,61,-9,-7,61,61,61,61,-8,-142,61,61,61,61,61,-144,61,-138,-57,61,-58,61,61,61,61,61,61,-125,-116,-120,-115,61,-118,-122,-117,-121,-124,-126,-123,-119,61,61,-181,-180,61,61,61,61,61,61,61,61,61,61,61,61,-241,61,-237,-236,-244,-239,-242,-240,-238,-6,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,-51,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,-245,61,-243,61,61,61,61,61,61,61,61,-168,61,61,61,61,61,61,61,-163,-158,61,61,61,61,61,-371,61,61,61,-153,61,-177,-145,61,-169,61,-174,61,61,-162,61,61,61,61,-372,61,61,61,61,61,61,-150,61,-146,-147,-155,-52,61,61,-164,61,61,61,-157,61,61,61,61,61,61,-178,61,61,-149,-148,61,-10,-159,-160,-165,61,-371,61,-154,61,61,61,-179,61,-152,-11,61,61,61,61,61,-372,61,61,-151,-12,-156,61,-166,-167,61,-14,-15,61,61,61,61,61,-13,-161,-16,-17,-18,-19,]),'RSQB':([10,12,19,23,27,30,32,35,37,38,46,48,51,52,65,67,68,72,75,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,182,183,184,190,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,281,282,283,284,285,286,295,300,302,303,304,305,311,336,344,351,358,364,371,372,373,374,375,376,377,378,388,393,394,395,397,422,447,448,449,450,451,467,504,505,506,519,520,521,522,557,566,567,568,571,597,598,599,601,625,626,627,],[-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,183,-295,-232,-296,-226,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,300,-291,-301,-233,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-326,-327,-325,-318,378,-324,-397,-292,-300,-302,-303,-234,-228,-253,-249,-257,-225,-315,-285,-330,-332,-328,-329,-320,-319,-316,-398,-305,-304,-235,-229,-220,-331,-333,-337,-321,-322,-306,-335,-334,-323,-376,-388,-394,-393,-336,-377,-379,-378,-389,-380,-391,-390,-395,-381,-392,-396,]),'PERCENT':([10,30,35,37,52,67,72,90,101,105,107,140,151,160,166,170,181,183,210,215,222,223,224,225,226,262,271,278,279,280,300,364,371,378,],[103,-297,-298,-278,-282,-295,-296,-288,-279,-272,103,-299,-280,-293,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-294,-314,-287,-317,-283,-292,-315,-285,-316,]),'DOUBLESLASH':([10,30,35,37,52,67,72,90,101,105,107,140,151,160,166,170,181,183,210,215,222,223,224,225,226,262,271,278,279,280,300,364,371,378,],[104,-297,-298,-278,-282,-295,-296,-288,-279,-272,104,-299,-280,-293,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-294,-314,-287,-317,-283,-292,-315,-285,-316,]),'EQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,82,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,173,174,181,183,190,198,200,201,203,204,210,215,222,223,224,225,226,232,237,238,239,240,241,247,254,261,262,267,268,269,271,275,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,381,386,388,395,397,398,422,456,612,630,636,659,669,671,682,688,695,],[-270,-250,121,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-100,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-426,291,-281,-291,-233,-227,-133,-132,-101,-231,-290,-289,-274,-276,-277,-275,-273,-252,121,121,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,368,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-427,461,-398,-235,-229,-136,-220,510,639,639,639,639,639,639,639,639,639,]),'PLUSEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,123,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'ELLIPSIS':([169,377,450,],[286,286,286,]),'LESSEQUAL':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,194,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,194,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'LSQB':([0,1,6,7,9,13,14,16,18,24,28,29,30,31,33,35,39,42,43,44,47,49,52,55,57,61,63,64,65,67,72,73,74,82,83,85,86,89,90,95,96,97,102,103,104,106,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,138,140,144,147,150,155,157,160,161,163,165,166,168,169,170,177,183,185,186,187,188,189,191,193,194,195,196,199,201,210,211,213,215,216,218,219,220,233,234,244,246,248,253,256,258,260,262,263,265,270,271,272,274,277,278,279,281,282,291,293,296,299,300,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,364,365,367,368,370,374,375,377,378,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[65,65,-140,65,65,65,-55,-143,-139,-137,-141,65,-297,65,65,-298,65,-56,65,-9,-7,65,169,65,65,65,-8,-142,65,-295,-296,65,65,65,65,-144,65,-138,-288,-57,65,-58,65,65,65,65,65,65,-125,-116,-120,-115,65,-118,-122,-117,-121,-124,-126,-123,-119,65,65,-181,-180,65,-299,65,65,65,65,65,-293,65,65,65,169,65,65,-286,65,-291,-241,65,-237,-236,-244,-239,-242,-240,-238,-6,65,65,-290,65,65,-289,65,65,65,65,65,65,65,65,65,65,65,-51,65,-294,65,65,65,-314,65,65,65,-287,-317,65,65,65,65,65,65,-292,65,65,-245,65,-243,65,65,65,65,65,65,65,65,-168,65,65,65,65,65,65,65,-163,-158,65,65,-315,65,65,65,-371,65,65,65,-316,-153,65,-177,-145,65,-169,65,-174,65,65,-162,65,65,65,65,-372,65,65,65,65,65,65,-150,65,-146,-147,-155,-52,65,65,-164,65,65,65,-157,65,65,65,65,65,65,-178,65,65,-149,-148,65,-10,-159,-160,-165,65,-371,65,-154,65,65,65,-179,65,-152,-11,65,65,65,65,65,-372,65,65,-151,-12,-156,65,-166,-167,65,-14,-15,65,65,65,65,65,-13,-161,-16,-17,-18,-19,]),'GREATER':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,187,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,187,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'VBAREQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,127,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'BREAK':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[69,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,69,-144,-138,-57,69,-58,-181,-180,69,-6,69,69,-51,69,69,69,-168,69,69,69,-163,-158,-153,-177,-145,-169,-174,69,69,-162,69,69,69,-150,-146,-147,-155,-52,69,69,-164,69,-157,69,-178,69,69,-149,-148,-10,-159,-160,-165,-154,-179,69,-152,-11,69,69,69,-151,-12,-156,69,-166,-167,-14,-15,69,-13,-161,-16,-17,-18,-19,]),'STAREQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,117,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'ELIF':([95,97,258,404,472,475,490,529,602,],[-57,-58,-51,473,-150,473,-52,-149,-151,]),'SLASHEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,126,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'NUMBER':([0,1,6,7,9,13,14,16,18,24,28,29,31,33,39,42,43,44,47,49,55,57,61,63,64,65,73,74,82,83,85,86,89,95,96,97,102,103,104,106,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,138,144,147,150,155,157,161,163,165,168,169,177,185,186,187,188,189,191,193,194,195,196,199,201,211,213,216,218,219,220,233,234,244,246,248,253,256,258,260,263,265,270,272,274,277,281,282,291,293,296,299,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,365,367,368,370,374,375,377,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[72,72,-140,72,72,72,-55,-143,-139,-137,-141,72,72,72,72,-56,72,-9,-7,72,72,72,72,-8,-142,72,72,72,72,72,-144,72,-138,-57,72,-58,72,72,72,72,72,72,-125,-116,-120,-115,72,-118,-122,-117,-121,-124,-126,-123,-119,72,72,-181,-180,72,72,72,72,72,72,72,72,72,72,72,72,-241,72,-237,-236,-244,-239,-242,-240,-238,-6,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-51,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,-245,72,-243,72,72,72,72,72,72,72,72,-168,72,72,72,72,72,72,72,-163,-158,72,72,72,72,72,-371,72,72,72,-153,72,-177,-145,72,-169,72,-174,72,72,-162,72,72,72,72,-372,72,72,72,72,72,72,-150,72,-146,-147,-155,-52,72,72,-164,72,72,72,-157,72,72,72,72,72,72,-178,72,72,-149,-148,72,-10,-159,-160,-165,72,-371,72,-154,72,72,72,-179,72,-152,-11,72,72,72,72,72,-372,72,72,-151,-12,-156,72,-166,-167,72,-14,-15,72,72,72,72,72,-13,-161,-16,-17,-18,-19,]),'RPAR':([1,10,12,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,82,90,91,92,93,101,105,107,113,131,132,140,143,149,151,156,160,162,164,165,166,170,173,174,181,183,190,198,200,201,203,204,210,212,213,214,215,222,223,224,225,226,232,239,240,241,247,251,254,261,262,267,268,269,271,273,275,276,278,279,280,287,288,289,290,292,294,295,300,305,311,312,313,314,316,324,325,336,340,344,349,351,358,362,363,364,366,369,370,371,378,379,380,381,383,384,386,388,395,397,398,400,403,405,407,415,422,443,444,445,446,452,453,456,458,459,460,462,477,478,480,484,485,500,507,508,509,511,512,516,521,522,531,532,533,535,537,538,539,554,555,559,562,563,577,579,591,593,594,596,601,603,620,622,627,645,647,665,],[90,-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-100,-288,210,-308,215,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,271,-284,-286,-426,-402,-281,-291,-233,-227,-133,-132,-101,-231,-290,-310,-309,-307,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,348,-256,-224,-294,-262,-263,-261,-314,364,-373,-357,-287,-317,-283,-428,381,-419,-407,-403,-421,-397,-292,-234,-228,-134,-135,399,402,-311,-312,-253,421,-249,427,-257,-225,-359,-361,-315,-362,-374,-358,-285,-316,-429,-430,-427,-408,-412,-422,-398,-235,-229,-136,469,471,-205,-201,-313,-220,-364,-363,-366,-375,-432,-431,-424,-417,-413,-399,-401,-206,-207,534,536,-382,-367,-433,-420,-404,-406,-418,-423,-394,-393,-209,-208,-202,578,-385,-384,-383,-360,-369,-425,-409,-411,-210,-386,-365,-414,-416,-400,-395,-387,-368,-405,-396,-370,-410,-415,]),'ASSERT':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[74,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,74,-144,-138,-57,74,-58,-181,-180,74,-6,74,74,-51,74,74,74,-168,74,74,74,-163,-158,-153,-177,-145,-169,-174,74,74,-162,74,74,74,-150,-146,-147,-155,-52,74,74,-164,74,-157,74,-178,74,74,-149,-148,-10,-159,-160,-165,-154,-179,74,-152,-11,74,74,74,-151,-12,-156,74,-166,-167,-14,-15,74,-13,-161,-16,-17,-18,-19,]),'RIGHTSHIFTEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,128,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'GREATEREQUAL':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,191,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,191,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'SEMI':([3,4,10,12,15,17,19,20,21,23,27,29,30,32,33,35,36,37,38,40,46,48,50,51,52,53,55,58,59,60,62,66,67,68,69,70,72,75,76,77,78,79,81,82,88,90,94,101,105,107,108,109,110,111,113,114,115,131,132,139,140,141,142,143,145,146,149,151,156,160,162,164,166,170,178,179,181,183,190,197,198,200,201,203,204,210,215,217,222,223,224,225,226,228,231,232,235,236,237,238,239,240,241,244,245,247,248,249,250,254,261,262,267,268,269,271,278,279,280,295,297,300,305,311,312,313,326,331,333,334,336,337,338,339,342,343,344,345,346,351,358,364,371,378,388,389,390,395,396,397,398,405,406,407,409,412,413,418,419,422,423,424,425,426,464,477,478,481,482,486,517,531,532,533,534,536,577,578,],[96,-188,-270,-250,-111,-72,-221,-85,-64,-264,-219,-93,-297,-246,-73,-298,-68,-278,-254,-71,-222,-230,-67,-258,-282,-92,-95,-88,-69,-87,-65,-89,-295,-232,-91,-90,-296,-226,-86,-131,-70,-187,-99,-100,-66,-288,216,-279,-272,-271,-203,-215,-189,-211,-251,-106,-114,-265,-266,-94,-299,-84,-338,-247,-75,-74,-255,-280,-223,-293,-260,-259,-284,-286,-96,-102,-281,-291,-233,-109,-227,-133,-132,-101,-231,-290,-289,-62,-274,-276,-277,-275,-273,-216,-212,-252,-113,-112,-128,-127,-267,-268,-269,-339,-340,-248,-79,-80,-76,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-103,-292,-234,-228,-134,-135,-63,-204,-217,-213,-253,-107,-130,-129,-342,-341,-249,-82,-81,-257,-225,-315,-285,-316,-398,-97,-105,-235,-110,-229,-136,-205,-190,-201,-191,-196,-197,-218,-214,-220,-343,-83,-78,-77,-104,-206,-207,-194,-193,-108,-98,-209,-208,-202,-192,-198,-210,-195,]),'DOUBLESLASHEQUAL':([10,12,15,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,101,105,107,113,131,132,140,143,149,151,156,160,162,164,166,170,181,183,190,198,200,201,204,210,215,222,223,224,225,226,232,239,240,241,247,254,261,262,267,268,269,271,278,279,280,295,300,305,311,312,313,336,344,351,358,364,371,378,388,395,397,398,422,],[-270,-250,124,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,-131,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-227,-133,-132,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-224,-294,-262,-263,-261,-314,-287,-317,-283,-397,-292,-234,-228,-134,-135,-253,-249,-257,-225,-315,-285,-316,-398,-235,-229,-136,-220,]),'COMMA':([10,12,19,23,27,30,32,35,37,38,46,48,51,52,67,68,72,75,77,90,92,98,99,101,105,107,108,109,111,113,131,132,140,142,143,146,149,151,156,159,160,162,164,166,170,173,174,178,179,181,183,184,190,197,198,200,204,210,212,215,222,223,224,225,226,228,231,232,239,240,241,245,247,249,250,254,261,262,264,267,268,269,271,275,276,278,279,280,281,282,283,284,286,287,289,290,295,300,304,305,311,313,325,327,329,331,333,334,336,337,342,344,345,351,358,359,361,362,364,366,369,371,372,373,374,375,376,378,380,381,384,386,388,389,390,393,395,397,398,405,407,415,418,419,422,423,424,426,436,438,439,443,446,447,448,449,451,452,456,458,460,467,478,485,500,504,505,506,507,509,516,520,521,522,531,533,537,538,539,555,557,559,562,571,577,579,588,593,598,601,603,619,626,627,],[-270,-250,-221,-264,-219,-297,-246,-298,-278,-254,-222,-230,-258,-282,-295,-232,-296,-226,201,-288,213,-170,220,-279,-272,-271,-203,-215,230,-251,-265,-266,-299,244,-247,248,-255,-280,-223,263,-293,-260,-259,-284,-286,-426,292,296,298,-281,-291,303,-233,309,-227,312,-231,-290,324,-289,-274,-276,-277,-275,-273,-216,335,-252,-267,-268,-269,343,-248,346,347,-256,-224,-294,360,-262,-263,-261,-314,-373,370,-287,-317,-283,-326,-327,-325,377,-324,379,382,383,-397,-292,394,-234,-228,-135,-312,-171,220,-204,-217,-213,-253,420,-342,-249,-82,-257,-225,-355,440,442,-315,444,-374,-285,-330,-332,-328,-329,450,-316,453,-427,459,-422,-398,463,298,-305,-235,-229,-136,477,-201,-313,-218,-214,-220,-343,-83,248,496,-356,498,503,-375,-331,-333,-337,-322,-432,-424,512,515,-306,532,-382,553,-335,-334,-323,-433,558,-423,570,-394,-393,-209,-202,-385,-384,-383,590,-336,-425,595,599,-210,-386,-353,623,-391,-395,-387,-354,-392,-396,]),'CLASS':([0,6,14,16,18,22,24,25,28,42,44,47,63,64,73,85,89,95,97,130,135,136,196,258,317,328,353,354,355,391,401,404,417,428,430,432,470,472,475,476,488,490,493,497,524,526,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[80,-140,-55,-143,-139,-183,-137,80,-141,-56,-9,-7,-8,-142,80,-144,-138,-57,-58,-182,-181,-180,-6,-51,-184,-168,80,-163,-158,-153,-177,-145,-169,-174,80,-162,-185,-150,-146,-147,-155,-52,-164,-157,-178,-186,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'RIGHTSHIFT':([10,23,30,33,35,37,51,52,67,72,90,101,105,107,131,132,140,151,160,162,164,166,170,181,183,210,215,222,223,224,225,226,239,240,241,262,267,268,269,271,278,279,280,300,364,371,378,612,630,636,659,669,671,682,688,695,],[-270,-264,-297,147,-298,-278,163,-282,-295,-296,-288,-279,-272,-271,-265,-266,-299,-280,-293,-260,163,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-267,-268,-269,-294,-262,-263,-261,-314,-287,-317,-283,-292,-315,-285,-316,635,635,635,635,635,635,635,635,635,]),'STRING':([0,1,6,7,9,13,14,16,18,24,28,29,30,31,33,35,39,42,43,44,47,49,55,57,61,63,64,65,73,74,82,83,85,86,89,95,96,97,102,103,104,106,112,116,117,118,119,120,121,122,123,124,125,126,127,128,129,133,134,135,136,138,140,144,147,150,155,157,161,163,165,168,169,177,185,186,187,188,189,191,193,194,195,196,199,201,211,213,216,218,219,220,233,234,244,246,248,253,256,258,260,263,265,270,272,274,277,281,282,291,293,296,299,301,303,306,307,308,309,310,312,314,315,316,318,324,328,330,341,343,346,347,350,353,354,355,356,360,365,367,368,370,374,375,377,391,394,401,404,414,417,420,428,429,430,432,435,437,440,442,444,447,450,461,463,466,468,472,473,475,476,488,490,491,492,493,494,495,496,497,498,501,502,505,510,518,524,525,528,529,530,540,543,546,547,549,552,553,556,565,569,570,573,574,575,576,580,582,583,585,586,587,589,590,599,600,602,613,615,616,617,618,621,629,633,635,637,639,640,642,643,644,651,666,667,679,],[35,35,-140,35,35,35,-55,-143,-139,-137,-141,35,140,35,35,-298,35,-56,35,-9,-7,35,35,35,35,-8,-142,35,35,35,35,35,-144,35,-138,-57,35,-58,35,35,35,35,35,35,-125,-116,-120,-115,35,-118,-122,-117,-121,-124,-126,-123,-119,35,35,-181,-180,35,-299,35,35,35,35,35,35,35,35,35,35,35,-241,35,-237,-236,-244,-239,-242,-240,-238,-6,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,-51,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,-245,35,-243,35,35,35,35,35,35,35,35,-168,35,35,35,35,35,35,35,-163,-158,35,35,35,35,35,-371,35,35,35,-153,35,-177,-145,35,-169,35,-174,35,35,-162,35,35,35,35,-372,35,35,35,35,35,35,-150,35,-146,-147,-155,-52,35,35,-164,35,35,35,-157,35,35,35,35,35,35,-178,35,35,-149,-148,35,-10,-159,-160,-165,35,-371,35,-154,35,35,35,-179,35,-152,605,-11,35,35,35,35,35,-372,35,35,-151,-12,-156,35,-166,-167,35,-14,-15,35,35,35,35,35,-13,-161,-16,-17,-18,-19,]),'COLONEQUAL':([612,630,636,659,669,671,682,688,695,],[637,637,637,637,637,637,637,637,637,]),'IS':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,131,132,140,143,149,151,160,162,164,166,170,181,183,190,210,215,222,223,224,225,226,232,239,240,241,247,254,262,267,268,269,271,278,279,280,300,305,336,344,351,364,371,378,395,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,189,-296,-288,-279,-272,-271,-251,-265,-266,-299,-247,-255,-280,-293,-260,-259,-284,-286,-281,-291,189,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-253,-249,-257,-315,-285,-316,-235,]),'YIELD':([0,1,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,116,117,118,119,120,121,122,123,124,125,126,127,128,129,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[82,82,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,82,-144,-138,-57,82,-58,82,-125,-116,-120,-115,82,-118,-122,-117,-121,-124,-126,-123,-119,-181,-180,82,-6,82,82,-51,82,82,82,-168,82,82,82,-163,-158,-153,-177,-145,-169,-174,82,82,-162,82,82,82,-150,-146,-147,-155,-52,82,82,-164,82,-157,82,-178,82,82,-149,-148,-10,-159,-160,-165,-154,-179,82,-152,-11,82,82,82,-151,-12,-156,82,-166,-167,-14,-15,82,-13,-161,-16,-17,-18,-19,]),'FINALLY':([95,97,258,259,354,355,432,490,493,546,549,617,618,],[-57,-58,-51,357,-163,434,-162,-52,-164,584,-165,-166,-167,]),'AT':([0,6,14,16,18,22,24,28,42,44,47,63,64,73,85,89,95,97,135,136,196,258,317,328,353,354,355,391,401,404,417,428,430,432,470,472,475,476,488,490,493,497,524,526,529,530,543,546,547,549,565,574,576,582,602,613,615,617,618,629,633,643,644,651,666,667,679,],[84,-140,-55,-143,-139,84,-137,-141,-56,-9,-7,-8,-142,84,-144,-138,-57,-58,-181,-180,-6,-51,-184,-168,84,-163,-158,-153,-177,-145,-169,-174,84,-162,-185,-150,-146,-147,-155,-52,-164,-157,-178,-186,-149,-148,-10,-159,-160,-165,-154,-179,-152,-11,-151,-12,-156,-166,-167,-14,-15,-13,-161,-16,-17,-18,-19,]),'AMPER':([10,23,30,35,37,38,51,52,67,72,90,101,105,107,131,132,140,149,151,160,162,164,166,170,181,183,210,215,222,223,224,225,226,239,240,241,254,262,267,268,269,271,278,279,280,300,351,364,371,378,],[-270,-264,-297,-298,-278,150,-258,-282,-295,-296,-288,-279,-272,-271,-265,-266,-299,253,-280,-293,-260,-259,-284,-286,-281,-291,-290,-289,-274,-276,-277,-275,-273,-267,-268,-269,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-257,-315,-285,-316,]),'IN':([10,12,23,30,32,35,37,38,51,52,67,68,72,90,101,105,107,113,114,131,132,140,142,143,149,151,154,160,162,164,166,170,181,183,190,192,210,215,222,223,224,225,226,232,239,240,241,244,245,247,254,262,267,268,269,271,278,279,280,300,305,323,336,342,343,344,351,364,371,378,392,395,423,],[-270,-250,-264,-297,-246,-298,-278,-254,-258,-282,-295,193,-296,-288,-279,-272,-271,-251,234,-265,-266,-299,-338,-247,-255,-280,256,-293,-260,-259,-284,-286,-281,-291,193,308,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-339,-340,-248,-256,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,414,-253,-342,-341,-249,-257,-315,-285,-316,466,-235,-343,]),'IF':([0,6,10,12,14,16,18,23,24,27,28,30,32,35,37,38,42,44,46,47,48,51,52,63,64,67,68,72,73,75,85,89,90,95,97,101,105,107,113,131,132,135,136,140,143,149,151,156,160,162,164,166,170,181,183,190,196,198,204,210,215,222,223,224,225,226,232,239,240,241,247,254,258,261,262,267,268,269,271,278,279,280,300,305,311,328,336,344,351,353,354,355,358,364,371,378,391,395,397,401,404,417,428,430,432,472,475,476,485,488,490,493,497,519,520,521,522,524,529,530,543,546,547,549,565,571,574,576,579,582,597,598,599,601,602,613,615,617,618,626,627,629,633,643,644,651,666,667,679,],[86,-140,-270,-250,-55,-143,-139,-264,-137,138,-141,-297,-246,-298,-278,-254,-56,-9,-222,-7,-230,-258,-282,-8,-142,-295,-232,-296,86,-226,-144,-138,-288,-57,-58,-279,-272,-271,-251,-265,-266,-181,-180,-299,-247,-255,-280,-223,-293,-260,-259,-284,-286,-281,-291,-233,-6,-227,-231,-290,-289,-274,-276,-277,-275,-273,-252,-267,-268,-269,-248,-256,-51,-224,-294,-262,-263,-261,-314,-287,-317,-283,-292,-234,-228,-168,-253,-249,-257,86,-163,-158,-225,-315,-285,-316,-153,-235,-229,-177,-145,-169,-174,86,-162,-150,-146,-147,540,-155,-52,-164,-157,569,-388,-394,-393,-178,-149,-148,-10,-159,-160,-165,-154,-389,-179,-152,540,-11,569,-391,-390,-395,-151,-12,-156,-166,-167,-392,-396,-14,-15,-13,-161,-16,-17,-18,-19,]),'FROM':([0,6,14,16,18,24,28,42,44,47,63,64,73,85,89,95,96,97,135,136,155,196,216,219,258,299,315,318,328,330,350,353,354,355,391,401,404,417,428,429,430,432,435,437,468,472,475,476,488,490,491,492,493,495,497,518,524,525,528,529,530,543,546,547,549,565,574,575,576,582,583,585,586,602,613,615,616,617,618,629,633,642,643,644,651,666,667,679,],[87,-140,-55,-143,-139,-137,-141,-56,-9,-7,-8,-142,87,-144,-138,-57,87,-58,-181,-180,87,-6,87,87,-51,87,87,87,-168,87,87,87,-163,-158,-153,-177,-145,-169,-174,87,87,-162,87,87,87,-150,-146,-147,-155,-52,87,87,-164,87,-157,87,-178,87,87,-149,-148,-10,-159,-160,-165,-154,-179,87,-152,-11,87,87,87,-151,-12,-156,87,-166,-167,-14,-15,87,-13,-161,-16,-17,-18,-19,]),} _lr_action = { } for _k, _v in _lr_action_items.items(): @@ -26,437 +26,437 @@ del _lr_goto_items _lr_productions = [ ("S' -> enaml","S'",1,None,None,None), - ('enaml -> enaml_module NEWLINE ENDMARKER','enaml',3,'p_enaml1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',324), - ('enaml -> enaml_module ENDMARKER','enaml',2,'p_enaml1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',325), - ('enaml -> NEWLINE ENDMARKER','enaml',2,'p_enaml2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',330), - ('enaml -> ENDMARKER','enaml',1,'p_enaml2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',331), - ('enaml_module -> enaml_module_body','enaml_module',1,'p_enaml_module','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',336), - ('enaml_module_body -> enaml_module_body enaml_module_item','enaml_module_body',2,'p_enaml_module_body1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',357), - ('enaml_module_body -> enaml_module_item','enaml_module_body',1,'p_enaml_module_body2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',362), - ('enaml_module_item -> declaration','enaml_module_item',1,'p_enaml_module_item2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',367), - ('enaml_module_item -> stmt','enaml_module_item',1,'p_enaml_module_item1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',372), - ('declaration -> ENAMLDEF NAME LPAR NAME RPAR COLON declaration_body','declaration',7,'p_declaration1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',380), - ('declaration -> ENAMLDEF NAME LPAR NAME RPAR COLON PASS NEWLINE','declaration',8,'p_declaration2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',392), - ('declaration -> ENAMLDEF NAME LPAR NAME RPAR COLON NAME COLON declaration_body','declaration',9,'p_declaration3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',402), - ('declaration -> ENAMLDEF NAME LPAR NAME RPAR COLON NAME COLON PASS NEWLINE','declaration',10,'p_declaration4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',418), - ('declaration_body -> NEWLINE INDENT declaration_body_items DEDENT','declaration_body',4,'p_declaration_body1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',428), - ('declaration_body -> NEWLINE INDENT identifier DEDENT','declaration_body',4,'p_declaration_body2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',435), - ('declaration_body -> NEWLINE INDENT identifier declaration_body_items DEDENT','declaration_body',5,'p_declaration_body3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',440), - ('declaration_body -> NEWLINE INDENT STRING NEWLINE declaration_body_items DEDENT','declaration_body',6,'p_declaration_body4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',447), - ('declaration_body -> NEWLINE INDENT STRING NEWLINE identifier DEDENT','declaration_body',6,'p_declaration_body5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',454), - ('declaration_body -> NEWLINE INDENT STRING NEWLINE identifier declaration_body_items DEDENT','declaration_body',7,'p_declaration_body6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',459), - ('declaration_body_items -> declaration_body_item','declaration_body_items',1,'p_declaration_body_items1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',466), - ('declaration_body_items -> declaration_body_items declaration_body_item','declaration_body_items',2,'p_declaration_body_items2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',471), - ('declaration_body_item -> attribute_declaration','declaration_body_item',1,'p_declaration_body_item1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',476), - ('declaration_body_item -> attribute_binding','declaration_body_item',1,'p_declaration_body_item2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',481), - ('declaration_body_item -> instantiation','declaration_body_item',1,'p_declaration_body_item3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',486), - ('declaration_body_item -> PASS NEWLINE','declaration_body_item',2,'p_declaration_body_item4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',491), - ('attribute_declaration -> NAME NAME NEWLINE','attribute_declaration',3,'p_attribute_declaration1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',499), - ('attribute_declaration -> NAME NAME COLON NAME NEWLINE','attribute_declaration',5,'p_attribute_declaration2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',504), - ('attribute_declaration -> NAME NAME binding','attribute_declaration',3,'p_attribute_declaration3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',514), - ('attribute_declaration -> NAME NAME COLON NAME binding','attribute_declaration',5,'p_attribute_declaration4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',522), - ('identifier -> NAME COLON NAME NEWLINE','identifier',4,'p_identifier','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',537), - ('instantiation -> NAME COLON instantiation_body','instantiation',3,'p_instantiation1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',549), - ('instantiation -> NAME COLON attribute_binding','instantiation',3,'p_instantiation2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',555), - ('instantiation -> NAME COLON PASS NEWLINE','instantiation',4,'p_instantiation3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',560), - ('instantiation -> NAME COLON NAME COLON instantiation_body','instantiation',5,'p_instantiation4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',565), - ('instantiation -> NAME COLON NAME COLON attribute_binding','instantiation',5,'p_instantiation5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',574), - ('instantiation -> NAME COLON NAME COLON PASS NEWLINE','instantiation',6,'p_instantiation6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',579), - ('instantiation_body -> NEWLINE INDENT instantiation_body_items DEDENT','instantiation_body',4,'p_instantiation_body1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',584), - ('instantiation_body -> NEWLINE INDENT identifier DEDENT','instantiation_body',4,'p_instantiation_body2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',591), - ('instantiation_body -> NEWLINE INDENT identifier instantiation_body_items DEDENT','instantiation_body',5,'p_instantiation_body3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',596), - ('instantiation_body_items -> instantiation_body_item','instantiation_body_items',1,'p_instantiation_body_items1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',603), - ('instantiation_body_items -> instantiation_body_items instantiation_body_item','instantiation_body_items',2,'p_instantiation_body_items2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',608), - ('instantiation_body_item -> instantiation','instantiation_body_item',1,'p_instantiation_body_item1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',613), - ('instantiation_body_item -> attribute_binding','instantiation_body_item',1,'p_instantiation_body_item2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',618), - ('instantiation_body_item -> PASS NEWLINE','instantiation_body_item',2,'p_instantiation_body_item3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',623), - ('attribute_binding -> NAME binding','attribute_binding',2,'p_attribute_binding','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',631), - ('binding -> EQUAL test NEWLINE','binding',3,'p_binding1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',636), - ('binding -> COLONEQUAL test NEWLINE','binding',3,'p_binding1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',637), - ('binding -> LEFTSHIFT test NEWLINE','binding',3,'p_binding1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',638), - ('binding -> RIGHTSHIFT test NEWLINE','binding',3,'p_binding1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',639), - ('binding -> DOUBLECOLON suite','binding',2,'p_binding2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',650), - ('suite -> simple_stmt','suite',1,'p_suite1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',668), - ('suite -> NEWLINE INDENT stmt_list DEDENT','suite',4,'p_suite2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',680), - ('stmt_list -> stmt stmt_list','stmt_list',2,'p_stmt_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',685), - ('stmt_list -> stmt','stmt_list',1,'p_stmt_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',697), - ('stmt -> simple_stmt','stmt',1,'p_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',709), - ('stmt -> compound_stmt','stmt',1,'p_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',710), - ('simple_stmt -> small_stmt NEWLINE','simple_stmt',2,'p_simple_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',715), - ('simple_stmt -> small_stmt_list NEWLINE','simple_stmt',2,'p_simple_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',723), - ('small_stmt_list -> small_stmt SEMI','small_stmt_list',2,'p_small_stmt_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',733), - ('small_stmt_list -> small_stmt small_stmt_list_list','small_stmt_list',2,'p_small_stmt_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',738), - ('small_stmt_list -> small_stmt small_stmt_list_list SEMI','small_stmt_list',3,'p_small_stmt_list3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',743), - ('small_stmt_list_list -> SEMI small_stmt','small_stmt_list_list',2,'p_small_stmt_list_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',748), - ('small_stmt_list_list -> small_stmt_list_list SEMI small_stmt','small_stmt_list_list',3,'p_small_stmt_list_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',753), - ('small_stmt -> expr_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',758), - ('small_stmt -> print_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',759), - ('small_stmt -> del_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',760), - ('small_stmt -> pass_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',761), - ('small_stmt -> flow_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',762), - ('small_stmt -> import_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',763), - ('small_stmt -> global_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',764), - ('small_stmt -> exec_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',765), - ('small_stmt -> assert_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',766), - ('print_stmt -> PRINT','print_stmt',1,'p_print_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',771), - ('print_stmt -> PRINT test','print_stmt',2,'p_print_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',780), - ('print_stmt -> PRINT print_list','print_stmt',2,'p_print_stmt3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',789), - ('print_stmt -> PRINT RIGHTSHIFT test','print_stmt',3,'p_print_stmt4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',804), - ('print_stmt -> PRINT RIGHTSHIFT test COMMA test','print_stmt',5,'p_print_stmt5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',813), - ('print_stmt -> PRINT RIGHTSHIFT test COMMA print_list','print_stmt',5,'p_print_stmt6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',822), - ('print_list -> test COMMA','print_list',2,'p_print_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',837), - ('print_list -> test print_list_list','print_list',2,'p_print_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',842), - ('print_list -> test print_list_list COMMA','print_list',3,'p_print_list3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',847), - ('print_list_list -> COMMA test','print_list_list',2,'p_print_list_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',852), - ('print_list_list -> print_list_list COMMA test','print_list_list',3,'p_print_list_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',857), - ('del_stmt -> DEL exprlist','del_stmt',2,'p_del_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',862), - ('pass_stmt -> PASS','pass_stmt',1,'p_pass_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',871), - ('flow_stmt -> break_stmt','flow_stmt',1,'p_flow_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',878), - ('flow_stmt -> continue_stmt','flow_stmt',1,'p_flow_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',879), - ('flow_stmt -> return_stmt','flow_stmt',1,'p_flow_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',880), - ('flow_stmt -> raise_stmt','flow_stmt',1,'p_flow_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',881), - ('flow_stmt -> yield_stmt','flow_stmt',1,'p_flow_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',882), - ('break_stmt -> BREAK','break_stmt',1,'p_break_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',887), - ('continue_stmt -> CONTINUE','continue_stmt',1,'p_continue_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',894), - ('return_stmt -> RETURN','return_stmt',1,'p_return_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',901), - ('return_stmt -> RETURN testlist','return_stmt',2,'p_return_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',908), - ('raise_stmt -> RAISE','raise_stmt',1,'p_raise_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',916), - ('raise_stmt -> RAISE test','raise_stmt',2,'p_raise_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',925), - ('raise_stmt -> RAISE test COMMA test','raise_stmt',4,'p_raise_stmt3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',934), - ('raise_stmt -> RAISE test COMMA test COMMA test','raise_stmt',6,'p_raise_stmt4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',943), - ('yield_stmt -> yield_expr','yield_stmt',1,'p_yield_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',952), - ('yield_expr -> YIELD','yield_expr',1,'p_yield_expr1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',957), - ('yield_expr -> YIELD testlist','yield_expr',2,'p_yield_expr2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',962), - ('global_stmt -> GLOBAL NAME','global_stmt',2,'p_global_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',968), - ('global_stmt -> GLOBAL NAME globals_list','global_stmt',3,'p_global_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',976), - ('globals_list -> COMMA NAME globals_list','globals_list',3,'p_globals_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',984), - ('globals_list -> COMMA NAME','globals_list',2,'p_globals_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',989), - ('exec_stmt -> EXEC expr','exec_stmt',2,'p_exec_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',994), - ('exec_stmt -> EXEC expr IN test','exec_stmt',4,'p_exec_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1003), - ('exec_stmt -> EXEC expr IN test COMMA test','exec_stmt',6,'p_exec_stmt3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1012), - ('assert_stmt -> ASSERT test','assert_stmt',2,'p_assert_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1021), - ('assert_stmt -> ASSERT test COMMA test','assert_stmt',4,'p_assert_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1029), - ('expr_stmt -> testlist','expr_stmt',1,'p_expr_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1037), - ('expr_stmt -> testlist augassign testlist','expr_stmt',3,'p_expr_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1044), - ('expr_stmt -> testlist augassign yield_expr','expr_stmt',3,'p_expr_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1045), - ('expr_stmt -> testlist equal_list','expr_stmt',2,'p_expr_stmt3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1061), - ('augassign -> AMPEREQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1077), - ('augassign -> CIRCUMFLEXEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1078), - ('augassign -> DOUBLESLASHEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1079), - ('augassign -> DOUBLESTAREQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1080), - ('augassign -> LEFTSHIFTEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1081), - ('augassign -> MINUSEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1082), - ('augassign -> PERCENTEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1083), - ('augassign -> PLUSEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1084), - ('augassign -> RIGHTSHIFTEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1085), - ('augassign -> SLASHEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1086), - ('augassign -> STAREQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1087), - ('augassign -> VBAREQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1088), - ('equal_list -> EQUAL testlist','equal_list',2,'p_equal_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1095), - ('equal_list -> EQUAL yield_expr','equal_list',2,'p_equal_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1096), - ('equal_list -> EQUAL testlist equal_list','equal_list',3,'p_equal_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1101), - ('equal_list -> EQUAL yield_expr equal_list','equal_list',3,'p_equal_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1102), - ('testlist -> test','testlist',1,'p_testlist1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1107), - ('testlist -> test COMMA','testlist',2,'p_testlist2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1112), - ('testlist -> test testlist_list','testlist',2,'p_testlist3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1117), - ('testlist -> test testlist_list COMMA','testlist',3,'p_testlist4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1122), - ('testlist_list -> COMMA test','testlist_list',2,'p_testlist_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1127), - ('testlist_list -> testlist_list COMMA test','testlist_list',3,'p_testlist_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1132), - ('compound_stmt -> if_stmt','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1137), - ('compound_stmt -> while_stmt','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1138), - ('compound_stmt -> for_stmt','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1139), - ('compound_stmt -> try_stmt','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1140), - ('compound_stmt -> with_stmt','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1141), - ('compound_stmt -> funcdef','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1142), - ('compound_stmt -> classdef','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1143), - ('compound_stmt -> decorated','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1144), - ('if_stmt -> IF test COLON suite','if_stmt',4,'p_if_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1149), - ('if_stmt -> IF test COLON suite elif_stmts','if_stmt',5,'p_if_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1160), - ('if_stmt -> IF test COLON suite else_stmt','if_stmt',5,'p_if_stmt3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1171), - ('if_stmt -> IF test COLON suite elif_stmts else_stmt','if_stmt',6,'p_if_stmt4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1182), - ('elif_stmts -> elif_stmts elif_stmt','elif_stmts',2,'p_elif_stmts1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1198), - ('elif_stmts -> elif_stmt','elif_stmts',1,'p_elif_stmts2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1205), - ('elif_stmt -> ELIF test COLON suite','elif_stmt',4,'p_elif_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1210), - ('else_stmt -> ELSE COLON suite','else_stmt',3,'p_else_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1221), - ('while_stmt -> WHILE test COLON suite','while_stmt',4,'p_while_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1226), - ('while_stmt -> WHILE test COLON suite ELSE COLON suite','while_stmt',7,'p_while_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1237), - ('for_stmt -> FOR exprlist IN testlist COLON suite','for_stmt',6,'p_for_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1248), - ('for_stmt -> FOR exprlist IN testlist COLON suite ELSE COLON suite','for_stmt',9,'p_for_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1262), - ('try_stmt -> TRY COLON suite FINALLY COLON suite','try_stmt',6,'p_try_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1276), - ('try_stmt -> TRY COLON suite except_clauses','try_stmt',4,'p_try_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1286), - ('try_stmt -> TRY COLON suite except_clauses ELSE COLON suite','try_stmt',7,'p_try_stmt3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1297), - ('try_stmt -> TRY COLON suite except_clauses FINALLY COLON suite','try_stmt',7,'p_try_stmt4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1308), - ('try_stmt -> TRY COLON suite except_clauses ELSE COLON suite FINALLY COLON suite','try_stmt',10,'p_try_stmt5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1325), - ('except_clauses -> except_clause except_clauses','except_clauses',2,'p_except_clauses1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1342), - ('except_clauses -> except_clause','except_clauses',1,'p_except_clauses2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1347), - ('except_clause -> EXCEPT COLON suite','except_clause',3,'p_except_clause1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1352), - ('except_clause -> EXCEPT test COLON suite','except_clause',4,'p_except_clause2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1363), - ('except_clause -> EXCEPT test AS test COLON suite','except_clause',6,'p_except_clause3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1374), - ('except_clause -> EXCEPT test COMMA test COLON suite','except_clause',6,'p_except_clause3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1375), - ('with_stmt -> WITH with_item COLON suite','with_stmt',4,'p_with_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1388), - ('with_stmt -> WITH with_item with_item_list COLON suite','with_stmt',5,'p_with_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1400), - ('with_item -> test','with_item',1,'p_with_item1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1420), - ('with_item -> test AS expr','with_item',3,'p_with_item2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1425), - ('with_item_list -> COMMA with_item with_item_list','with_item_list',3,'p_with_item_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1432), - ('with_item_list -> COMMA with_item','with_item_list',2,'p_with_item_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1437), - ('funcdef -> DEF NAME parameters COLON suite','funcdef',5,'p_funcdef','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1442), - ('parameters -> LPAR RPAR','parameters',2,'p_parameters1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1454), - ('parameters -> LPAR varargslist RPAR','parameters',3,'p_parameters2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1459), - ('classdef -> CLASS NAME COLON suite','classdef',4,'p_classdef1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1464), - ('classdef -> CLASS NAME LPAR RPAR COLON suite','classdef',6,'p_classdef2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1476), - ('classdef -> CLASS NAME LPAR testlist RPAR COLON suite','classdef',7,'p_classdef3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1488), - ('decorated -> decorators funcdef','decorated',2,'p_decorated','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1503), - ('decorated -> decorators classdef','decorated',2,'p_decorated','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1504), - ('decorators -> decorator decorators','decorators',2,'p_decorators1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1512), - ('decorators -> decorator','decorators',1,'p_decorators2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1517), - ('decorator -> AT dotted_name NEWLINE','decorator',3,'p_decorator1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1522), - ('decorator -> AT dotted_name LPAR RPAR NEWLINE','decorator',5,'p_decorator2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1530), - ('decorator -> AT dotted_name LPAR arglist RPAR NEWLINE','decorator',6,'p_decorator3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1543), - ('import_stmt -> import_name','import_stmt',1,'p_import_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1557), - ('import_stmt -> import_from','import_stmt',1,'p_import_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1562), - ('import_name -> IMPORT dotted_as_names','import_name',2,'p_import_name','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1566), - ('import_from -> FROM dotted_name IMPORT STAR','import_from',4,'p_import_from1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1573), - ('import_from -> FROM dotted_name IMPORT import_as_names','import_from',4,'p_import_from2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1581), - ('import_from -> FROM dotted_name IMPORT LPAR import_as_names RPAR','import_from',6,'p_import_from3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1588), - ('import_from -> FROM import_from_dots dotted_name IMPORT STAR','import_from',5,'p_import_from4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1595), - ('import_from -> FROM import_from_dots dotted_name IMPORT import_as_name','import_from',5,'p_import_from5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1603), - ('import_from -> FROM import_from_dots dotted_name IMPORT LPAR import_as_names RPAR','import_from',7,'p_import_from6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1610), - ('import_from -> FROM import_from_dots IMPORT STAR','import_from',4,'p_import_from7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1617), - ('import_from -> FROM import_from_dots IMPORT import_as_names','import_from',4,'p_import_from8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1625), - ('import_from -> FROM import_from_dots IMPORT LPAR import_as_names RPAR','import_from',6,'p_import_from9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1632), - ('import_from_dots -> DOT','import_from_dots',1,'p_import_from_dots1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1639), - ('import_from_dots -> import_from_dots DOT','import_from_dots',2,'p_import_from_dots2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1644), - ('import_as_name -> NAME','import_as_name',1,'p_import_as_name1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1649), - ('import_as_name -> NAME AS NAME','import_as_name',3,'p_import_as_name2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1654), - ('dotted_as_name -> dotted_name','dotted_as_name',1,'p_dotted_as_name1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1659), - ('dotted_as_name -> dotted_name AS NAME','dotted_as_name',3,'p_dotted_as_name2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1665), - ('import_as_names -> import_as_name','import_as_names',1,'p_import_as_names1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1671), - ('import_as_names -> import_as_name COMMA','import_as_names',2,'p_import_as_names2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1676), - ('import_as_names -> import_as_name import_as_names_list','import_as_names',2,'p_import_as_names3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1681), - ('import_as_names -> import_as_name import_as_names_list COMMA','import_as_names',3,'p_import_as_names4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1686), - ('import_as_names_list -> COMMA import_as_name','import_as_names_list',2,'p_import_as_names_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1691), - ('import_as_names_list -> import_as_names_list COMMA import_as_name','import_as_names_list',3,'p_import_as_names_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1696), - ('dotted_as_names -> dotted_as_name','dotted_as_names',1,'p_dotted_as_names1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1701), - ('dotted_as_names -> dotted_as_name dotted_as_names_list','dotted_as_names',2,'p_dotted_as_names2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1706), - ('dotted_as_names_list -> COMMA dotted_as_name','dotted_as_names_list',2,'p_dotted_as_names_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1711), - ('dotted_as_names_list -> dotted_as_names_list COMMA dotted_as_name','dotted_as_names_list',3,'p_dotted_as_names_star_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1716), - ('dotted_name -> NAME','dotted_name',1,'p_dotted_name1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1721), - ('dotted_name -> NAME dotted_name_list','dotted_name',2,'p_dotted_name2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1726), - ('dotted_name_list -> DOT NAME','dotted_name_list',2,'p_dotted_name_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1731), - ('dotted_name_list -> dotted_name_list DOT NAME','dotted_name_list',3,'p_dotted_name_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1736), - ('test -> or_test','test',1,'p_test1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1741), - ('test -> or_test IF or_test ELSE test','test',5,'p_test2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1746), - ('test -> lambdef','test',1,'p_test3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1752), - ('or_test -> and_test','or_test',1,'p_or_test1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1757), - ('or_test -> and_test or_test_list','or_test',2,'p_or_test2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1762), - ('or_test_list -> OR and_test','or_test_list',2,'p_or_test_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1769), - ('or_test_list -> or_test_list OR and_test','or_test_list',3,'p_or_test_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1774), - ('and_test -> not_test','and_test',1,'p_and_test1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1779), - ('and_test -> not_test and_test_list','and_test',2,'p_and_test2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1784), - ('and_test_list -> AND not_test','and_test_list',2,'p_and_test_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1791), - ('and_test_list -> and_test_list AND not_test','and_test_list',3,'p_and_test_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1796), - ('not_test -> comparison','not_test',1,'p_not_test','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1801), - ('not_test -> NOT not_test','not_test',2,'p_not_test2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1806), - ('comparison -> expr','comparison',1,'p_comparison1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1812), - ('comparison -> expr comparison_list','comparison',2,'p_comparison2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1817), - ('comparison_list -> comp_op expr','comparison_list',2,'p_comparison_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1825), - ('comparison_list -> comparison_list comp_op expr','comparison_list',3,'p_comparison_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1830), - ('comp_op -> LESS','comp_op',1,'p_comp_op1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1835), - ('comp_op -> GREATER','comp_op',1,'p_comp_op2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1840), - ('comp_op -> EQEQUAL','comp_op',1,'p_comp_op3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1845), - ('comp_op -> GREATEREQUAL','comp_op',1,'p_comp_op4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1850), - ('comp_op -> LESSEQUAL','comp_op',1,'p_comp_op5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1855), - ('comp_op -> NOTEQUAL','comp_op',1,'p_comp_op6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1860), - ('comp_op -> IN','comp_op',1,'p_comp_op7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1865), - ('comp_op -> NOT IN','comp_op',2,'p_comp_op8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1870), - ('comp_op -> IS','comp_op',1,'p_comp_op9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1875), - ('comp_op -> IS NOT','comp_op',2,'p_comp_op10','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1880), - ('expr -> xor_expr','expr',1,'p_expr1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1885), - ('expr -> xor_expr expr_list','expr',2,'p_expr2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1890), - ('expr_list -> VBAR xor_expr','expr_list',2,'p_expr_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1898), - ('expr_list -> expr_list VBAR xor_expr','expr_list',3,'p_expr_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1903), - ('xor_expr -> and_expr','xor_expr',1,'p_xor_expr1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1908), - ('xor_expr -> and_expr xor_expr_list','xor_expr',2,'p_xor_expr2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1913), - ('xor_expr_list -> CIRCUMFLEX and_expr','xor_expr_list',2,'p_xor_expr_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1921), - ('xor_expr_list -> xor_expr_list CIRCUMFLEX and_expr','xor_expr_list',3,'p_xor_expr_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1926), - ('and_expr -> shift_expr','and_expr',1,'p_and_expr1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1931), - ('and_expr -> shift_expr and_expr_list','and_expr',2,'p_and_expr2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1936), - ('and_expr_list -> AMPER shift_expr','and_expr_list',2,'p_and_expr_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1944), - ('and_expr_list -> and_expr_list AMPER shift_expr','and_expr_list',3,'p_and_expr_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1949), - ('shift_expr -> arith_expr','shift_expr',1,'p_shift_expr1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1954), - ('shift_expr -> arith_expr shift_list','shift_expr',2,'p_shift_expr2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1959), - ('shift_list -> shift_op','shift_list',1,'p_shift_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1967), - ('shift_list -> shift_list shift_op','shift_list',2,'p_shift_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1972), - ('shift_op -> LEFTSHIFT arith_expr','shift_op',2,'p_shift_op1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1977), - ('shift_op -> RIGHTSHIFT arith_expr','shift_op',2,'p_shift_op2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1982), - ('arith_expr -> term','arith_expr',1,'p_arith_expr1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1987), - ('arith_expr -> term arith_expr_list','arith_expr',2,'p_arith_expr2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1992), - ('arith_expr_list -> arith_op','arith_expr_list',1,'p_arith_expr_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2000), - ('arith_expr_list -> arith_expr_list arith_op','arith_expr_list',2,'p_arith_expr_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2005), - ('arith_op -> PLUS term','arith_op',2,'p_arith_op1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2010), - ('arith_op -> MINUS term','arith_op',2,'p_arith_op2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2016), - ('term -> factor','term',1,'p_term1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2021), - ('term -> factor term_list','term',2,'p_term2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2026), - ('term_list -> term_op','term_list',1,'p_term_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2034), - ('term_list -> term_list term_op','term_list',2,'p_term_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2039), - ('term_op -> STAR factor','term_op',2,'p_term_op1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2044), - ('term_op -> SLASH factor','term_op',2,'p_term_op2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2049), - ('term_op -> PERCENT factor','term_op',2,'p_term_op3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2054), - ('term_op -> DOUBLESLASH factor','term_op',2,'p_term_op4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2059), - ('factor -> power','factor',1,'p_factor1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2064), - ('factor -> PLUS factor','factor',2,'p_factor2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2069), - ('factor -> MINUS factor','factor',2,'p_factor3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2077), - ('factor -> TILDE factor','factor',2,'p_factor4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2085), - ('power -> atom','power',1,'p_power1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2093), - ('power -> atom DOUBLESTAR factor','power',3,'p_power2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2098), - ('power -> atom power_list','power',2,'p_power3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2104), - ('power -> atom power_list DOUBLESTAR factor','power',4,'p_power4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2120), - ('power_list -> trailer','power_list',1,'p_power_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2137), - ('power_list -> power_list trailer','power_list',2,'p_power_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2142), - ('atom -> LPAR RPAR','atom',2,'p_atom1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2147), - ('atom -> LPAR yield_expr RPAR','atom',3,'p_atom2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2152), - ('atom -> LPAR testlist_comp RPAR','atom',3,'p_atom3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2157), - ('atom -> LSQB RSQB','atom',2,'p_atom4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2171), - ('atom -> LSQB listmaker RSQB','atom',3,'p_atom5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2176), - ('atom -> LBRACE RBRACE','atom',2,'p_atom6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2188), - ('atom -> LBRACE dictorsetmaker RBRACE','atom',3,'p_atom7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2193), - ('atom -> NAME','atom',1,'p_atom8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2214), - ('atom -> NUMBER','atom',1,'p_atom9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2219), - ('atom -> atom_string_list','atom',1,'p_atom10','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2225), - ('atom_string_list -> STRING','atom_string_list',1,'p_atom_string_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2231), - ('atom_string_list -> atom_string_list STRING','atom_string_list',2,'p_atom_string_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2236), - ('listmaker -> test list_for','listmaker',2,'p_listmaker1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2246), - ('listmaker -> test','listmaker',1,'p_listmaker2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2251), - ('listmaker -> test COMMA','listmaker',2,'p_listmaker3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2256), - ('listmaker -> test listmaker_list','listmaker',2,'p_listmaker4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2261), - ('listmaker -> test listmaker_list COMMA','listmaker',3,'p_listmaker5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2267), - ('listmaker_list -> COMMA test','listmaker_list',2,'p_listmaker_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2273), - ('listmaker_list -> listmaker_list COMMA test','listmaker_list',3,'p_listmaker_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2278), - ('testlist_comp -> test comp_for','testlist_comp',2,'p_testlist_comp1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2283), - ('testlist_comp -> test','testlist_comp',1,'p_testlist_comp2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2288), - ('testlist_comp -> test COMMA','testlist_comp',2,'p_testlist_comp3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2293), - ('testlist_comp -> test testlist_comp_list','testlist_comp',2,'p_testlist_comp4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2298), - ('testlist_comp -> test testlist_comp_list COMMA','testlist_comp',3,'p_testlist_comp5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2304), - ('testlist_comp_list -> COMMA test','testlist_comp_list',2,'p_testlist_comp_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2310), - ('testlist_comp_list -> testlist_comp_list COMMA test','testlist_comp_list',3,'p_testlist_comp_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2315), - ('trailer -> LPAR RPAR','trailer',2,'p_trailer1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2320), - ('trailer -> LPAR arglist RPAR','trailer',3,'p_trailer2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2325), - ('trailer -> LSQB subscriptlist RSQB','trailer',3,'p_trailer3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2332), - ('trailer -> DOT NAME','trailer',2,'p_trailer4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2337), - ('subscriptlist -> subscript','subscriptlist',1,'p_subscriptlist1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2342), - ('subscriptlist -> subscript COMMA','subscriptlist',2,'p_subscriptlist2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2347), - ('subscriptlist -> subscript subscriptlist_list','subscriptlist',2,'p_subscriptlist3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2353), - ('subscriptlist -> subscript subscriptlist_list COMMA','subscriptlist',3,'p_subscriptlist4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2359), - ('subscriptlist_list -> COMMA subscript','subscriptlist_list',2,'p_subscriptlist_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2365), - ('subscriptlist_list -> subscriptlist_list COMMA subscript','subscriptlist_list',3,'p_subscript_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2370), - ('subscript -> ELLIPSIS','subscript',1,'p_subscript1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2375), - ('subscript -> test','subscript',1,'p_subcript2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2380), - ('subscript -> COLON','subscript',1,'p_subscript3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2385), - ('subscript -> DOUBLECOLON','subscript',1,'p_subscript4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2390), - ('subscript -> test COLON','subscript',2,'p_subscript5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2396), - ('subscript -> test DOUBLECOLON','subscript',2,'p_subscrip6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2401), - ('subscript -> COLON test','subscript',2,'p_subscript7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2407), - ('subscript -> COLON test COLON','subscript',3,'p_subscript8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2412), - ('subscript -> DOUBLECOLON test','subscript',2,'p_subscript9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2418), - ('subscript -> test COLON test','subscript',3,'p_subscript10','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2423), - ('subscript -> test COLON test COLON','subscript',4,'p_subscript11','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2428), - ('subscript -> COLON test COLON test','subscript',4,'p_subscript12','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2434), - ('subscript -> test COLON test COLON test','subscript',5,'p_subscript13','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2439), - ('subscript -> test DOUBLECOLON test','subscript',3,'p_subscript14','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2444), - ('exprlist -> expr','exprlist',1,'p_exprlist1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2449), - ('exprlist -> expr COMMA','exprlist',2,'p_exprlist2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2454), - ('exprlist -> expr exprlist_list','exprlist',2,'p_exprlist3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2461), - ('exprlist -> expr exprlist_list COMMA','exprlist',3,'p_exprlist4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2468), - ('exprlist_list -> COMMA expr','exprlist_list',2,'p_exprlist_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2475), - ('exprlist_list -> exprlist_list COMMA expr','exprlist_list',3,'p_exprlist_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2480), - ('dictorsetmaker -> test COLON test comp_for','dictorsetmaker',4,'p_dictorsetmaker1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2485), - ('dictorsetmaker -> test COLON test','dictorsetmaker',3,'p_dictorsetmaker2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2490), - ('dictorsetmaker -> test COLON test COMMA','dictorsetmaker',4,'p_dictorsetmaker3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2496), - ('dictorsetmaker -> test COLON test dosm_colon_list','dictorsetmaker',4,'p_dictorsetmaker4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2502), - ('dictorsetmaker -> test COLON test dosm_colon_list COMMA','dictorsetmaker',5,'p_dictorsetmaker5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2508), - ('dictorsetmaker -> test comp_for','dictorsetmaker',2,'p_dictorsetmaker6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2514), - ('dictorsetmaker -> test COMMA','dictorsetmaker',2,'p_dictorsetmaker7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2519), - ('dictorsetmaker -> test dosm_comma_list','dictorsetmaker',2,'p_dictorsetmaker8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2525), - ('dictorsetmaker -> test dosm_comma_list COMMA','dictorsetmaker',3,'p_dictorsetmaker9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2531), - ('dosm_colon_list -> COMMA test COLON test','dosm_colon_list',4,'p_dosm_colon_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2537), - ('dosm_colon_list -> dosm_colon_list COMMA test COLON test','dosm_colon_list',5,'p_dosm_colon_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2542), - ('dosm_comma_list -> COMMA test','dosm_comma_list',2,'p_dosm_comma_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2547), - ('dosm_comma_list -> dosm_comma_list COMMA test','dosm_comma_list',3,'p_dosm_comma_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2552), - ('arglist -> argument','arglist',1,'p_arglist1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2557), - ('arglist -> argument COMMA','arglist',2,'p_arglist2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2565), - ('arglist -> STAR test','arglist',2,'p_arglist3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2573), - ('arglist -> STAR test COMMA DOUBLESTAR test','arglist',5,'p_arglist4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2578), - ('arglist -> DOUBLESTAR test','arglist',2,'p_arglist5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2583), - ('arglist -> arglist_list argument','arglist',2,'p_arglist6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2588), - ('arglist -> arglist_list argument COMMA','arglist',3,'p_arglist7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2600), - ('arglist -> arglist_list STAR test','arglist',3,'p_arglist8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2612), - ('arglist -> arglist_list STAR test COMMA DOUBLESTAR test','arglist',6,'p_arglist9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2624), - ('arglist -> arglist_list DOUBLESTAR test','arglist',3,'p_arglist10','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2636), - ('arglist -> STAR test COMMA argument','arglist',4,'p_arglist11','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2648), - ('arglist -> STAR test COMMA argument COMMA DOUBLESTAR test','arglist',7,'p_arglist12','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2659), - ('arglist -> STAR test COMMA arglist_list argument','arglist',5,'p_arglist13','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2670), - ('arglist -> STAR test COMMA arglist_list argument COMMA DOUBLESTAR test','arglist',8,'p_arglist14','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2681), - ('arglist_list -> argument COMMA','arglist_list',2,'p_arglist_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2692), - ('arglist_list -> arglist_list argument COMMA','arglist_list',3,'p_arglist_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2697), - ('argument -> test','argument',1,'p_argument1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2702), - ('argument -> test comp_for','argument',2,'p_argument2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2707), - ('argument -> test EQUAL test','argument',3,'p_argument3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2714), - ('list_for -> FOR exprlist IN testlist_safe','list_for',4,'p_list_for1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2722), - ('list_for -> FOR exprlist IN testlist_safe list_iter','list_for',5,'p_list_for2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2729), - ('list_iter -> list_for','list_iter',1,'p_list_iter1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2743), - ('list_iter -> list_if','list_iter',1,'p_list_iter2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2748), - ('list_if -> IF old_test','list_if',2,'p_list_if1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2753), - ('list_if -> IF old_test list_iter','list_if',3,'p_list_if2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2758), - ('comp_for -> FOR exprlist IN or_test','comp_for',4,'p_comp_for1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2763), - ('comp_for -> FOR exprlist IN or_test comp_iter','comp_for',5,'p_comp_for2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2770), - ('comp_iter -> comp_for','comp_iter',1,'p_comp_iter1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2784), - ('comp_iter -> comp_if','comp_iter',1,'p_comp_iter2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2789), - ('comp_if -> IF old_test','comp_if',2,'p_comp_if1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2794), - ('comp_if -> IF old_test comp_iter','comp_if',3,'p_comp_if2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2799), - ('testlist_safe -> old_test','testlist_safe',1,'p_testlist_safe1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2804), - ('testlist_safe -> old_test testlist_safe_list','testlist_safe',2,'p_testlist_safe2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2809), - ('testlist_safe -> old_test testlist_safe_list COMMA','testlist_safe',3,'p_testlist_safe3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2815), - ('testlist_safe_list -> COMMA old_test','testlist_safe_list',2,'p_testlist_safe_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2821), - ('testlist_safe_list -> testlist_safe_list COMMA old_test','testlist_safe_list',3,'p_testlist_safe_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2826), - ('old_test -> or_test','old_test',1,'p_old_test1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2831), - ('old_test -> old_lambdef','old_test',1,'p_old_test2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2836), - ('old_lambdef -> LAMBDA COLON old_test','old_lambdef',3,'p_old_lambdef1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2841), - ('old_lambdef -> LAMBDA varargslist COLON old_test','old_lambdef',4,'p_old_lambdef2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2848), - ('lambdef -> LAMBDA COLON test','lambdef',3,'p_lambdef1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2855), - ('lambdef -> LAMBDA varargslist COLON test','lambdef',4,'p_lambdef2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2862), - ('varargslist -> fpdef COMMA STAR NAME','varargslist',4,'p_varargslist1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2869), - ('varargslist -> fpdef COMMA STAR NAME COMMA DOUBLESTAR NAME','varargslist',7,'p_varargslist2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2876), - ('varargslist -> fpdef COMMA DOUBLESTAR NAME','varargslist',4,'p_varargslist3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2883), - ('varargslist -> fpdef','varargslist',1,'p_varargslist4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2890), - ('varargslist -> fpdef COMMA','varargslist',2,'p_varargslist5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2897), - ('varargslist -> fpdef varargslist_list COMMA STAR NAME','varargslist',5,'p_varargslist6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2904), - ('varargslist -> fpdef varargslist_list COMMA STAR NAME COMMA DOUBLESTAR NAME','varargslist',8,'p_varargslist7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2913), - ('varargslist -> fpdef varargslist_list COMMA DOUBLESTAR NAME','varargslist',5,'p_varargslist8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2922), - ('varargslist -> fpdef varargslist_list','varargslist',2,'p_varargslist9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2931), - ('varargslist -> fpdef varargslist_list COMMA','varargslist',3,'p_varargslist10','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2940), - ('varargslist -> fpdef EQUAL test COMMA STAR NAME','varargslist',6,'p_varargslist11','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2949), - ('varargslist -> fpdef EQUAL test COMMA STAR NAME COMMA DOUBLESTAR NAME','varargslist',9,'p_varargslist12','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2956), - ('varargslist -> fpdef EQUAL test COMMA DOUBLESTAR NAME','varargslist',6,'p_varargslist13','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2963), - ('varargslist -> fpdef EQUAL test','varargslist',3,'p_varargslist14','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2970), - ('varargslist -> fpdef EQUAL test COMMA','varargslist',4,'p_varargslist15','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2977), - ('varargslist -> fpdef EQUAL test varargslist_list COMMA STAR NAME','varargslist',7,'p_varargslist16','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2984), - ('varargslist -> fpdef EQUAL test varargslist_list COMMA STAR NAME COMMA DOUBLESTAR NAME','varargslist',10,'p_varargslist17','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2997), - ('varargslist -> fpdef EQUAL test varargslist_list COMMA DOUBLESTAR NAME','varargslist',7,'p_varargslist18','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3010), - ('varargslist -> fpdef EQUAL test varargslist_list','varargslist',4,'p_varargslist19','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3023), - ('varargslist -> fpdef EQUAL test varargslist_list COMMA','varargslist',5,'p_varargslist20','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3036), - ('varargslist -> STAR NAME','varargslist',2,'p_varargslist21','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3049), - ('varargslist -> STAR NAME COMMA DOUBLESTAR NAME','varargslist',5,'p_varargslist22','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3055), - ('varargslist -> DOUBLESTAR NAME','varargslist',2,'p_varargslist23','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3061), - ('varargslist_list -> COMMA fpdef','varargslist_list',2,'p_varargslist_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3068), - ('varargslist_list -> COMMA fpdef EQUAL test','varargslist_list',4,'p_varargslist_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3073), - ('varargslist_list -> varargslist_list COMMA fpdef','varargslist_list',3,'p_varargslist_list3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3078), - ('varargslist_list -> varargslist_list COMMA fpdef EQUAL test','varargslist_list',5,'p_varargslist_list4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3089), - ('fpdef -> NAME','fpdef',1,'p_fpdef1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3097), - ('fpdef -> LPAR fplist RPAR','fpdef',3,'p_fpdef2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3102), - ('fplist -> fpdef','fplist',1,'p_fplist1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3109), - ('fplist -> fpdef COMMA','fplist',2,'p_fplist2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3114), - ('fplist -> fpdef fplist_list','fplist',2,'p_fplist3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3122), - ('fplist -> fpdef fplist_list COMMA','fplist',3,'p_fplist4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3131), - ('fplist_list -> COMMA fpdef','fplist_list',2,'p_fplist_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3140), - ('fplist_list -> fplist_list COMMA fpdef','fplist_list',3,'p_fplist_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3145), + ('enaml -> enaml_module NEWLINE ENDMARKER','enaml',3,'p_enaml1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',351), + ('enaml -> enaml_module ENDMARKER','enaml',2,'p_enaml1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',352), + ('enaml -> NEWLINE ENDMARKER','enaml',2,'p_enaml2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',357), + ('enaml -> ENDMARKER','enaml',1,'p_enaml2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',358), + ('enaml_module -> enaml_module_body','enaml_module',1,'p_enaml_module','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',363), + ('enaml_module_body -> enaml_module_body enaml_module_item','enaml_module_body',2,'p_enaml_module_body1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',384), + ('enaml_module_body -> enaml_module_item','enaml_module_body',1,'p_enaml_module_body2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',389), + ('enaml_module_item -> declaration','enaml_module_item',1,'p_enaml_module_item2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',394), + ('enaml_module_item -> stmt','enaml_module_item',1,'p_enaml_module_item1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',399), + ('declaration -> ENAMLDEF NAME LPAR NAME RPAR COLON declaration_body','declaration',7,'p_declaration1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',407), + ('declaration -> ENAMLDEF NAME LPAR NAME RPAR COLON PASS NEWLINE','declaration',8,'p_declaration2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',414), + ('declaration -> ENAMLDEF NAME LPAR NAME RPAR COLON NAME COLON declaration_body','declaration',9,'p_declaration3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',424), + ('declaration -> ENAMLDEF NAME LPAR NAME RPAR COLON NAME COLON PASS NEWLINE','declaration',10,'p_declaration4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',438), + ('declaration_body -> NEWLINE INDENT declaration_body_items DEDENT','declaration_body',4,'p_declaration_body1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',448), + ('declaration_body -> NEWLINE INDENT identifier DEDENT','declaration_body',4,'p_declaration_body2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',455), + ('declaration_body -> NEWLINE INDENT identifier declaration_body_items DEDENT','declaration_body',5,'p_declaration_body3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',460), + ('declaration_body -> NEWLINE INDENT STRING NEWLINE declaration_body_items DEDENT','declaration_body',6,'p_declaration_body4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',467), + ('declaration_body -> NEWLINE INDENT STRING NEWLINE identifier DEDENT','declaration_body',6,'p_declaration_body5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',474), + ('declaration_body -> NEWLINE INDENT STRING NEWLINE identifier declaration_body_items DEDENT','declaration_body',7,'p_declaration_body6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',479), + ('declaration_body_items -> declaration_body_item','declaration_body_items',1,'p_declaration_body_items1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',486), + ('declaration_body_items -> declaration_body_items declaration_body_item','declaration_body_items',2,'p_declaration_body_items2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',491), + ('declaration_body_item -> attribute_declaration','declaration_body_item',1,'p_declaration_body_item1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',496), + ('declaration_body_item -> attribute_binding','declaration_body_item',1,'p_declaration_body_item2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',501), + ('declaration_body_item -> instantiation','declaration_body_item',1,'p_declaration_body_item3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',506), + ('declaration_body_item -> PASS NEWLINE','declaration_body_item',2,'p_declaration_body_item4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',511), + ('attribute_declaration -> NAME NAME NEWLINE','attribute_declaration',3,'p_attribute_declaration1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',519), + ('attribute_declaration -> NAME NAME COLON NAME NEWLINE','attribute_declaration',5,'p_attribute_declaration2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',524), + ('attribute_declaration -> NAME NAME binding','attribute_declaration',3,'p_attribute_declaration3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',529), + ('attribute_declaration -> NAME NAME COLON NAME binding','attribute_declaration',5,'p_attribute_declaration4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',537), + ('identifier -> NAME COLON NAME NEWLINE','identifier',4,'p_identifier','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',548), + ('instantiation -> NAME COLON instantiation_body','instantiation',3,'p_instantiation1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',560), + ('instantiation -> NAME COLON attribute_binding','instantiation',3,'p_instantiation2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',566), + ('instantiation -> NAME COLON PASS NEWLINE','instantiation',4,'p_instantiation3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',571), + ('instantiation -> NAME COLON NAME COLON instantiation_body','instantiation',5,'p_instantiation4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',576), + ('instantiation -> NAME COLON NAME COLON attribute_binding','instantiation',5,'p_instantiation5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',585), + ('instantiation -> NAME COLON NAME COLON PASS NEWLINE','instantiation',6,'p_instantiation6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',590), + ('instantiation_body -> NEWLINE INDENT instantiation_body_items DEDENT','instantiation_body',4,'p_instantiation_body1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',595), + ('instantiation_body -> NEWLINE INDENT identifier DEDENT','instantiation_body',4,'p_instantiation_body2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',602), + ('instantiation_body -> NEWLINE INDENT identifier instantiation_body_items DEDENT','instantiation_body',5,'p_instantiation_body3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',607), + ('instantiation_body_items -> instantiation_body_item','instantiation_body_items',1,'p_instantiation_body_items1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',614), + ('instantiation_body_items -> instantiation_body_items instantiation_body_item','instantiation_body_items',2,'p_instantiation_body_items2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',619), + ('instantiation_body_item -> instantiation','instantiation_body_item',1,'p_instantiation_body_item1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',624), + ('instantiation_body_item -> attribute_binding','instantiation_body_item',1,'p_instantiation_body_item2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',629), + ('instantiation_body_item -> PASS NEWLINE','instantiation_body_item',2,'p_instantiation_body_item3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',634), + ('attribute_binding -> NAME binding','attribute_binding',2,'p_attribute_binding','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',642), + ('binding -> EQUAL test NEWLINE','binding',3,'p_binding1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',647), + ('binding -> LEFTSHIFT test NEWLINE','binding',3,'p_binding1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',648), + ('binding -> COLONEQUAL test NEWLINE','binding',3,'p_binding2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',659), + ('binding -> RIGHTSHIFT test NEWLINE','binding',3,'p_binding2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',660), + ('binding -> DOUBLECOLON suite','binding',2,'p_binding3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',672), + ('suite -> simple_stmt','suite',1,'p_suite1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',690), + ('suite -> NEWLINE INDENT stmt_list DEDENT','suite',4,'p_suite2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',702), + ('stmt_list -> stmt stmt_list','stmt_list',2,'p_stmt_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',707), + ('stmt_list -> stmt','stmt_list',1,'p_stmt_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',719), + ('stmt -> simple_stmt','stmt',1,'p_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',731), + ('stmt -> compound_stmt','stmt',1,'p_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',732), + ('simple_stmt -> small_stmt NEWLINE','simple_stmt',2,'p_simple_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',737), + ('simple_stmt -> small_stmt_list NEWLINE','simple_stmt',2,'p_simple_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',745), + ('small_stmt_list -> small_stmt SEMI','small_stmt_list',2,'p_small_stmt_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',755), + ('small_stmt_list -> small_stmt small_stmt_list_list','small_stmt_list',2,'p_small_stmt_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',760), + ('small_stmt_list -> small_stmt small_stmt_list_list SEMI','small_stmt_list',3,'p_small_stmt_list3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',765), + ('small_stmt_list_list -> SEMI small_stmt','small_stmt_list_list',2,'p_small_stmt_list_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',770), + ('small_stmt_list_list -> small_stmt_list_list SEMI small_stmt','small_stmt_list_list',3,'p_small_stmt_list_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',775), + ('small_stmt -> expr_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',780), + ('small_stmt -> print_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',781), + ('small_stmt -> del_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',782), + ('small_stmt -> pass_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',783), + ('small_stmt -> flow_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',784), + ('small_stmt -> import_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',785), + ('small_stmt -> global_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',786), + ('small_stmt -> exec_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',787), + ('small_stmt -> assert_stmt','small_stmt',1,'p_small_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',788), + ('print_stmt -> PRINT','print_stmt',1,'p_print_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',793), + ('print_stmt -> PRINT test','print_stmt',2,'p_print_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',802), + ('print_stmt -> PRINT print_list','print_stmt',2,'p_print_stmt3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',811), + ('print_stmt -> PRINT RIGHTSHIFT test','print_stmt',3,'p_print_stmt4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',826), + ('print_stmt -> PRINT RIGHTSHIFT test COMMA test','print_stmt',5,'p_print_stmt5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',835), + ('print_stmt -> PRINT RIGHTSHIFT test COMMA print_list','print_stmt',5,'p_print_stmt6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',844), + ('print_list -> test COMMA','print_list',2,'p_print_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',859), + ('print_list -> test print_list_list','print_list',2,'p_print_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',864), + ('print_list -> test print_list_list COMMA','print_list',3,'p_print_list3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',869), + ('print_list_list -> COMMA test','print_list_list',2,'p_print_list_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',874), + ('print_list_list -> print_list_list COMMA test','print_list_list',3,'p_print_list_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',879), + ('del_stmt -> DEL exprlist','del_stmt',2,'p_del_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',884), + ('pass_stmt -> PASS','pass_stmt',1,'p_pass_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',893), + ('flow_stmt -> break_stmt','flow_stmt',1,'p_flow_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',900), + ('flow_stmt -> continue_stmt','flow_stmt',1,'p_flow_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',901), + ('flow_stmt -> return_stmt','flow_stmt',1,'p_flow_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',902), + ('flow_stmt -> raise_stmt','flow_stmt',1,'p_flow_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',903), + ('flow_stmt -> yield_stmt','flow_stmt',1,'p_flow_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',904), + ('break_stmt -> BREAK','break_stmt',1,'p_break_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',909), + ('continue_stmt -> CONTINUE','continue_stmt',1,'p_continue_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',916), + ('return_stmt -> RETURN','return_stmt',1,'p_return_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',923), + ('return_stmt -> RETURN testlist','return_stmt',2,'p_return_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',930), + ('raise_stmt -> RAISE','raise_stmt',1,'p_raise_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',938), + ('raise_stmt -> RAISE test','raise_stmt',2,'p_raise_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',947), + ('raise_stmt -> RAISE test COMMA test','raise_stmt',4,'p_raise_stmt3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',956), + ('raise_stmt -> RAISE test COMMA test COMMA test','raise_stmt',6,'p_raise_stmt4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',965), + ('yield_stmt -> yield_expr','yield_stmt',1,'p_yield_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',974), + ('yield_expr -> YIELD','yield_expr',1,'p_yield_expr1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',979), + ('yield_expr -> YIELD testlist','yield_expr',2,'p_yield_expr2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',984), + ('global_stmt -> GLOBAL NAME','global_stmt',2,'p_global_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',990), + ('global_stmt -> GLOBAL NAME globals_list','global_stmt',3,'p_global_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',998), + ('globals_list -> COMMA NAME globals_list','globals_list',3,'p_globals_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1006), + ('globals_list -> COMMA NAME','globals_list',2,'p_globals_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1011), + ('exec_stmt -> EXEC expr','exec_stmt',2,'p_exec_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1016), + ('exec_stmt -> EXEC expr IN test','exec_stmt',4,'p_exec_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1025), + ('exec_stmt -> EXEC expr IN test COMMA test','exec_stmt',6,'p_exec_stmt3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1034), + ('assert_stmt -> ASSERT test','assert_stmt',2,'p_assert_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1043), + ('assert_stmt -> ASSERT test COMMA test','assert_stmt',4,'p_assert_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1051), + ('expr_stmt -> testlist','expr_stmt',1,'p_expr_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1059), + ('expr_stmt -> testlist augassign testlist','expr_stmt',3,'p_expr_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1066), + ('expr_stmt -> testlist augassign yield_expr','expr_stmt',3,'p_expr_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1067), + ('expr_stmt -> testlist equal_list','expr_stmt',2,'p_expr_stmt3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1083), + ('augassign -> AMPEREQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1099), + ('augassign -> CIRCUMFLEXEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1100), + ('augassign -> DOUBLESLASHEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1101), + ('augassign -> DOUBLESTAREQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1102), + ('augassign -> LEFTSHIFTEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1103), + ('augassign -> MINUSEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1104), + ('augassign -> PERCENTEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1105), + ('augassign -> PLUSEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1106), + ('augassign -> RIGHTSHIFTEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1107), + ('augassign -> SLASHEQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1108), + ('augassign -> STAREQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1109), + ('augassign -> VBAREQUAL','augassign',1,'p_augassign','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1110), + ('equal_list -> EQUAL testlist','equal_list',2,'p_equal_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1117), + ('equal_list -> EQUAL yield_expr','equal_list',2,'p_equal_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1118), + ('equal_list -> EQUAL testlist equal_list','equal_list',3,'p_equal_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1123), + ('equal_list -> EQUAL yield_expr equal_list','equal_list',3,'p_equal_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1124), + ('testlist -> test','testlist',1,'p_testlist1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1129), + ('testlist -> test COMMA','testlist',2,'p_testlist2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1134), + ('testlist -> test testlist_list','testlist',2,'p_testlist3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1139), + ('testlist -> test testlist_list COMMA','testlist',3,'p_testlist4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1144), + ('testlist_list -> COMMA test','testlist_list',2,'p_testlist_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1149), + ('testlist_list -> testlist_list COMMA test','testlist_list',3,'p_testlist_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1154), + ('compound_stmt -> if_stmt','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1159), + ('compound_stmt -> while_stmt','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1160), + ('compound_stmt -> for_stmt','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1161), + ('compound_stmt -> try_stmt','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1162), + ('compound_stmt -> with_stmt','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1163), + ('compound_stmt -> funcdef','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1164), + ('compound_stmt -> classdef','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1165), + ('compound_stmt -> decorated','compound_stmt',1,'p_compound_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1166), + ('if_stmt -> IF test COLON suite','if_stmt',4,'p_if_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1171), + ('if_stmt -> IF test COLON suite elif_stmts','if_stmt',5,'p_if_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1182), + ('if_stmt -> IF test COLON suite else_stmt','if_stmt',5,'p_if_stmt3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1193), + ('if_stmt -> IF test COLON suite elif_stmts else_stmt','if_stmt',6,'p_if_stmt4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1204), + ('elif_stmts -> elif_stmts elif_stmt','elif_stmts',2,'p_elif_stmts1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1220), + ('elif_stmts -> elif_stmt','elif_stmts',1,'p_elif_stmts2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1227), + ('elif_stmt -> ELIF test COLON suite','elif_stmt',4,'p_elif_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1232), + ('else_stmt -> ELSE COLON suite','else_stmt',3,'p_else_stmt','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1243), + ('while_stmt -> WHILE test COLON suite','while_stmt',4,'p_while_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1248), + ('while_stmt -> WHILE test COLON suite ELSE COLON suite','while_stmt',7,'p_while_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1259), + ('for_stmt -> FOR exprlist IN testlist COLON suite','for_stmt',6,'p_for_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1270), + ('for_stmt -> FOR exprlist IN testlist COLON suite ELSE COLON suite','for_stmt',9,'p_for_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1284), + ('try_stmt -> TRY COLON suite FINALLY COLON suite','try_stmt',6,'p_try_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1298), + ('try_stmt -> TRY COLON suite except_clauses','try_stmt',4,'p_try_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1308), + ('try_stmt -> TRY COLON suite except_clauses ELSE COLON suite','try_stmt',7,'p_try_stmt3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1319), + ('try_stmt -> TRY COLON suite except_clauses FINALLY COLON suite','try_stmt',7,'p_try_stmt4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1330), + ('try_stmt -> TRY COLON suite except_clauses ELSE COLON suite FINALLY COLON suite','try_stmt',10,'p_try_stmt5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1347), + ('except_clauses -> except_clause except_clauses','except_clauses',2,'p_except_clauses1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1364), + ('except_clauses -> except_clause','except_clauses',1,'p_except_clauses2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1369), + ('except_clause -> EXCEPT COLON suite','except_clause',3,'p_except_clause1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1374), + ('except_clause -> EXCEPT test COLON suite','except_clause',4,'p_except_clause2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1385), + ('except_clause -> EXCEPT test AS test COLON suite','except_clause',6,'p_except_clause3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1396), + ('except_clause -> EXCEPT test COMMA test COLON suite','except_clause',6,'p_except_clause3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1397), + ('with_stmt -> WITH with_item COLON suite','with_stmt',4,'p_with_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1410), + ('with_stmt -> WITH with_item with_item_list COLON suite','with_stmt',5,'p_with_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1422), + ('with_item -> test','with_item',1,'p_with_item1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1442), + ('with_item -> test AS expr','with_item',3,'p_with_item2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1447), + ('with_item_list -> COMMA with_item with_item_list','with_item_list',3,'p_with_item_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1454), + ('with_item_list -> COMMA with_item','with_item_list',2,'p_with_item_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1459), + ('funcdef -> DEF NAME parameters COLON suite','funcdef',5,'p_funcdef','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1464), + ('parameters -> LPAR RPAR','parameters',2,'p_parameters1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1476), + ('parameters -> LPAR varargslist RPAR','parameters',3,'p_parameters2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1481), + ('classdef -> CLASS NAME COLON suite','classdef',4,'p_classdef1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1486), + ('classdef -> CLASS NAME LPAR RPAR COLON suite','classdef',6,'p_classdef2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1498), + ('classdef -> CLASS NAME LPAR testlist RPAR COLON suite','classdef',7,'p_classdef3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1510), + ('decorated -> decorators funcdef','decorated',2,'p_decorated','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1525), + ('decorated -> decorators classdef','decorated',2,'p_decorated','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1526), + ('decorators -> decorator decorators','decorators',2,'p_decorators1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1534), + ('decorators -> decorator','decorators',1,'p_decorators2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1539), + ('decorator -> AT dotted_name NEWLINE','decorator',3,'p_decorator1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1544), + ('decorator -> AT dotted_name LPAR RPAR NEWLINE','decorator',5,'p_decorator2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1552), + ('decorator -> AT dotted_name LPAR arglist RPAR NEWLINE','decorator',6,'p_decorator3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1565), + ('import_stmt -> import_name','import_stmt',1,'p_import_stmt1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1579), + ('import_stmt -> import_from','import_stmt',1,'p_import_stmt2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1584), + ('import_name -> IMPORT dotted_as_names','import_name',2,'p_import_name','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1588), + ('import_from -> FROM dotted_name IMPORT STAR','import_from',4,'p_import_from1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1595), + ('import_from -> FROM dotted_name IMPORT import_as_names','import_from',4,'p_import_from2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1603), + ('import_from -> FROM dotted_name IMPORT LPAR import_as_names RPAR','import_from',6,'p_import_from3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1610), + ('import_from -> FROM import_from_dots dotted_name IMPORT STAR','import_from',5,'p_import_from4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1617), + ('import_from -> FROM import_from_dots dotted_name IMPORT import_as_name','import_from',5,'p_import_from5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1625), + ('import_from -> FROM import_from_dots dotted_name IMPORT LPAR import_as_names RPAR','import_from',7,'p_import_from6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1632), + ('import_from -> FROM import_from_dots IMPORT STAR','import_from',4,'p_import_from7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1639), + ('import_from -> FROM import_from_dots IMPORT import_as_names','import_from',4,'p_import_from8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1647), + ('import_from -> FROM import_from_dots IMPORT LPAR import_as_names RPAR','import_from',6,'p_import_from9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1654), + ('import_from_dots -> DOT','import_from_dots',1,'p_import_from_dots1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1661), + ('import_from_dots -> import_from_dots DOT','import_from_dots',2,'p_import_from_dots2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1666), + ('import_as_name -> NAME','import_as_name',1,'p_import_as_name1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1671), + ('import_as_name -> NAME AS NAME','import_as_name',3,'p_import_as_name2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1676), + ('dotted_as_name -> dotted_name','dotted_as_name',1,'p_dotted_as_name1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1681), + ('dotted_as_name -> dotted_name AS NAME','dotted_as_name',3,'p_dotted_as_name2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1687), + ('import_as_names -> import_as_name','import_as_names',1,'p_import_as_names1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1693), + ('import_as_names -> import_as_name COMMA','import_as_names',2,'p_import_as_names2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1698), + ('import_as_names -> import_as_name import_as_names_list','import_as_names',2,'p_import_as_names3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1703), + ('import_as_names -> import_as_name import_as_names_list COMMA','import_as_names',3,'p_import_as_names4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1708), + ('import_as_names_list -> COMMA import_as_name','import_as_names_list',2,'p_import_as_names_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1713), + ('import_as_names_list -> import_as_names_list COMMA import_as_name','import_as_names_list',3,'p_import_as_names_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1718), + ('dotted_as_names -> dotted_as_name','dotted_as_names',1,'p_dotted_as_names1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1723), + ('dotted_as_names -> dotted_as_name dotted_as_names_list','dotted_as_names',2,'p_dotted_as_names2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1728), + ('dotted_as_names_list -> COMMA dotted_as_name','dotted_as_names_list',2,'p_dotted_as_names_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1733), + ('dotted_as_names_list -> dotted_as_names_list COMMA dotted_as_name','dotted_as_names_list',3,'p_dotted_as_names_star_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1738), + ('dotted_name -> NAME','dotted_name',1,'p_dotted_name1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1743), + ('dotted_name -> NAME dotted_name_list','dotted_name',2,'p_dotted_name2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1748), + ('dotted_name_list -> DOT NAME','dotted_name_list',2,'p_dotted_name_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1753), + ('dotted_name_list -> dotted_name_list DOT NAME','dotted_name_list',3,'p_dotted_name_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1758), + ('test -> or_test','test',1,'p_test1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1763), + ('test -> or_test IF or_test ELSE test','test',5,'p_test2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1768), + ('test -> lambdef','test',1,'p_test3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1774), + ('or_test -> and_test','or_test',1,'p_or_test1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1779), + ('or_test -> and_test or_test_list','or_test',2,'p_or_test2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1784), + ('or_test_list -> OR and_test','or_test_list',2,'p_or_test_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1791), + ('or_test_list -> or_test_list OR and_test','or_test_list',3,'p_or_test_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1796), + ('and_test -> not_test','and_test',1,'p_and_test1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1801), + ('and_test -> not_test and_test_list','and_test',2,'p_and_test2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1806), + ('and_test_list -> AND not_test','and_test_list',2,'p_and_test_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1813), + ('and_test_list -> and_test_list AND not_test','and_test_list',3,'p_and_test_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1818), + ('not_test -> comparison','not_test',1,'p_not_test','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1823), + ('not_test -> NOT not_test','not_test',2,'p_not_test2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1828), + ('comparison -> expr','comparison',1,'p_comparison1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1834), + ('comparison -> expr comparison_list','comparison',2,'p_comparison2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1839), + ('comparison_list -> comp_op expr','comparison_list',2,'p_comparison_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1847), + ('comparison_list -> comparison_list comp_op expr','comparison_list',3,'p_comparison_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1852), + ('comp_op -> LESS','comp_op',1,'p_comp_op1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1857), + ('comp_op -> GREATER','comp_op',1,'p_comp_op2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1862), + ('comp_op -> EQEQUAL','comp_op',1,'p_comp_op3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1867), + ('comp_op -> GREATEREQUAL','comp_op',1,'p_comp_op4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1872), + ('comp_op -> LESSEQUAL','comp_op',1,'p_comp_op5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1877), + ('comp_op -> NOTEQUAL','comp_op',1,'p_comp_op6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1882), + ('comp_op -> IN','comp_op',1,'p_comp_op7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1887), + ('comp_op -> NOT IN','comp_op',2,'p_comp_op8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1892), + ('comp_op -> IS','comp_op',1,'p_comp_op9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1897), + ('comp_op -> IS NOT','comp_op',2,'p_comp_op10','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1902), + ('expr -> xor_expr','expr',1,'p_expr1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1907), + ('expr -> xor_expr expr_list','expr',2,'p_expr2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1912), + ('expr_list -> VBAR xor_expr','expr_list',2,'p_expr_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1920), + ('expr_list -> expr_list VBAR xor_expr','expr_list',3,'p_expr_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1925), + ('xor_expr -> and_expr','xor_expr',1,'p_xor_expr1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1930), + ('xor_expr -> and_expr xor_expr_list','xor_expr',2,'p_xor_expr2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1935), + ('xor_expr_list -> CIRCUMFLEX and_expr','xor_expr_list',2,'p_xor_expr_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1943), + ('xor_expr_list -> xor_expr_list CIRCUMFLEX and_expr','xor_expr_list',3,'p_xor_expr_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1948), + ('and_expr -> shift_expr','and_expr',1,'p_and_expr1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1953), + ('and_expr -> shift_expr and_expr_list','and_expr',2,'p_and_expr2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1958), + ('and_expr_list -> AMPER shift_expr','and_expr_list',2,'p_and_expr_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1966), + ('and_expr_list -> and_expr_list AMPER shift_expr','and_expr_list',3,'p_and_expr_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1971), + ('shift_expr -> arith_expr','shift_expr',1,'p_shift_expr1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1976), + ('shift_expr -> arith_expr shift_list','shift_expr',2,'p_shift_expr2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1981), + ('shift_list -> shift_op','shift_list',1,'p_shift_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1989), + ('shift_list -> shift_list shift_op','shift_list',2,'p_shift_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1994), + ('shift_op -> LEFTSHIFT arith_expr','shift_op',2,'p_shift_op1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',1999), + ('shift_op -> RIGHTSHIFT arith_expr','shift_op',2,'p_shift_op2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2004), + ('arith_expr -> term','arith_expr',1,'p_arith_expr1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2009), + ('arith_expr -> term arith_expr_list','arith_expr',2,'p_arith_expr2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2014), + ('arith_expr_list -> arith_op','arith_expr_list',1,'p_arith_expr_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2022), + ('arith_expr_list -> arith_expr_list arith_op','arith_expr_list',2,'p_arith_expr_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2027), + ('arith_op -> PLUS term','arith_op',2,'p_arith_op1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2032), + ('arith_op -> MINUS term','arith_op',2,'p_arith_op2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2038), + ('term -> factor','term',1,'p_term1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2043), + ('term -> factor term_list','term',2,'p_term2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2048), + ('term_list -> term_op','term_list',1,'p_term_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2056), + ('term_list -> term_list term_op','term_list',2,'p_term_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2061), + ('term_op -> STAR factor','term_op',2,'p_term_op1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2066), + ('term_op -> SLASH factor','term_op',2,'p_term_op2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2071), + ('term_op -> PERCENT factor','term_op',2,'p_term_op3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2076), + ('term_op -> DOUBLESLASH factor','term_op',2,'p_term_op4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2081), + ('factor -> power','factor',1,'p_factor1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2086), + ('factor -> PLUS factor','factor',2,'p_factor2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2091), + ('factor -> MINUS factor','factor',2,'p_factor3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2099), + ('factor -> TILDE factor','factor',2,'p_factor4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2107), + ('power -> atom','power',1,'p_power1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2115), + ('power -> atom DOUBLESTAR factor','power',3,'p_power2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2120), + ('power -> atom power_list','power',2,'p_power3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2126), + ('power -> atom power_list DOUBLESTAR factor','power',4,'p_power4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2142), + ('power_list -> trailer','power_list',1,'p_power_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2159), + ('power_list -> power_list trailer','power_list',2,'p_power_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2164), + ('atom -> LPAR RPAR','atom',2,'p_atom1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2169), + ('atom -> LPAR yield_expr RPAR','atom',3,'p_atom2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2174), + ('atom -> LPAR testlist_comp RPAR','atom',3,'p_atom3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2179), + ('atom -> LSQB RSQB','atom',2,'p_atom4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2193), + ('atom -> LSQB listmaker RSQB','atom',3,'p_atom5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2198), + ('atom -> LBRACE RBRACE','atom',2,'p_atom6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2210), + ('atom -> LBRACE dictorsetmaker RBRACE','atom',3,'p_atom7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2215), + ('atom -> NAME','atom',1,'p_atom8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2236), + ('atom -> NUMBER','atom',1,'p_atom9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2241), + ('atom -> atom_string_list','atom',1,'p_atom10','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2247), + ('atom_string_list -> STRING','atom_string_list',1,'p_atom_string_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2253), + ('atom_string_list -> atom_string_list STRING','atom_string_list',2,'p_atom_string_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2258), + ('listmaker -> test list_for','listmaker',2,'p_listmaker1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2268), + ('listmaker -> test','listmaker',1,'p_listmaker2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2273), + ('listmaker -> test COMMA','listmaker',2,'p_listmaker3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2278), + ('listmaker -> test listmaker_list','listmaker',2,'p_listmaker4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2283), + ('listmaker -> test listmaker_list COMMA','listmaker',3,'p_listmaker5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2289), + ('listmaker_list -> COMMA test','listmaker_list',2,'p_listmaker_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2295), + ('listmaker_list -> listmaker_list COMMA test','listmaker_list',3,'p_listmaker_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2300), + ('testlist_comp -> test comp_for','testlist_comp',2,'p_testlist_comp1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2305), + ('testlist_comp -> test','testlist_comp',1,'p_testlist_comp2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2310), + ('testlist_comp -> test COMMA','testlist_comp',2,'p_testlist_comp3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2315), + ('testlist_comp -> test testlist_comp_list','testlist_comp',2,'p_testlist_comp4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2320), + ('testlist_comp -> test testlist_comp_list COMMA','testlist_comp',3,'p_testlist_comp5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2326), + ('testlist_comp_list -> COMMA test','testlist_comp_list',2,'p_testlist_comp_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2332), + ('testlist_comp_list -> testlist_comp_list COMMA test','testlist_comp_list',3,'p_testlist_comp_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2337), + ('trailer -> LPAR RPAR','trailer',2,'p_trailer1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2342), + ('trailer -> LPAR arglist RPAR','trailer',3,'p_trailer2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2347), + ('trailer -> LSQB subscriptlist RSQB','trailer',3,'p_trailer3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2354), + ('trailer -> DOT NAME','trailer',2,'p_trailer4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2359), + ('subscriptlist -> subscript','subscriptlist',1,'p_subscriptlist1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2364), + ('subscriptlist -> subscript COMMA','subscriptlist',2,'p_subscriptlist2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2369), + ('subscriptlist -> subscript subscriptlist_list','subscriptlist',2,'p_subscriptlist3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2375), + ('subscriptlist -> subscript subscriptlist_list COMMA','subscriptlist',3,'p_subscriptlist4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2381), + ('subscriptlist_list -> COMMA subscript','subscriptlist_list',2,'p_subscriptlist_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2387), + ('subscriptlist_list -> subscriptlist_list COMMA subscript','subscriptlist_list',3,'p_subscript_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2392), + ('subscript -> ELLIPSIS','subscript',1,'p_subscript1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2397), + ('subscript -> test','subscript',1,'p_subcript2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2402), + ('subscript -> COLON','subscript',1,'p_subscript3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2407), + ('subscript -> DOUBLECOLON','subscript',1,'p_subscript4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2412), + ('subscript -> test COLON','subscript',2,'p_subscript5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2418), + ('subscript -> test DOUBLECOLON','subscript',2,'p_subscrip6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2423), + ('subscript -> COLON test','subscript',2,'p_subscript7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2429), + ('subscript -> COLON test COLON','subscript',3,'p_subscript8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2434), + ('subscript -> DOUBLECOLON test','subscript',2,'p_subscript9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2440), + ('subscript -> test COLON test','subscript',3,'p_subscript10','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2445), + ('subscript -> test COLON test COLON','subscript',4,'p_subscript11','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2450), + ('subscript -> COLON test COLON test','subscript',4,'p_subscript12','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2456), + ('subscript -> test COLON test COLON test','subscript',5,'p_subscript13','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2461), + ('subscript -> test DOUBLECOLON test','subscript',3,'p_subscript14','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2466), + ('exprlist -> expr','exprlist',1,'p_exprlist1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2471), + ('exprlist -> expr COMMA','exprlist',2,'p_exprlist2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2476), + ('exprlist -> expr exprlist_list','exprlist',2,'p_exprlist3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2483), + ('exprlist -> expr exprlist_list COMMA','exprlist',3,'p_exprlist4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2490), + ('exprlist_list -> COMMA expr','exprlist_list',2,'p_exprlist_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2497), + ('exprlist_list -> exprlist_list COMMA expr','exprlist_list',3,'p_exprlist_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2502), + ('dictorsetmaker -> test COLON test comp_for','dictorsetmaker',4,'p_dictorsetmaker1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2507), + ('dictorsetmaker -> test COLON test','dictorsetmaker',3,'p_dictorsetmaker2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2512), + ('dictorsetmaker -> test COLON test COMMA','dictorsetmaker',4,'p_dictorsetmaker3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2518), + ('dictorsetmaker -> test COLON test dosm_colon_list','dictorsetmaker',4,'p_dictorsetmaker4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2524), + ('dictorsetmaker -> test COLON test dosm_colon_list COMMA','dictorsetmaker',5,'p_dictorsetmaker5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2530), + ('dictorsetmaker -> test comp_for','dictorsetmaker',2,'p_dictorsetmaker6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2536), + ('dictorsetmaker -> test COMMA','dictorsetmaker',2,'p_dictorsetmaker7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2541), + ('dictorsetmaker -> test dosm_comma_list','dictorsetmaker',2,'p_dictorsetmaker8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2547), + ('dictorsetmaker -> test dosm_comma_list COMMA','dictorsetmaker',3,'p_dictorsetmaker9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2553), + ('dosm_colon_list -> COMMA test COLON test','dosm_colon_list',4,'p_dosm_colon_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2559), + ('dosm_colon_list -> dosm_colon_list COMMA test COLON test','dosm_colon_list',5,'p_dosm_colon_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2564), + ('dosm_comma_list -> COMMA test','dosm_comma_list',2,'p_dosm_comma_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2569), + ('dosm_comma_list -> dosm_comma_list COMMA test','dosm_comma_list',3,'p_dosm_comma_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2574), + ('arglist -> argument','arglist',1,'p_arglist1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2579), + ('arglist -> argument COMMA','arglist',2,'p_arglist2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2587), + ('arglist -> STAR test','arglist',2,'p_arglist3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2595), + ('arglist -> STAR test COMMA DOUBLESTAR test','arglist',5,'p_arglist4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2600), + ('arglist -> DOUBLESTAR test','arglist',2,'p_arglist5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2605), + ('arglist -> arglist_list argument','arglist',2,'p_arglist6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2610), + ('arglist -> arglist_list argument COMMA','arglist',3,'p_arglist7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2622), + ('arglist -> arglist_list STAR test','arglist',3,'p_arglist8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2634), + ('arglist -> arglist_list STAR test COMMA DOUBLESTAR test','arglist',6,'p_arglist9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2646), + ('arglist -> arglist_list DOUBLESTAR test','arglist',3,'p_arglist10','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2658), + ('arglist -> STAR test COMMA argument','arglist',4,'p_arglist11','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2670), + ('arglist -> STAR test COMMA argument COMMA DOUBLESTAR test','arglist',7,'p_arglist12','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2681), + ('arglist -> STAR test COMMA arglist_list argument','arglist',5,'p_arglist13','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2692), + ('arglist -> STAR test COMMA arglist_list argument COMMA DOUBLESTAR test','arglist',8,'p_arglist14','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2703), + ('arglist_list -> argument COMMA','arglist_list',2,'p_arglist_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2714), + ('arglist_list -> arglist_list argument COMMA','arglist_list',3,'p_arglist_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2719), + ('argument -> test','argument',1,'p_argument1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2724), + ('argument -> test comp_for','argument',2,'p_argument2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2729), + ('argument -> test EQUAL test','argument',3,'p_argument3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2736), + ('list_for -> FOR exprlist IN testlist_safe','list_for',4,'p_list_for1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2744), + ('list_for -> FOR exprlist IN testlist_safe list_iter','list_for',5,'p_list_for2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2751), + ('list_iter -> list_for','list_iter',1,'p_list_iter1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2765), + ('list_iter -> list_if','list_iter',1,'p_list_iter2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2770), + ('list_if -> IF old_test','list_if',2,'p_list_if1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2775), + ('list_if -> IF old_test list_iter','list_if',3,'p_list_if2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2780), + ('comp_for -> FOR exprlist IN or_test','comp_for',4,'p_comp_for1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2785), + ('comp_for -> FOR exprlist IN or_test comp_iter','comp_for',5,'p_comp_for2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2792), + ('comp_iter -> comp_for','comp_iter',1,'p_comp_iter1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2806), + ('comp_iter -> comp_if','comp_iter',1,'p_comp_iter2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2811), + ('comp_if -> IF old_test','comp_if',2,'p_comp_if1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2816), + ('comp_if -> IF old_test comp_iter','comp_if',3,'p_comp_if2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2821), + ('testlist_safe -> old_test','testlist_safe',1,'p_testlist_safe1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2826), + ('testlist_safe -> old_test testlist_safe_list','testlist_safe',2,'p_testlist_safe2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2831), + ('testlist_safe -> old_test testlist_safe_list COMMA','testlist_safe',3,'p_testlist_safe3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2837), + ('testlist_safe_list -> COMMA old_test','testlist_safe_list',2,'p_testlist_safe_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2843), + ('testlist_safe_list -> testlist_safe_list COMMA old_test','testlist_safe_list',3,'p_testlist_safe_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2848), + ('old_test -> or_test','old_test',1,'p_old_test1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2853), + ('old_test -> old_lambdef','old_test',1,'p_old_test2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2858), + ('old_lambdef -> LAMBDA COLON old_test','old_lambdef',3,'p_old_lambdef1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2863), + ('old_lambdef -> LAMBDA varargslist COLON old_test','old_lambdef',4,'p_old_lambdef2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2870), + ('lambdef -> LAMBDA COLON test','lambdef',3,'p_lambdef1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2877), + ('lambdef -> LAMBDA varargslist COLON test','lambdef',4,'p_lambdef2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2884), + ('varargslist -> fpdef COMMA STAR NAME','varargslist',4,'p_varargslist1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2891), + ('varargslist -> fpdef COMMA STAR NAME COMMA DOUBLESTAR NAME','varargslist',7,'p_varargslist2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2898), + ('varargslist -> fpdef COMMA DOUBLESTAR NAME','varargslist',4,'p_varargslist3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2905), + ('varargslist -> fpdef','varargslist',1,'p_varargslist4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2912), + ('varargslist -> fpdef COMMA','varargslist',2,'p_varargslist5','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2919), + ('varargslist -> fpdef varargslist_list COMMA STAR NAME','varargslist',5,'p_varargslist6','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2926), + ('varargslist -> fpdef varargslist_list COMMA STAR NAME COMMA DOUBLESTAR NAME','varargslist',8,'p_varargslist7','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2935), + ('varargslist -> fpdef varargslist_list COMMA DOUBLESTAR NAME','varargslist',5,'p_varargslist8','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2944), + ('varargslist -> fpdef varargslist_list','varargslist',2,'p_varargslist9','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2953), + ('varargslist -> fpdef varargslist_list COMMA','varargslist',3,'p_varargslist10','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2962), + ('varargslist -> fpdef EQUAL test COMMA STAR NAME','varargslist',6,'p_varargslist11','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2971), + ('varargslist -> fpdef EQUAL test COMMA STAR NAME COMMA DOUBLESTAR NAME','varargslist',9,'p_varargslist12','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2978), + ('varargslist -> fpdef EQUAL test COMMA DOUBLESTAR NAME','varargslist',6,'p_varargslist13','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2985), + ('varargslist -> fpdef EQUAL test','varargslist',3,'p_varargslist14','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2992), + ('varargslist -> fpdef EQUAL test COMMA','varargslist',4,'p_varargslist15','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',2999), + ('varargslist -> fpdef EQUAL test varargslist_list COMMA STAR NAME','varargslist',7,'p_varargslist16','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3006), + ('varargslist -> fpdef EQUAL test varargslist_list COMMA STAR NAME COMMA DOUBLESTAR NAME','varargslist',10,'p_varargslist17','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3019), + ('varargslist -> fpdef EQUAL test varargslist_list COMMA DOUBLESTAR NAME','varargslist',7,'p_varargslist18','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3032), + ('varargslist -> fpdef EQUAL test varargslist_list','varargslist',4,'p_varargslist19','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3045), + ('varargslist -> fpdef EQUAL test varargslist_list COMMA','varargslist',5,'p_varargslist20','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3058), + ('varargslist -> STAR NAME','varargslist',2,'p_varargslist21','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3071), + ('varargslist -> STAR NAME COMMA DOUBLESTAR NAME','varargslist',5,'p_varargslist22','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3077), + ('varargslist -> DOUBLESTAR NAME','varargslist',2,'p_varargslist23','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3083), + ('varargslist_list -> COMMA fpdef','varargslist_list',2,'p_varargslist_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3090), + ('varargslist_list -> COMMA fpdef EQUAL test','varargslist_list',4,'p_varargslist_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3095), + ('varargslist_list -> varargslist_list COMMA fpdef','varargslist_list',3,'p_varargslist_list3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3100), + ('varargslist_list -> varargslist_list COMMA fpdef EQUAL test','varargslist_list',5,'p_varargslist_list4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3111), + ('fpdef -> NAME','fpdef',1,'p_fpdef1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3119), + ('fpdef -> LPAR fplist RPAR','fpdef',3,'p_fpdef2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3124), + ('fplist -> fpdef','fplist',1,'p_fplist1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3131), + ('fplist -> fpdef COMMA','fplist',2,'p_fplist2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3136), + ('fplist -> fpdef fplist_list','fplist',2,'p_fplist3','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3144), + ('fplist -> fpdef fplist_list COMMA','fplist',3,'p_fplist4','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3153), + ('fplist_list -> COMMA fpdef','fplist_list',2,'p_fplist_list1','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3162), + ('fplist_list -> fplist_list COMMA fpdef','fplist_list',3,'p_fplist_list2','c:\\Users\\i341972\\Desktop\\git_repos\\enaml\\enaml\\core\\parser.py',3167), ] diff --git a/enaml/core/parser.py b/enaml/core/parser.py index ed49d919..83afaf3e 100644 --- a/enaml/core/parser.py +++ b/enaml/core/parser.py @@ -236,7 +236,35 @@ def ast_for_dotted_name(dotted_name): return res -def build_attr_declaration(kw, name, type_node, default, lineno, p): +# The nodes which can be inverted to form an assignable expression. +_INVERTABLE = (ast.Name, ast.Attribute, ast.Call, ast.Subscript) + +def validate_invertable(node, lineno, p): + """ Validates that its possible for the compiler to generated + inversion code for the given ast node. + + Currently, code is invertable if the expression terminates with + a node of the following types: Name, Attribute, Call, Subscript. + + Parameters + ---------- + node : ast.AST + The ast expression node to validate. + + lineno : int + The line number of the declaration. + + p : Yacc Production + The Ply object passed to the parser rule. This is used to + extract the filename for syntax error reporting. + + """ + if not isinstance(node, _INVERTABLE): + msg = "can't assign to expression of this form" + syntax_error(msg, FakeToken(p.lexer.lexer, lineno)) + + +def build_attr_declaration(kw, name, attr_type, default, lineno, p): """ Builds an ast node for an attr or event declaration. Parameters @@ -248,9 +276,8 @@ def build_attr_declaration(kw, name, type_node, default, lineno, p): name : string The name of the attribute or event being declared. - type_node : enaml_ast.Python node or None - The expression node for the type being declared, or None if not - using a type. + attr_type : str or None + The type being declared, or None if not using a type. default : AttributeBinding or None The default attribute binding or None if not supply the default. @@ -273,11 +300,11 @@ def build_attr_declaration(kw, name, type_node, default, lineno, p): syntax_error(msg, FakeToken(p.lexer.lexer, lineno)) if kw == 'attr': res = enaml_ast.AttributeDeclaration( - name, type_node, default, False, lineno, + name, attr_type, default, False, lineno, ) else: res = enaml_ast.AttributeDeclaration( - name, type_node, default, True, lineno, + name, attr_type, default, True, lineno, ) return res @@ -380,11 +407,7 @@ def p_declaration1(p): ''' declaration : ENAMLDEF NAME LPAR NAME RPAR COLON declaration_body ''' lineno = p.lineno(1) doc, idn, items = p[7] - base = ast.Expression(body=ast.Name(id=p[4], ctx=Load)) - base.lineno = lineno - ast.fix_missing_locations(base) - base_node = enaml_ast.Python(base, lineno) - p[0] = enaml_ast.Declaration(p[2], base_node, idn, doc, items, lineno) + p[0] = enaml_ast.Declaration(p[2], p[4], idn, doc, items, lineno) def p_declaration2(p): @@ -499,12 +522,7 @@ def p_attribute_declaration1(p): def p_attribute_declaration2(p): ''' attribute_declaration : NAME NAME COLON NAME NEWLINE ''' - lineno = p.lineno(1) - expr = ast.Expression(body=ast.Name(id=p[4], ctx=Load)) - expr.lineno = lineno - ast.fix_missing_locations(expr) - expr_node = enaml_ast.Python(expr, lineno) - p[0] = build_attr_declaration(p[1], p[2], expr_node, None, p.lineno(1), p) + p[0] = build_attr_declaration(p[1], p[2], p[4], None, p.lineno(1), p) def p_attribute_declaration3(p): @@ -518,13 +536,9 @@ def p_attribute_declaration3(p): def p_attribute_declaration4(p): ''' attribute_declaration : NAME NAME COLON NAME binding ''' lineno = p.lineno(1) - expr = ast.Expression(body=ast.Name(id=p[4], ctx=Load)) - expr.lineno = lineno - ast.fix_missing_locations(expr) - expr_node = enaml_ast.Python(expr, lineno) name = p[2] binding = enaml_ast.AttributeBinding(name, p[5], lineno) - p[0] = build_attr_declaration(p[1], name, expr_node, binding, lineno, p) + p[0] = build_attr_declaration(p[1], name, p[4], binding, lineno, p) #------------------------------------------------------------------------------ @@ -631,9 +645,7 @@ def p_attribute_binding(p): def p_binding1(p): ''' binding : EQUAL test NEWLINE - | COLONEQUAL test NEWLINE - | LEFTSHIFT test NEWLINE - | RIGHTSHIFT test NEWLINE ''' + | LEFTSHIFT test NEWLINE ''' lineno = p.lineno(1) operator = translate_operator(p[1]) expr = ast.Expression(body=p[2]) @@ -644,6 +656,19 @@ def p_binding1(p): def p_binding2(p): + ''' binding : COLONEQUAL test NEWLINE + | RIGHTSHIFT test NEWLINE ''' + lineno = p.lineno(1) + validate_invertable(p[2], lineno, p) + operator = translate_operator(p[1]) + expr = ast.Expression(body=p[2]) + expr.lineno = lineno + ast.fix_missing_locations(expr) + expr_node = enaml_ast.Python(expr, lineno) + p[0] = enaml_ast.BoundExpression(operator, expr_node, lineno) + + +def p_binding3(p): ''' binding : DOUBLECOLON suite ''' lineno = p.lineno(1) operator = translate_operator(p[1]) From 1d29d6e9d10c9432f3993804242038813640bb60 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 20:00:46 -0500 Subject: [PATCH 10/34] Operate on byteplay code lists instead of code objects. Add support for code inversion. --- enaml/core/code_tracing.py | 132 +++++++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 42 deletions(-) diff --git a/enaml/core/code_tracing.py b/enaml/core/code_tracing.py index 30ea47f2..f21cfd53 100644 --- a/enaml/core/code_tracing.py +++ b/enaml/core/code_tracing.py @@ -3,9 +3,9 @@ # All rights reserved. #------------------------------------------------------------------------------ from .byteplay import ( - Code, LOAD_ATTR, LOAD_CONST, ROT_TWO, DUP_TOP, CALL_FUNCTION, POP_TOP, - LOAD_FAST, BUILD_TUPLE, ROT_THREE, UNPACK_SEQUENCE, DUP_TOPX, - BINARY_SUBSCR, GET_ITER, LOAD_NAME, LOAD_GLOBAL + LOAD_ATTR, LOAD_CONST, ROT_TWO, DUP_TOP, CALL_FUNCTION, POP_TOP, LOAD_FAST, + BUILD_TUPLE, ROT_THREE, UNPACK_SEQUENCE, DUP_TOPX, BINARY_SUBSCR, GET_ITER, + LOAD_NAME, RETURN_VALUE ) @@ -110,7 +110,7 @@ def fail(self): """ Called by the modified code to raise an inversion exception. """ - raise RuntimeError('Cannot assign to the given expression') + raise RuntimeError("can't assign to expression") def load_name(self, name, value): """ Called before the LOAD_NAME opcode is executed. @@ -194,46 +194,25 @@ def binary_subscr(self, obj, idx, value): self.fail() -def transform_code(code, trace): - """ Transform a code object into a Python function. +def inject_tracing(codelist): + """ Inject tracing code into the given code list. - This will disassemble the given code object and rewrite it to enable - Enaml's dynamic scoping and tracing features. + This will inject the bytecode operations required to trace the + execution of the code using a `CodeTracer` object. The generated + opcodes expect a fast local '_[tracer]' to be available when the + code is executed. Parameters ---------- - code : types.CodeType - The Python code object which should transformed. - - trace : bool - Whether or not to add tracing code to the function. If this is - True, the arguments of the returned function are extended so - that the first argument to the function is a `CodeTracer` - instance. + codelist : list + The list of byteplay code ops to modify. Returns ------- - result : types.CodeType - A Python code object which implements the desired functionality. + result : list + A *new* list of code ops which implement the desired behavior. """ - bp_code = Code.from_code(code) - code_list = list(bp_code.code) - - # Replacing LOAD_GLOBAL with LOAD_NAME enables dynamic scoping by - # way of a custom locals mapping. There is a C extension module - # with a function `call_func` which allows a Python function to - # be called with a locals mapping, which is normally not possible. - for idx, (op, op_arg) in enumerate(code_list): - if op == LOAD_GLOBAL: - code_list[idx] = (LOAD_NAME, op_arg) - - # If tracing code is not required, the transformation is complete. - if not trace: - bp_code.code = code_list - bp_code.newlocals = False - return bp_code.to_code() - # This builds a mapping of code idx to a list of ops, which are the # tracing bytecode instructions which will be inserted into the code # object being transformed. The ops assume that a tracer object is @@ -242,7 +221,7 @@ def transform_code(code, trace): # that the tracer has no visible side effects, the tracing is # transparent. inserts = {} - for idx, (op, op_arg) in enumerate(code_list): + for idx, (op, op_arg) in enumerate(codelist): if op == LOAD_ATTR: code = [ # obj (DUP_TOP, None), # obj -> obj @@ -301,14 +280,83 @@ def transform_code(code, trace): # Create a new code list which interleaves the generated code with # the original code at the appropriate location. new_code = [] - for idx, code_op in enumerate(code_list): + for idx, code_op in enumerate(codelist): if idx in inserts: new_code.extend(inserts[idx]) new_code.append(code_op) + return new_code + + +def inject_inversion(codelist): + """ Inject inversion code into the given code list. - # Create the new code object which takes a tracer as the first arg. - bp_code.code = new_code - bp_code.newlocals = False - bp_code.args = ('_[tracer]',) + bp_code.args - return bp_code.to_code() + This will inject the bytecode operations required to invert the + execution of the code using a `CodeInverter` object. The generated + opcodes expect the fast local '_[inverter]' and '_[value]' to be + available when the code is executed. + + Parameters + ---------- + codelist : list + The list of byteplay code ops to modify. + + Returns + ------- + result : list + A *new* list of code ops which implement the desired behavior. + + Raises + ------ + ValueError + The given code is not suitable for inversion. + + """ + opcode, oparg = codelist[-2] + if opcode == LOAD_NAME and len(codelist) == 3: + new_code = codelist[:-2] + new_code.extend([ + (LOAD_FAST, '_[inverter]'), + (LOAD_ATTR, 'load_name'), + (LOAD_CONST, oparg), + (LOAD_FAST, '_[value]'), + (CALL_FUNCTION, 0x0002), + (RETURN_VALUE, None), + ]) + elif opcode == LOAD_ATTR: + new_code = codelist[:-2] + new_code.extend([ + (LOAD_FAST, '_[inverter]'), + (LOAD_ATTR, 'load_attr'), + (ROT_TWO, None), + (LOAD_CONST, oparg), + (LOAD_FAST, '_[value]'), + (CALL_FUNCTION, 0x0003), + (RETURN_VALUE, None), + ]) + elif opcode == CALL_FUNCTION: + n_stack_args = (oparg & 0xFF) + 2 * ((oparg >> 8) & 0xFF) + new_code = codelist[:-2] + new_code.extend([ + (BUILD_TUPLE, n_stack_args), + (LOAD_FAST, '_[inverter]'), + (LOAD_ATTR, 'call_function'), + (ROT_THREE, None), + (LOAD_CONST, oparg), + (LOAD_FAST, '_[value]'), + (CALL_FUNCTION, 0x0004), + (RETURN_VALUE, None), + ]) + elif opcode == BINARY_SUBSCR: + new_code = codelist[:-2] + new_code.extend([ + (LOAD_FAST, '_[inverter]'), + (LOAD_ATTR, 'binary_subscr'), + (ROT_THREE, None), + (LOAD_FAST, '_[value]'), + (CALL_FUNCTION, 0x0003), + (RETURN_VALUE, None), + ]) + else: + raise ValueError("can't invert code") + return new_code From 3dfc398aa28263ee3cc5004d35969d96142a5fab Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 20:02:15 -0500 Subject: [PATCH 11/34] Update and optimize compiler for new code injection semantics --- enaml/core/enaml_compiler.py | 452 +++++++++++++++++++++++++---------- 1 file changed, 331 insertions(+), 121 deletions(-) diff --git a/enaml/core/enaml_compiler.py b/enaml/core/enaml_compiler.py index 57725fe1..673e0642 100644 --- a/enaml/core/enaml_compiler.py +++ b/enaml/core/enaml_compiler.py @@ -9,13 +9,14 @@ from .byteplay import ( Code, LOAD_FAST, CALL_FUNCTION, LOAD_GLOBAL, STORE_FAST, LOAD_CONST, LOAD_ATTR, STORE_SUBSCR, RETURN_VALUE, POP_TOP, MAKE_FUNCTION, STORE_NAME, - LOAD_NAME, DUP_TOP, SetLineno, + LOAD_NAME, DUP_TOP, SetLineno, BINARY_SUBSCR, STORE_ATTR, ROT_TWO ) +from .code_tracing import inject_tracing, inject_inversion # Increment this number whenever the compiler changes the code which it # generates. This number is used by the import hooks to know which version -# of a .enamlc file is valid for the Enaml compiler version in use. If +# of a .enamlc file is valid for the Enaml compiler version in use. If # this number is not incremented on change, it may result in .enamlc # files which fail on import. # @@ -23,9 +24,9 @@ # --------------- # 1 : Initial compiler version - 2 February 2012 # 2 : Update line number handling - 26 March 2012 -# When compiling code objects with mode='eval', Python ignores the -# line number specified by the ast. The workaround is to compile the -# code object, then make a new copy of it with the proper firstlineno +# When compiling code objects with mode='eval', Python ignores the +# line number specified by the ast. The workaround is to compile the +# code object, then make a new copy of it with the proper firstlineno # set via the types.CodeType constructor. # 3 : Update the generated code to remove the toolkit - 21 June 2012 # This updates the compiler for the coming switch to async UI's @@ -33,18 +34,18 @@ # magic scope maintained is for that of operators. # 4 : Update component building - 27 July 2012 # This updates the compiler to handle the new Enaml creation semantics -# that don't rely on __enaml_call__. Instead the parent is passed +# that don't rely on __enaml_call__. Instead the parent is passed # directly to the component cls which is a subclass of Declarative. # That class handles calling the builder functions upon instance # creation. This allows us to get rid of the EnamlDef class and # make enamldef constructs proper subclasses of Declarative. # 5 : Change the import names - 28 July 2012 -# This changes the imported helper name from _make_decl_subclass_ -# to _make_enamldef_helper_ which is more descriptive, but equally +# This changes the imported helper name from _make_decl_subclass_ +# to _make_enamldef_helper_ which is more descriptive, but equally # mangled. It also updates the method name used on the Declarative # component for adding attribute from _add_decl_attr to the more -# descriptive _add_user_attribute. Finally, it adds the eval_compile -# function for compiling Python code in 'eval' mode with proper line +# descriptive _add_user_attribute. Finally, it adds the eval_compile +# function for compiling Python code in 'eval' mode with proper line # number handling. COMPILER_VERSION = 5 @@ -52,7 +53,7 @@ # The Enaml compiler translates an Enaml AST into Python bytecode. # # Given this sample declaration in Enaml:: -# +# # FooWindow(Window): # id: foo # a = '12' @@ -66,15 +67,14 @@ # # def FooWindow(instance, identifiers, operators): # f_globals = globals() -# eval_ = eval # _var_1 = instance # identifiers['foo'] = _var_1 -# op = eval_('__operator_Equal__', operators) -# op(_var_1, 'a', , identifiers, f_globals, operators) -# _var_2 = eval_('PushButton', f_globals)(_var_1) +# op = operators['__operator_Equal__'] +# op(_var_1, 'a', , identifiers) +# _var_2 = f_globals['PushButton'](_var_1) # identifiers['btn'] = _var_2 -# op = eval_('__operator_Equal__', operators) -# op(_var_2, 'text', , identifiers, f_globals, operators) +# op = operators['__operator_Equal__'] +# op(_var_2, 'text', , identifiers) # return _var_1 # # FooWindow = _make_enamldef_helper_('FooWindow', Window, FooWindow) @@ -108,28 +108,220 @@ def update_firstlineno(code, firstlineno): return types.CodeType( code.co_argcount, code.co_nlocals, code.co_stacksize, code.co_flags, code.co_code, code.co_consts, code.co_names, code.co_varnames, - code.co_filename, code.co_name, firstlineno, code.co_lnotab, + code.co_filename, code.co_name, firstlineno, code.co_lnotab, code.co_freevars, code.co_cellvars, ) -def eval_compile(item, filename, lineno): - """ Compile the item in eval mode, updating the lineno as necessary. +#------------------------------------------------------------------------------ +# Expression Compilers +#------------------------------------------------------------------------------ +def replace_global_loads(codelist, explicit=None): + """ A code transformer which rewrites LOAD_GLOBAL opcodes. + + This transform will replace the LOAD_GLOBAL opcodes with LOAD_NAME + opcodes. The operation is performed in-place. Parameters ---------- - item : string or ast - A string of Python code, or a Python AST object. + codelist : list + The list of byteplay code ops to modify. + + explicit : set or None + The set of global names declared explicitly and which should + remain untransformed. + + """ + # Replacing LOAD_GLOBAL with LOAD_NAME enables dynamic scoping by + # way of a custom locals mapping. The `call_func` function in the + # `funchelper` module enables passing a locals map to a function. + explicit = explicit or set() + for idx, (op, op_arg) in enumerate(codelist): + if op == LOAD_GLOBAL and op_arg not in explicit: + codelist[idx] = (LOAD_NAME, op_arg) - filename : string - The string filename to use when compiling. - lineno : int - The line number to use for the returned code object. +def optimize_locals(codelist): + """ Optimize the given code object for fast locals access. + + All STORE_NAME opcodes will be replace with STORE_FAST. Names which + are stored and then loaded via LOAD_NAME are rewritten to LOAD_FAST. + This transformation is applied in-place. + + Parameters + ---------- + codelist : list + The list of byteplay code ops to modify. """ - code = compile(item, filename, mode='eval') - return update_firstlineno(code, lineno) + fast_locals = set() + for idx, (op, op_arg) in enumerate(codelist): + if op == STORE_NAME: + fast_locals.add(op_arg) + codelist[idx] = (STORE_FAST, op_arg) + for idx, (op, op_arg) in enumerate(codelist): + if op == LOAD_NAME and op_arg in fast_locals: + codelist[idx] = (LOAD_FAST, op_arg) + + +def compile_simple(py_ast, filename): + """ Compile an ast into a code object implementing operator `=`. + + Parameters + ---------- + py_ast : ast.Expression + A Python ast Expression node. + + filename : str + The filename which generated the expression. + + Returns + ------- + result : types.CodeType + A Python code object which implements the desired behavior. + + """ + code = compile(py_ast, filename, mode='eval') + code = update_firstlineno(code, py_ast.lineno) + bp_code = Code.from_code(code) + replace_global_loads(bp_code.code) + optimize_locals(bp_code.code) + bp_code.newlocals = False + return bp_code.to_code() + + +def compile_notify(py_ast, filename): + """ Compile an ast into a code object implementing operator `::`. + + Parameters + ---------- + py_ast : ast.Module + A Python ast Module node. + + filename : str + The filename which generated the expression. + + Returns + ------- + result : types.CodeType + A Python code object which implements the desired behavior. + + """ + explicit_globals = set() + for node in ast.walk(py_ast): + if isinstance(node, ast.Global): + explicit_globals.update(node.names) + code = compile(py_ast, filename, mode='exec') + bp_code = Code.from_code(code) + replace_global_loads(bp_code.code, explicit_globals) + optimize_locals(bp_code.code) + bp_code.newlocals = False + return bp_code.to_code() + + +def compile_subscribe(py_ast, filename): + """ Compile an ast into a code object implementing operator `<<`. + + Parameters + ---------- + py_ast : ast.Expression + A Python ast Expression node. + + filename : str + The filename which generated the expression. + + Returns + ------- + result : types.CodeType + A Python code object which implements the desired behavior. + + """ + code = compile(py_ast, filename, mode='eval') + code = update_firstlineno(code, py_ast.lineno) + bp_code = Code.from_code(code) + replace_global_loads(bp_code.code) + optimize_locals(bp_code.code) + bp_code.code = inject_tracing(bp_code.code) + bp_code.newlocals = False + bp_code.args = ('_[tracer]',) + bp_code.args + return bp_code.to_code() + + +def compile_update(py_ast, filename): + """ Compile an ast into a code object implementing operator `>>`. + + Parameters + ---------- + py_ast : ast.Expression + A Python ast Expression node. + + filename : str + The filename which generated the expression. + + Returns + ------- + result : types.CodeType + A Python code object which implements the desired behavior. + + """ + code = compile(py_ast, filename, mode='eval') + code = update_firstlineno(code, py_ast.lineno) + bp_code = Code.from_code(code) + replace_global_loads(bp_code.code) + optimize_locals(bp_code.code) + bp_code.code = inject_inversion(bp_code.code) + bp_code.newlocals = False + bp_code.args = ('_[inverter]', '_[value]') + bp_code.args + return bp_code.to_code() + + +def compile_delegate(py_ast, filename): + """ Compile an ast into a code object implementing operator `:=`. + + This will generate two code objects: one which is equivalent to + operator `<<` and another which is equivalent to `>>`. + + Parameters + ---------- + py_ast : ast.Expression + A Python ast Expression node. + + filename : str + The filename which generated the expression. + + Returns + ------- + result : tuple + A 2-tuple of types.CodeType equivalent to operators `<<` and + `>>` respectively. + + """ + code = compile(py_ast, filename, mode='eval') + code = update_firstlineno(code, py_ast.lineno) + bp_code = Code.from_code(code) + bp_code.newlocals = False + codelist = bp_code.code[:] + bp_args = tuple(bp_code.args) + replace_global_loads(codelist) + optimize_locals(codelist) + sub_list = inject_tracing(codelist) + bp_code.code = sub_list + bp_code.args = ('_[tracer]',) + bp_args + sub_code = bp_code.to_code() + upd_list = inject_inversion(codelist) + bp_code.code = upd_list + bp_code.args = ('_[inverter]', '_[value]') + bp_args + upd_code = bp_code.to_code() + return (sub_code, upd_code) + + +COMPILE_OP_MAP = { + '__operator_Equal__': compile_simple, + '__operator_ColonColon__': compile_notify, + '__operator_LessLess__': compile_subscribe, + '__operator_GreaterGreater__': compile_update, + '__operator_ColonEqual__': compile_delegate, +} #------------------------------------------------------------------------------ @@ -141,7 +333,9 @@ class _NodeVisitor(object): """ def visit(self, node): - """ The main visitor dispatch method. + """ The main visitor dispatch method. + + Unhandled nodes will raise an error. """ name = 'visit_%s' % node.__class__.__name__ @@ -151,8 +345,22 @@ def visit(self, node): method = self.default_visit method(node) + def visit_nonstrict(self, node): + """ A nonstrict visitor dispatch method. + + Unhandled nodes will be ignored. + + """ + name = 'visit_%s' % node.__class__.__name__ + try: + method = getattr(self, name) + except AttributeError: + pass + else: + method(node) + def default_visit(self, node): - """ The default visitor method. Raises an error since there + """ The default visitor method. Raises an error since there should not be any unhandled nodes. """ @@ -170,7 +378,7 @@ class DeclarationCompiler(_NodeVisitor): def compile(cls, node, filename): """ The main entry point of the DeclarationCompiler. - This compiler compiles the given Declaration node into a code + This compiler compiles the given Declaration node into a code object for a builder function. Parameters @@ -186,7 +394,7 @@ def compile(cls, node, filename): compiler.visit(node) code_ops = compiler.code_ops code = Code( - code_ops, [], ['instance', 'identifiers', 'operators'], False, + code_ops, [], ['instance', 'identifiers', 'operators'], False, False, True, node.name, filename, node.lineno, node.doc, ) return code @@ -215,7 +423,7 @@ def curr_name(self): return self.name_stack[-1] def visit_Declaration(self, node): - """ Creates the bytecode ops for a declaration node. + """ Creates the bytecode ops for a declaration node. This node visitor pulls the passed in root into a local var and stores it's identifier if one is given. It also loads @@ -228,12 +436,9 @@ def visit_Declaration(self, node): extend_ops([ # f_globals = globals() - (LOAD_GLOBAL, 'globals'), + (LOAD_NAME, 'globals'), (CALL_FUNCTION, 0x0000), (STORE_FAST, 'f_globals'), - # eval_ = eval - (LOAD_GLOBAL, 'eval'), - (STORE_FAST, 'eval_'), # _var_1 = instance (LOAD_FAST, 'instance'), (STORE_FAST, name), @@ -247,11 +452,11 @@ def visit_Declaration(self, node): (LOAD_CONST, node.identifier), (STORE_SUBSCR, None), ]) - + visit = self.visit for item in node.body: visit(item) - + extend_ops([ # return _var_1 (LOAD_FAST, name), @@ -261,7 +466,7 @@ def visit_Declaration(self, node): self.pop_name() def visit_AttributeDeclaration(self, node): - """ Creates the bytecode ops for an attribute declaration. + """ Creates the bytecode ops for an attribute declaration. The attributes will have already been added to the subclass, so this visitor just dispatches to any default bindings which may @@ -274,59 +479,74 @@ def visit_AttributeDeclaration(self, node): self.visit(node.default) def visit_AttributeBinding(self, node): - """ Creates the bytecode ops for an attribute binding. + """ Creates the bytecode ops for an attribute binding. - This visitor handles loading and calling the appropriate + This visitor handles loading and calling the appropriate operator. """ - fn = self.filename - op_code = eval_compile(node.binding.op, fn, node.binding.lineno) py_ast = node.binding.expr.py_ast - if isinstance(py_ast, ast.Module): - expr_code = compile(py_ast, fn, mode='exec') + op = node.binding.op + op_compiler = COMPILE_OP_MAP[op] + code = op_compiler(py_ast, self.filename) + if isinstance(code, tuple): # operator `::` + sub_code, upd_code = code + self.extend_ops([ + # sub_func.__setter__ = upd_func + # operators['__operator_ColonEqual__'](obj, attr, sub_func, identifiers) + (SetLineno, node.binding.lineno), + (LOAD_FAST, 'operators'), + (LOAD_CONST, op), + (BINARY_SUBSCR, None), + (LOAD_FAST, self.curr_name()), + (LOAD_CONST, node.name), + (LOAD_CONST, sub_code), + (MAKE_FUNCTION, 0), + (DUP_TOP, None), + (LOAD_CONST, upd_code), + (MAKE_FUNCTION, 0), + (ROT_TWO, None), + (STORE_ATTR, '_setter'), + (LOAD_FAST, 'identifiers'), + (CALL_FUNCTION, 0x0004), + (POP_TOP, None), + ]) else: - expr_code = eval_compile(py_ast, fn, py_ast.lineno) - self.extend_ops([ - # op = eval('__operator_Equal__', operators) - # op(item, 'a', code, identifiers, f_globals, operators) - (LOAD_FAST, 'eval_'), - (LOAD_CONST, op_code), - (LOAD_FAST, 'operators'), - (CALL_FUNCTION, 0x0002), - (LOAD_FAST, self.curr_name()), - (LOAD_CONST, node.name), - (LOAD_CONST, expr_code), - (LOAD_FAST, 'identifiers'), - (LOAD_FAST, 'f_globals'), - (LOAD_FAST, 'operators'), - (CALL_FUNCTION, 0x0006), - (POP_TOP, None), - ]) + self.extend_ops([ + # operators['__operator_Equal__'](obj, attr, func, identifiers) + (SetLineno, node.binding.lineno), + (LOAD_FAST, 'operators'), + (LOAD_CONST, op), + (BINARY_SUBSCR, None), + (LOAD_FAST, self.curr_name()), + (LOAD_CONST, node.name), + (LOAD_CONST, code), + (MAKE_FUNCTION, 0), + (LOAD_FAST, 'identifiers'), + (CALL_FUNCTION, 0x0004), + (POP_TOP, None), + ]) def visit_Instantiation(self, node): - """ Create the bytecode ops for a component instantiation. + """ Create the bytecode ops for a component instantiation. - This visitor handles calling another derived component and + This visitor handles calling another derived component and storing its identifier, if given. - + """ extend_ops = self.extend_ops parent_name = self.curr_name() name = self.name_gen.next() self.push_name(name) - op_code = eval_compile(node.name, self.filename, node.lineno) extend_ops([ - # _var_2 = eval('PushButton', f_globals)(parent) - (LOAD_FAST, 'eval_'), - (LOAD_CONST, op_code), - (LOAD_FAST, 'f_globals'), - (CALL_FUNCTION, 0x0002), + # _var_2 = globals()['PushButton'](parent) + (SetLineno, node.lineno), + (LOAD_NAME, node.name), (LOAD_FAST, parent_name), (CALL_FUNCTION, 0x0001), (STORE_FAST, name), ]) - + if node.identifier: extend_ops([ # identifiers['btn'] = _var_2 @@ -339,7 +559,7 @@ def visit_Instantiation(self, node): visit = self.visit for item in node.body: visit(item) - + self.pop_name() @@ -348,7 +568,7 @@ def visit_Instantiation(self, node): #------------------------------------------------------------------------------ class EnamlCompiler(_NodeVisitor): """ A visitor that will compile an enaml module ast node. - + The entry point is the `compile` classmethod which will compile the ast into an appropriate python code object for a module. @@ -361,10 +581,10 @@ def compile(cls, module_ast, filename): ---------- module_ast : Instance(enaml_ast.Module) The enaml module ast node that should be compiled. - + filename : str The string filename of the module ast being compiled. - + """ compiler = cls(filename) compiler.visit(module_ast) @@ -386,7 +606,7 @@ def compile(cls, module_ast, filename): end_code = compile(end, filename, mode='exec') # Skip the SetLineo and ReturnValue codes extend_ops(Code.from_code(end_code).code[1:-2]) - + # Add in the final return value ops extend_ops([ (LOAD_CONST, None), @@ -413,17 +633,18 @@ def __init__(self, filename): self.extend_ops = self.code_ops.extend def visit_Module(self, node): - """ The Module node visitor method. + """ The Module node visitor method. This visitor dispatches to all of the body nodes of the module. """ + visit = self.visit for item in node.body: - self.visit(item) - + visit(item) + def visit_Python(self, node): """ The Python node visitor method. - + This visitor adds a chunk of raw Python into the module. """ @@ -433,9 +654,9 @@ def visit_Python(self, node): self.extend_ops(bpc.code[1:-2]) def visit_Declaration(self, node): - """ The Declaration node visitor. + """ The Declaration node visitor. - This generates the bytecode ops whic create a new type for the + This generates the bytecode ops whic create a new type for the enamldef and then adds the user defined attributes and events. It also dispatches to the DeclarationCompiler which will create the builder function for the new type. @@ -444,19 +665,12 @@ def visit_Declaration(self, node): name = node.name extend_ops = self.extend_ops filename = self.filename - func_code = DeclarationCompiler.compile(node, filename) - base_code = eval_compile(node.base.py_ast, filename, node.base.lineno) - extend_ops([ (SetLineno, node.lineno), (LOAD_NAME, '_make_enamldef_helper_'), (LOAD_CONST, name), - (LOAD_NAME, 'eval'), - (LOAD_CONST, base_code), - (LOAD_NAME, 'globals'), - (CALL_FUNCTION, 0x0000), - (CALL_FUNCTION, 0x0002), + (LOAD_NAME, node.base), (LOAD_CONST, func_code), (MAKE_FUNCTION, 0), (CALL_FUNCTION, 0x0003), @@ -470,36 +684,32 @@ def visit_Declaration(self, node): (LOAD_ATTR, '_add_user_attribute'), ]) - # This loop adds the ops to add the user attrs and events. + # Dispatch to add any class-level info contained within the + # declaration body. Visit nonstrict since not all child nodes + # are valid at the class-level. The '_add_user_attribute' + # class method is left on the top of the stack and popped + # at the end of the visitors. + visit = self.visit_nonstrict for child_node in node.body: - if type(child_node).__name__ == 'AttributeDeclaration': - extend_ops([ - (SetLineno, child_node.lineno), - (DUP_TOP, None), - (LOAD_CONST, child_node.name), - ]) - attr_type = child_node.type - if attr_type is not None: - attr_type_code = eval_compile( - attr_type.py_ast, filename, attr_type.lineno - ) - extend_ops([ - (LOAD_NAME, 'eval'), - (LOAD_CONST, attr_type_code), - (LOAD_NAME, 'globals'), - (CALL_FUNCTION, 0x0000), - (CALL_FUNCTION, 0x0002), - (LOAD_CONST, child_node.is_event), - (CALL_FUNCTION, 0x0003), - (POP_TOP, None), - ]) - else: - extend_ops([ - (LOAD_NAME, 'object'), - (LOAD_CONST, child_node.is_event), - (CALL_FUNCTION, 0x0003), - (POP_TOP, None), - ]) + visit(child_node) extend_ops([(POP_TOP, None)]) + def visit_AttributeDeclaration(self, node): + """ Creates the bytecode ops for an attribute declaration. + + This will add the ops to add the user attrs and events to + the new type. + + """ + attr_type = node.type or 'object' + self.extend_ops([ + (SetLineno, node.lineno), + (DUP_TOP, None), + (LOAD_CONST, node.name), + (LOAD_NAME, attr_type), + (LOAD_CONST, node.is_event), + (CALL_FUNCTION, 0x0003), + (POP_TOP, None), + ]) + From a73e67f7111fec8ac866852e35b5283decf4f285 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 20:02:51 -0500 Subject: [PATCH 12/34] Add DelegationExpression using new code injection semantics. --- enaml/core/new_expressions.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/enaml/core/new_expressions.py b/enaml/core/new_expressions.py index dd58356b..ef0bca5b 100644 --- a/enaml/core/new_expressions.py +++ b/enaml/core/new_expressions.py @@ -376,3 +376,28 @@ def eval(self, obj, name): AbstractExpression.register(SubscriptionExpression) + +#------------------------------------------------------------------------------ +# Delegation Expression +#------------------------------------------------------------------------------ +class DelegationExpression(SubscriptionExpression): + """ + + """ + #-------------------------------------------------------------------------- + # AbstractListener Interface + #-------------------------------------------------------------------------- + def value_changed(self, obj, name, old, new): + """ Called when the attribute on the object has changed. + + """ + nonlocals = Nonlocals(obj, None) + inverter = StandardInverter(nonlocals) + overrides = {'nonlocals': nonlocals} + scope = DynamicScope(obj, self._identifiers, overrides, None) + with obj.operators: + call_func(self._func._setter, (inverter, new), {}, scope) + + +AbstractListener.register(DelegationExpression) + From 0860588aa00b15e523eaf9da442b0524d3eaadc4 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 20:03:16 -0500 Subject: [PATCH 13/34] Update the new operators for the new code injection semantics. --- enaml/core/new_operators.py | 39 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/enaml/core/new_operators.py b/enaml/core/new_operators.py index 9462650f..f17dba59 100644 --- a/enaml/core/new_operators.py +++ b/enaml/core/new_operators.py @@ -2,70 +2,51 @@ # Copyright (c) 2012, Enthought, Inc. # All rights reserved. #------------------------------------------------------------------------------ -import types -from .code_tracing import transform_code from .new_expressions import ( SimpleExpression, NotificationExpression, SubscriptionExpression, - UpdateExpression, + UpdateExpression, DelegationExpression ) -_cached_code = {} - - -def op_simple(cmpnt, attr, code, identifiers, f_globals, operators): +def op_simple(cmpnt, attr, func, identifiers): """ The default Enaml operator for '=' expressions. It binds an instance of SimpleExpression to the component. """ - if code in _cached_code: - func = _cached_code[code] - else: - c = transform_code(code, False) - func = _cached_code[code] = types.FunctionType(c, f_globals) expr = SimpleExpression(func, identifiers) cmpnt._bind_expression(attr, expr) -def op_notify(cmpnt, attr, code, identifiers, f_globals, operators): +def op_notify(cmpnt, attr, func, identifiers): """ The default Enaml operator for '::' expressions. It binds an instance of NotificationExpression to the component. """ - if code in _cached_code: - func = _cached_code[code] - else: - c = transform_code(code, False) - func = _cached_code[code] = types.FunctionType(c, f_globals) expr = NotificationExpression(func, identifiers) cmpnt._bind_listener(attr, expr) -def op_update(cmpnt, attr, code, identifiers, f_globals, operators): +def op_update(cmpnt, attr, func, identifiers): """ The default Enaml operator for '>>' expressions. It binds an instance of UpdateExpression to the component. """ - return + expr = UpdateExpression(func, identifiers) + cmpnt._bind_listener(attr, expr) -def op_subscribe(cmpnt, attr, code, identifiers, f_globals, operators): +def op_subscribe(cmpnt, attr, func, identifiers): """ The default Enaml operator for '<<' expressions. It binds an instance of SubscriptionExpression to the component using monitors which understand traits attribute access via dotted notation and the builtin getattr function. """ - if code in _cached_code: - func = _cached_code[code] - else: - c = transform_code(code, True) - func = _cached_code[code] = types.FunctionType(c, f_globals) expr = SubscriptionExpression(func, identifiers) cmpnt._bind_expression(attr, expr) -def op_delegate(cmpnt, attr, code, identifiers, f_globals, operators): +def op_delegate(cmpnt, attr, func, identifiers): """ The default Enaml operator for ':=' expressions. It binds an instance of DelegationExpression to the component using monitors which understand traits attribute access via dotted notation and @@ -74,7 +55,9 @@ def op_delegate(cmpnt, attr, code, identifiers, f_globals, operators): builtin getattr function. """ - return + expr = DelegationExpression(func, identifiers) + cmpnt._bind_expression(attr, expr) + cmpnt._bind_listener(attr, expr) OPERATORS = { From cd8a207d9568f51de70eaed507f0d4355caa0c64 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 20:19:20 -0500 Subject: [PATCH 14/34] Add the code tracer to the dynamic scopes to trace dynamic loads. --- enaml/core/new_expressions.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/enaml/core/new_expressions.py b/enaml/core/new_expressions.py index ef0bca5b..4bf4faaa 100644 --- a/enaml/core/new_expressions.py +++ b/enaml/core/new_expressions.py @@ -59,7 +59,7 @@ def _bind_trait(self, obj, name): #-------------------------------------------------------------------------- # AbstractScopeListener Interface #-------------------------------------------------------------------------- - def dynamic_load(self, obj, attr): + def dynamic_load(self, obj, attr, value): """ Called when an object attribute is dynamically loaded. This will attach a listener to the object if it is a HasTraits @@ -365,14 +365,11 @@ def eval(self, obj, name): notifier._expr = None # break the ref cycle notifier = self._notifier = Notifier(self, name) tracer = TraitsTracer(notifier) - overrides = {'nonlocals': Nonlocals(obj, None)} - scope = DynamicScope(obj, self._identifiers, overrides, None) + overrides = {'nonlocals': Nonlocals(obj, tracer)} + scope = DynamicScope(obj, self._identifiers, overrides, tracer) with obj.operators: - try: - return call_func(self._func, (tracer,), {}, scope) - except Exception, e: - print e - return '' + return call_func(self._func, (tracer,), {}, scope) + AbstractExpression.register(SubscriptionExpression) From e541dacb766be73e8e536b84d038b882fb29cbf8 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Wed, 21 Nov 2012 20:26:47 -0500 Subject: [PATCH 15/34] Remove the inversion of setattr, it doesn't make sense. --- enaml/core/new_expressions.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/enaml/core/new_expressions.py b/enaml/core/new_expressions.py index 4bf4faaa..588901b1 100644 --- a/enaml/core/new_expressions.py +++ b/enaml/core/new_expressions.py @@ -170,8 +170,7 @@ def call_function(self, func, argtuple, argspec, value): """ Called before the CALL_FUNCTION opcode is executed. This method inverts a call to the builtin `getattr` into a call - to the builtin `setattr`, and allows the builtin `setattr` to - execute unmodified. All other calls will raise. + to the builtin `setattr`. All other calls will raise. See also: `CodeInverter.call_function`. """ @@ -180,9 +179,6 @@ def call_function(self, func, argtuple, argspec, value): if (func is getattr and (nargs == 2 or nargs == 3) and nkwargs == 0): obj, attr = argtuple[0], argtuple[1] setattr(obj, attr, value) - elif (func is setattr and nargs == 3 and nkwargs == 0): - obj, attr = argtuple[0], argtuple[1] - setattr(obj, attr, value) else: self.fail() From 2c92280d74eff7955ea1fea1e673c94bc86f8975 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Fri, 23 Nov 2012 16:10:03 -0500 Subject: [PATCH 16/34] Fix a bug in the ctypes `call_func` implementation. This fixes a bug in the argument passing of the ctypes `call_func` implementation. The original version did not create the PyObject** address correctly. --- enaml/core/funchelper.py | 59 +++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/enaml/core/funchelper.py b/enaml/core/funchelper.py index d67d6638..56638ed6 100644 --- a/enaml/core/funchelper.py +++ b/enaml/core/funchelper.py @@ -2,26 +2,38 @@ # Copyright (c) 2012, Enthought, Inc. # All rights reserved. #------------------------------------------------------------------------------ -from ctypes import pythonapi, py_object, POINTER, c_int, byref from types import FunctionType +from ctypes import ( + pythonapi, py_object, c_int, c_long, Structure, ARRAY, c_void_p +) PyEval_EvalCodeEx = pythonapi.PyEval_EvalCodeEx PyEval_EvalCodeEx.restype = py_object PyEval_EvalCodeEx.argtypes = [ - py_object, # code object - py_object, # globals dict - py_object, # locals mapping - POINTER(py_object), # args array - c_int, # num args - POINTER(py_object), # keywords array - c_int, # num keywords - POINTER(py_object), # defaults array - c_int, # num defaults - py_object, # closure + py_object, # code object + py_object, # globals dict + py_object, # locals mapping + c_void_p, # args array (PyObject**) + c_int, # num args + c_void_p, # keywords array (PyObject**) + c_int, # num keywords + c_void_p, # defaults array (PyObject**) + c_int, # num defaults + py_object, # closure ] +class PyTupleObject(Structure): + _fields_ = [ + ('ob_refcnt', c_long), + ('ob_type', py_object), + ('ob_size', c_long), + ('ob_item', ARRAY(py_object, 1)), + ] +OB_ITEM_OFFSET = PyTupleObject.ob_item.offset + + def call_func(func, args, kwargs, f_locals=None): """ Call a function which has been modified by the Enaml compiler to support tracing and dynamic scoping. @@ -55,11 +67,13 @@ def call_func(func, args, kwargs, f_locals=None): if not isinstance(kwargs, dict): raise TypeError('keywords must be a dict') - if f_locals is not None and not hasattr(f_locals, '__getitem__'): + if f_locals is None: + f_locals = py_object() + elif not hasattr(f_locals, '__getitem__'): raise TypeError('locals must be a mapping') - defaults = func.func_defaults - num_defaults = len(defaults) if defaults else 0 + num_args = len(args) + args_array = c_void_p(id(args) + OB_ITEM_OFFSET) if kwargs: keywords = [] @@ -69,22 +83,23 @@ def call_func(func, args, kwargs, f_locals=None): keywords = tuple(keywords) num_keywords = len(keywords) / 2 else: - keywords = None + keywords = () num_keywords = 0 + keywords_array = c_void_p(id(keywords) + OB_ITEM_OFFSET) - args_ptr = byref(py_object(args[0])) if args else None - defaults_ptr = byref(py_object(defaults[0])) if defaults else None - keywords_ptr = byref(py_object(keywords[0])) if keywords else None + defaults = func.func_defaults or () + num_defaults = len(defaults) + defaults_array = c_void_p(id(defaults) + OB_ITEM_OFFSET) result = PyEval_EvalCodeEx( func.func_code, func.func_globals, f_locals, - args_ptr, - len(args), - keywords_ptr, + args_array, + num_args, + keywords_array, num_keywords, - defaults_ptr, + defaults_array, num_defaults, func.func_closure ) From 22c3410888fc7c1652ce0eeb1c8f8dc7f9c9ac72 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Fri, 23 Nov 2012 22:41:55 -0500 Subject: [PATCH 17/34] Separate the listenable expression into its own type --- enaml/core/abstract_expressions.py | 35 ++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/enaml/core/abstract_expressions.py b/enaml/core/abstract_expressions.py index 6950bb8b..2db3cf16 100644 --- a/enaml/core/abstract_expressions.py +++ b/enaml/core/abstract_expressions.py @@ -3,13 +3,14 @@ # All rights reserved. #------------------------------------------------------------------------------ from abc import ABCMeta, abstractmethod +from enaml.signaling import Signal class AbstractListener(object): """ An interface definition for creating attribute listeners. - Listeners can be regisitered with `Declarative` instances in order - to track changes to their attributes. + Listeners are registered with `Declarative` instances using the + `bind_listener` method to track changes to their attributes. """ __metaclass__ = ABCMeta @@ -39,19 +40,14 @@ def value_changed(self, obj, name, old, new): class AbstractExpression(object): """ An abstract interface definition for creating expressions. - Expressions can be registered with `Declarative` instances in order - to provide dynamically computed values at runtime. + Expressions are registered with `Declarative` instances using the + `bind_expression` method to provide computed attribute values. """ __metaclass__ = ABCMeta - #: An Enaml Signal which should be emitted by the expression when - #: the the expression is invalidated. If an expression does not - #: support invalidation, this may be None. - invalidated = None - @abstractmethod - def eval(self, obj): + def eval(self, obj, name): """ Evaluate and return the results of the expression. Parameters @@ -59,8 +55,25 @@ def eval(self, obj): obj : Declarative The declarative object which owns the expression. - + name : str + The attribute name on `obj` for which this expression is + providing the value. """ raise NotImplementedError + +class AbstractListenableExpression(AbstractExpression): + """ An abstract interface definition for creating listenable + expressions. + + Listenable expressions are registered with `Declarative` instances + using the `bind_expression` method to provide dynamically computed + attribute values at runtime. + + """ + #: An Enaml Signal emitted by the expression when it becomes invalid. + #: The payload of the signal will be the name that was passed to the + #: `eval` method during the last expression evaluation. + invalidated = Signal() + From 42ea43e72bdd85c4194554472a1fce49258c7f73 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Fri, 23 Nov 2012 22:55:13 -0500 Subject: [PATCH 18/34] Optimize tracing and notification. Maintain a hash of notifiers which are attached and only rebind when the hash changes. --- enaml/core/new_expressions.py | 181 +++++++++++++++++++--------------- 1 file changed, 99 insertions(+), 82 deletions(-) diff --git a/enaml/core/new_expressions.py b/enaml/core/new_expressions.py index 588901b1..65dbe4c8 100644 --- a/enaml/core/new_expressions.py +++ b/enaml/core/new_expressions.py @@ -3,12 +3,15 @@ # All rights reserved. #------------------------------------------------------------------------------ from collections import namedtuple +from weakref import ref from traits.api import HasTraits, Disallow, TraitListObject, TraitDictObject from enaml.signaling import Signal -from .abstract_expressions import AbstractExpression, AbstractListener +from .abstract_expressions import ( + AbstractExpression, AbstractListener, AbstractListenableExpression +) from .code_tracing import CodeTracer, CodeInverter from .dynamic_scope import DynamicScope, AbstractScopeListener, Nonlocals from .funchelper import call_func @@ -18,26 +21,23 @@ # Traits Code Tracer #------------------------------------------------------------------------------ class TraitsTracer(CodeTracer): - """ A CodeTracer for tracing expressions using Traits. + """ A CodeTracer for tracing expressions which use Traits. + + This tracer maintains a running set of `traced_items` which are the + (obj, name) pairs of traits items discovered during tracing. """ - def __init__(self, notifier): + def __init__(self): """ Initialize a TraitsTracer. - Parameters - ---------- - notifier : AbstractNotifier - The notifier to use as a handler for traits dependencies. - """ - self._notifier = notifier - self._bound = set() + self.traced_items = set() #-------------------------------------------------------------------------- # Private API #-------------------------------------------------------------------------- - def _bind_trait(self, obj, name): - """ Bind the a handler for the named trait on the object. + def _trace_trait(self, obj, name): + """ Add the trait object and name pair to the traced items. Parameters ---------- @@ -48,13 +48,11 @@ def _bind_trait(self, obj, name): The trait name to for which to bind a handler. """ + # Traits will happily force create a trait for things which aren't + # actually traits. This tries to avoid most of that when possible. trait = obj.trait(name) - if trait is not None and trait is not Disallow: - key = (obj, name) - bound = self._bound - if key not in bound: - obj.on_trait_change(self._notifier.notify, name) - bound.add(key) + if trait is not None and trait.trait_type is not Disallow: + self.traced_items.add((obj, name)) #-------------------------------------------------------------------------- # AbstractScopeListener Interface @@ -67,7 +65,7 @@ def dynamic_load(self, obj, attr, value): """ if isinstance(obj, HasTraits): - self._bind_trait(obj, attr) + self._trace_trait(obj, attr) #-------------------------------------------------------------------------- # CodeTracer Interface @@ -80,7 +78,7 @@ def load_attr(self, obj, attr): """ if isinstance(obj, HasTraits): - self._bind_trait(obj, attr) + self._trace_trait(obj, attr) def call_function(self, func, argtuple, argspec): """ Called before the CALL_FUNCTION opcode is executed. @@ -95,33 +93,34 @@ def call_function(self, func, argtuple, argspec): if (func is getattr and (nargs == 2 or nargs == 3) and nkwargs == 0): obj, attr = argtuple[0], argtuple[1] if isinstance(obj, HasTraits) and isinstance(attr, basestring): - self._bind_trait(obj, attr) + self._trace_trait(obj, attr) def binary_subscr(self, obj, idx): """ Called before the BINARY_SUBSCR opcode is executed. - This will attach a trait if the object is a `TraitListObject` - or a `TraitDictObject`. See also: `CodeTracer.get_iter`. + This will attach a traits items listener if the object is a + `TraitListObject` or a `TraitDictObject`. + See also: `CodeTracer.get_iter`. """ if isinstance(obj, (TraitListObject, TraitDictObject)): - o = obj.object() - if o is not None: + traits_obj = obj.object() + if traits_obj is not None: if obj.name_items: - self._bind_trait(o, obj.name_items) + self._trace_trait(traits_obj, obj.name_items) def get_iter(self, obj): """ Called before the GET_ITER opcode is executed. - This will attach a trait if the object is a `TraitListObject`. - See also: `CodeTracer.get_iter`. + This will attach a traits items listener if the object is a + `TraitListObject`. See also: `CodeTracer.get_iter`. """ if isinstance(obj, TraitListObject): - o = obj.object() - if o is not None: + traits_obj = obj.object() + if traits_obj is not None: if obj.name_items: - self._bind_trait(o, obj.name_items) + self._trace_trait(traits_obj, obj.name_items) AbstractScopeListener.register(TraitsTracer) @@ -160,7 +159,7 @@ def load_name(self, name, value): def load_attr(self, obj, attr, value): """ Called before the LOAD_ATTR opcode is executed. - This method performs STORE_ATTR via the builting `setattr`. + This method performs STORE_ATTR via the builtin `setattr`. See also: `CodeInverter.load_attr`. """ @@ -192,38 +191,6 @@ def binary_subscr(self, obj, idx, value): obj[idx] = value -#------------------------------------------------------------------------------ -# Notifier -#------------------------------------------------------------------------------ -class Notifier(object): - """ A simple object used to attach notification handlers. - - """ - __slots__ = ('_expr', '_name', '__weakref__') - - def __init__(self, expr, name): - """ Initialize a TraitNotifier. - - Parameters - ---------- - expr : AbstractExpression - The expression whose `invalidated` signal should be emitted - when the notifier is triggered. - - name : str - The name to which the expression is bound. - - """ - self._expr = expr - self._name = name - - def notify(self): - """ Notify that the expression is invalid. - - """ - self._expr.invalidated.emit(self._name) - - #------------------------------------------------------------------------------ # Base Expression #------------------------------------------------------------------------------ @@ -239,8 +206,9 @@ def __init__(self, func, identifiers): Parameters ---------- func : types.FunctionType - A function whose bytecode has been patch support dynamic - scoping but not tracing. + A function created by the Enaml compiler with bytecode that + has been patched to support the semantics required of the + expression. identifiers : dict The dictionary of identifiers available to the function. @@ -259,9 +227,6 @@ class SimpleExpression(BaseExpression): """ __slots__ = () - # SimpleExpression does not support invalidation. - invalidated = None - #-------------------------------------------------------------------------- # AbstractExpression Interface #-------------------------------------------------------------------------- @@ -339,42 +304,94 @@ def value_changed(self, obj, name, old, new): #------------------------------------------------------------------------------ # Subcsription Expression #------------------------------------------------------------------------------ +class SubscriptionNotifier(object): + """ A simple object used for attaching notification handlers. + + """ + __slots__ = ('expr', 'name', 'hashval', '__weakref__') + + def __init__(self, expr, name, hashval): + """ Initialize a Notifier. + + Parameters + ---------- + expr : AbstractListenableExpression + The expression whose `invalidated` signal should be emitted + when the notifier is triggered. It must be weakref-able. + + name : str + The name to which the expression is bound. + + hashval : int + A hash value to use for testing equivalency of notifiers. + + """ + self.expr = ref(expr) + self.name = name + self.hashval = hashval + + def notify(self): + """ Notify that the expression is invalid. + + """ + expr = self.expr() + if expr is not None: + expr.invalidated.emit(self.name) + + class SubscriptionExpression(BaseExpression): - """ An implementation of AbstractExpression for the `<<` operator. + """ An implementation of AbstractListenableExpression for the `<<` + operator. """ - # Slots not declared because Signal requires a __dict__ - invalidated = Signal() + # Note: __slots__ are not declared because Enaml Signals require a + # __dict__ to exist on the instance. - # Internal storage for the notifier + #: Private storage for the SubscriptionNotifier. _notifier = None #-------------------------------------------------------------------------- - # AbstractExpression Interface + # AbstractListenableExpression Interface #-------------------------------------------------------------------------- + invalidated = Signal() + def eval(self, obj, name): """ Evaluate and return the expression value. """ - notifier = self._notifier - if notifier is not None: - notifier._expr = None # break the ref cycle - notifier = self._notifier = Notifier(self, name) - tracer = TraitsTracer(notifier) + tracer = TraitsTracer() overrides = {'nonlocals': Nonlocals(obj, tracer)} scope = DynamicScope(obj, self._identifiers, overrides, tracer) with obj.operators: - return call_func(self._func, (tracer,), {}, scope) + result = call_func(self._func, (tracer,), {}, scope) + + # In most cases, the object comprising the dependencies of an + # expression will not change during subsequent evaluations of + # the expression. Rather than creating a new notifier on each + # pass and repeating the work of creating the change handlers, + # a hash of the dependencies is computed and a new notifier is + # created only when the hash changes. + items = frozenset(tracer.traced_items) + notifier = self._notifier + if notifier is None or hash(items) != notifier.hashval: + notifier = SubscriptionNotifier(self, name, hash(items)) + self._notifier = notifier + handler = notifier.notify + for obj, attr in items: + obj.on_trait_change(handler, attr) + + return result -AbstractExpression.register(SubscriptionExpression) +AbstractListenableExpression.register(SubscriptionExpression) #------------------------------------------------------------------------------ # Delegation Expression #------------------------------------------------------------------------------ class DelegationExpression(SubscriptionExpression): - """ + """ An object which implements the `:=` operator by implementing the + AbstractListenableExpression and AbstractListener interfaces. """ #-------------------------------------------------------------------------- From 6e21accd3103c83a1f1cc75c3f962e0256e7d19a Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Fri, 23 Nov 2012 23:26:25 -0500 Subject: [PATCH 19/34] Use a keyval instead of a hash to eliminate the possibilty of hash collisions. This is slightly slower than hashing, but guaranteed correct. It's still much faster than not maintaining a keyvalue at all. --- enaml/core/new_expressions.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/enaml/core/new_expressions.py b/enaml/core/new_expressions.py index 65dbe4c8..ecfdcc1b 100644 --- a/enaml/core/new_expressions.py +++ b/enaml/core/new_expressions.py @@ -308,9 +308,9 @@ class SubscriptionNotifier(object): """ A simple object used for attaching notification handlers. """ - __slots__ = ('expr', 'name', 'hashval', '__weakref__') + __slots__ = ('expr', 'name', 'keyval', '__weakref__') - def __init__(self, expr, name, hashval): + def __init__(self, expr, name, keyval): """ Initialize a Notifier. Parameters @@ -322,13 +322,13 @@ def __init__(self, expr, name, hashval): name : str The name to which the expression is bound. - hashval : int - A hash value to use for testing equivalency of notifiers. + keyval : object + An object to use for testing equivalency of notifiers. """ self.expr = ref(expr) self.name = name - self.hashval = hashval + self.keyval = keyval def notify(self): """ Notify that the expression is invalid. @@ -369,15 +369,19 @@ def eval(self, obj, name): # expression will not change during subsequent evaluations of # the expression. Rather than creating a new notifier on each # pass and repeating the work of creating the change handlers, - # a hash of the dependencies is computed and a new notifier is - # created only when the hash changes. - items = frozenset(tracer.traced_items) + # a key for the dependencies is computed and a new notifier is + # created only when the key changes. The key uses the id of an + # object instead of the object itself so strong references to + # the object are not maintained by the expression. + id_ = id + traced = tracer.traced_items + keyval = frozenset((id_(obj), attr) for obj, attr in traced) notifier = self._notifier - if notifier is None or hash(items) != notifier.hashval: - notifier = SubscriptionNotifier(self, name, hash(items)) + if notifier is None or keyval != notifier.keyval: + notifier = SubscriptionNotifier(self, name, keyval) self._notifier = notifier handler = notifier.notify - for obj, attr in items: + for obj, attr in traced: obj.on_trait_change(handler, attr) return result From 9389a35716da9673b86e04fb99f9ac9a54393635 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Fri, 23 Nov 2012 23:29:08 -0500 Subject: [PATCH 20/34] Move binding methods to the public api on Declarative --- enaml/core/declarative.py | 134 ++++++++++++++++++++---------------- enaml/core/new_operators.py | 53 +++++++------- 2 files changed, 100 insertions(+), 87 deletions(-) diff --git a/enaml/core/declarative.py b/enaml/core/declarative.py index 9a0631ad..cba1c50a 100644 --- a/enaml/core/declarative.py +++ b/enaml/core/declarative.py @@ -6,7 +6,9 @@ Instance, List, Property, Str, Dict, Disallow, ReadOnly, TraitType, ) -from .abstract_expressions import AbstractExpression, AbstractListener +from .abstract_expressions import ( + AbstractExpression, AbstractListener, AbstractListenableExpression +) from .dynamic_scope import DynamicAttributeError from .object import Object from .operator_context import OperatorContext @@ -294,13 +296,45 @@ def _add_user_attribute(cls, name, attr_type, is_event): cls.__base_traits__[name] = ctrait cls.__class_traits__[name] = ctrait - def _bind_expression(self, name, expression): - """ A private method used by the Enaml execution engine. + def _on_expr_invalidated(self, name): + """ A signal handler invoked when an expression is invalidated. - This method is called by the Enaml operators to bind the given - expression object to the given attribute name. If the attribute - does not exist, an exception is raised. A strong reference to - the expression object is kept internally. + This handler is connected to the `invalidated` signal on bound + expressions which support dynamic notification. When a given + expression is invalidated, it is recomputed and the value of + its attribute is updated. + + Parameters + ---------- + name : str + The attribute name to which the invalid expression is bound. + + """ + value = self.eval_expression(name) + if value is not NotImplemented: + setattr(self, name, value) + + def _anytrait_changed(self, name, old, new): + """ An any trait changed handler for listener notification. + + This handler will notify any bound listeners when their attribute + of interest has changed. Using an `anytrait` handler reduces the + number of notifier objects which must be created. + + """ + super(Declarative, self)._anytrait_changed(name, old, new) + self.run_listeners(name, old, new) + + #-------------------------------------------------------------------------- + # Public API + #-------------------------------------------------------------------------- + def bind_expression(self, name, expression): + """ Bind an expression to the given attribute name. + + This method can be called to bind a value-providing expression + to the given attribute name. If the named attribute does not + exist, an exception is raised. Listenable expressions are + supported. Parameters ---------- @@ -317,23 +351,20 @@ def _bind_expression(self, name, expression): raise AttributeError(msg % (self, name)) exprs = self._expressions - handler = self._on_expr_invalidated if name in exprs: old = exprs[name] - if old.invalidated is not None: - old.invalidated.disconnect(handler) - else: - # Add support for default value computation. ExpressionTrait - # must only be added once; it will call `eval_expression` - # as needed and retrieve the most current expression value. - if not isinstance(curr.trait_type, ExpressionTrait): - self.add_trait(name, ExpressionTrait(curr)) - - if expression.invalidated is not None: - expression.invalidated.connect(handler) + if isinstance(old, AbstractListenableExpression): + old.invalidated.disconnect(self._on_expr_invalidated) + if isinstance(expression, AbstractListenableExpression): + expression.invalidated.connect(self._on_expr_invalidated) exprs[name] = expression - def _bind_listener(self, name, listener): + # Hookup support for default value computation. ExpressionTrait + # will call `eval_expression` when its `get` method is called. + if not isinstance(curr.trait_type, ExpressionTrait): + self.add_trait(name, ExpressionTrait(curr)) + + def bind_listener(self, name, listener): """ A private method used by the Enaml execution engine. This method is called by the Enaml operators to bind the given @@ -359,56 +390,19 @@ def _bind_listener(self, name, listener): lsnrs[name] = [] lsnrs[name].append(listener) - def _on_expr_invalidated(self, name): - """ A signal handler invoked when an expression is invalidated. - - This handler is connected to the `invalidated` signal on bound - expressions which support dynamic notification. When a given - expression is invalidated, it is recomputed and the value of - its attribute is updated. - - Parameters - ---------- - name : str - The attribute name to which the invalid expression is bound. - - """ - value = self.eval_expression(name) - if value is not NotImplemented: - setattr(self, name, value) - - def _anytrait_changed(self, name, old, new): - """ An any trait changed handler for listener notification. - - This handler will notify any bound listeners when their attribute - of interest has changed. Using an `anytrait` handler reduces the - number of notifier objects which must be created. - - """ - super(Declarative, self)._anytrait_changed(name, old, new) - lsnrs = self._listeners - if name in lsnrs: - for listener in lsnrs[name]: - listener.value_changed(self, name, old, new) - - #-------------------------------------------------------------------------- - # Public API - #-------------------------------------------------------------------------- def eval_expression(self, name): """ Evaluate a bound expression with the given name. - This will not update the value of the bound attribute. - Parameters ---------- name : str - The name of the attribute to which the expression is bound. + The name of the attribute with the bound expression. Returns ------- result : object or NotImplemented - The results of the expression, or NotImplemented if there - is no expression bound to the given name. + The result of evaluating the expression, or NotImplemented + if there is no expression bound to the given name. """ exprs = self._expressions @@ -416,6 +410,26 @@ def eval_expression(self, name): return exprs[name].eval(self, name) return NotImplemented + def run_listeners(self, name, old, new): + """ Run the listeners bound to the given attribute name. + + Parameters + ---------- + name : str + The name of the attribute with the bound listeners. + + old : object + The old value to pass to the listeners. + + new : object + The new value to pass to the listeners. + + """ + lsnrs = self._listeners + if name in lsnrs: + for listener in lsnrs[name]: + listener.value_changed(self, name, old, new) + def destroy(self): """ A reimplemented parent class destructor method. diff --git a/enaml/core/new_operators.py b/enaml/core/new_operators.py index f17dba59..904b2b40 100644 --- a/enaml/core/new_operators.py +++ b/enaml/core/new_operators.py @@ -8,56 +8,55 @@ ) -def op_simple(cmpnt, attr, func, identifiers): - """ The default Enaml operator for '=' expressions. It binds an - instance of SimpleExpression to the component. +def op_simple(obj, name, func, identifiers): + """ The default Enaml operator for `=` expressions. + + It binds an instance of SimpleExpression to the object. """ expr = SimpleExpression(func, identifiers) - cmpnt._bind_expression(attr, expr) + obj.bind_expression(name, expr) + +def op_notify(obj, name, func, identifiers): + """ The default Enaml operator for `::` expressions. -def op_notify(cmpnt, attr, func, identifiers): - """ The default Enaml operator for '::' expressions. It binds an - instance of NotificationExpression to the component. + It binds an instance of NotificationExpression to the object. """ expr = NotificationExpression(func, identifiers) - cmpnt._bind_listener(attr, expr) + obj.bind_listener(name, expr) + +def op_update(obj, name, func, identifiers): + """ The default Enaml operator for `>>` expressions. -def op_update(cmpnt, attr, func, identifiers): - """ The default Enaml operator for '>>' expressions. It binds an - instance of UpdateExpression to the component. + It binds an instance of UpdateExpression to the object. """ expr = UpdateExpression(func, identifiers) - cmpnt._bind_listener(attr, expr) + obj.bind_listener(name, expr) -def op_subscribe(cmpnt, attr, func, identifiers): - """ The default Enaml operator for '<<' expressions. It binds an - instance of SubscriptionExpression to the component using monitors - which understand traits attribute access via dotted notation and - the builtin getattr function. +def op_subscribe(obj, name, func, identifiers): + """ The default Enaml operator for `<<` expressions. + + It binds an instance of SubscriptionExpression to the object. """ expr = SubscriptionExpression(func, identifiers) - cmpnt._bind_expression(attr, expr) + obj.bind_expression(name, expr) + +def op_delegate(obj, name, func, identifiers): + """ The default Enaml operator for `:=` expressions. -def op_delegate(cmpnt, attr, func, identifiers): - """ The default Enaml operator for ':=' expressions. It binds an - instance of DelegationExpression to the component using monitors - which understand traits attribute access via dotted notation and - the builtin getattr function, and inverters which understand the - dotted attribute access, implicit attribute access, and also the - builtin getattr function. + It binds an instance of DelegationExpression to the object. """ expr = DelegationExpression(func, identifiers) - cmpnt._bind_expression(attr, expr) - cmpnt._bind_listener(attr, expr) + obj.bind_expression(name, expr) + obj.bind_listener(name, expr) OPERATORS = { From 9839a42ed7b4358f00a16360193d12ca8d5f0c22 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Sat, 24 Nov 2012 13:26:01 -0500 Subject: [PATCH 21/34] Move the new expressions and operators to current. Remove unneeded old code. --- enaml/core/expressions.py | 946 ++++++++++------------------------ enaml/core/inverters.py | 308 ----------- enaml/core/monitors.py | 376 -------------- enaml/core/new_expressions.py | 417 --------------- enaml/core/new_operators.py | 69 --- enaml/core/nonlocals.py | 148 ------ enaml/core/operators.py | 120 ++--- 7 files changed, 293 insertions(+), 2091 deletions(-) delete mode 100644 enaml/core/inverters.py delete mode 100644 enaml/core/monitors.py delete mode 100644 enaml/core/new_expressions.py delete mode 100644 enaml/core/new_operators.py delete mode 100644 enaml/core/nonlocals.py diff --git a/enaml/core/expressions.py b/enaml/core/expressions.py index f0b9e5de..ecfdcc1b 100644 --- a/enaml/core/expressions.py +++ b/enaml/core/expressions.py @@ -1,847 +1,417 @@ #------------------------------------------------------------------------------ -# Copyright (c) 2011, Enthought, Inc. +# Copyright (c) 2012, Enthought, Inc. # All rights reserved. #------------------------------------------------------------------------------ -from abc import ABCMeta, abstractmethod -from collections import namedtuple, defaultdict -from contextlib import contextmanager +from collections import namedtuple from weakref import ref -from traits.api import Disallow +from traits.api import HasTraits, Disallow, TraitListObject, TraitDictObject from enaml.signaling import Signal -from .byteplay import Code -from .monitors import AbstractMonitor -from .trait_types import UninitializedAttributeError +from .abstract_expressions import ( + AbstractExpression, AbstractListener, AbstractListenableExpression +) +from .code_tracing import CodeTracer, CodeInverter +from .dynamic_scope import DynamicScope, AbstractScopeListener, Nonlocals +from .funchelper import call_func #------------------------------------------------------------------------------ -# Expression Helpers +# Traits Code Tracer #------------------------------------------------------------------------------ -@contextmanager -def swap_attribute(obj, attr, value): - """ Swap an attribute of an object with the given value for the - duration of the context, restoring it on exit. The attribute must - already exist on the object prior to entering the context. +class TraitsTracer(CodeTracer): + """ A CodeTracer for tracing expressions which use Traits. - Parameters - ---------- - obj : object - The object which owns the attribute. - - attr : string - The name of the attribute on the object. - - value : object - The value to apply to the attribute for the duration of the - context. + This tracer maintains a running set of `traced_items` which are the + (obj, name) pairs of traits items discovered during tracing. """ - old = getattr(obj, attr) - setattr(obj, attr, value) - yield - setattr(obj, attr, old) + def __init__(self): + """ Initialize a TraitsTracer. + """ + self.traced_items = set() -#------------------------------------------------------------------------------ -# Execution Scope -#------------------------------------------------------------------------------ -class ExecutionScope(object): - """ A custom mapping object that implements the scope resolution - order for the evaluation of code objects in Enaml expressions. - - Notes - ----- - Strong references are kept to all objects passed to the constructor, - so these scope objects should be created as needed and discarded in - order to avoid issues with reference cycles. - - """ - def __init__(self, obj, identifiers, overrides, attr_cb): - """ Initialize an execution scope. + #-------------------------------------------------------------------------- + # Private API + #-------------------------------------------------------------------------- + def _trace_trait(self, obj, name): + """ Add the trait object and name pair to the traced items. Parameters ---------- - obj : Declarative - The Declarative instance on which the expression is bound. + obj : HasTraits + The traits object owning the attribute. - identifiers : dict - The dictionary of identifiers that are available to the - expression. These are checked before the attribute space - of the component. + name : str + The trait name to for which to bind a handler. - overrides : dict - An dictionary of override values to check before identifiers. + """ + # Traits will happily force create a trait for things which aren't + # actually traits. This tries to avoid most of that when possible. + trait = obj.trait(name) + if trait is not None and trait.trait_type is not Disallow: + self.traced_items.add((obj, name)) - attr_cb : callable or None - A callable which is called when an implicit attribute is - found and accessed on the object. The arguments passed are - the object and the attribute name. + #-------------------------------------------------------------------------- + # AbstractScopeListener Interface + #-------------------------------------------------------------------------- + def dynamic_load(self, obj, attr, value): + """ Called when an object attribute is dynamically loaded. - """ - self._obj = obj - self._identifiers = identifiers - self._overrides = overrides - self._attr_cb = attr_cb - self._assignments = {} + This will attach a listener to the object if it is a HasTraits + instance. See also: `AbstractScopeListener.dynamic_load`. - def __getitem__(self, name): - """ Lookup an item from the namespace. + """ + if isinstance(obj, HasTraits): + self._trace_trait(obj, attr) - Returns the named item from the namespace according to the - following precedence rules: + #-------------------------------------------------------------------------- + # CodeTracer Interface + #-------------------------------------------------------------------------- + def load_attr(self, obj, attr): + """ Called before the LOAD_ATTR opcode is executed. - 1) assignments - 2) override - 3) identifiers - 4) implicit attrs - 5) f_globals - 6) toolkit - 7) builtins + This will attach a listener to the object if it is a HasTraits + instance. See also: `CodeTracer.dynamic_load`. - Parameters - ---------- - name : string - The name that should be looked up in the namespace. + """ + if isinstance(obj, HasTraits): + self._trace_trait(obj, attr) - Returns - ------- - result : object - The value associated with the name, if found. + def call_function(self, func, argtuple, argspec): + """ Called before the CALL_FUNCTION opcode is executed. - Raises - ------ - KeyError : Exception - If the name is not found, a KeyError is raised. + This will attach a listener if the func is the builtin `getattr` + and the object is a HasTraits instance. + See also: `CodeTracer.call_function` """ - # Check the assignments dict first since this is where all - # local variable assignments will be stored. - dct = self._assignments - if name in dct: - return dct[name] - - # The overrides have the highest precedence of all framework - # supplied values. - dct = self._overrides - if name in dct: - return dct[name] - - # Identifiers have the highest precedence of value able to - # be supplied by a user of the framework. - dct = self._identifiers - if name in dct: - return dct[name] - - # After identifiers, the implicit attributes of the component - # hierarchy have precedence. - parent = self._obj - while parent is not None: - try: - res = getattr(parent, name) - except AttributeError: - parent = parent.parent - else: - # Call the attribute callback if given. - cb = self._attr_cb - if cb is not None: - cb(parent, name) - return res - - raise KeyError(name) - - def __setitem__(self, name, val): - """ Stores the value into the internal assignments dict. This + nargs = argspec & 0xFF + nkwargs = (argspec >> 8) & 0xFF + if (func is getattr and (nargs == 2 or nargs == 3) and nkwargs == 0): + obj, attr = argtuple[0], argtuple[1] + if isinstance(obj, HasTraits) and isinstance(attr, basestring): + self._trace_trait(obj, attr) - """ - self._assignments[name] = val + def binary_subscr(self, obj, idx): + """ Called before the BINARY_SUBSCR opcode is executed. - def __delitem__(self, name): - """ Deletes the value from the internal assignments dict. + This will attach a traits items listener if the object is a + `TraitListObject` or a `TraitDictObject`. + See also: `CodeTracer.get_iter`. """ - del self._assignments[name] + if isinstance(obj, (TraitListObject, TraitDictObject)): + traits_obj = obj.object() + if traits_obj is not None: + if obj.name_items: + self._trace_trait(traits_obj, obj.name_items) + + def get_iter(self, obj): + """ Called before the GET_ITER opcode is executed. - def __contains__(self, name): - """ Return True if the name is found in the scope, False - otherwise. + This will attach a traits items listener if the object is a + `TraitListObject`. See also: `CodeTracer.get_iter`. """ - # This method must be supplied in order for pdb to work properly - # from within code blocks. Any attribute callback is temporarily - # uninstalled so that it is not executed when simply checking for - # the existance of the item in the scope. - with swap_attribute(self, '_attr_cb', None): - if isinstance(name, basestring): - try: - self.__getitem__(name) - except KeyError: - res = False - else: - res = True - else: - res = False - return res + if isinstance(obj, TraitListObject): + traits_obj = obj.object() + if traits_obj is not None: + if obj.name_items: + self._trace_trait(traits_obj, obj.name_items) + + +AbstractScopeListener.register(TraitsTracer) #------------------------------------------------------------------------------ -# Nonlocal Scope +# Standard Code Inverter #------------------------------------------------------------------------------ -class NonlocalScope(object): - """ An object which implements implicit attribute scoping starting - at a given object in the tree. It is used in conjuction with a - nonlocals() instance to allow for explicit referencing of values - which would otherwise be implicitly scoped. +class StandardInverter(CodeInverter): + """ The standard code inverter for Enaml expressions. """ - def __init__(self, obj, attr_cb): - """ Initialize a nonlocal scope. + def __init__(self, nonlocals): + """ Initialize a StandardInverter. Parameters ---------- - obj : Declarative - The Declarative instance which forms the first level of - the scope. - - attr_cb : callable or None - A callable which is called when an implicit attribute is - found and accessed on the object. The arguments passed are - the object and the attribute name. - - """ - self._nls_obj = obj - self._nls_attr_cb = attr_cb - - def __repr__(self): - """ A pretty representation of the NonlocalScope. + nonlocals : Nonlocals + The nonlocal scope for the executing expression. """ - templ = 'NonlocalScope[%s]' - return templ % self._nls_obj + self._nonlocals = nonlocals - def __call__(self, level=0): - """ Returns a new nonlocal scope object offset the given number - of levels in the hierarchy. + #-------------------------------------------------------------------------- + # CodeInverter Interface + #-------------------------------------------------------------------------- + def load_name(self, name, value): + """ Called before the LOAD_NAME opcode is executed. - Parameters - ---------- - level : int, optional - The number of levels up the tree to offset. The default is - zero and indicates no offset. The level must be >= 0. + This method performs STORE_NAME by storing to the nonlocals. + See also: `CodeInverter.load_name`. """ - if not isinstance(level, int) or level < 0: - msg = ('The nonlocal scope level must be an int >= 0. ' - 'Got %r instead.') - raise ValueError(msg % level) - - offset = 0 - target = self._nls_obj - while target is not None and offset != level: - target = target.parent - offset += 1 + self._nonlocals[name] = value - if offset != level: - msg = 'Scope level %s is out of range' - raise ValueError(msg % level) + def load_attr(self, obj, attr, value): + """ Called before the LOAD_ATTR opcode is executed. - return NonlocalScope(target, self._nls_attr_cb) - - def __getattr__(self, name): - """ A convenience method which allows accessing items in the - scope via getattr instead of getitem. + This method performs STORE_ATTR via the builtin `setattr`. + See also: `CodeInverter.load_attr`. """ - try: - return self.__getitem__(name) - except KeyError: - msg = "%s has no attribute '%s'" % (self, name) - raise AttributeError(msg) + setattr(obj, attr, value) + + def call_function(self, func, argtuple, argspec, value): + """ Called before the CALL_FUNCTION opcode is executed. - def __setattr__(self, name, value): - """ A convenience method which allows setting items in the - scope via setattr instead of setitem. + This method inverts a call to the builtin `getattr` into a call + to the builtin `setattr`. All other calls will raise. + See also: `CodeInverter.call_function`. """ - if name in ('_nls_obj', '_nls_attr_cb'): - super(NonlocalScope, self).__setattr__(name, value) + nargs = argspec & 0xFF + nkwargs = (argspec >> 8) & 0xFF + if (func is getattr and (nargs == 2 or nargs == 3) and nkwargs == 0): + obj, attr = argtuple[0], argtuple[1] + setattr(obj, attr, value) else: - try: - self.__setitem__(name, value) - except KeyError: - msg = "%s has no attribute '%s'" % (self, name) - raise AttributeError(msg) + self.fail() - def __getitem__(self, name): - """ Returns the named item beginning at the current scope object - and progressing up the tree until the named attribute is found. - A KeyError is raised if the attribute is not found. + def binary_subscr(self, obj, idx, value): + """ Called before the BINARY_SUBSCR opcode is executed. - """ - parent = self._nls_obj - while parent is not None: - try: - res = getattr(parent, name) - except AttributeError: - parent = parent.parent - else: - cb = self._nls_attr_cb - if cb is not None: - cb(parent, name) - return res - raise KeyError(name) - - def __setitem__(self, name, value): - """ Sets the value of the scope by beginning at the current scope - object and progressing up the tree until the named attribute is - found. A KeyError is raise in the attribute is not found. - - """ - parent = self._nls_obj - while parent is not None: - # It's not sufficient to try to do setattr(...) here and - # catch the AttributeError, because HasStrictTraits raises - # a TraitError in these cases and it becomes impossible - # to distinguish that error from a trait typing error - # without checking the message of the exception. - try: - getattr(parent, name) - except UninitializedAttributeError: - pass - except AttributeError: - parent = parent.parent - continue - setattr(parent, name, value) - return - raise KeyError(name) - - def __contains__(self, name): - """ Return True if the name is found in the scope, False - otherwise. + This method performs a STORE_SUBSCR operation through standard + setitem semantics. See also: `CodeInverter.binary_subscr`. """ - with swap_attribute(self, '_nls_attr_cb', None): - if isinstance(name, basestring): - try: - self.__getitem__(name) - except KeyError: - res = False - else: - res = True - else: - res = False - return res + obj[idx] = value #------------------------------------------------------------------------------ -# Abstract Expression +# Base Expression #------------------------------------------------------------------------------ -class AbstractExpression(object): - """ The base abstract expression class which defines the base api - for Expression handlers. These objects are typically created by - the Enaml operators. +class BaseExpression(object): + """ The base class of the standard Enaml expression classes. """ - __metaclass__ = ABCMeta + __slots__ = ('_func', '_identifiers') - #: A signal which is emitted when the expression has changed. It is - #: emmitted with three arguments: expression, name, and value; where - #: expression is the instance which emitted the signal, name is the - #: attribute name to which the expression is bound, and value is the - #: computed value of the expression. - expression_changed = Signal() - - def __init__(self, obj, name, code, identifiers, f_globals, operators): - """ Initializes and expression object. + def __init__(self, func, identifiers): + """ Initialize a BaseExpression. Parameters ---------- - obj : Declarative - The base component to which this expression is being bound. - - name : string - The name of the attribute on the owner to which this - expression is bound. - - code : types.CodeType object - The compiled code object for the Python expression. - - identifiers : dict - The dictionary of identifiers that are available to the + func : types.FunctionType + A function created by the Enaml compiler with bytecode that + has been patched to support the semantics required of the expression. - f_globals : dict - The globals dictionary in which the expression should - execute. - - operators : OperatorContext - The operator context used when creating this expression. - This context is entered before evaluating any code objects. - This ensures that any components created by the expression - share the same operator context as this expression, unless - explicitly overridden. - - """ - self.obj_ref = ref(obj) - self.name = name - self.code = code - self.identifiers = identifiers - self.f_globals = f_globals - self.operators = operators - - @abstractmethod - def eval(self): - """ Evaluates the expression and returns the result. If an - expression does not provide (or cannot provide) a value, it - should return NotImplemented. - - Returns - ------- - result : object or NotImplemented - The result of evaluating the expression or NotImplemented - if the expression is unable to provide a value. - - """ - raise NotImplementedError - - @abstractmethod - def notify(self, old, new): - """ A method called by the owner component when the trait on - which it is bound has changed. - - Parameters - ---------- - old : object - The old value of the attribute. - - new : object - The new value of the attribute. + identifiers : dict + The dictionary of identifiers available to the function. """ - raise NotImplementedError + self._func = func + self._identifiers = identifiers #------------------------------------------------------------------------------ # Simple Expression #------------------------------------------------------------------------------ -class SimpleExpression(AbstractExpression): - """ A concrete implementation of AbstractEvalExpression. An instance - of SimpleExpression does not track changes in the expression or emit - the expression_changed signal. Is also does not support notification. +class SimpleExpression(BaseExpression): + """ An implementation of AbstractExpression for the `=` operator. """ - def eval(self): - """ Evaluates and returns the results of the expression. + __slots__ = () - """ - obj = self.obj_ref() - if obj is None: - return NotImplemented + #-------------------------------------------------------------------------- + # AbstractExpression Interface + #-------------------------------------------------------------------------- + def eval(self, obj, name): + """ Evaluate and return the expression value. - overrides = {'nonlocals': NonlocalScope(obj, None)} - scope = ExecutionScope(obj, self.identifiers, overrides, None) - - with self.operators: - res = eval(self.code, self.f_globals, scope) - - return res + """ + overrides = {'nonlocals': Nonlocals(obj, None)} + scope = DynamicScope(obj, self._identifiers, overrides, None) + with obj.operators: + return call_func(self._func, (), {}, scope) - def notify(self, old, new): - """ A no-op notification method since SimpleExpression does not - support notification. - """ - pass +AbstractExpression.register(SimpleExpression) #------------------------------------------------------------------------------ -# Notifification Expression +# Notification Expression #------------------------------------------------------------------------------ -class NotificationExpression(AbstractExpression): - """ A concrete implementation of AbstractExpression. An instance - of NotificationExpression does not support evaluation and does not - emit the expression_changed signal, but it does support notification. - An 'event' object will be added to the scope of the expression which - will contain information about the trait change. +class NotificationExpression(BaseExpression): + """ An implementation of AbstractListener for the `::` operator. """ + __slots__ = () + #: A namedtuple which is used to pass arguments to the expression. event = namedtuple('event', 'obj name old new') - def eval(self): - """ A no-op eval method since NotificationExpression does not - support evaluation. + #-------------------------------------------------------------------------- + # AbstractListener Interface + #-------------------------------------------------------------------------- + def value_changed(self, obj, name, old, new): + """ Called when the attribute on the object has changed. """ - return NotImplemented - - def notify(self, old, new): - """ Evaluates the underlying expression, and provides an 'event' - object in the evaluation scope which contains information about - the trait change. - - """ - obj = self.obj_ref() - if obj is None: - return - overrides = { - 'event': self.event(obj, self.name, old, new), - 'nonlocals': NonlocalScope(obj, None), + 'event': self.event(obj, name, old, new), + 'nonlocals': Nonlocals(obj, None), } - scope = ExecutionScope(obj, self.identifiers, overrides, None) + scope = DynamicScope(obj, self._identifiers, overrides, None) + with obj.operators: + call_func(self._func, (), {}, scope) + - with self.operators: - eval(self.code, self.f_globals, scope) +AbstractListener.register(NotificationExpression) #------------------------------------------------------------------------------ # Update Expression #------------------------------------------------------------------------------ -class UpdateExpression(AbstractExpression): - """ A concrete implementation of AbstractExpression which sets the - value on the contituents of the expression according to any provided - inverters. +class UpdateExpression(BaseExpression): + """ An implementation of AbstractListener for the `>>` operator. """ - def __init__(self, inverter_classes, *args): - """ Initialize an UpdateExpression - - Parameters - ---------- - inverter_classes : iterable of AbstractInverter subclasses - An iterable of concrete AbstractInverter subclasses which - will invert the given expression code into a mirrored - operation which sets the value on the appropriate object. + __slots__ = () - args - The arguments required to initialize an AbstractExpression + #-------------------------------------------------------------------------- + # AbstractListener Interface + #-------------------------------------------------------------------------- + def value_changed(self, obj, name, old, new): + """ Called when the attribute on the object has changed. """ - super(UpdateExpression, self).__init__(*args) + nonlocals = Nonlocals(obj, None) + inverter = StandardInverter(nonlocals) + overrides = {'nonlocals': nonlocals} + scope = DynamicScope(obj, self._identifiers, overrides, None) + with obj.operators: + call_func(self._func, (inverter, new), {}, scope) - inverters = [] - bp_code = Code.from_code(self.code) - code_list = bp_code.code - for inv_cls in inverter_classes: - inverter = inv_cls() - new_code = inverter.get_inverted_code(code_list) - if new_code is not None: - bp_code.code = new_code - inverters.append(bp_code.to_code()) - - if not inverters: - msg = ("Unable to delegate expression to the '%s' attribute of " - "the %s object. The provided expression is not structured " - "in a way which is suitable for delegation by any of " - "the supplied code inverters.") - raise ValueError(msg % (self.name, self.obj_ref())) - - self.inverters = tuple(inverters) - - def eval(self): - """ A no-op eval method since UpdateExpression does not support - evaluation. - - """ - return NotImplemented - - def notify(self, old, new): - """ A notification method which runs through the list of inverted - code objects which attempt to set the value. The process stops on - the first successful inversion. If none of the invertors are - successful, a RuntimeError is raised. - - """ - obj = self.obj_ref() - if obj is None: - return - - # The overrides dict is populated with information about the - # expression and the change. The values allow the generated - # inverter codes to access the information which is required - # to perform the operation. The items are added using names - # which are not valid Python identifiers and therefore do - # not risk clashing with names in the expression. This is - # the same technique used by the Python interpreter itself. - overrides = { - '_[expr]': self, '_[obj]': obj, '_[old]': old, '_[new]': new, - '_[name]': self.name, 'nonlocals': NonlocalScope(obj, None), - } - scope = ExecutionScope(obj, self.identifiers, overrides, None) - - # Run through the inverters, giving each a chance to do the - # inversion. The process ends with the first success. If - # none of the invertors are successful an error is raised. - f_globals = self.f_globals - with self.operators: - for inverter in self.inverters: - if eval(inverter, f_globals, scope): - break - else: - msg = ("Unable to delegate expression to the %r attribute " - "of the %s object. None of the provided inverters were " - "successful in assigning the value.") - raise RuntimeError(msg % (self.name, obj)) +AbstractListener.register(UpdateExpression) #------------------------------------------------------------------------------ -# Subscription Expression +# Subcsription Expression #------------------------------------------------------------------------------ -class _ImplicitAttributeBinder(object): - """ A thin class which supports attaching a notifier to an implicit - attribute lookup. +class SubscriptionNotifier(object): + """ A simple object used for attaching notification handlers. """ - # This doesn't need to be provided as a monitor because implicit - # attribute lookups, when successful, will always be on an instance - # of Declarative and should never need to be hooked by an Enaml - # extension. - def __init__(self, parent): - """ Initialize an _ImplicitAttributeBinder + __slots__ = ('expr', 'name', 'keyval', '__weakref__') - Parameters - ---------- - parent : SubscriptionExpression - The parent SubscriptionExpression instance. Only a weak - reference to the parent is stored. - - """ - self.parent_ref = ref(parent) - - def __call__(self, obj, name): - """ Binds the change handler to the given object/attribute - pair, provided the attribute points to a valid trait. + def __init__(self, expr, name, keyval): + """ Initialize a Notifier. Parameters ---------- - obj : Declarative - The Declarative instance that owns the attribute. + expr : AbstractListenableExpression + The expression whose `invalidated` signal should be emitted + when the notifier is triggered. It must be weakref-able. - name : string - The attribute name of interest + name : str + The name to which the expression is bound. + + keyval : object + An object to use for testing equivalency of notifiers. """ - trait = obj.trait(name) - if trait is not None and trait is not Disallow: - obj.on_trait_change(self.notify, name) + self.expr = ref(expr) + self.name = name + self.keyval = keyval def notify(self): - """ The trait change handler callback. It calls the monitor - changed method on the parent when the trait changes, provided - the parent has not already been garbage collected. + """ Notify that the expression is invalid. """ - parent = self.parent_ref() - if parent is not None: - parent._on_monitor_changed() + expr = self.expr() + if expr is not None: + expr.invalidated.emit(self.name) -class SubscriptionExpression(AbstractExpression): - """ A concrete implementation of AbstractExpression. An instance - of SubcriptionExpression emits the expression_changed signal when - the value of the underlying expression changes. It does not - support notification. +class SubscriptionExpression(BaseExpression): + """ An implementation of AbstractListenableExpression for the `<<` + operator. """ - def __init__(self, monitor_classes, *args): - """ Initialize a SubscriptionExpression + # Note: __slots__ are not declared because Enaml Signals require a + # __dict__ to exist on the instance. - Parameters - ---------- - monitor_classes : iterable of AbstractMonitor subclasses - An iterable of AbstractMonitor subclasses which will - be used to generating the monitoring code for the - expression. + #: Private storage for the SubscriptionNotifier. + _notifier = None - args - The arguments required to initialize an AbstractExpression + #-------------------------------------------------------------------------- + # AbstractListenableExpression Interface + #-------------------------------------------------------------------------- + invalidated = Signal() - """ - super(SubscriptionExpression, self).__init__(*args) - - # Create the monitor instances and connect their signals - monitors = [] - handler = self._on_monitor_changed - for mcls in monitor_classes: - if not issubclass(mcls, AbstractMonitor): - msg = ('Monitors must be subclasses of AbstractMonitor. ' - 'Got %s instead.') - raise TypeError(msg % mcls) - monitor = mcls() - monitor.expression_changed.connect(handler) - monitors.append(monitor) - - # Collect the generated code from the monitors that will be - # inserted into the code for the expression. - bp_code = Code.from_code(self.code) - code_list = list(bp_code.code) - insertions = defaultdict(list) - for monitor in monitors: - for idx, code in monitor.get_insertion_code(code_list): - insertions[idx].extend(code) - - # Create a new code list which interleaves the code generated - # by the monitors at the appropriate location in the expression. - new_code = [] - for idx, code_op in enumerate(code_list): - if idx in insertions: - new_code.extend(insertions[idx]) - new_code.append(code_op) - - bp_code.code = new_code - self.eval_code = bp_code.to_code() - self.monitors = tuple(monitors) - self.implicit_binder = _ImplicitAttributeBinder(self) - self.old_value = NotImplemented - - def _on_monitor_changed(self): - """ The signal callback which is fired from a monitor when the - expression changes. It will fire the expression_changed signal - provided that the value of the expression has actually changed. + def eval(self, obj, name): + """ Evaluate and return the expression value. """ - new_value = self.eval() - - # Guard against exceptions being raise during comparison, such - # as when comparing two numpy arrays. - try: - different = new_value != self.old_value - except Exception: - different = True + tracer = TraitsTracer() + overrides = {'nonlocals': Nonlocals(obj, tracer)} + scope = DynamicScope(obj, self._identifiers, overrides, tracer) + with obj.operators: + result = call_func(self._func, (tracer,), {}, scope) - if different: - self.old_value = new_value - self.expression_changed.emit(self, self.name, new_value) - - def eval(self): - """ Evaluates the expression and returns the result. It also - resets the monitors before evaluating the expression to help - ensures that duplicate notifications are avoided. - - """ - # Reset the monitors before every evaluation so that any old - # notifiers are disconnected. This avoids muti-notifications. - self.implicit_binder = binder = _ImplicitAttributeBinder(self) - for monitor in self.monitors: - monitor.reset() + # In most cases, the object comprising the dependencies of an + # expression will not change during subsequent evaluations of + # the expression. Rather than creating a new notifier on each + # pass and repeating the work of creating the change handlers, + # a key for the dependencies is computed and a new notifier is + # created only when the key changes. The key uses the id of an + # object instead of the object itself so strong references to + # the object are not maintained by the expression. + id_ = id + traced = tracer.traced_items + keyval = frozenset((id_(obj), attr) for obj, attr in traced) + notifier = self._notifier + if notifier is None or keyval != notifier.keyval: + notifier = SubscriptionNotifier(self, name, keyval) + self._notifier = notifier + handler = notifier.notify + for obj, attr in traced: + obj.on_trait_change(handler, attr) - obj = self.obj_ref() - if obj is None: - return NotImplemented + return result - overrides = {'nonlocals': NonlocalScope(obj, binder)} - scope = ExecutionScope(obj, self.identifiers, overrides, binder) - with self.operators: - res = eval(self.eval_code, self.f_globals, scope) - - return res - - def notify(self, old, new): - """ A no-op notification method since SubscriptionExpression does - not support notification. - - """ - pass +AbstractListenableExpression.register(SubscriptionExpression) #------------------------------------------------------------------------------ # Delegation Expression #------------------------------------------------------------------------------ class DelegationExpression(SubscriptionExpression): - """ A SubscriptionExpression subclass that adds notification support - by setting the value on the contituents of the expression according - to any provide inverters. + """ An object which implements the `:=` operator by implementing the + AbstractListenableExpression and AbstractListener interfaces. """ - def __init__(self, inverter_classes, *args): - """ Initialize a DelegationExpression - - Parameters - ---------- - inverter_classes : iterable of AbstractInverter subclasses - An iterable of concrete AbstractInverter subclasses which - will invert the given expression code into a mirrored - operation which sets the value on the appropriate object. - - args - The arguments required to initialize a SubscriptionExpression + #-------------------------------------------------------------------------- + # AbstractListener Interface + #-------------------------------------------------------------------------- + def value_changed(self, obj, name, old, new): + """ Called when the attribute on the object has changed. """ - super(DelegationExpression, self).__init__(*args) - - inverters = [] - bp_code = Code.from_code(self.code) - code_list = bp_code.code - - for inv_cls in inverter_classes: - inverter = inv_cls() - new_code = inverter.get_inverted_code(code_list) - if new_code is not None: - bp_code.code = new_code - inverters.append(bp_code.to_code()) - - if not inverters: - msg = ("Unable to delegate expression to the '%s' attribute of " - "the %s object. The provided expression is not structured " - "in a way which is suitable for delegation by any of " - "the supplied code inverters.") - raise ValueError(msg % (self.name, self.obj_ref())) - - self.inverters = inverters - - def notify(self, old, new): - """ A notification method which runs through the list of inverted - code objects which attempt to set the value. The process stops on - the first successful inversion. If none of the invertors are - successful, a RuntimeError is raised. + nonlocals = Nonlocals(obj, None) + inverter = StandardInverter(nonlocals) + overrides = {'nonlocals': nonlocals} + scope = DynamicScope(obj, self._identifiers, overrides, None) + with obj.operators: + call_func(self._func._setter, (inverter, new), {}, scope) - """ - obj = self.obj_ref() - if obj is None: - return - - # We don't need to attempt the inversion if the new value - # is the same as the last value generated by the expression. - # This helps prevent bouncing back and forth which can be - # induced by excessive notification. Guard against exceptions - # being raise during comparison, such as when comparing two - # numpy arrays. - try: - different = new != self.old_value - except Exception: - different = True - - if not different: - return - - # The override dict is populated with information about the - # expression and the change. The values allow the generated - # inverter codes to access the information which is required - # to perform the operation. The items are added using names - # which are not valid Python identifiers and therefore do - # not risk clashing with names in the expression. This is - # the same technique used by the Python interpreter itself. - overrides = { - '_[expr]': self, '_[obj]': obj, '_[old]': old, '_[new]': new, - '_[name]': self.name, 'nonlocals': NonlocalScope(obj, None), - } - scope = ExecutionScope(obj, self.identifiers, overrides, None) - - # Run through the inverters, giving each a chance to do the - # inversion. The process ends with the first success. If - # none of the invertors are successful an error is raised. - f_globals = self.f_globals - with self.operators: - for inverter in self.inverters: - if eval(inverter, f_globals, scope): - break - else: - msg = ("Unable to delegate expression to the '%s' attribute " - "of the %s object. None of the provided inverters were " - "successful in assigning the value.") - raise RuntimeError(msg) + +AbstractListener.register(DelegationExpression) diff --git a/enaml/core/inverters.py b/enaml/core/inverters.py deleted file mode 100644 index 735d5934..00000000 --- a/enaml/core/inverters.py +++ /dev/null @@ -1,308 +0,0 @@ -#------------------------------------------------------------------------------ -# Copyright (c) 2011, Enthought, Inc. -# All rights reserved. -#------------------------------------------------------------------------------ -from abc import ABCMeta, abstractmethod - -from .byteplay import ( - LOAD_NAME, CALL_FUNCTION, ROT_THREE, LOAD_CONST, LOAD_ATTR, ROT_TWO, - BUILD_TUPLE, RETURN_VALUE, -) - - -#------------------------------------------------------------------------------ -# Abstract Inverter -#------------------------------------------------------------------------------ -class AbstractInverter(object): - """ An abstract base class which defines the api for creating code - inverter objects. An inverter is responsible for converting a code - list supplied by an expression into the inverse of that expression - which applies the new value onto the expression. For example: - - The expression: - getattr(foo, 'bar') - - Becomes: - setattr(foo, 'bar', value) - - Likewise, the expression: - [spam.ham[0] for spam in foo][0].bar - - Would be translated into: - [spam.ham[0] for spam in foo][0].bar = value - - The value, among other information, is provided by the expression - by inserting the following names into the scope, which can be - retrieved with the LOAD_NAME op-code: - - * [expr] : The expression object - * [obj] : The component object which triggered the change - * [name] : The attribute on the component which changed - * [old] : The old value of the attribute. - * [new] : The new value of the attribute which should be - applied to the inverted expression. - - The generated expression should return True if it successfully - completed the operation, False otherwise. - - """ - __metaclass__ = ABCMeta - - @abstractmethod - def get_inverted_code(self, code_list): - """ Generates the byteplay code operations which represent - the inverted expression. If the inverter is unable to invert - the given expression, it should return None. - - Parameters - ---------- - code_list : list of (op_code, op_arg) - The list of byteplay code operations for the expression. - - Returns - ------- - result : list of (op_code, op_arg) or None - A new list of code ops for the inverted expression, or - None if the inverter is unable to invert the expression. - The generated code, when executed, should return True if - the operation was successful, False otherwise. Exceptions - raised by the user code should be propagated. - - """ - raise NotImplementedError - - -#------------------------------------------------------------------------------ -# Abstract Attribute Inverter -#------------------------------------------------------------------------------ -class AbstractAttributeInverter(AbstractInverter): - """ An AbstractInverter subclass which converts a bytecode expression - ending in LOAD_ATTR into an appropriate expression which calls a - delegate to do the setattr operation. - - """ - def get_inverted_code(self, code_list): - """ Generates and returns a new code list for expressions ending - in a LOAD_ATTR op_code. - - """ - attr_code, attr_arg = code_list[-2] - if attr_code == LOAD_ATTR: - handler = self.get_setattr_handler() - new_code = code_list[:-2] - new_code.extend([ - (LOAD_CONST, handler), - (ROT_TWO, None), - (LOAD_CONST, attr_arg), - (LOAD_NAME, '_[new]'), - (CALL_FUNCTION, 0x0003), - (RETURN_VALUE, None), - ]) - return new_code - - @abstractmethod - def get_setattr_handler(self): - """ Returns a function which accepts three arguments: an object, - an attribute name, and a value, and performs a setattr operation - with the items. The function that performs the operation should - return True on success and False on failure. This method must be - implemented by subclasses. - - """ - raise NotImplementedError - - -#------------------------------------------------------------------------------ -# Generic Attribute Inverter -#------------------------------------------------------------------------------ -class GenericAttributeInverter(AbstractAttributeInverter): - """ A concrete implementation of AbstractAttributeInverter which - performs the attribute operation using the builtin setattr. - - """ - @staticmethod - def _attribute_inverter(obj, name, value): - """ Performs a setattr on the object and returns True. - - """ - setattr(obj, name, value) - return True - - def get_setattr_handler(self): - """ Returns the builtin setattr function which is used to - perform the set attribute operation. - - """ - return self._attribute_inverter - - -#------------------------------------------------------------------------------ -# Abstract Call Inverter -#------------------------------------------------------------------------------ -class AbstractCallInverter(AbstractInverter): - """ An AbstractInverter subclass which converts a bytecode expression - ending in a CALL_FUNCTION into an appropriate expression which calls a - delegate to do the setattr operation. - - """ - @staticmethod - def _call_wrapper(handler): - """ A call inverter helper function which takes the handler - and returns a closure which will unpack the stack arguments, - calls the handler, the return its value. - - """ - def closure(func_obj, arg_tuple, arg_spec, value): - nargs = arg_spec & 0xFF - args = arg_tuple[:nargs] - kwargs = dict(zip(arg_tuple[nargs::2], arg_tuple[nargs+1::2])) - return handler(func_obj, args, kwargs, value) - return closure - - def get_inverted_code(self, code_list): - """ Generates and returns a new code list for expressions ending - in a CALL_FUNCTION op_code. - - """ - func_code, func_arg = code_list[-2] - if func_code == CALL_FUNCTION: - handler = self._call_wrapper(self.get_call_handler()) - new_code = code_list[:-2] - n_stack_args = (func_arg & 0xFF) + 2 * ((func_arg >> 8) & 0xFF) - new_code.extend([ - (BUILD_TUPLE, n_stack_args), - (LOAD_CONST, handler), - (ROT_THREE, None), - (LOAD_CONST, func_arg), - (LOAD_NAME, '_[new]'), - (CALL_FUNCTION, 0x0004), - (RETURN_VALUE, None), - ]) - return new_code - - @abstractmethod - def get_call_handler(self): - """ Returns a function which accepts four arguments: the object - that would have been called, the arguments being passed, the - keyword arguments being passed, and the value that should be - applied. The function that performs the operation should return - True on success and False on failure. This method must be - implemented by subclasses. - - """ - raise NotImplementedError - - -#------------------------------------------------------------------------------ -# Getattr Inverter -#------------------------------------------------------------------------------ -class GetattrInverter(AbstractCallInverter): - """ A concrete implementation of AbstractCallInverter which inverts - a call to getattr into a call to setattr. - - """ - @staticmethod - def _getattr_inverter(func_obj, args, kwargs, value): - """ Performs the getattr inversion provided that the function - being called is the builtin getattr with an appropriate arg - spec. - - """ - if func_obj is getattr: - if len(args) >= 2 and len(kwargs) == 0: - setattr(args[0], args[1], value) - return True - return False - - def get_call_handler(self): - """ Returns a function which accepts four arguments: the object - that would have been called, the arguments being passed, the - keyword arguments being passed, and the value that should be - applied. - - """ - return self._getattr_inverter - - -#------------------------------------------------------------------------------ -# Abstract Name Inverter -#------------------------------------------------------------------------------ -class AbstractNameInverter(AbstractInverter): - """ An AbstractInverter subclass which converts a bytecode expression - which consists soley of a LOAD_NAME op_code into an appropriate - expression which calls a delegate to do the setattr operation. - - """ - def get_inverted_code(self, code_list): - """ Generates and returns a new code list for expressions which - consist solely of a LOAD_NAME op_code. - - """ - name_code, name_arg = code_list[-2] - if name_code == LOAD_NAME and len(code_list) == 3: - handler = self.get_name_handler() - new_code = code_list[:-2] - new_code.extend([ - (LOAD_CONST, handler), - (LOAD_NAME, '_[expr]'), - (LOAD_NAME, '_[obj]'), - (LOAD_NAME, '_[name]'), - (LOAD_CONST, name_arg), - (LOAD_NAME, '_[new]'), - (CALL_FUNCTION, 0x0005), - (RETURN_VALUE, None), - ]) - return new_code - - @abstractmethod - def get_name_handler(self): - """ Returns a function which accepts five arguments: the - expression object which owns this inverter, the object which - owns the attribute that changed, the name of the attribute that - changed, the name on which to store the value, and the value - which should be stored. The function that performs the operation - should return True on success and False on failure. This method - must be implemented by subclasses. - - """ - raise NotImplementedError - - -#------------------------------------------------------------------------------ -# Generic Name Inverter -#------------------------------------------------------------------------------ -class ImplicitAttrInverter(AbstractNameInverter): - """ A concrete implementation of AbstractNameInverter which inverts - a name access into a setattr operation on an implicit attribute - in the component hierarchy. - - """ - @staticmethod - def _name_inverter(expr, obj, attr, store_name, value): - """ Performs the name inversion by walking the component tree - looking for an object which has an attribute of the right - name. Will return False if no valid target is found, if the - name references an identifier, or if the assignment would - result in a direct cycle. - - """ - if store_name in expr.identifiers or attr == store_name: - return False - while obj is not None: - if hasattr(obj, store_name): - setattr(obj, store_name, value) - return True - else: - obj = obj.parent - return False - - def get_name_handler(self): - """ Returns a function which accepts five arguments: the - expression object which owns this inverter, the object which - owns the attribute that changed, the name of the attribute that - changed, the new value of that attribute, and the name onto - which the value should be applied. - - """ - return self._name_inverter - diff --git a/enaml/core/monitors.py b/enaml/core/monitors.py deleted file mode 100644 index 24507d59..00000000 --- a/enaml/core/monitors.py +++ /dev/null @@ -1,376 +0,0 @@ -#------------------------------------------------------------------------------ -# Copyright (c) 2011, Enthought, Inc. -# All rights reserved. -#------------------------------------------------------------------------------ -from abc import ABCMeta, abstractmethod -from weakref import ref - -from traits.api import HasTraits, Disallow - -from enaml.signaling import Signal - -from .byteplay import ( - CALL_FUNCTION, ROT_THREE, LOAD_CONST, LOAD_ATTR, ROT_TWO, BUILD_TUPLE, - UNPACK_SEQUENCE, POP_TOP, DUP_TOP, -) - - -#------------------------------------------------------------------------------ -# Abstract Monitor -#------------------------------------------------------------------------------ -class AbstractMonitor(object): - """ An abstract base class which defines the api for implementing - an expression monitor. - - An expression Monitor is responsible for generating bytecode which - will be inserted into a Python expression and which inspects the - Python stack during the evaluation to determine if it is appropriate - to attach some form of notifier to the constiuents. If a notifier is - warranted, it should make the appropriate connections to emit the - expression_changed signal when the expression has changed. - - """ - __metaclass__ = ABCMeta - - #: A signal which is emitted when the expression has changed. - expression_changed = Signal() - - @abstractmethod - def get_insertion_code(self, code_list): - """ Generates the byteplay code operations to be inserted into - the expression code object in order to monitor execution. - - Parameters - ---------- - code_list : list of (op_code, op_arg) - The list of byteplay code operations for the expression. - If no code need be generated, an empty list should be - returned. - - Returns - ------- - result : list of (insertion_idx, code_ops) - A list of 2-tuples where the first item is an integer index - into the original code_list and the second item is the list - of byteplay code operations to insert into the final code. - - Notes - ----- - The generated instertion code *must* have a net-zero effect on - the Python stack. This means that the inserted code should leave - the stack exactly the way it found it. If this is not maintained, - then random exceptions and/or crashes *will* result. - - """ - raise NotImplementedError - - @abstractmethod - def reset(self): - """ Unhook any previously connected notifiers. This method is - called by the owner expression when notifiers should be removed. - - """ - raise NotImplementedError - - -#------------------------------------------------------------------------------ -# Abstract Attribute Monitor -#------------------------------------------------------------------------------ -class AbstractAttributeMonitor(AbstractMonitor): - """ An abstract monitor which monitors the expression evaluation for - attribute access and calls a method with the object and attribute - which is being accessed. - - """ - def get_insertion_code(self, code_list): - """ Generates the byteplay code operations to be inserted into - the expression code object to monitor attribute accesses. When - an attribute access occurs, the 'monitor_attribute' method will - be called with the object and attribute name as arguments. - - """ - # A weak closure which is injected into the stack to call the - # monitor method upon attribute access. - def code_binder(obj, attr, selfref=ref(self)): - this = selfref() - if this is not None: - this.monitor_attribute(obj, attr) - - # The list of code segments that will be inserted into the - # new bytecode for the expression. - insertion_code = [] - - for idx, (op, op_arg) in enumerate(code_list): - # This bit of code is injected between the object on TOS - # and its pending attribute access. The TOS obj is duped, - # the rotated above the binder code. The attr is loaded, - # and the binder is called with the object and attr. The - # return value of the binder is discarded. This leaves the - # original TOS and pending attribute access to continue on - # as normal - if op == LOAD_ATTR: - code = [ - (DUP_TOP, None), - (LOAD_CONST, code_binder), - (ROT_TWO, None), - (LOAD_CONST, op_arg), - (CALL_FUNCTION, 0x0002), - (POP_TOP, None), - ] - insertion_code.append((idx, code)) - - return insertion_code - - @abstractmethod - def monitor_attribute(self, obj, attr): - """ Hooks up any necessary monitors for the given object and - attribute. - - Parameters - ---------- - obj : object - The object on which the attribute access is being performed. - - attr : string - The name of the attribute which is being accessed on the - object. - - """ - raise NotImplementedError - - -#------------------------------------------------------------------------------ -# Abstract Call Monitor -#------------------------------------------------------------------------------ -class AbstractCallMonitor(AbstractMonitor): - """ An abstract monitor which monitors the expression evaluation for - function calls and calls a method with the object and arguments which - are being called. - - """ - def get_insertion_code(self, code_list): - """ Generates the byteplay code operations to be inserted into - the expression code object to monitor function calls. When an - attribute access occurs, the 'monitor_function' method will be - called with the object, args, and kwargs. - - """ - # A weak closure which is injected into the stack to call the - # monitor method on function call. - def code_binder(func_obj, arg_tuple, arg_spec, selfref=ref(self)): - this = selfref() - if this is not None: - nargs = arg_spec & 0xFF - args = arg_tuple[:nargs] - kwargs = dict(zip(arg_tuple[nargs::2], arg_tuple[nargs+1::2])) - this.monitor_function(func_obj, args, kwargs) - # The UNPACK_SEQUENCE op_codes which will unpack these - # return values will unpack things onto the stack in the - # reverse of how they are provided. So, we pre-reverse them - # so they come out in the right order. - return (tuple(reversed(arg_tuple)), func_obj) - - # The list of code segments that will be inserted into the - # new bytecode for the expression. - insertion_code = [] - - for idx, (op, op_arg) in enumerate(code_list): - # This bit of code is injected just before a function call - # is performed. The arguments on the stack are packed into - # tuple. The code binder is then pushed onto the stack and - # rotated under the func_obj and arg_tuple. The arg spec - # is then loaded and the code binder is invoked. The return - # value of the code binder is the original func_obj and - # arg_tuple. This return tuple is unpacked, and then the - # arg_tuple is unpacked and the function call proceeds as - # normal. - if op == CALL_FUNCTION: - # This computes the number of objects on the stack - # between TOS and the object being called. Only the - # last 16bits of the op_arg are signifcant. The lowest - # 8 are the number of positional args on the stack, - # the upper 8 is the number of kwargs. For kwargs, the - # number of items on the stack is twice this number - # since the values on the stack alternate name, value. - n_stack_args = (op_arg & 0xFF) + 2 * ((op_arg >> 8) & 0xFF) - code = [ - (BUILD_TUPLE, n_stack_args), - (LOAD_CONST, code_binder), - (ROT_THREE, None), - (LOAD_CONST, op_arg), - (CALL_FUNCTION, 0x0003), - (UNPACK_SEQUENCE, 2), - (UNPACK_SEQUENCE, n_stack_args), - ] - insertion_code.append((idx, code)) - - # TODO - CALL_FUNCTION_VAR, CALL_FUNCTION_KW, CALL_FUNCTION_VAR_KW - - return insertion_code - - @abstractmethod - def monitor_function(self, func_obj, args, kwargs): - """ Hooks up any necessary monitors for the given function object - and the args and kwargs with which it is being called. - - Parameters - ---------- - func_obj : callable object - The function-like object which is being called. - - args : tuple - The arguments being passed to the function. - - kwargs : dict - The keyword arguments being passed to the function. - - """ - raise NotImplementedError - - -#------------------------------------------------------------------------------ -# Trait Notification Handler -#------------------------------------------------------------------------------ -class _TraitNotificationHandler(object): - """ A thin class which makes it easier to manage the lifetime of - a trait notifier. - - """ - def __init__(self, parent, obj, attr): - """ Initialize a TraitNotificationHandler. - - Parameters - ---------- - parent : AbstractMonitor - The AbstractMonitor instance which is the parent of this - handler. Only a weak reference to the parent is kept. - - obj : HasTraits - The HasTraits instance on which we are attaching a listener. - - attr : string - The trait attribute on the object to which we should listen. - - """ - self._parent_ref = ref(parent) - obj.on_trait_change(self.notify, attr) - - def notify(self): - """ The trait change callback which will emit the expression - changed signal on the parent. - - """ - parent = self._parent_ref() - if parent is not None: - parent.expression_changed.emit() - - -#------------------------------------------------------------------------------ -# Trait Handler Mixin -#------------------------------------------------------------------------------ -class TraitHandlerMixin(object): - """ A mixin class which adds the common binding code for the trait - monitor classes below. - - """ - def __init__(self, *args, **kwargs): - super(TraitHandlerMixin, self).__init__(*args, **kwargs) - # A dictionary which holds the notification handlers. A key - # in the dictionary is an (obj_id, attr) tuple and the value - # is the notification handler for that pair. The object id - # is used to avoid ref cycles and potential hashing issues. - self._handlers = {} - - def reset(self): - """ Clears the existing handlers which results in the notifiers - being destroyed. - - """ - self._handlers.clear() - - def do_binding(self, obj, attr): - """ Hooks up a notifier to the object attribute pair if the - object is a HasTraits instance and the attribute refers to - a valid trait on the object. - - """ - # Don't hook up multiple identifiers to the same object/attr - # pair. Use the id of the object to prevent an accidental ref - # cycle to the object. - handlers = self._handlers - key = (id(obj), attr) - if key in handlers: - return - - if isinstance(obj, HasTraits): - # Only hook up a notifier if the attribute access refers to - # a proper trait. We check for Disallow trait types since - # those can be returned by instances of HasStrictTraits - trait = obj.trait(attr) - if trait is not None and trait.trait_type is not Disallow: - handler = _TraitNotificationHandler(self, obj, attr) - handlers[key] = handler - - -#------------------------------------------------------------------------------ -# Trait Attribute Monitor -#------------------------------------------------------------------------------ -class TraitAttributeMonitor(TraitHandlerMixin, AbstractAttributeMonitor): - """ An AbstractAttributeMonitor implementation which binds listeners - to trait attributes on HasTraits classes. - - """ - def monitor_attribute(self, obj, attr): - """ Hooks up any necessary trait change notifiers for the given - object and attribute. - - Parameters - ---------- - obj : object - The object on which the attribute access is being performed. - - attr : string - The name of the attribute which is being accessed on the - object. - - """ - self.do_binding(obj, attr) - - -#------------------------------------------------------------------------------ -# Trait Getattr Monitor -#------------------------------------------------------------------------------ -class TraitGetattrMonitor(TraitHandlerMixin, AbstractCallMonitor): - """ An AbstractCallMonitor implementation which binds listeners to - trait attributes on HasTraits classes which are accessed through a - call to the builtin getattr. - - """ - def monitor_function(self, func_obj, args, kwargs): - """ Hooks up any necessary trait change notifiers for the given - call to getattr - - Parameters - ---------- - func_obj : callable object - The function-like object which is being called. If this is - not the builtin getattr, or if the call spec is invalid for - getattr, this method is a no-op. - - args : tuple - The arguments being passed to the function. - - kwargs : dict - The keyword arguments being passed to the function. - - """ - n_args = len(args) - if func_obj is not getattr or n_args < 2 or n_args > 3 or kwargs: - return - - obj, attr = args[0], args[1] - if not isinstance(attr, basestring): - return - - self.do_binding(obj, attr) - diff --git a/enaml/core/new_expressions.py b/enaml/core/new_expressions.py deleted file mode 100644 index ecfdcc1b..00000000 --- a/enaml/core/new_expressions.py +++ /dev/null @@ -1,417 +0,0 @@ -#------------------------------------------------------------------------------ -# Copyright (c) 2012, Enthought, Inc. -# All rights reserved. -#------------------------------------------------------------------------------ -from collections import namedtuple -from weakref import ref - -from traits.api import HasTraits, Disallow, TraitListObject, TraitDictObject - -from enaml.signaling import Signal - -from .abstract_expressions import ( - AbstractExpression, AbstractListener, AbstractListenableExpression -) -from .code_tracing import CodeTracer, CodeInverter -from .dynamic_scope import DynamicScope, AbstractScopeListener, Nonlocals -from .funchelper import call_func - - -#------------------------------------------------------------------------------ -# Traits Code Tracer -#------------------------------------------------------------------------------ -class TraitsTracer(CodeTracer): - """ A CodeTracer for tracing expressions which use Traits. - - This tracer maintains a running set of `traced_items` which are the - (obj, name) pairs of traits items discovered during tracing. - - """ - def __init__(self): - """ Initialize a TraitsTracer. - - """ - self.traced_items = set() - - #-------------------------------------------------------------------------- - # Private API - #-------------------------------------------------------------------------- - def _trace_trait(self, obj, name): - """ Add the trait object and name pair to the traced items. - - Parameters - ---------- - obj : HasTraits - The traits object owning the attribute. - - name : str - The trait name to for which to bind a handler. - - """ - # Traits will happily force create a trait for things which aren't - # actually traits. This tries to avoid most of that when possible. - trait = obj.trait(name) - if trait is not None and trait.trait_type is not Disallow: - self.traced_items.add((obj, name)) - - #-------------------------------------------------------------------------- - # AbstractScopeListener Interface - #-------------------------------------------------------------------------- - def dynamic_load(self, obj, attr, value): - """ Called when an object attribute is dynamically loaded. - - This will attach a listener to the object if it is a HasTraits - instance. See also: `AbstractScopeListener.dynamic_load`. - - """ - if isinstance(obj, HasTraits): - self._trace_trait(obj, attr) - - #-------------------------------------------------------------------------- - # CodeTracer Interface - #-------------------------------------------------------------------------- - def load_attr(self, obj, attr): - """ Called before the LOAD_ATTR opcode is executed. - - This will attach a listener to the object if it is a HasTraits - instance. See also: `CodeTracer.dynamic_load`. - - """ - if isinstance(obj, HasTraits): - self._trace_trait(obj, attr) - - def call_function(self, func, argtuple, argspec): - """ Called before the CALL_FUNCTION opcode is executed. - - This will attach a listener if the func is the builtin `getattr` - and the object is a HasTraits instance. - See also: `CodeTracer.call_function` - - """ - nargs = argspec & 0xFF - nkwargs = (argspec >> 8) & 0xFF - if (func is getattr and (nargs == 2 or nargs == 3) and nkwargs == 0): - obj, attr = argtuple[0], argtuple[1] - if isinstance(obj, HasTraits) and isinstance(attr, basestring): - self._trace_trait(obj, attr) - - def binary_subscr(self, obj, idx): - """ Called before the BINARY_SUBSCR opcode is executed. - - This will attach a traits items listener if the object is a - `TraitListObject` or a `TraitDictObject`. - See also: `CodeTracer.get_iter`. - - """ - if isinstance(obj, (TraitListObject, TraitDictObject)): - traits_obj = obj.object() - if traits_obj is not None: - if obj.name_items: - self._trace_trait(traits_obj, obj.name_items) - - def get_iter(self, obj): - """ Called before the GET_ITER opcode is executed. - - This will attach a traits items listener if the object is a - `TraitListObject`. See also: `CodeTracer.get_iter`. - - """ - if isinstance(obj, TraitListObject): - traits_obj = obj.object() - if traits_obj is not None: - if obj.name_items: - self._trace_trait(traits_obj, obj.name_items) - - -AbstractScopeListener.register(TraitsTracer) - - -#------------------------------------------------------------------------------ -# Standard Code Inverter -#------------------------------------------------------------------------------ -class StandardInverter(CodeInverter): - """ The standard code inverter for Enaml expressions. - - """ - def __init__(self, nonlocals): - """ Initialize a StandardInverter. - - Parameters - ---------- - nonlocals : Nonlocals - The nonlocal scope for the executing expression. - - """ - self._nonlocals = nonlocals - - #-------------------------------------------------------------------------- - # CodeInverter Interface - #-------------------------------------------------------------------------- - def load_name(self, name, value): - """ Called before the LOAD_NAME opcode is executed. - - This method performs STORE_NAME by storing to the nonlocals. - See also: `CodeInverter.load_name`. - - """ - self._nonlocals[name] = value - - def load_attr(self, obj, attr, value): - """ Called before the LOAD_ATTR opcode is executed. - - This method performs STORE_ATTR via the builtin `setattr`. - See also: `CodeInverter.load_attr`. - - """ - setattr(obj, attr, value) - - def call_function(self, func, argtuple, argspec, value): - """ Called before the CALL_FUNCTION opcode is executed. - - This method inverts a call to the builtin `getattr` into a call - to the builtin `setattr`. All other calls will raise. - See also: `CodeInverter.call_function`. - - """ - nargs = argspec & 0xFF - nkwargs = (argspec >> 8) & 0xFF - if (func is getattr and (nargs == 2 or nargs == 3) and nkwargs == 0): - obj, attr = argtuple[0], argtuple[1] - setattr(obj, attr, value) - else: - self.fail() - - def binary_subscr(self, obj, idx, value): - """ Called before the BINARY_SUBSCR opcode is executed. - - This method performs a STORE_SUBSCR operation through standard - setitem semantics. See also: `CodeInverter.binary_subscr`. - - """ - obj[idx] = value - - -#------------------------------------------------------------------------------ -# Base Expression -#------------------------------------------------------------------------------ -class BaseExpression(object): - """ The base class of the standard Enaml expression classes. - - """ - __slots__ = ('_func', '_identifiers') - - def __init__(self, func, identifiers): - """ Initialize a BaseExpression. - - Parameters - ---------- - func : types.FunctionType - A function created by the Enaml compiler with bytecode that - has been patched to support the semantics required of the - expression. - - identifiers : dict - The dictionary of identifiers available to the function. - - """ - self._func = func - self._identifiers = identifiers - - -#------------------------------------------------------------------------------ -# Simple Expression -#------------------------------------------------------------------------------ -class SimpleExpression(BaseExpression): - """ An implementation of AbstractExpression for the `=` operator. - - """ - __slots__ = () - - #-------------------------------------------------------------------------- - # AbstractExpression Interface - #-------------------------------------------------------------------------- - def eval(self, obj, name): - """ Evaluate and return the expression value. - - """ - overrides = {'nonlocals': Nonlocals(obj, None)} - scope = DynamicScope(obj, self._identifiers, overrides, None) - with obj.operators: - return call_func(self._func, (), {}, scope) - - -AbstractExpression.register(SimpleExpression) - - -#------------------------------------------------------------------------------ -# Notification Expression -#------------------------------------------------------------------------------ -class NotificationExpression(BaseExpression): - """ An implementation of AbstractListener for the `::` operator. - - """ - __slots__ = () - - #: A namedtuple which is used to pass arguments to the expression. - event = namedtuple('event', 'obj name old new') - - #-------------------------------------------------------------------------- - # AbstractListener Interface - #-------------------------------------------------------------------------- - def value_changed(self, obj, name, old, new): - """ Called when the attribute on the object has changed. - - """ - overrides = { - 'event': self.event(obj, name, old, new), - 'nonlocals': Nonlocals(obj, None), - } - scope = DynamicScope(obj, self._identifiers, overrides, None) - with obj.operators: - call_func(self._func, (), {}, scope) - - -AbstractListener.register(NotificationExpression) - - -#------------------------------------------------------------------------------ -# Update Expression -#------------------------------------------------------------------------------ -class UpdateExpression(BaseExpression): - """ An implementation of AbstractListener for the `>>` operator. - - """ - __slots__ = () - - #-------------------------------------------------------------------------- - # AbstractListener Interface - #-------------------------------------------------------------------------- - def value_changed(self, obj, name, old, new): - """ Called when the attribute on the object has changed. - - """ - nonlocals = Nonlocals(obj, None) - inverter = StandardInverter(nonlocals) - overrides = {'nonlocals': nonlocals} - scope = DynamicScope(obj, self._identifiers, overrides, None) - with obj.operators: - call_func(self._func, (inverter, new), {}, scope) - - -AbstractListener.register(UpdateExpression) - - -#------------------------------------------------------------------------------ -# Subcsription Expression -#------------------------------------------------------------------------------ -class SubscriptionNotifier(object): - """ A simple object used for attaching notification handlers. - - """ - __slots__ = ('expr', 'name', 'keyval', '__weakref__') - - def __init__(self, expr, name, keyval): - """ Initialize a Notifier. - - Parameters - ---------- - expr : AbstractListenableExpression - The expression whose `invalidated` signal should be emitted - when the notifier is triggered. It must be weakref-able. - - name : str - The name to which the expression is bound. - - keyval : object - An object to use for testing equivalency of notifiers. - - """ - self.expr = ref(expr) - self.name = name - self.keyval = keyval - - def notify(self): - """ Notify that the expression is invalid. - - """ - expr = self.expr() - if expr is not None: - expr.invalidated.emit(self.name) - - -class SubscriptionExpression(BaseExpression): - """ An implementation of AbstractListenableExpression for the `<<` - operator. - - """ - # Note: __slots__ are not declared because Enaml Signals require a - # __dict__ to exist on the instance. - - #: Private storage for the SubscriptionNotifier. - _notifier = None - - #-------------------------------------------------------------------------- - # AbstractListenableExpression Interface - #-------------------------------------------------------------------------- - invalidated = Signal() - - def eval(self, obj, name): - """ Evaluate and return the expression value. - - """ - tracer = TraitsTracer() - overrides = {'nonlocals': Nonlocals(obj, tracer)} - scope = DynamicScope(obj, self._identifiers, overrides, tracer) - with obj.operators: - result = call_func(self._func, (tracer,), {}, scope) - - # In most cases, the object comprising the dependencies of an - # expression will not change during subsequent evaluations of - # the expression. Rather than creating a new notifier on each - # pass and repeating the work of creating the change handlers, - # a key for the dependencies is computed and a new notifier is - # created only when the key changes. The key uses the id of an - # object instead of the object itself so strong references to - # the object are not maintained by the expression. - id_ = id - traced = tracer.traced_items - keyval = frozenset((id_(obj), attr) for obj, attr in traced) - notifier = self._notifier - if notifier is None or keyval != notifier.keyval: - notifier = SubscriptionNotifier(self, name, keyval) - self._notifier = notifier - handler = notifier.notify - for obj, attr in traced: - obj.on_trait_change(handler, attr) - - return result - - -AbstractListenableExpression.register(SubscriptionExpression) - - -#------------------------------------------------------------------------------ -# Delegation Expression -#------------------------------------------------------------------------------ -class DelegationExpression(SubscriptionExpression): - """ An object which implements the `:=` operator by implementing the - AbstractListenableExpression and AbstractListener interfaces. - - """ - #-------------------------------------------------------------------------- - # AbstractListener Interface - #-------------------------------------------------------------------------- - def value_changed(self, obj, name, old, new): - """ Called when the attribute on the object has changed. - - """ - nonlocals = Nonlocals(obj, None) - inverter = StandardInverter(nonlocals) - overrides = {'nonlocals': nonlocals} - scope = DynamicScope(obj, self._identifiers, overrides, None) - with obj.operators: - call_func(self._func._setter, (inverter, new), {}, scope) - - -AbstractListener.register(DelegationExpression) - diff --git a/enaml/core/new_operators.py b/enaml/core/new_operators.py deleted file mode 100644 index 904b2b40..00000000 --- a/enaml/core/new_operators.py +++ /dev/null @@ -1,69 +0,0 @@ -#------------------------------------------------------------------------------ -# Copyright (c) 2012, Enthought, Inc. -# All rights reserved. -#------------------------------------------------------------------------------ -from .new_expressions import ( - SimpleExpression, NotificationExpression, SubscriptionExpression, - UpdateExpression, DelegationExpression -) - - -def op_simple(obj, name, func, identifiers): - """ The default Enaml operator for `=` expressions. - - It binds an instance of SimpleExpression to the object. - - """ - expr = SimpleExpression(func, identifiers) - obj.bind_expression(name, expr) - - -def op_notify(obj, name, func, identifiers): - """ The default Enaml operator for `::` expressions. - - It binds an instance of NotificationExpression to the object. - - """ - expr = NotificationExpression(func, identifiers) - obj.bind_listener(name, expr) - - -def op_update(obj, name, func, identifiers): - """ The default Enaml operator for `>>` expressions. - - It binds an instance of UpdateExpression to the object. - - """ - expr = UpdateExpression(func, identifiers) - obj.bind_listener(name, expr) - - -def op_subscribe(obj, name, func, identifiers): - """ The default Enaml operator for `<<` expressions. - - It binds an instance of SubscriptionExpression to the object. - - """ - expr = SubscriptionExpression(func, identifiers) - obj.bind_expression(name, expr) - - -def op_delegate(obj, name, func, identifiers): - """ The default Enaml operator for `:=` expressions. - - It binds an instance of DelegationExpression to the object. - - """ - expr = DelegationExpression(func, identifiers) - obj.bind_expression(name, expr) - obj.bind_listener(name, expr) - - -OPERATORS = { - '__operator_Equal__': op_simple, - '__operator_LessLess__': op_subscribe, - '__operator_ColonEqual__': op_delegate, - '__operator_ColonColon__': op_notify, - '__operator_GreaterGreater__': op_update, -} - diff --git a/enaml/core/nonlocals.py b/enaml/core/nonlocals.py deleted file mode 100644 index 2914aae7..00000000 --- a/enaml/core/nonlocals.py +++ /dev/null @@ -1,148 +0,0 @@ -#------------------------------------------------------------------------------ -# Copyright (c) 2012, Enthought, Inc. -# All rights reserved. -#------------------------------------------------------------------------------ -class Nonlocals(object): - """ An object which implements implicit attribute scoping starting - at a given object in the tree. It is used in conjuction with a - nonlocals() instance to allow for explicit referencing of values - which would otherwise be implicitly scoped. - - """ - def __init__(self, obj, attr_cb): - """ Initialize a nonlocal scope. - - Parameters - ---------- - obj : Declarative - The Declarative instance which forms the first level of - the scope. - - attr_cb : callable or None - A callable which is called when an implicit attribute is - found and accessed on the object. The arguments passed are - the object and the attribute name. - - """ - self._nls_obj = obj - self._nls_attr_cb = attr_cb - - def __repr__(self): - """ A pretty representation of the NonlocalScope. - - """ - templ = 'NonlocalScope[%s]' - return templ % self._nls_obj - - def __call__(self, level=0): - """ Returns a new nonlocal scope object offset the given number - of levels in the hierarchy. - - Parameters - ---------- - level : int, optional - The number of levels up the tree to offset. The default is - zero and indicates no offset. The level must be >= 0. - - """ - if not isinstance(level, int) or level < 0: - msg = ('The nonlocal scope level must be an int >= 0. ' - 'Got %r instead.') - raise ValueError(msg % level) - - offset = 0 - target = self._nls_obj - while target is not None and offset != level: - target = target.parent - offset += 1 - - if offset != level: - msg = 'Scope level %s is out of range' - raise ValueError(msg % level) - - return NonlocalScope(target, self._nls_attr_cb) - - def __getattr__(self, name): - """ A convenience method which allows accessing items in the - scope via getattr instead of getitem. - - """ - try: - return self.__getitem__(name) - except KeyError: - msg = "%s has no attribute '%s'" % (self, name) - raise AttributeError(msg) - - def __setattr__(self, name, value): - """ A convenience method which allows setting items in the - scope via setattr instead of setitem. - - """ - if name in ('_nls_obj', '_nls_attr_cb'): - super(NonlocalScope, self).__setattr__(name, value) - else: - try: - self.__setitem__(name, value) - except KeyError: - msg = "%s has no attribute '%s'" % (self, name) - raise AttributeError(msg) - - def __getitem__(self, name): - """ Returns the named item beginning at the current scope object - and progressing up the tree until the named attribute is found. - A KeyError is raised if the attribute is not found. - - """ - parent = self._nls_obj - while parent is not None: - try: - res = getattr(parent, name) - except AttributeError: - parent = parent.parent - else: - cb = self._nls_attr_cb - if cb is not None: - cb(parent, name) - return res - raise KeyError(name) - - def __setitem__(self, name, value): - """ Sets the value of the scope by beginning at the current scope - object and progressing up the tree until the named attribute is - found. A KeyError is raise in the attribute is not found. - - """ - parent = self._nls_obj - while parent is not None: - # It's not sufficient to try to do setattr(...) here and - # catch the AttributeError, because HasStrictTraits raises - # a TraitError in these cases and it becomes impossible - # to distinguish that error from a trait typing error - # without checking the message of the exception. - try: - getattr(parent, name) - except UninitializedAttributeError: - pass - except AttributeError: - parent = parent.parent - continue - setattr(parent, name, value) - return - raise KeyError(name) - - def __contains__(self, name): - """ Return True if the name is found in the scope, False - otherwise. - - """ - with swap_attribute(self, '_nls_attr_cb', None): - if isinstance(name, basestring): - try: - self.__getitem__(name) - except KeyError: - res = False - else: - res = True - else: - res = False - return res diff --git a/enaml/core/operators.py b/enaml/core/operators.py index bd1207f0..904b2b40 100644 --- a/enaml/core/operators.py +++ b/enaml/core/operators.py @@ -1,112 +1,62 @@ #------------------------------------------------------------------------------ -# Copyright (c) 2011, Enthought, Inc. +# Copyright (c) 2012, Enthought, Inc. # All rights reserved. #------------------------------------------------------------------------------ -from .expressions import ( - SimpleExpression, NotificationExpression, SubscriptionExpression, - DelegationExpression, UpdateExpression, +from .new_expressions import ( + SimpleExpression, NotificationExpression, SubscriptionExpression, + UpdateExpression, DelegationExpression ) -from .inverters import ( - GenericAttributeInverter, GetattrInverter, ImplicitAttrInverter, -) -from .monitors import TraitAttributeMonitor, TraitGetattrMonitor -#------------------------------------------------------------------------------ -# Builtin Enaml Operators -#------------------------------------------------------------------------------ -#: Operators are passed a number of arguments from the Enaml runtime -#: engine in order to perform their work. The arguments are, in order: -#: -#: cmpnt : Declarative -#: The Declarative instance which owns the expression which -#: is being bound. -#: -#: attr : string -#: The name of the attribute on the component which is being -#: bound. -#: -#: code : types.CodeType -#: The compiled code object for the Python expression given -#: given by the user. It is compiled with mode='eval'. -#: -#: identifiers : dict -#: The dictionary of identifiers available to the expression. -#: This dictionary is shared amongst all expressions within -#: a given lexical scope. It should therefore not be modified -#: or copied since identifiers may continue to be added to -#: this dict as runtime execution continues. -#: -#: f_globals : dict -#: The dictionary of globals available to the expression. -#: The same rules about sharing and copying that apply to -#: the identifiers dict, apply here as well. -#: -#: operators : OperatorContext -#: The operator context used when looking up the operator. -#: For the standard operators, this context is passed along -#: to the generated expressions. -#: -#: Operators may do whatever they please with the information provided -#: to them. The default operators in Enaml use this information to -#: create and bind Enaml expression objects to the component. However, -#: this is not a requirement and developers who are extending Enaml -#: are free to get creative with the operators. - - -def op_simple(cmpnt, attr, code, identifiers, f_globals, operators): - """ The default Enaml operator for '=' expressions. It binds an - instance of SimpleExpression to the component. +def op_simple(obj, name, func, identifiers): + """ The default Enaml operator for `=` expressions. + + It binds an instance of SimpleExpression to the object. """ - expr = SimpleExpression(cmpnt, attr, code, identifiers, f_globals, operators) - cmpnt._bind_expression(attr, expr) + expr = SimpleExpression(func, identifiers) + obj.bind_expression(name, expr) -def op_notify(cmpnt, attr, code, identifiers, f_globals, operators): - """ The default Enaml operator for '::' expressions. It binds an - instance of NotificationExpression to the component. +def op_notify(obj, name, func, identifiers): + """ The default Enaml operator for `::` expressions. + + It binds an instance of NotificationExpression to the object. """ - expr = NotificationExpression(cmpnt, attr, code, identifiers, f_globals, operators) - cmpnt._bind_expression(attr, expr, notify_only=True) + expr = NotificationExpression(func, identifiers) + obj.bind_listener(name, expr) + +def op_update(obj, name, func, identifiers): + """ The default Enaml operator for `>>` expressions. -def op_update(cmpnt, attr, code, identifiers, f_globals, operators): - """ The default Enaml operator for '>>' expressions. It binds an - instance of UpdateExpression to the component. + It binds an instance of UpdateExpression to the object. """ - inverters = [GenericAttributeInverter, GetattrInverter, ImplicitAttrInverter] - expr = UpdateExpression(inverters, cmpnt, attr, code, identifiers, f_globals, operators) - cmpnt._bind_expression(attr, expr, notify_only=True) + expr = UpdateExpression(func, identifiers) + obj.bind_listener(name, expr) -def op_subscribe(cmpnt, attr, code, identifiers, f_globals, operators): - """ The default Enaml operator for '<<' expressions. It binds an - instance of SubscriptionExpression to the component using monitors - which understand traits attribute access via dotted notation and - the builtin getattr function. +def op_subscribe(obj, name, func, identifiers): + """ The default Enaml operator for `<<` expressions. + + It binds an instance of SubscriptionExpression to the object. """ - monitors = [TraitAttributeMonitor, TraitGetattrMonitor] - expr = SubscriptionExpression(monitors, cmpnt, attr, code, identifiers, f_globals, operators) - cmpnt._bind_expression(attr, expr) + expr = SubscriptionExpression(func, identifiers) + obj.bind_expression(name, expr) + +def op_delegate(obj, name, func, identifiers): + """ The default Enaml operator for `:=` expressions. -def op_delegate(cmpnt, attr, code, identifiers, f_globals, operators): - """ The default Enaml operator for ':=' expressions. It binds an - instance of DelegationExpression to the component using monitors - which understand traits attribute access via dotted notation and - the builtin getattr function, and inverters which understand the - dotted attribute access, implicit attribute access, and also the - builtin getattr function. + It binds an instance of DelegationExpression to the object. """ - inverters = [GenericAttributeInverter, GetattrInverter, ImplicitAttrInverter] - monitors = [TraitAttributeMonitor, TraitGetattrMonitor] - expr = DelegationExpression(inverters, monitors, cmpnt, attr, code, identifiers, f_globals, operators) - cmpnt._bind_expression(attr, expr) + expr = DelegationExpression(func, identifiers) + obj.bind_expression(name, expr) + obj.bind_listener(name, expr) OPERATORS = { From d25f344e3988ce09095300460e028a63e8ff99ae Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Sat, 24 Nov 2012 13:29:30 -0500 Subject: [PATCH 22/34] point the default operator context at the updated operators --- enaml/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/enaml/__init__.py b/enaml/__init__.py index f462ca35..d535f0b8 100644 --- a/enaml/__init__.py +++ b/enaml/__init__.py @@ -6,11 +6,11 @@ #------------------------------------------------------------------------------ # Logging Setup #------------------------------------------------------------------------------ -# Add a NullHandler to make sure that all enaml loggers don't complain when they -# get used. +# Add a NullHandler so enaml loggers don't complain when they get used. import logging class NullHandler(logging.Handler): + def handle(self, record): pass @@ -33,7 +33,7 @@ def imports(): """ Lazily imports and returns an enaml imports context. """ - from .core.import_hooks import imports + from enaml.core.import_hooks import imports return imports() @@ -79,7 +79,7 @@ def default_operator_context(): if ctxt_func is not None: return ctxt_func() from enaml.core.operator_context import OperatorContext - from enaml.core.new_operators import OPERATORS + from enaml.core.operators import OPERATORS return OperatorContext(OPERATORS) From 5f9f4e106f1d72f10ca6f19d8302dfeea46d3a31 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Sat, 24 Nov 2012 13:29:57 -0500 Subject: [PATCH 23/34] Whitespace commit --- enaml/core/abstract_expressions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/enaml/core/abstract_expressions.py b/enaml/core/abstract_expressions.py index 2db3cf16..e6d2596e 100644 --- a/enaml/core/abstract_expressions.py +++ b/enaml/core/abstract_expressions.py @@ -3,6 +3,7 @@ # All rights reserved. #------------------------------------------------------------------------------ from abc import ABCMeta, abstractmethod + from enaml.signaling import Signal From beeb2a6e583a516a60e3601821c7b1cc12b5055b Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Sat, 24 Nov 2012 13:30:27 -0500 Subject: [PATCH 24/34] Update documentation --- enaml/core/code_tracing.py | 79 +++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/enaml/core/code_tracing.py b/enaml/core/code_tracing.py index f21cfd53..7058f0df 100644 --- a/enaml/core/code_tracing.py +++ b/enaml/core/code_tracing.py @@ -15,8 +15,8 @@ class CodeTracer(object): This class defines the interface for a code tracer object, which is an object which can be passed as the first argument to a code object which has been transformed to enable tracing. Methods on the tracer - are called with relevant arguments from the Python stack, when that - particular code segment is executing. The return values of a tracer + are called with relevant arguments from the Python stack when that + particular code segment is executing. The return value of a tracer method is ignored; exceptions are propagated. """ @@ -98,16 +98,16 @@ class CodeInverter(object): This class defines the interface for a code inverter object, which is an object which can be passed as the first argument to a code object which has been transformed to enable inversion. The methods on the - inverter are called with relevant arguments from the Python stack, + inverter are called with relevant arguments from the Python stack when that particular code segment is executing. The return values of a tracer method is ignored; exceptions are propagated. The default behavior of an inverter is to raise. Implementations - must provide their own code. + must provide their own code in order to enable inversion. """ def fail(self): - """ Called by the modified code to raise an inversion exception. + """ Called by handlers to raise an inversion exception. """ raise RuntimeError("can't assign to expression") @@ -284,6 +284,7 @@ def inject_tracing(codelist): if idx in inserts: new_code.extend(inserts[idx]) new_code.append(code_op) + return new_code @@ -312,51 +313,49 @@ def inject_inversion(codelist): """ opcode, oparg = codelist[-2] + new_code = codelist[:-2] if opcode == LOAD_NAME and len(codelist) == 3: - new_code = codelist[:-2] - new_code.extend([ - (LOAD_FAST, '_[inverter]'), - (LOAD_ATTR, 'load_name'), - (LOAD_CONST, oparg), - (LOAD_FAST, '_[value]'), - (CALL_FUNCTION, 0x0002), - (RETURN_VALUE, None), + new_code.extend([ #: + (LOAD_FAST, '_[inverter]'), #: inverter + (LOAD_ATTR, 'load_name'), #: invertfunc + (LOAD_CONST, oparg), #: invertfunc -> name + (LOAD_FAST, '_[value]'), #: invertfunc -> name - > value + (CALL_FUNCTION, 0x0002), #: retval + (RETURN_VALUE, None), #: ]) elif opcode == LOAD_ATTR: - new_code = codelist[:-2] - new_code.extend([ - (LOAD_FAST, '_[inverter]'), - (LOAD_ATTR, 'load_attr'), - (ROT_TWO, None), - (LOAD_CONST, oparg), - (LOAD_FAST, '_[value]'), - (CALL_FUNCTION, 0x0003), - (RETURN_VALUE, None), + new_code.extend([ #: obj + (LOAD_FAST, '_[inverter]'), #: obj -> inverter + (LOAD_ATTR, 'load_attr'), #: obj -> invertfunc + (ROT_TWO, None), #: invertfunc -> obj + (LOAD_CONST, oparg), #: invertfunc -> obj -> attr + (LOAD_FAST, '_[value]'), #: invertfunc -> obj -> attr -> value + (CALL_FUNCTION, 0x0003), #: retval + (RETURN_VALUE, None), #: ]) elif opcode == CALL_FUNCTION: n_stack_args = (oparg & 0xFF) + 2 * ((oparg >> 8) & 0xFF) - new_code = codelist[:-2] - new_code.extend([ - (BUILD_TUPLE, n_stack_args), - (LOAD_FAST, '_[inverter]'), - (LOAD_ATTR, 'call_function'), - (ROT_THREE, None), - (LOAD_CONST, oparg), - (LOAD_FAST, '_[value]'), - (CALL_FUNCTION, 0x0004), - (RETURN_VALUE, None), + new_code.extend([ #: func -> arg(0) -> arg(1) -> ... -> arg(n-1) + (BUILD_TUPLE, n_stack_args), #: func -> argtuple + (LOAD_FAST, '_[inverter]'), #: func -> argtuple -> inverter + (LOAD_ATTR, 'call_function'), #: func -> argtuple -> invertfunc + (ROT_THREE, None), #: invertfunc -> func -> argtuple + (LOAD_CONST, oparg), #: invertfunc -> func -> argtuple -> argspec + (LOAD_FAST, '_[value]'), #: invertfunc -> func -> argtuple -> argspec -> value + (CALL_FUNCTION, 0x0004), #: retval + (RETURN_VALUE, None), #: ]) elif opcode == BINARY_SUBSCR: - new_code = codelist[:-2] - new_code.extend([ - (LOAD_FAST, '_[inverter]'), - (LOAD_ATTR, 'binary_subscr'), - (ROT_THREE, None), - (LOAD_FAST, '_[value]'), - (CALL_FUNCTION, 0x0003), - (RETURN_VALUE, None), + new_code.extend([ #: obj -> index + (LOAD_FAST, '_[inverter]'), #: obj -> index -> inverter + (LOAD_ATTR, 'binary_subscr'), #: obj -> index -> invertfunc + (ROT_THREE, None), #: invertfunc -> obj -> index + (LOAD_FAST, '_[value]'), #: invertfunc -> obj -> index -> value + (CALL_FUNCTION, 0x0003), #: retval + (RETURN_VALUE, None), #: ]) else: raise ValueError("can't invert code") + return new_code From 4774c755448dc9d8cf0ae941e904d3d1d30a66d0 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Sat, 24 Nov 2012 13:30:55 -0500 Subject: [PATCH 25/34] update documentation --- enaml/core/compiler_helpers.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/enaml/core/compiler_helpers.py b/enaml/core/compiler_helpers.py index f9927c8a..b8a7f49d 100644 --- a/enaml/core/compiler_helpers.py +++ b/enaml/core/compiler_helpers.py @@ -9,12 +9,12 @@ def _make_enamldef_helper_(name, base, builder): """ A compiler helper function for creating a new EnamlDef type. - This function is called by the bytecode generated by the Enaml + This function is called by the bytecode generated by the Enaml compiler when an enaml module is imported. It is used to make new - types from the 'enamldef' keyword. + types from the 'enamldef' keyword. - This helper will raise an exception if the base type is of the - enamldef is of an incompatible type. + This helper will raise an exception if the base type is of an + incompatible type. Parameters ---------- @@ -26,7 +26,7 @@ def _make_enamldef_helper_(name, base, builder): of Declarative. builder : FunctionType - The builder function created by the Enaml compiler. This + The builder function created by the Enaml compiler. This function will be used during instantiation to populate new instances with children and expressions. @@ -41,7 +41,7 @@ def _make_enamldef_helper_(name, base, builder): msg = "can't derive enamldef from '%s'" raise TypeError(msg % base) decl_cls = EnamlDef(name, (base,), dct) - # The list of builder functions is created in reverse order, with + # The list of builder functions is created in reverse order, with # the oldest builder appearing first in the list, so that newer # builders will override the effects of older builders. decl_cls._builders = base._builders + [builder] From fc0c1e8beb8430dc0a7cfb2f2ef3842a5ac7974f Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Sat, 24 Nov 2012 13:31:15 -0500 Subject: [PATCH 26/34] Disable listener during scope testing --- enaml/core/dynamic_scope.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/enaml/core/dynamic_scope.py b/enaml/core/dynamic_scope.py index 813a5333..0305fa48 100644 --- a/enaml/core/dynamic_scope.py +++ b/enaml/core/dynamic_scope.py @@ -125,16 +125,21 @@ def __getitem__(self, name): raise KeyError(name) def __contains__(self, name): - """ Return True if the name is in scope, False otherwise. + """ Returns True if the name is in scope, False otherwise. """ if isinstance(name, basestring): + # Temporarily disable the listener during scope testing. + listener = self._listener + self._listener = None try: self.__getitem__(name) except KeyError: res = False else: res = True + finally: + self._listener = listener else: res = False return res @@ -290,8 +295,7 @@ def __contains__(self, name): """ if isinstance(name, basestring): - # Temporarily disable the listener to prevent property - # bindings due to scope testing. + # Temporarily disable the listener during scope testing. listener = self._nls_listener self._nls_listener = None try: From 9a6bccc2067db4f6f9c55c901fcbc9040d067e88 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Sat, 24 Nov 2012 13:31:54 -0500 Subject: [PATCH 27/34] Update documentation --- enaml/core/operators.py | 60 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/enaml/core/operators.py b/enaml/core/operators.py index 904b2b40..1ec777a7 100644 --- a/enaml/core/operators.py +++ b/enaml/core/operators.py @@ -2,7 +2,35 @@ # Copyright (c) 2012, Enthought, Inc. # All rights reserved. #------------------------------------------------------------------------------ -from .new_expressions import ( +""" The default Enaml operators. + +The operator functions are called by the Enaml runtime to implement the +expression binding semantics of the Enaml operators. The functions are +passed a number of arguments in order to perform their work: + +Parameters +---------- +obj : Declarative + The Declarative object which owns the expression which is being + bound. + +name : string + The name of the attribute on the object which is being bound. + +func : types.FunctionType + A function with bytecode that has been patched by the Enaml compiler + for semantics specific to the operator. The docs for each operator + given a more complete description of this function, since it varies + for each operator. + +identifiers : dict + The dictionary of identifiers available to the expression. This dict + is shared amongst all expressions within a given lexical scope. It + should therefore not be modified or copied since identifiers may + continue to be added to this dict as runtime execution continues. + +""" +from .expressions import ( SimpleExpression, NotificationExpression, SubscriptionExpression, UpdateExpression, DelegationExpression ) @@ -11,7 +39,10 @@ def op_simple(obj, name, func, identifiers): """ The default Enaml operator for `=` expressions. - It binds an instance of SimpleExpression to the object. + This operator binds an instance of SimpleExpression to the attribute + on the object. The function takes no arguments and returns the value + of the expression. It is patched for dynamic scoping and it should be + invoked with `funchelper.call_func(...)`. """ expr = SimpleExpression(func, identifiers) @@ -21,7 +52,10 @@ def op_simple(obj, name, func, identifiers): def op_notify(obj, name, func, identifiers): """ The default Enaml operator for `::` expressions. - It binds an instance of NotificationExpression to the object. + This operator binds an instance of NotificationExpression to the + attribute on the object. The function takes no arguments and will + return None. It is patched for dynamic scoping and it should be + invoked with `funchelper.call_func(...)`. """ expr = NotificationExpression(func, identifiers) @@ -31,7 +65,11 @@ def op_notify(obj, name, func, identifiers): def op_update(obj, name, func, identifiers): """ The default Enaml operator for `>>` expressions. - It binds an instance of UpdateExpression to the object. + This operator binds an instance of UpdateExpression to the attribute + on the object. The function takes two arguments: a code inverter and + the new value of the attribute, and returns None. It is patched for + dynamic scoping and code inversion and it should be invoked with + `funchelper.call_func(...)`. """ expr = UpdateExpression(func, identifiers) @@ -41,7 +79,11 @@ def op_update(obj, name, func, identifiers): def op_subscribe(obj, name, func, identifiers): """ The default Enaml operator for `<<` expressions. - It binds an instance of SubscriptionExpression to the object. + This operator binds an instance of SubscriptionExpression to the + attribute on the object. The function takes one argument: a code + tracer, and returns the value of the expression. It is patched for + dynamic scoping and code tracing and it should be invoked with + `funchelper.call_func(...)`. """ expr = SubscriptionExpression(func, identifiers) @@ -51,7 +93,13 @@ def op_subscribe(obj, name, func, identifiers): def op_delegate(obj, name, func, identifiers): """ The default Enaml operator for `:=` expressions. - It binds an instance of DelegationExpression to the object. + This operator binds an instance of DelegationExpression to the + attribute on the object. The semantics of the function are the same + as that of `op_subscribe`. The function also has an attribute named + `_update` which is a function implementing `op_update` semantics. + Both functions should be invoked with `funchelper.call_func(...)`. + In this fashion, `op_delegate` is the combination of `op_subscribe` + and `op_update`. """ expr = DelegationExpression(func, identifiers) From 47be41b392e93296944bc089b407d3c93b75b1d9 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Sat, 24 Nov 2012 13:32:20 -0500 Subject: [PATCH 28/34] Update documentation --- enaml/core/expressions.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/enaml/core/expressions.py b/enaml/core/expressions.py index ecfdcc1b..dc053bc9 100644 --- a/enaml/core/expressions.py +++ b/enaml/core/expressions.py @@ -60,8 +60,8 @@ def _trace_trait(self, obj, name): def dynamic_load(self, obj, attr, value): """ Called when an object attribute is dynamically loaded. - This will attach a listener to the object if it is a HasTraits - instance. See also: `AbstractScopeListener.dynamic_load`. + This will trace the object if it is a HasTraits instance. + See also: `AbstractScopeListener.dynamic_load`. """ if isinstance(obj, HasTraits): @@ -73,8 +73,8 @@ def dynamic_load(self, obj, attr, value): def load_attr(self, obj, attr): """ Called before the LOAD_ATTR opcode is executed. - This will attach a listener to the object if it is a HasTraits - instance. See also: `CodeTracer.dynamic_load`. + This will trace the object if it is a HasTraits instance. + See also: `CodeTracer.dynamic_load`. """ if isinstance(obj, HasTraits): @@ -83,9 +83,8 @@ def load_attr(self, obj, attr): def call_function(self, func, argtuple, argspec): """ Called before the CALL_FUNCTION opcode is executed. - This will attach a listener if the func is the builtin `getattr` - and the object is a HasTraits instance. - See also: `CodeTracer.call_function` + This will trace the func is the builtin `getattr` and the object + is a HasTraits instance. See also: `CodeTracer.call_function` """ nargs = argspec & 0xFF @@ -98,9 +97,8 @@ def call_function(self, func, argtuple, argspec): def binary_subscr(self, obj, idx): """ Called before the BINARY_SUBSCR opcode is executed. - This will attach a traits items listener if the object is a - `TraitListObject` or a `TraitDictObject`. - See also: `CodeTracer.get_iter`. + This will trace the object if it is a `TraitListObject` or a + `TraitDictObject`. See also: `CodeTracer.get_iter`. """ if isinstance(obj, (TraitListObject, TraitDictObject)): @@ -112,8 +110,8 @@ def binary_subscr(self, obj, idx): def get_iter(self, obj): """ Called before the GET_ITER opcode is executed. - This will attach a traits items listener if the object is a - `TraitListObject`. See also: `CodeTracer.get_iter`. + This will trace the object if it is a `TraitListObject` + See also: `CodeTracer.get_iter`. """ if isinstance(obj, TraitListObject): @@ -291,8 +289,8 @@ def value_changed(self, obj, name, old, new): """ nonlocals = Nonlocals(obj, None) - inverter = StandardInverter(nonlocals) overrides = {'nonlocals': nonlocals} + inverter = StandardInverter(nonlocals) scope = DynamicScope(obj, self._identifiers, overrides, None) with obj.operators: call_func(self._func, (inverter, new), {}, scope) @@ -365,7 +363,7 @@ def eval(self, obj, name): with obj.operators: result = call_func(self._func, (tracer,), {}, scope) - # In most cases, the object comprising the dependencies of an + # In most cases, the objects comprising the dependencies of an # expression will not change during subsequent evaluations of # the expression. Rather than creating a new notifier on each # pass and repeating the work of creating the change handlers, @@ -410,7 +408,7 @@ def value_changed(self, obj, name, old, new): overrides = {'nonlocals': nonlocals} scope = DynamicScope(obj, self._identifiers, overrides, None) with obj.operators: - call_func(self._func._setter, (inverter, new), {}, scope) + call_func(self._func._update, (inverter, new), {}, scope) AbstractListener.register(DelegationExpression) From 0b84311959aba78a78b741d4ddec1a0198d57463 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Sat, 24 Nov 2012 13:53:10 -0500 Subject: [PATCH 29/34] update docs and bump the compiler version number --- enaml/core/enaml_compiler.py | 51 +++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/enaml/core/enaml_compiler.py b/enaml/core/enaml_compiler.py index 673e0642..7d8ed1e6 100644 --- a/enaml/core/enaml_compiler.py +++ b/enaml/core/enaml_compiler.py @@ -47,7 +47,19 @@ # descriptive _add_user_attribute. Finally, it adds the eval_compile # function for compiling Python code in 'eval' mode with proper line # number handling. -COMPILER_VERSION = 5 +# 6 : Compile with code tracing - 24 November 2012 +# This updates the compiler to generate code using the idea of code +# tracing instead of monitors and inverters. The compiler compiles +# the expressions into functions which are augmented to accept +# additional arguments. These arguments are tracer objects which will +# have methods called in response to bytecode ops executing. These +# methods can then attach listeners as necessary. This is an easier +# paradigm to develop with than the previous incarnation. This new +# way also allows the compiler to generate the final code objects +# upfront, instead of needed to specialize at runtime for a given +# operator context. This results in a much smaller footprint since +# then number of code objects created is n instead of n x m. +COMPILER_VERSION = 6 # The Enaml compiler translates an Enaml AST into Python bytecode. @@ -144,7 +156,7 @@ def replace_global_loads(codelist, explicit=None): def optimize_locals(codelist): """ Optimize the given code object for fast locals access. - All STORE_NAME opcodes will be replace with STORE_FAST. Names which + All STORE_NAME opcodes will be replaced with STORE_FAST. Names which are stored and then loaded via LOAD_NAME are rewritten to LOAD_FAST. This transformation is applied in-place. @@ -435,19 +447,16 @@ def visit_Declaration(self, node): self.push_name(name) extend_ops([ - # f_globals = globals() - (LOAD_NAME, 'globals'), + (LOAD_NAME, 'globals'), # f_globals = globals() (CALL_FUNCTION, 0x0000), (STORE_FAST, 'f_globals'), - # _var_1 = instance - (LOAD_FAST, 'instance'), + (LOAD_FAST, 'instance'), # _var_1 = instance (STORE_FAST, name), ]) if node.identifier: extend_ops([ - # identifiers['foo'] = _var_1 - (LOAD_FAST, name), + (LOAD_FAST, name), # identifiers['foo'] = _var_1 (LOAD_FAST, 'identifiers'), (LOAD_CONST, node.identifier), (STORE_SUBSCR, None), @@ -458,8 +467,7 @@ def visit_Declaration(self, node): visit(item) extend_ops([ - # return _var_1 - (LOAD_FAST, name), + (LOAD_FAST, name), # return _var_1 (RETURN_VALUE, None), ]) @@ -492,10 +500,8 @@ def visit_AttributeBinding(self, node): if isinstance(code, tuple): # operator `::` sub_code, upd_code = code self.extend_ops([ - # sub_func.__setter__ = upd_func - # operators['__operator_ColonEqual__'](obj, attr, sub_func, identifiers) (SetLineno, node.binding.lineno), - (LOAD_FAST, 'operators'), + (LOAD_FAST, 'operators'), # operators[op](obj, attr, sub_func, identifiers) (LOAD_CONST, op), (BINARY_SUBSCR, None), (LOAD_FAST, self.curr_name()), @@ -506,16 +512,15 @@ def visit_AttributeBinding(self, node): (LOAD_CONST, upd_code), (MAKE_FUNCTION, 0), (ROT_TWO, None), - (STORE_ATTR, '_setter'), + (STORE_ATTR, '_update'), # sub_func._update = upd_func (LOAD_FAST, 'identifiers'), (CALL_FUNCTION, 0x0004), (POP_TOP, None), ]) else: self.extend_ops([ - # operators['__operator_Equal__'](obj, attr, func, identifiers) (SetLineno, node.binding.lineno), - (LOAD_FAST, 'operators'), + (LOAD_FAST, 'operators'), # operators[op](obj, attr, func, identifiers) (LOAD_CONST, op), (BINARY_SUBSCR, None), (LOAD_FAST, self.curr_name()), @@ -539,9 +544,8 @@ def visit_Instantiation(self, node): name = self.name_gen.next() self.push_name(name) extend_ops([ - # _var_2 = globals()['PushButton'](parent) (SetLineno, node.lineno), - (LOAD_NAME, node.name), + (LOAD_NAME, node.name), # _var_2 = globals()['PushButton'](parent) (LOAD_FAST, parent_name), (CALL_FUNCTION, 0x0001), (STORE_FAST, name), @@ -549,8 +553,7 @@ def visit_Instantiation(self, node): if node.identifier: extend_ops([ - # identifiers['btn'] = _var_2 - (LOAD_FAST, name), + (LOAD_FAST, name), # identifiers['btn'] = _var_2 (LOAD_FAST, 'identifiers'), (LOAD_CONST, node.identifier), (STORE_SUBSCR, None), @@ -649,9 +652,9 @@ def visit_Python(self, node): """ py_code = compile(node.py_ast, self.filename, mode='exec') - bpc = Code.from_code(py_code) + bp_code = Code.from_code(py_code) # Skip the SetLineo and ReturnValue codes - self.extend_ops(bpc.code[1:-2]) + self.extend_ops(bp_code.code[1:-2]) def visit_Declaration(self, node): """ The Declaration node visitor. @@ -668,7 +671,7 @@ def visit_Declaration(self, node): func_code = DeclarationCompiler.compile(node, filename) extend_ops([ (SetLineno, node.lineno), - (LOAD_NAME, '_make_enamldef_helper_'), + (LOAD_NAME, '_make_enamldef_helper_'), # Foo = _make_enamldef_helper_(name, base, buildfunc) (LOAD_CONST, name), (LOAD_NAME, node.base), (LOAD_CONST, func_code), @@ -705,7 +708,7 @@ def visit_AttributeDeclaration(self, node): attr_type = node.type or 'object' self.extend_ops([ (SetLineno, node.lineno), - (DUP_TOP, None), + (DUP_TOP, None), #cls._add_user_attribute(name, type, is_event) (LOAD_CONST, node.name), (LOAD_NAME, attr_type), (LOAD_CONST, node.is_event), From 003be3acd8ea94eabe5c6e37bf0d95d871c9f220 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Sat, 24 Nov 2012 14:12:09 -0500 Subject: [PATCH 30/34] Fix bug in updated parser rules for enamldefs --- enaml/core/parser.py | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/enaml/core/parser.py b/enaml/core/parser.py index 369b4da6..1bf771d2 100644 --- a/enaml/core/parser.py +++ b/enaml/core/parser.py @@ -405,19 +405,13 @@ def p_enaml_module_item1(p): #------------------------------------------------------------------------------ def p_declaration1(p): ''' declaration : ENAMLDEF NAME LPAR NAME RPAR COLON declaration_body ''' - lineno = p.lineno(1) doc, idn, items = p[7] - p[0] = enaml_ast.Declaration(p[2], p[4], idn, doc, items, lineno) + p[0] = enaml_ast.Declaration(p[2], p[4], idn, doc, items, p.lineno(1)) def p_declaration2(p): ''' declaration : ENAMLDEF NAME LPAR NAME RPAR COLON PASS NEWLINE ''' - lineno = p.lineno(1) - base = ast.Expression(body=ast.Name(id=p[4], ctx=Load)) - base.lineno = lineno - ast.fix_missing_locations(base) - base_node = enaml_ast.Python(base, lineno) - p[0] = enaml_ast.Declaration(p[2], base_node, None, '', [], lineno) + p[0] = enaml_ast.Declaration(p[2], p[4], None, '', [], p.lineno(1)) def p_declaration3(p): @@ -427,21 +421,12 @@ def p_declaration3(p): if idn is not None: msg = 'multiple identifiers declared' syntax_error(msg, FakeToken(p.lexer.lexer, lineno)) - base = ast.Expression(body=ast.Name(id=p[4], ctx=Load)) - base.lineno = lineno - ast.fix_missing_locations(base) - base_node = enaml_ast.Python(base, lineno) - p[0] = enaml_ast.Declaration(p[2], base_node, p[7], doc, items, lineno) + p[0] = enaml_ast.Declaration(p[2], p[4], p[7], doc, items, lineno) def p_declaration4(p): ''' declaration : ENAMLDEF NAME LPAR NAME RPAR COLON NAME COLON PASS NEWLINE ''' - lineno = p.lineno(1) - base = ast.Expression(body=ast.Name(id=p[4], ctx=Load)) - base.lineno = lineno - ast.fix_missing_locations(base) - base_node = enaml_ast.Python(base, lineno) - p[0] = enaml_ast.Declaration(p[2], base_node, p[7], '', [], lineno) + p[0] = enaml_ast.Declaration(p[2], p[4], p[7], '', [], p.lineno(1)) def p_declaration_body1(p): From 719dddaaa4c253ad50460af54c170708f4b80274 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Sat, 24 Nov 2012 14:24:17 -0500 Subject: [PATCH 31/34] Get rid of the code watcher prototype. --- code_watcher.py | 204 ------------------------------------------------ 1 file changed, 204 deletions(-) delete mode 100644 code_watcher.py diff --git a/code_watcher.py b/code_watcher.py deleted file mode 100644 index 264cd761..00000000 --- a/code_watcher.py +++ /dev/null @@ -1,204 +0,0 @@ -import types -from enaml.core.byteplay import ( - Code, LOAD_ATTR, LOAD_CONST, ROT_TWO, DUP_TOP, CALL_FUNCTION, POP_TOP, - LOAD_FAST, STORE_FAST, BUILD_TUPLE, ROT_THREE, UNPACK_SEQUENCE, DUP_TOPX, - BINARY_SUBSCR, GET_ITER, LOAD_NAME, LOAD_GLOBAL, DELETE_NAME, DELETE_GLOBAL -) - -from enaml.core._funchelper import call_func - - -class Watcher(object): - - def load_name(self, name): - print 'load name', name - - def call_function(self, func, args, kwargs): - print 'call function', args, kwargs - - def get_item(self, obj, index): - print 'get item', obj, index - - def get_attr(self, obj, attr): - print 'get attr', obj, attr - - -def translate_code(code, f_globals): - bp_code = Code.from_code(code) - code_list = list(bp_code.code) - - # Make a first pass over the code list and replace LOAD_GLOBAL with - # LOAD_NAME. This enables dynamic scoping using a custom locals map. - for idx, (op, op_arg) in enumerate(code_list): - if op == LOAD_GLOBAL: - code_list[idx] = (LOAD_NAME, op_arg) - - # The list of code segments that will be inserted into the - # new bytecode for the expression. - inserts = [] - for idx, (op, op_arg) in enumerate(code_list): - # This bit of code is injected between the object on TOS - # and its pending attribute access. The TOS obj is duped, - # the rotated above the binder code. The attr is loaded, - # and the binder is called with the object and attr. The - # return value of the binder is discarded. This leaves the - # original TOS and pending attribute access to continue on - # as normal - if op == LOAD_ATTR: - code = [ # obj - (DUP_TOP, None), # obj -> obj - (LOAD_FAST, '_[tracer]'), # obj -> obj -> tracer - (LOAD_ATTR, 'load_attr'), # obj -> obj -> tracefunc - (ROT_TWO, None), # obj -> tracefunc -> obj - (LOAD_CONST, op_arg), # obj -> tracefunc -> obj -> attr - (CALL_FUNCTION, 0x0002), # obj -> retval - (POP_TOP, None), # obj - ] - inserts.append((idx, code)) - elif op == CALL_FUNCTION: - # This computes the number of objects on the stack - # between TOS and the object being called. Only the - # last 16bits of the op_arg are signifcant. The lowest - # 8 are the number of positional args on the stack, - # the upper 8 is the number of kwargs. For kwargs, the - # number of items on the stack is twice this number - # since the values on the stack alternate name, value. - n_stack_args = (op_arg & 0xFF) + 2 * ((op_arg >> 8) & 0xFF) - code = [ # func -> arg(0) -> arg(1) -> ... -> arg(n-1) - (BUILD_TUPLE, n_stack_args), # func -> argtuple - (DUP_TOPX, 2), # func -> argtuple -> func -> argtuple - (LOAD_FAST, '_[tracer]'), # func -> argtuple -> func -> argtuple -> tracer - (LOAD_ATTR, 'call_function'), # func -> argtuple -> func -> argtuple -> tracefunc - (ROT_THREE, None), # func -> argtuple -> tracefunc -> func -> argtuple - (LOAD_CONST, op_arg), # func -> argtuple -> tracefunc -> func -> argtuple -> argspec - (CALL_FUNCTION, 0x0003), # func -> argtuple -> retval - (POP_TOP, None), # func -> argtuple - (UNPACK_SEQUENCE, n_stack_args), # func -> arg(n-1) -> arg(n-2) -> ... -> arg(0) - (BUILD_TUPLE, n_stack_args), # func -> reversedargtuple - (UNPACK_SEQUENCE, n_stack_args), # func -> arg(0) -> arg(1) -> ... -> arg(n-1) - ] - inserts.append((idx, code)) - elif op == BINARY_SUBSCR: - code = [ # obj -> idx - (DUP_TOPX, 2), # obj -> idx -> obj -> idx -> tracer - (LOAD_FAST, '_[tracer]'), # obj -> idx -> obj -> idx -> tracer - (LOAD_ATTR, 'binary_subscr'), # obj -> idx -> obj -> idx -> tracefunc - (ROT_THREE, None), # obj -> idx -> tracefunc -> obj -> idx - (CALL_FUNCTION, 0x0002), # obj -> idx -> retval - (POP_TOP, None), # obj -> idx - ] - inserts.append((idx, code)) - elif op == GET_ITER: - code = [ # obj - (DUP_TOP, None), # obj -> obj - (LOAD_FAST, '_[tracer]'), # obj -> obj -> tracer - (LOAD_ATTR, 'get_iter'), # obj -> obj -> tracefunc - (ROT_TWO, None), # obj -> tracefunc -> obj - (CALL_FUNCTION, 0x0001), # obj -> retval - (POP_TOP, None), # obj - ] - inserts.append((idx, code)) - elif op == LOAD_NAME: - code = [ # - (LOAD_FAST, '_[tracer]'), # tracer - (LOAD_ATTR, 'load_name'), # tracefunc - (LOAD_CONST, op_arg), # tracefunc -> name - (CALL_FUNCTION, 0x0001), # retval - (POP_TOP, None), # - ] - inserts.append((idx, code)) - - insertions = {} - for idx, code in inserts: - insertions[idx] = code - - # Create a new code list which interleaves the code generated - # by the monitors at the appropriate location in the expression. - new_code = [] - for idx, code_op in enumerate(code_list): - if idx in insertions: - new_code.extend(insertions[idx]) - new_code.append(code_op) - - bp_code.code = new_code - bp_code.newlocals = False - bp_code.args = ('_[tracer]',) + bp_code.args - eval_code = bp_code.to_code() - - return types.FunctionType(eval_code, f_globals) - - -class CustomScope(dict): - - def __getitem__(self, name): - print - print '############# getitem', name - print - raise KeyError - - def __setitem__(self, name, value): - print - print '############ setitem', name, value - print - raise KeyError - - def __delitem__(self, name): - print - print '############ delitem', name - print - raise KeyError - - -class CodeTracer(object): - - def __init__(self, code, f_globals): - self._s = CustomScope() - self._watchers = [] - self._func = translate_code(code, f_globals) - - def __call__(self, watcher, *args, **kwargs): - self._watchers.append(watcher) - try: - a = (self,) + args - call_func(self._func, a, kwargs, self._s) - finally: - self._watchers.pop() - - def load_name(self, name): - print 'load_name', name - - def load_attr(self, obj, attr): - print 'load attr', obj, attr - - def call_function(self, func, arg_tuple, nargs): - print 'call function', func, arg_tuple - - def binary_subscr(self, obj, idx): - print 'binary subscr', type(obj), idx - - def get_iter(self, obj): - print 'get iter', obj - - -class Foo(object): - def __init__(self, *args, **kwargs): pass - a = 1 - b = 2 - c = 3 - - -foobar = 12 - -def tester(): - f = Foo() - Bar = Foo - c = (f.a, f.b, f.c, f) - c[-1].a - fs = [Bar(1, 2, w=12) for i in range(10)] - d = [f.b for f in fs] - - -if __name__ == '__main__': - t = CodeTracer(tester.func_code, tester.func_globals) - t(None) - From bb52f84abe853e68b6ec7b1ce047c788898eeeff Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Sat, 24 Nov 2012 14:49:24 -0500 Subject: [PATCH 32/34] Properly bracket c++ code with `extern "C"` --- enaml/extensions/callableref.cpp | 3 +++ enaml/extensions/funchelper.cpp | 5 ++++- enaml/extensions/signaling.cpp | 3 +++ enaml/extensions/weakmethod.cpp | 3 +++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/enaml/extensions/callableref.cpp b/enaml/extensions/callableref.cpp index 6b7b568e..91a6acff 100644 --- a/enaml/extensions/callableref.cpp +++ b/enaml/extensions/callableref.cpp @@ -9,6 +9,7 @@ using namespace PythonHelpers; +extern "C" { // Type structure for CallableRef instances typedef struct { @@ -202,3 +203,5 @@ initcallableref( void ) PyModule_AddObject( mod, "CallableRef", cr_type.release() ); } +} // extern "C" + diff --git a/enaml/extensions/funchelper.cpp b/enaml/extensions/funchelper.cpp index fd7340e3..bac27342 100644 --- a/enaml/extensions/funchelper.cpp +++ b/enaml/extensions/funchelper.cpp @@ -13,7 +13,8 @@ dynamic scoping. The code below is a slightly tweaked `function_call` from Python's funcobject.c */ -extern "C" { static PyObject* call_trace_func( PyObject*, PyObject* ); } +extern "C" { + static PyObject* call_func( PyObject* mod, PyObject* args ) { @@ -113,3 +114,5 @@ initfunchelper( void ) return; } +} // extern "C" + diff --git a/enaml/extensions/signaling.cpp b/enaml/extensions/signaling.cpp index f6343b56..b2affc41 100644 --- a/enaml/extensions/signaling.cpp +++ b/enaml/extensions/signaling.cpp @@ -10,6 +10,7 @@ using namespace PythonHelpers; +extern "C" { typedef struct { PyObject_HEAD @@ -869,3 +870,5 @@ initsignaling( void ) return; } +} // extern "C" + diff --git a/enaml/extensions/weakmethod.cpp b/enaml/extensions/weakmethod.cpp index 3270cdea..82f5f44c 100644 --- a/enaml/extensions/weakmethod.cpp +++ b/enaml/extensions/weakmethod.cpp @@ -9,6 +9,7 @@ using namespace PythonHelpers; +extern "C" { // Type structure for WeakMethod instances typedef struct { @@ -316,3 +317,5 @@ initweakmethod( void ) PyModule_AddObject( mod, "WeakMethod", wm_type.release() ); } +} // extern "C" + From e1551c9e5830a8243c363b7d591e6f5b3622a03b Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Mon, 26 Nov 2012 09:29:07 -0500 Subject: [PATCH 33/34] Ignore .pyd files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a9d21d73..f92777e3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.swp *.egg-info *.so +*.pyd *.DS_Store *.enamlc *.c From 8521ede96b4c0901527093566002c445eeb7a408 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Mon, 26 Nov 2012 10:03:28 -0500 Subject: [PATCH 34/34] Minor cleanup of docs. Remove no-op code. --- enaml/extensions/funchelper.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/enaml/extensions/funchelper.cpp b/enaml/extensions/funchelper.cpp index bac27342..95b5f7d2 100644 --- a/enaml/extensions/funchelper.cpp +++ b/enaml/extensions/funchelper.cpp @@ -5,6 +5,8 @@ #include +extern "C" { + /* Call a function with an optional locals mapping. This allows Enaml to generate bytecode with the LOAD_GLOBAL opcode @@ -13,8 +15,6 @@ dynamic scoping. The code below is a slightly tweaked `function_call` from Python's funcobject.c */ -extern "C" { - static PyObject* call_func( PyObject* mod, PyObject* args ) { @@ -110,8 +110,6 @@ PyMODINIT_FUNC initfunchelper( void ) { PyObject* mod = Py_InitModule( "funchelper", funchelper_methods ); - if( !mod ) - return; } } // extern "C"