[Numpy-svn] r3379 - trunk/numpy/f2py/lib/parser

numpy-svn at scipy.org numpy-svn at scipy.org
Mon Oct 23 07:42:15 EDT 2006


Author: pearu
Date: 2006-10-23 06:42:09 -0500 (Mon, 23 Oct 2006)
New Revision: 3379

Modified:
   trunk/numpy/f2py/lib/parser/expressions.py
   trunk/numpy/f2py/lib/parser/pattern_tools.py
   trunk/numpy/f2py/lib/parser/test_expressions.py
Log:
F2PY G3: Cont. implementing Fortran expression parser and unittests.

Modified: trunk/numpy/f2py/lib/parser/expressions.py
===================================================================
--- trunk/numpy/f2py/lib/parser/expressions.py	2006-10-22 21:42:46 UTC (rev 3378)
+++ trunk/numpy/f2py/lib/parser/expressions.py	2006-10-23 11:42:09 UTC (rev 3379)
@@ -49,8 +49,10 @@
         if isinstance(result, tuple):
             obj = object.__new__(cls)
             obj.string = string
-            if cls.__dict__.has_key('init'):
+            if hasattr(cls, 'init'):
                 obj.init(*result)
+            #if cls.__dict__.has_key('init'):
+            #    obj.init(*result)
             return obj
         elif isinstance(result, Base):
             return result
@@ -201,166 +203,264 @@
         return '%s(%r,%r)' % (self.__class__.__name__, self.items[0],self.items[1])
 
     def __str__(self):
+        return self.tostr()
         if self.__class__.__dict__.has_key('tostr'):
             return self.tostr()
         return repr(self)
 
     def __repr__(self):
+        return self.torepr()
         if self.__class__.__dict__.has_key('torepr'):
             return self.torepr()
         return '%s(%r)' % (self.__class__.__name__, self.string)
 
-class Expr(Base):
+class SequenceBase(Base):
+
+    def match(separator, subcls, string):
+        line, repmap = string_replace_map(string)
+        lst = []
+        for p in line.split(separator):
+            p = p.strip()
+            for k in Base.findall(p):
+                p = p.replace(k,repmap[k])
+            lst.append(subcls(p))
+        return separator, tuple(lst)
+    match = staticmethod(match)
+    def init(self, separator, items):
+        self.separator = separator
+        self.items = items
+    def tostr(self): return (self.separator+' ').join(map(str, self.items))
+    def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.separator, self.items)
+    
+class UnaryOpBase(Base):
+    def init(self, op, rhs):
+        self.op = op
+        self.rhs = rhs
+        return    
+    def tostr(self):
+        return '%s %s' % (self.op, self.rhs)
+    def torepr(self):
+        return '%s(%r, %r)' % (self.__class__.__name__,self.op, self.rhs)
+    def match(op_pattern, rhs_cls, string):
+        line, repmap = string_replace_map(string)
+        t = op_pattern.lsplit(line)
+        if t is None:
+            return rhs_cls(string)
+        lhs, op, rhs = t
+        for k in Base.findall(rhs):
+            rhs = rhs.replace(k, repmap[k])
+        assert not lhs,`lhs`
+        rhs_obj = rhs_cls(rhs)
+        return t[1], rhs_obj
+    match = staticmethod(match)
+
+class BinaryOpBase(Base):
     """
+    <..> = <lhs> <op> <rhs>
+    """
+    def match(lhs_cls, op_pattern, rhs_cls, string):
+        line, repmap = string_replace_map(string)
+        t = op_pattern.rsplit(line)
+        if t is None or len(t)!=3: return
+        lhs, op, rhs = t
+        if lhs is None: return
+        if rhs is None: return
+        for k in Base.findall(lhs):
+            lhs = lhs.replace(k, repmap[k])
+        for k in Base.findall(rhs):
+            rhs = rhs.replace(k, repmap[k])
+        lhs_obj = lhs_cls(lhs)
+        rhs_obj = rhs_cls(rhs)
+        return lhs_obj, t[1], rhs_obj
+    match = staticmethod(match)
+    def init(self, lhs, op, rhs):
+        self.lhs = lhs
+        self.op = op
+        self.rhs = rhs
+        return    
+    def tostr(self):
+        return '%s %s %s' % (self.lhs, self.op, self.rhs)
+    def torepr(self):
+        return '%s(%r, %r, %r)' % (self.__class__.__name__,self.lhs, self.op, self.rhs)
+
+class RBinaryOpBase(BinaryOpBase):
+    """
+    <..> = [ <lhs> <op> ] <rhs>
+    """
+    def match(lhs_cls, op_pattern, rhs_cls, string):
+        line, repmap = string_replace_map(string)
+        t = op_pattern.rsplit(line)
+        if t is None:
+            return rhs_cls(string)
+        lhs, op, rhs = t
+        for k in Base.findall(lhs):
+            lhs = lhs.replace(k, repmap[k])
+        for k in Base.findall(rhs):
+            rhs = rhs.replace(k, repmap[k])
+        lhs_obj = lhs_cls(lhs)
+        rhs_obj = rhs_cls(rhs)
+        return lhs_obj, t[1], rhs_obj
+    match = staticmethod(match)
+
+class LBinaryOpBase(BinaryOpBase):
+    """
+    <..> = <lhs> [ <op> <rhs> ]
+    """
+    def match(lhs_cls, op_pattern, rhs_cls, string):
+        line, repmap = string_replace_map(string)
+        t = op_pattern.lsplit(line)
+        if t is None:
+            return lhs_cls(string)
+        lhs, op, rhs = t
+        for k in Base.findall(lhs):
+            lhs = lhs.replace(k, repmap[k])
+        for k in Base.findall(rhs):
+            rhs = rhs.replace(k, repmap[k])
+        lhs_obj = lhs_cls(lhs)
+        rhs_obj = rhs_cls(rhs)
+        return lhs_obj, t[1], rhs_obj
+    match = staticmethod(match)
+
+class Expr(RBinaryOpBase):
+    """
     <expr> = [ <expr> <defined-binary-op> ] <level-5-expr>
     <defined-binary-op> = . <letter> [ <letter> ]... .
+    TODO: defined_binary_op must not be intrinsic_binary_op!!
     """
+    #subclass_names = ['Level_5_Expr']
     def match(string):
-        return Base.match_binary_operand_right(\
-            Expr,pattern.defined_binary_op.named(),Level_5_Expr,string)
+        return RBinaryOpBase.match(Expr, pattern.defined_binary_op.named(), Level_5_Expr,
+                                 string)
     match = staticmethod(match)
-    init = Base.init_binary_operand
-    tostr = Base.tostr_binary_operand
-    torepr = Base.torepr_binary_operand
 
-class Level_5_Expr(Expr):
+class Level_5_Expr(RBinaryOpBase):
     """
     <level-5-expr> = [ <level-5-expr> <equiv-op> ] <equiv-operand>
     <equiv-op> = .EQV.
                | .NEQV.
     """
+    #subclass_names = ['Equiv_Operand']
     def match(string):
-        return Base.match_binary_operand_right(\
+        return RBinaryOpBase.match(\
             Level_5_Expr,pattern.equiv_op.named(),Equiv_Operand,string)
     match = staticmethod(match)
-    init = Base.init_binary_operand
-    tostr = Base.tostr_binary_operand
-    torepr = Base.torepr_binary_operand
     
-class Equiv_Operand(Level_5_Expr):
+class Equiv_Operand(RBinaryOpBase):
     """
     <equiv-operand> = [ <equiv-operand> <or-op> ] <or-operand>
     <or-op>  = .OR.
     """
+    #subclass_names = ['Or_Operand']
     def match(string):
-        return Base.match_binary_operand_right(\
+        return RBinaryOpBase.match(\
             Equiv_Operand,pattern.or_op.named(),Or_Operand,string)
     match = staticmethod(match)
-    init = Base.init_binary_operand
-    tostr = Base.tostr_binary_operand
-    torepr = Base.torepr_binary_operand
     
-class Or_Operand(Equiv_Operand):
+class Or_Operand(RBinaryOpBase):
     """
     <or-operand> = [ <or-operand> <and-op> ] <and-operand>    
     <and-op> = .AND.
-
     """
+    #subclass_names = ['And_Operand']
     def match(string):
-        return Base.match_binary_operand_right(\
+        return RBinaryOpBase.match(\
             Or_Operand,pattern.and_op.named(),And_Operand,string)
     match = staticmethod(match)
-    init = Base.init_binary_operand
-    tostr = Base.tostr_binary_operand
-    torepr = Base.torepr_binary_operand
     
-class And_Operand(Or_Operand):
+class And_Operand(UnaryOpBase):
     """
     <and-operand> = [ <not-op> ] <level-4-expr>
     <not-op> = .NOT.
     """
+    #subclass_names = ['Level_4_Expr']
     def match(string):
-        return Base.match_unary_operand(\
+        return UnaryOpBase.match(\
             pattern.not_op.named(),Level_4_Expr,string)
     match = staticmethod(match)
-    init = Base.init_unary_operand
-    tostr = Base.tostr_unary_operand
-    torepr = Base.torepr_unary_operand
     
-class Level_4_Expr(And_Operand):
+class Level_4_Expr(RBinaryOpBase):
     """
     <level-4-expr> = [ <level-3-expr> <rel-op> ] <level-3-expr>
     <rel-op> = .EQ. | .NE. | .LT. | .LE. | .GT. | .GE. | == | /= | < | <= | > | >=
     """
+    #subclass_names = ['Level_3_Expr']
     def match(string):
-        return Base.match_binary_operand_right(\
+        return RBinaryOpBase.match(\
             Level_3_Expr,pattern.rel_op.named(),Level_3_Expr,string)
     match = staticmethod(match)
-    init = Base.init_binary_operand
-    tostr = Base.tostr_binary_operand
-    torepr = Base.torepr_binary_operand
     
-class Level_3_Expr(Level_4_Expr):
+class Level_3_Expr(RBinaryOpBase):
     """
     <level-3-expr> = [ <level-3-expr> <concat-op> ] <level-2-expr>
     <concat-op>    = //
     """
+    #subclass_names = ['Level_2_Expr']
     def match(string):
-        return Base.match_binary_operand_right(\
+        return RBinaryOpBase.match(\
             Level_3_Expr,pattern.concat_op.named(),Level_2_Expr,string)
     match = staticmethod(match)
-    init = Base.init_binary_operand
-    tostr = Base.tostr_binary_operand
-    torepr = Base.torepr_binary_operand
     
-class Level_2_Expr(Level_3_Expr):
+class Level_2_Expr(BinaryOpBase):
     """
     <level-2-expr> = [ [ <level-2-expr> ] <add-op> ] <add-operand>
     <add-op>   = +
                  | -
     """
-
+    subclass_names = ['Add_Operand']
     def match(string):
-        return Base.match_binary_unary_operand_right(\
-            Level_2_Expr,pattern.add_op.named(),Add_Operand,string)
+        lhs_cls, op_pattern, rhs_cls = Level_2_Expr,pattern.add_op.named(),Add_Operand
+        line, repmap = string_replace_map(string)
+        t = op_pattern.rsplit(line)
+        if t is None:
+            return rhs_cls(string)
+        lhs, op, rhs = t
+        if lhs is not None:
+            for k in Base.findall(lhs):
+                lhs = lhs.replace(k, repmap[k])
+            lhs_obj = lhs_cls(lhs)
+        else:
+            lhs_obj = None
+        for k in Base.findall(rhs):
+            rhs = rhs.replace(k, repmap[k])
+        rhs_obj = rhs_cls(rhs)
+        return lhs_obj, t[1], rhs_obj
     match = staticmethod(match)
-    init = Base.init_binary_operand
-    tostr = Base.tostr_binary_unary_operand
-    torepr = Base.torepr_binary_operand
     
-class Add_Operand(Level_2_Expr):
+class Add_Operand(RBinaryOpBase):
     """
     <add-operand> = [ <add-operand> <mult-op> ] <mult-operand>
     <mult-op>  = *
                  | /
     """
-
+    #subclass_names = ['Mult_Operand']
     def match(string):
-        return Base.match_binary_operand_right(\
+        return RBinaryOpBase.match(\
             Add_Operand,pattern.mult_op.named(),Mult_Operand,string)
     match = staticmethod(match)
-    init = Base.init_binary_operand
-    tostr = Base.tostr_binary_operand
-    torepr = Base.torepr_binary_operand
     
-class Mult_Operand(Add_Operand):
+class Mult_Operand(LBinaryOpBase):
     """
     <mult-operand> = <level-1-expr> [ <power-op> <mult-operand> ]
     <power-op> = **
     """
-
+    #subclass_names = ['Level_1_Expr']
     def match(string):
-        return Base.match_binary_operand_left(\
+        return LBinaryOpBase.match(\
             Level_1_Expr,pattern.power_op.named(),Mult_Operand,string)
     match = staticmethod(match)
-    init = Base.init_binary_operand
-    tostr = Base.tostr_binary_operand
-    torepr = Base.torepr_binary_operand
     
-class Level_1_Expr(Mult_Operand):
+class Level_1_Expr(UnaryOpBase):
     """
     <level-1-expr> = [ <defined-unary-op> ] <primary>
     <defined-unary-op> = . <letter> [ <letter> ]... .
     """
+    #subclass_names = ['Primary']
     def match(string):
-        return Base.match_unary_operand(\
+        return UnaryOpBase.match(\
             pattern.defined_unary_op.named(),Primary,string)
     match = staticmethod(match)
-    init = Base.init_unary_operand
-    tostr = Base.tostr_unary_operand
-    torepr = Base.torepr_unary_operand
     
-class Primary(Level_1_Expr):
+class Primary(Base):
     """
     <primary> = <constant>
                 | <designator>
@@ -370,17 +470,133 @@
                 | <type-param-inquiry>
                 | <type-param-name>
                 | ( <expr> )
+    """
+    subclass_names = ['Constant', 'Designator','Array_Constructor','Structure_Constructor',
+                      'Function_Reference', 'Type_Param_Inquiry', 'Type_Param_Name', 'Parenthesis']
+
+class Type_Param_Name(Base):
+    """
+    <type-param-name> = <name>
+    """
+    subclass_names = ['Name']
+
+class Type_Param_Inquiry(BinaryOpBase):
+    """
     <type-param-inquiry> = <designator> % <type-param-name>
     """
+    subclass_names = []
+    def match(string):
+        return BinaryOpBase.match(\
+            Designator, pattern.percent_op.named(), Type_Param_Name, string)
+    match = staticmethod(match)
 
+class Structure_Constructor(Base):
+    """
+    <structure-constructor> = <derived-type-spec> ( [ <component-spec-list> ] )
+                            | [ <keyword> = ] <component-data-source>
+    """
+    subclass_names = []
+    def match(string):
+        line, repmap = string_replace_map(string)
+        if line[-1]==')':
+            i = line.rfind('(')
+            if i==-1: return
+            specline = line[:i].rstrip()
+            for k in Base.findall(specline):
+                specline = specline.replace(k,repmap[k])
+            try:
+                spec = Derived_Type_Spec(specline)
+            except NoMatchError:
+                spec = None
+            if spec is not None:
+                l = line[i+1:-1].strip()
+                for k in Base.findall(l):
+                    l = l.replace(k,repmap[k])
+                if not l: return spec,'(',None,')'
+                return spec,'(',Component_Spec_List(l),')'
+        if '=' not in string: return None, Component_Data_Source(string)
+        lhs,rhs = string.split('=',1)
+        return Keyword(lhs.rstrip()), Component_Data_Source(rhs.lstrip())        
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self):
+        if len(self.items)==4:
+            if self.items[2] is None: return '%s()' % (self.items[0])
+            return '%s(%s)' % (self.items[0],self.items[2])
+        if self.items[0] is None:
+            return str(self.items[1])
+        return '%s = %s' % (self.items[0], self.items[1])
+    torepr = Base.torepr_list
 
+class Component_Data_Source(Base):
+    """
+    <component-data-source> = <expr>
+                              | <data-target>
+                              | <proc-target>
+    """
+    subclass_names = ['Expr','Data-Target','Proc-Target']
 
-class Array_Constructor(Primary):
+class Data_Target(Base):
     """
+    <data-target> = <variable>
+                    | <expr>
+    """
+    subclass_names = ['Variable','Expr']
+
+class Proc_Target(Base):
+    """
+    <proc-target> = <expr>
+                    | <procedure-name>
+                    | <proc-component-ref>
+    """
+    subclass_names = ['Expr','Procedure_Name','Proc_Component_Ref']
+
+class Proc_Component_Ref(BinaryOpBase):
+    """
+    <proc-component-ref> = <variable> % <procedure-component-name>
+    """
+    subclass_names = []
+    def match(string):
+        return BinaryOpBase.match(\
+            Variable, pattern.percent_op.named(), Procedure_Component_Name, string)            
+    match = staticmethod(match)
+
+class Component_Spec(Base):
+    """
+    <component-spec> = [ <keyword> = ] <component-data-source>
+    """
+    subclass_names = []
+    def match(string):
+        if '=' not in string: return None, Component_Data_Source(string)
+        lhs,rhs = string.split('=',1)
+        return Keyword(lhs.rstrip()), Component_Data_Source(rhs.lstrip())
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self):
+        if self.items[0] is None: return str(self.items[1])
+        return '%s = %s' % tuple(self.items)
+    def torepr(self):
+        return '%s(%r, %r)' % (self.__class__.__name__, self.items[0],self.items[1])
+
+class Component_Spec_List(Base):
+    """
+    <component-spec-list> = <component-spec> [ , <component-spec> ]...
+    """
+    subclass_names = []
+    def match(string):
+        return Base.match_list_of(Component_Spec, string)
+    match = staticmethod(match)
+    init = Base.init_list
+    tostr = Base.tostr_list
+    torepr = Base.torepr_list
+
+class Array_Constructor(Base):
+    """
     <array-constructor> = (/ <ac-spec> /)
                           | <left-square-bracket> <ac-spec> <right-square-bracket>
 
     """
+    subclass_names = []
     def match(string):
         if string[:2]+string[-2:]=='(//)':
             return '(/',Ac_Spec(string[2:-2].strip()),'/)'
@@ -397,6 +613,7 @@
     <ac-spec> = <type-spec> ::
                 | [ <type-spec> :: ] <ac-value-list>
     """
+    subclass_names = []
     def match(string):
         if string.endswith('::'):
             return Type_Spec(string[:-2].rstrip()),None
@@ -426,6 +643,7 @@
     """
     <ac-value-list> = <ac-value> [ , <ac-value> ]...
     """
+    subclass_names = []
     def match(string):
         return Base.match_list_of(Ac_Value, string)
     match = staticmethod(match)
@@ -438,12 +656,14 @@
     <ac-value> = <expr>
                  | <ac-implied-do>
     """
+    subclass_names = ['Ac_Implied_Do','Expr']
     extra_subclasses = [Expr]
 
-class Ac_Implied_Do(Ac_Value):
+class Ac_Implied_Do(Base):
     """
     <ac-implied-do> = ( <ac-value-list> , <ac-implied-do-control> )
     """
+    subclass_names = []
     def match(string):
         if string[0]+string[-1] != '()': return
         line, repmap = string_replace_map(string[1:-1].strip())
@@ -467,6 +687,7 @@
     """
     <ac-implied-do-control> = <ac-do-variable> = <scalar-int-expr> , <scalar-int-expr> [ , <scalar-int-expr> ]    
     """
+    subclass_names = []
     def match(string):
         i = string.find('=')
         if i==-1: return
@@ -485,6 +706,7 @@
     """
     <scalar-int-expr> = <expr>
     """
+    subclass_names = ['Expr']
     extra_subclasses = [Expr]
 
 class Ac_Do_Variable(Base):
@@ -492,14 +714,16 @@
     <ac-do-variable> = <scalar-int-variable>
     <ac-do-variable> shall be a named variable    
     """
+    subclass_names = ['Name']
 
 class Type_Spec(Base):
     """
     <type-spec> = <intrinsic-type-spec>
                   | <derived-type-spec>
     """
+    subclass_names = ['Intrinsic_Type_Spec', 'Derived_Type_Spec']
 
-class Intrinsic_Type_Spec(Type_Spec):
+class Intrinsic_Type_Spec(Base):
     """
     <intrinsic-type-spec> = INTEGER [ <kind-selector> ]
                             | REAL [ <kind-selector> ]
@@ -507,11 +731,11 @@
                             | COMPLEX [ <kind-selector> ]
                             | CHARACTER [ <char-selector> ]
                             | LOGICAL [ <kind-selector> ]
-
     Extensions:
                             | DOUBLE PRECISION
                             | BYTE
     """
+    subclass_names = []
     def match(string):
         if string[:7].upper()=='INTEGER':
             t = string[:7].upper()
@@ -559,6 +783,7 @@
     Extensions:
                       | * <char-length>
     """
+    subclass_names = []
     def match(string):
         if string[0]+string[-1] != '()':
             if not string.startswith('*'): return
@@ -587,6 +812,7 @@
                       | ( <type-param-value> , [ KIND = ] <scalar-int-initialization-expr> )
                       | ( KIND = <scalar-int-initialization-expr> [ , LEN = <type-param-value> ] )
     """
+    subclass_names = ['Lenght_Selector']
     def match(string):
         if string[0]+string[-1] != '()': return
         line, repmap = string_replace_map(string[1:-1].strip())
@@ -638,11 +864,12 @@
     def torepr(self):
         return '%s(%r, %r)' % (self.__class__.__name__, self.items[0],self.items[1])
     
-class Lenght_Selector(Char_Selector):
+class Lenght_Selector(Base):
     """
     <length-selector> = ( [ LEN = ] <type-param-value> )
                         | * <char-length> [ , ]
     """
+    subclass_names = []
     def match(string):
         if string[0]+string[-1] == '()':
             line = string[1:-1].strip()
@@ -668,8 +895,9 @@
 class Char_Length(Base):
     """
     <char-length> = ( <type-param-value> )
-                    | scalar-int-literal-constant
+                    | <scalar-int-literal-constant>
     """
+    subclass_names = []
     def match(string):
         if string[0]+string[-1] == '()':
             return '(',Type_Param_Value(string[1:-1].strip()),')'
@@ -685,15 +913,25 @@
         return '%s(%r, %r, %r)' % (self.__class__.__name__, self.items[0],self.items[1],self.items[2])
 
 
-Scalar_Int_Expr = Expr
-Scalar_Int_Initialization_Expr = Expr
+class Scalar_Int_Expr(Base):
+    """
+    <scalar-int-expr> = <expr>
+    """
+    subclass_names = ['Expr']
 
+class Scalar_Int_Initialization_Expr(Base):
+    """
+    <scalar-int-initialization-expr> = <expr>
+    """
+    subclass_names = ['Expr']
+
 class Type_Param_Value(Base):
     """
     <type-param-value> = <scalar-int-expr>
                        | *
                        | :
     """
+    subclass_names = ['Scalar_Int_Expr']
     extra_subclasses = [Scalar_Int_Expr]
     def match(string):
         if string in ['*',':']: return string,
@@ -703,19 +941,62 @@
     def tostr(self): return str(self.value)
     def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.value)
 
-class Derived_Type_Spec(Type_Spec):
+class Derived_Type_Spec(Base):
     """
     <derived-type-spec> = <type-name> [ ( <type-param-spec-list> ) ]
+    """
+    subclass_names = []
+    def match(string):
+        i = string.find('(')
+        if i==-1: return Type_Name(string),None
+        if string[-1] != ')': return
+        return Type_Name(string[:i].rstrip()), Type_Param_Spec_List(string[i+1:-1].strip())
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self):
+        if self.items[1] is None: return str(self.items[0])
+        return '%s(%s)' % tuple(self.items)
+    def torepr(self):
+        return '%s(%r, %r)' % (self.__class__.__name__, self.items[0],self.items[1])
+
+class Type_Param_Spec(Base):
+    """
     <type-param-spec> = [ <keyword> = ] <type-param-value>
     """
+    subclass_names = []
+    def match(string):
+        if '=' not in string: return None, Type_Param_Value(string)
+        lhs,rhs = string.split('=',1)
+        return Keyword(lhs.rstrip()), Type_Param_Value(rhs.lstrip())
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self):
+        if self.items[0] is None: return str(self.items[1])
+        return '%s = %s' % tuple(self.items)
+    def torepr(self):
+        return '%s(%r, %r)' % (self.__class__.__name__, self.items[0],self.items[1])
 
-class Constant(Primary):
+class Type_Param_Spec_List(Base):
     """
+    <type-param-spec> = <type-param> [ , <type-param> ]...
+    """
+    subclass_names = []
+    def match(string):
+        return Base.match_list_of(Type_Param_Spec, string)
+    match = staticmethod(match)
+    init = Base.init_list
+    tostr = Base.tostr_list
+    torepr = Base.torepr_list
+
+
+class Constant(Base):
+    """
     <constant> = <literal-constant>
                  | <named-constant>
     """
+    subclass_names = ['Literal_Constant','Named_Constant']
 
-class Designator(Primary):
+class Designator(Base):
     """
     <designator> = <object-name>
                    | <array-element>
@@ -734,9 +1015,11 @@
     <substring-range> = [ <scalar-int-expr> ] : [ <scalar-int-expr> ]
     <structure-component> = <data-ref>
     """
+    subclass_names = ['Object_Name','Array_Element','Array_Section','Structure_Component',
+                      'Substring'
+                      ]
 
-
-class Literal_Constant(Constant):
+class Literal_Constant(Base):
     """
     <literal-constant> = <int-literal-constant>
                          | <real-literal-constant>
@@ -745,11 +1028,14 @@
                          | <char-literal-constant>
                          | <boz-literal-constant>
     """
+    subclass_names = ['Int_Literal_Constant', 'Real_Literal_Constant','Complex_Literal_Constant',
+                      'Logical_Literal_Constant','Char_Literal_Constant','Boz_Literal_Constant']
 
-class Int_Literal_Constant(Literal_Constant):
+class Int_Literal_Constant(Base):
     """
     <int-literal-constant> = <digit-string> [ _ <kind-param> ]
     """
+    subclass_names = []
     def match(string):
         m = pattern.abs_int_literal_constant_named.match(string)
         if m is None: return
@@ -759,11 +1045,16 @@
     tostr = Base.tostr_number
     torepr = Base.torepr_number
 
-Scalar_Int_Literal_Constant = Int_Literal_Constant
+class Scalar_Int_Literal_Constant(Base):
+    """
+    <scalar-int-literal-constant> = <int-literal-constant>
+    """
+    subclass_names = ['Int_Literal_Constant']
 
-class Real_Literal_Constant(Literal_Constant):
+class Real_Literal_Constant(Base):
     """
     """
+    subclass_names = []
     def match(string):
         m = pattern.abs_real_literal_constant_named.match(string)
         if m is None: return
@@ -773,13 +1064,14 @@
     tostr = Base.tostr_number
     torepr = Base.torepr_number
 
-class Complex_Literal_Constant(Literal_Constant):
+class Complex_Literal_Constant(Base):
     """
     <complex-literal-constant> = ( <real-part>, <imag-part> )
     <real-part> = <imag-part> = <signed-int-literal-constant>
                                 | <signed-real-literal-constant>
                                 | <named-constant>
     """
+    subclass_names = []
     def match(string):
         if string[0]+string[-1]!='()': return
         if not pattern.abs_complex_literal_constant.match(string):
@@ -797,6 +1089,7 @@
                   | <signed-real-literal-constant>
                   | <named-constant>
     """
+    subclass_names = []
     def match(string):
         clses = [Int_Literal_Constant, Real_Literal_Constant]
         if string[0] in '+-':
@@ -826,16 +1119,18 @@
     """
     <imag-part> = <real-part>
     """
+    subclass_names = []
     match = staticmethod(Real_Part.match)
     init = Real_Part.init
     tostr = Real_Part.tostr
     torepr = Real_Part.torepr
 
-class Char_Literal_Constant(Literal_Constant):
+class Char_Literal_Constant(Base):
     """
     <char-literal-constant> = [ <kind-param> _ ] ' <rep-char> '
                               | [ <kind-param> _ ] \" <rep-char> \"
     """
+    subclass_names = []
     def match(string):
         if string[-1] not in '"\'': return
         if string[-1]=='"':
@@ -857,11 +1152,12 @@
         return '%s_%s' % (self.items[1], self.items[0])
     def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1])
 
-class Logical_Literal_Constant(Literal_Constant):
+class Logical_Literal_Constant(Base):
     """
     <logical-literal-constant> = .TRUE. [ _ <kind-param> ]
                                  | .FALSE. [ _ <kind-param> ]
     """
+    subclass_names = []
     def match(string):
         m = pattern.abs_logical_literal_constant_named.match(string)
         if m is None: return
@@ -873,19 +1169,20 @@
         return '%s_%s' % (self.items[0], self.items[1])
     def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1])
 
-class Boz_Literal_Constant(Literal_Constant):
+class Boz_Literal_Constant(Base):
     """
     <boz-literal-constant> = <binary-constant>
                              | <octal-constant>
                              | <hex-constant>
     """
+    subclass_names = ['Binary_Constant','Octal_Constant','Hex_Constant']
 
-
-class Binary_Constant(Boz_Literal_Constant):
+class Binary_Constant(Base):
     """
     <binary-constant> = B ' <digit> [ <digit> ]... '
                         | B \" <digit> [ <digit> ]... \"
     """
+    subclass_names = []
     def match(string):
         if pattern.abs_binary_constant.match(string): return (string,)
         return
@@ -893,11 +1190,12 @@
     tostr = Base.tostr_string
     torepr = Base.torepr_string
 
-class Octal_Constant(Boz_Literal_Constant):
+class Octal_Constant(Base):
     """
     <octal-constant> = O ' <digit> [ <digit> ]... '
                        | O \" <digit> [ <digit> ]... \"
     """
+    subclass_names = []
     def match(string):
         if pattern.abs_octal_constant.match(string): return (string,)
         return
@@ -905,11 +1203,12 @@
     tostr = Base.tostr_string
     torepr = Base.torepr_string
 
-class Hex_Constant(Boz_Literal_Constant):
+class Hex_Constant(Base):
     """
     <hex-constant> = Z ' <digit> [ <digit> ]... '
                      | Z \" <digit> [ <digit> ]... \"
     """
+    subclass_names = []
     def match(string):
         if pattern.abs_hex_constant.match(string): return (string,)
         return
@@ -917,21 +1216,23 @@
     tostr = Base.tostr_string
     torepr = Base.torepr_string
 
-class Named_Constant(Constant):
+class Named_Constant(Base):
     """
     <named-constant> = <name>
     """
+    subclass_names = ['Name']
 
-
-class Object_Name(Designator):
+class Object_Name(Base):
     """
     <object-name> = <name>
     """
-
-class Function_Reference(Primary):
+    subclass_names = ['Name']
+    
+class Function_Reference(Base):
     """
     <function-reference> = <procedure-designator> ( [ <actual-arg-spec-list> ] )
     """
+    subclass_names = []
     def match(string):
         if string[-1] != ')': return None
         line, repmap = string_replace_map(string)
@@ -957,18 +1258,60 @@
         return '%s(%s)' % (self.items[0],self.items[2])
     torepr = Base.torepr_list
         
-    
+
+
 class Procedure_Designator(Base):
     """
     <procedure-designator> = <procedure-name>
                            | <proc-component-ref>
                            | <data-ref> % <binding-name>
     """
-        
+    subclass_names = ['Procedure_Name','Proc_Component_Ref']
+    def match(string):
+        return BinaryOpBase.match(\
+            Data_Ref, pattern.percent_op.named(),  Binding_Name, string)
+    match = staticmethod(match)
+
+class Part_Ref(Base):
+    """
+    <part-ref> = <part-name> [ ( <section-subscript-list> ) ]
+    """
+    subclass_names = ['Part_Name']
+    def match(string):
+        if string.endswith(')'):
+            i = string.find('(')
+            if i==-1: return
+            return Part_Name(string[:i].rstrip()),'(',Section_Subscript_List(string[i+1:-1].strip()),')'
+        return
+    match = staticmethod(match)
+    init = Base.init_list
+
+class Part_Name(Base):
+    """
+    <part-name> = <name>
+    """
+    subclass_names = ['Name']
+    
+class Binding_Name(Base):
+    """
+    <binding-name> = <name>
+    """
+    subclass_names = ['Name']
+
+class Data_Ref(SequenceBase):
+    """
+    <data-ref> = <part-ref> [ % <part-ref> ]...
+    """
+    subclass_names = []
+    def match(string):
+        return SequenceBase.match(r'%', Part_Ref, string)
+    match = staticmethod(match)
+
 class Actual_Arg_Spec_List(Base):
     """
     <actual-arg-spec-list> = <actual-arg-spec> [ , <actual-arg-spec> ]...
     """
+    subclass_names = []
     def match(string):
         return Base.match_list_of(Actual_Arg_Spec, string)
     match = staticmethod(match)
@@ -976,17 +1319,11 @@
     tostr = Base.tostr_list
     torepr = Base.torepr_list
 
-def try_cls(cls, string):
-    try:
-        return cls(string)
-    except NoMatchError:
-        pass
-    return
-
 class Actual_Arg_Spec(Base):
     """
     <actual-arg-spec> = [ <keyword> = ] <actual-arg>
-    """    
+    """
+    subclass_names = []
     def match(string):
         if pattern.keyword_equal.match(string):
             i = string.find('=')
@@ -1013,9 +1350,23 @@
     """
     <keyword> = <name>
     """
+    subclass_names = ['Name']
 
-class Actual_Arg(Actual_Arg_Spec):
+class Type_Name(Base):
     """
+    <type-name> = <name>
+    <type-name> shall not be DOUBLEPRECISION or the name of intrinsic type
+    """
+    subclass_names = []
+    def match(string):
+        if pattern.abs_intrinsic_type_name.match(string): return
+        return Name(string)
+    match = staticmethod(match)
+    tostr = Base.tostr_string
+    torepr = Base.torepr_string        
+    
+class Actual_Arg(Base):
+    """
     <actual-arg> = <expr>
                  | <variable>
                  | <procedure-name>
@@ -1025,17 +1376,33 @@
     <variable> = <designator>
     <proc-component-ref> = <variable> % <procedure-component-name>
     """
+    subclass_names = ['Expr','Variable','Procedure_Name','Alt_Return_Spec']
     extra_subclasses = [Expr]
-    
-class Procedure_Name(Procedure_Designator, Actual_Arg):
+
+class Variable(Base):
     """
+    <variable> = <designator>
+    """
+    subclass_names = ['Designator']
+    extra_subclasses = [Designator]
+
+class Procedure_Component_Name(Base):
+    """
+    <procedure-component-name> = <name>
+    """
+    subclass_names = ['Name']
+
+class Procedure_Name(Base):
+    """
     <procedure-name> = <name>
     """
+    subclass_names = ['Name']
     
-class Parenthesis(Primary):
+class Parenthesis(Base):
     """
-    ( <expr> )
+    <parenthesis> = ( <expr> )
     """
+    subclass_names = []
     def match(string):
         if string[0]+string[-1]=='()':
             return '(',Expr(string[1:-1].strip()),')'
@@ -1045,10 +1412,11 @@
     tostr = Base.tostr_binary_operand
     torepr = Base.torepr_binary_operand
 
-class Name(Object_Name, Named_Constant, Procedure_Name, Keyword, Ac_Do_Variable):
+class Name(Base):
     """
     <name> = <letter> [ <alphanumeric_character> ]...
     """
+    subclass_names = []
     def match(string):
         if pattern.abs_name.match(string):
             return string,
@@ -1058,9 +1426,32 @@
     torepr = Base.torepr_string
     
 ClassType = type(Base)
+Base_classes = {}
 for clsname in dir():
     cls = eval(clsname)
     if isinstance(cls, ClassType) and issubclass(cls, Base):
+        Base_classes[cls.__name__] = cls
+
+for clsname, cls in Base_classes.items():
+    subclass_names = getattr(cls, 'subclass_names', None)
+    if subclass_names is None:
+        print '%s class is missing subclass_names list' % (clsname)
+        continue
+    try:
+        l = Base.subclasses[clsname]
+    except KeyError:
+        Base.subclasses[clsname] = l = []
+    for n in subclass_names:
+        if Base_classes.has_key(n):
+            l.append(Base_classes[n])
+        else:
+            print '%s not implemented needed by %s' % (n,clsname)
+
+print 
+for clsname in dir():
+    break
+    cls = eval(clsname)
+    if isinstance(cls, ClassType) and issubclass(cls, Base):
         extra_subclasses = cls.__dict__.get('extra_subclasses',[])
         if extra_subclasses:
             try:
@@ -1075,5 +1466,16 @@
                     Base.subclasses[basecls.__name__].append(cls)
                 except KeyError:
                     Base.subclasses[basecls.__name__] = [cls]
+
+for cls in Base_classes.values():
+    subclasses = Base.subclasses.get(cls.__name__,[])
+    subclasses_names = [c.__name__ for c in subclasses]
+    subclass_names = getattr(cls,'subclass_names', [])
+    for n in subclasses_names:
+        if n not in subclass_names:
+            print '%s needs to be added to %s subclasses_name list' % (n,cls.__name__)
+    for n in subclass_names:
+        if n not in subclasses_names:
+            print '%s needs to be added to %s subclass_name list' % (n,cls.__name__)
 #import pprint
 #pprint.pprint(Base.subclasses)

Modified: trunk/numpy/f2py/lib/parser/pattern_tools.py
===================================================================
--- trunk/numpy/f2py/lib/parser/pattern_tools.py	2006-10-22 21:42:46 UTC (rev 3378)
+++ trunk/numpy/f2py/lib/parser/pattern_tools.py	2006-10-23 11:42:09 UTC (rev 3379)
@@ -26,8 +26,8 @@
     p1.named(name) -> match of <p1> has name
     p1.match(string) -> return string match with <p1>
     p1.flags(<re.I,..>)
-    p1.rsplit(..)
-    p1.lsplit(..)
+    p1.rsplit(..) -> split a string from the rightmost p1 occurrence
+    p1.lsplit(..) -> split a string from the leftmost p1 occurrence
     """
     _special_symbol_map = {'.': '[.]',
                            '*': '[*]',
@@ -253,6 +253,7 @@
 and_op = Pattern('<and-op>','[.]AND[.]',flags=re.I)
 or_op = Pattern('<or-op>','[.]OR[.]',flags=re.I)
 equiv_op = Pattern('<equiv-op>','[.](EQV|NEQV)[.]',flags=re.I)
+percent_op = Pattern('<percent-op>',r'%',flags=re.I)
 intrinsic_operator = power_op | mult_op | add_op | concat_op | rel_op | not_op | and_op | or_op | equiv_op
 extended_intrinsic_operator = intrinsic_operator
 
@@ -283,6 +284,9 @@
 abs_octal_constant = abs(octal_constant)
 abs_hex_constant = abs(hex_constant)
 
+intrinsic_type_name = Pattern('<intrinsic-type-name>',r'(INTEGER|REAL|COMPLEX|LOGICAL|CHARACTER|DOUBLE\s*COMPLEX|DOUBLE\s*PRECISION|BYTE)',flags=re.I)
+abs_intrinsic_type_name = abs(intrinsic_type_name)
+
 def _test():
     assert name.match('a1_a')
     assert abs(name).match('a1_a')

Modified: trunk/numpy/f2py/lib/parser/test_expressions.py
===================================================================
--- trunk/numpy/f2py/lib/parser/test_expressions.py	2006-10-22 21:42:46 UTC (rev 3378)
+++ trunk/numpy/f2py/lib/parser/test_expressions.py	2006-10-23 11:42:09 UTC (rev 3379)
@@ -4,6 +4,27 @@
 
 from expressions import *
 
+class test_Expr(NumpyTestCase):
+
+    def check_simple(self):
+        cls = Expr
+        a = cls('a .op. b')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'a .op. b')
+        assert_equal(repr(a),"Expr(Name('a'), '.op.', Name('b'))")
+
+        a = cls('a')
+        assert isinstance(a,Name),`a`
+        assert_equal(str(a),'a')
+
+class test_Procedure_Designator(NumpyTestCase):
+
+    def check_part_ref(self):
+        cls = Part_Ref
+        a = cls('a')
+        assert isinstance(a, Name),`a`
+        assert_equal(str(a),'a')
+        
 class test_Type_Spec(NumpyTestCase):
 
     def check_kind_selector(self):
@@ -124,7 +145,84 @@
         a = cls('double precision')
         assert isinstance(a,cls),`a`
         assert_equal(str(a),'DOUBLE PRECISION')
+
+    def check_type_param_spec(self):
+        cls = Type_Param_Spec
+        a = cls('a')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'a')
+        assert_equal(repr(a),"Type_Param_Spec(None, Name('a'))")
+
+        a = cls('k=a')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'k = a')
+
+        a = cls('k=:')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'k = :')
+
+    def check_type_param_spec_list(self):
+        cls = Type_Param_Spec_List
+        a = cls('a')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'a')
+        assert_equal(repr(a),"Type_Param_Spec_List(Type_Param_Spec(None, Name('a')))")
+
+        a = cls('a,b')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'a, b')
+
+        a = cls('k=a,c,g=1')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'k = a, c, g = 1')
+
+class test_Type_Param_Inquiry(NumpyTestCase):
     
+    def check_simple(self):
+        cls = Type_Param_Inquiry
+        a = cls('a % b')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'a % b')
+        assert_equal(repr(a),"Type_Param_Inquiry(Name('a'), '%', Name('b'))")
+
+class test_Function_Reference(NumpyTestCase):
+
+    def check_simple(self):
+        cls = Function_Reference
+        a = cls('f()')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'f()')
+        assert_equal(repr(a),"Function_Reference(Name('f'), '(', None, ')')")
+
+        a = cls('f(2,k=1,a)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'f(2, k = 1, a)')
+
+class test_Structure_Constructor(NumpyTestCase):
+
+    def check_proc_component_ref(self):
+        cls = Proc_Component_Ref
+        a = cls('a % b')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'a % b')
+        assert_equal(repr(a),"Proc_Component_Ref(Name('a'), '%', Name('b'))")
+
+    def check_structure_constructor(self):
+        cls = Structure_Constructor
+        a = cls('t()')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'t()')
+        assert_equal(repr(a),"Structure_Constructor(Derived_Type_Spec(Name('t'), None), '(', None, ')')")
+
+        a = cls('t(s=1, a)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'t(s = 1, a)')
+
+        a = cls('a=k')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'a = k')
+        assert_equal(repr(a),"Structure_Constructor(Name('a'), Name('k'))")
+    
 class test_Array_Constructor(NumpyTestCase):
 
     def check_ac_implied_do_control(self):




More information about the Numpy-svn mailing list