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

numpy-svn at scipy.org numpy-svn at scipy.org
Wed Oct 25 06:41:15 EDT 2006


Author: pearu
Date: 2006-10-25 05:41:11 -0500 (Wed, 25 Oct 2006)
New Revision: 3397

Modified:
   trunk/numpy/f2py/lib/parser/expressions.py
   trunk/numpy/f2py/lib/parser/test_expressions.py
Log:
F2PY: Optimised Fortran expr parser. Fixed bugs.

Modified: trunk/numpy/f2py/lib/parser/expressions.py
===================================================================
--- trunk/numpy/f2py/lib/parser/expressions.py	2006-10-25 09:05:57 UTC (rev 3396)
+++ trunk/numpy/f2py/lib/parser/expressions.py	2006-10-25 10:41:11 UTC (rev 3397)
@@ -16,20 +16,8 @@
 from splitline import string_replace_map
 import pattern_tools as pattern
 
-class DefinedOp:
-    def __new__(cls, letters):
-        if not letters: return None
-        obj = object.__new__(cls)
-        obj._init(letters)
-        return obj
+############################# Base classes ################################
 
-    def _init(self, letters):
-        self.letters = letters.upper()
-        return
-
-    def __str__(self): return '.%s.' % (self.letters)
-    def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.letters)
-
 class NoMatchError(Exception):
     pass
 
@@ -90,17 +78,19 @@
 
 class SequenceBase(Base):
     """
-    <sequence-base> = <obj> [ , <obj> ]...
+    <sequence-base> = <obj>, <obj> [ , <obj> ]...
     """
     def match(separator, subcls, string):
         line, repmap = string_replace_map(string)
+        if separator not in line:
+            return
         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))
-        if len(lst)==1: return lst[0]
+        #if len(lst)==1: return lst[0]
         return separator, tuple(lst)
     match = staticmethod(match)
     def init(self, separator, items):
@@ -116,7 +106,7 @@
     
 class UnaryOpBase(Base):
     """
-    <unary-op-base> = [ <unary-op> ] <rhs>
+    <unary-op-base> = <unary-op> <rhs>
     """
     def init(self, op, rhs):
         self.op = op
@@ -128,7 +118,8 @@
         return '%s(%r, %r)' % (self.__class__.__name__,self.op, self.rhs)
     def match(op_pattern, rhs_cls, string):
         m = op_pattern.match(string)
-        if not m: return rhs_cls(string)
+        if not m: return
+        #if not m: return rhs_cls(string)
         rhs = string[m.end():].lstrip()        
         if not rhs: return
         op = string[:m.end()].rstrip().upper()
@@ -138,10 +129,14 @@
 class BinaryOpBase(Base):
     """
     <binary-op-base> = <lhs> <op> <rhs>
+    <op> is searched from right by default.
     """
-    def match(lhs_cls, op_pattern, rhs_cls, string):
+    def match(lhs_cls, op_pattern, rhs_cls, string, right=True):
         line, repmap = string_replace_map(string)
-        t = op_pattern.rsplit(line)
+        if right:
+            t = op_pattern.rsplit(line)
+        else:
+            t = op_pattern.lsplit(line)
         if t is None or len(t)!=3: return
         lhs, op, rhs = t
         if not lhs: return
@@ -165,54 +160,12 @@
     def torepr(self):
         return '%s(%r, %r, %r)' % (self.__class__.__name__,self.lhs, self.op, self.rhs)
 
-class RBinaryOpBase(BinaryOpBase):
-    """
-    <rbinary-op-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:
-            return rhs_cls(string)
-        lhs, op, rhs = t
-        if not lhs: return
-        op = op.upper()
-        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, op, rhs_obj
-    match = staticmethod(match)
-
-class LBinaryOpBase(BinaryOpBase):
-    """
-    <lbinary-op-base> = <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
-        if not rhs: return
-        op = op.upper()
-        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, op, rhs_obj
-    match = staticmethod(match)
-
 class KeywordValueBase(BinaryOpBase):
     """
-    <keyword-value-base> = [ <keyword> = ] <rhs>
+    <keyword-value-base> = <keyword> = <rhs>
     """
     def match(cls, string):
-        if '=' not in string: return cls(string)
+        if '=' not in string: return
         lhs,rhs = string.split('=',1)
         return Keyword(lhs.rstrip()),'=',cls(rhs.lstrip())
     match = staticmethod(match)
@@ -340,54 +293,134 @@
     subclass_names = []
     def match(string): return StringBase.match(pattern.abs_hex_constant, string)
     match = staticmethod(match)
+
+
+class Int_Literal_Constant(NumberBase):
+    """
+    <int-literal-constant> = <digit-string> [ _ <kind-param> ]
+    """
+    subclass_names = []
+    def match(string):
+        return NumberBase.match(pattern.abs_int_literal_constant_named, string)
+    match = staticmethod(match)
+
+class Signed_Int_Literal_Constant(NumberBase):
+    """
+    <signed-int-literal-constant> = [ <sign> ] <int-literal-constant>
+    """
+    subclass_names = ['Int_Literal_Constant'] # never used because sign is included in pattern
+    def match(string):
+        return NumberBase.match(pattern.abs_signed_int_literal_constant_named, string)
+    match = staticmethod(match)
+
+class Real_Literal_Constant(NumberBase):
+    """
+    """
+    subclass_names = []
+    def match(string):
+        return NumberBase.match(pattern.abs_real_literal_constant_named, string)
+    match = staticmethod(match)
+
+class Signed_Real_Literal_Constant(NumberBase):
+    """
+    <signed-real-literal-constant> = [ <sign> ] <real-literal-constant>
+    """
+    subclass_names = ['Real_Literal_Constant'] # never used
+    def match(string):
+        return NumberBase.match(pattern.abs_signed_real_literal_constant_named, string)
+    match = staticmethod(match)
+
+class Logical_Literal_Constant(NumberBase):
+    """
+    <logical-literal-constant> = .TRUE. [ _ <kind-param> ]
+                                 | .FALSE. [ _ <kind-param> ]
+    """
+    subclass_names = []
+    def match(string):
+        return NumberBase.match(pattern.abs_logical_literal_constant_named, string)    
+    match = staticmethod(match)
+
+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]=='"':
+            abs_a_n_char_literal_constant_named = pattern.abs_a_n_char_literal_constant_named2
+        else:
+            abs_a_n_char_literal_constant_named = pattern.abs_a_n_char_literal_constant_named1
+        line, repmap = string_replace_map(string)
+        m = abs_a_n_char_literal_constant_named.match(line)
+        if not m: return
+        kind_param = m.group('kind_param')
+        line = m.group('value')
+        for k in Base.findall(line):
+            line = line.replace(k,repmap[k])
+        return line, kind_param
+    match = staticmethod(match)
+    def init(self, value, kind_param):
+        self.value = value
+        self.kind_param = kind_param
+        return
+    def tostr(self):
+        if self.kind_param is None: return str(self.value)
+        return '%s_%s' % (self.kind_param, self.value)
+    def torepr(self):
+        return '%s(%r, %r)' % (self.__class__.__name__, self.value, self.kind_param)
+
+#####
+
     
-class Expr(RBinaryOpBase):
+class Expr(BinaryOpBase):
     """
     <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 = []
-    use_names = ['Expr', 'Level_5_Expr']
+    subclass_names = ['Level_5_Expr']
+    use_names = ['Expr']
     def match(string):
-        return RBinaryOpBase.match(Expr, pattern.defined_binary_op.named(), Level_5_Expr,
+        return BinaryOpBase.match(Expr, pattern.defined_binary_op.named(), Level_5_Expr,
                                    string)
     match = staticmethod(match)
 
-class Level_5_Expr(RBinaryOpBase):
+class Level_5_Expr(BinaryOpBase):
     """
     <level-5-expr> = [ <level-5-expr> <equiv-op> ] <equiv-operand>
     <equiv-op> = .EQV.
                | .NEQV.
     """
-    subclass_names = []
-    use_names = ['Level_5_Expr','Equiv_Operand']
+    subclass_names = ['Equiv_Operand']
+    use_names = ['Level_5_Expr']
     def match(string):
-        return RBinaryOpBase.match(\
+        return BinaryOpBase.match(\
             Level_5_Expr,pattern.equiv_op.named(),Equiv_Operand,string)
     match = staticmethod(match)
     
-class Equiv_Operand(RBinaryOpBase):
+class Equiv_Operand(BinaryOpBase):
     """
     <equiv-operand> = [ <equiv-operand> <or-op> ] <or-operand>
     <or-op>  = .OR.
     """
-    subclass_names = []
-    use_names = ['Equiv_Operand','Or_Operand']
+    subclass_names = ['Or_Operand']
+    use_names = ['Equiv_Operand']
     def match(string):
-        return RBinaryOpBase.match(\
+        return BinaryOpBase.match(\
             Equiv_Operand,pattern.or_op.named(),Or_Operand,string)
     match = staticmethod(match)
     
-class Or_Operand(RBinaryOpBase):
+class Or_Operand(BinaryOpBase):
     """
     <or-operand> = [ <or-operand> <and-op> ] <and-operand>    
     <and-op> = .AND.
     """
-    subclass_names = []
+    subclass_names = ['And_Operand']
     use_names = ['Or_Operand','And_Operand']
     def match(string):
-        return RBinaryOpBase.match(\
+        return BinaryOpBase.match(\
             Or_Operand,pattern.and_op.named(),And_Operand,string)
     match = staticmethod(match)
     
@@ -396,38 +429,38 @@
     <and-operand> = [ <not-op> ] <level-4-expr>
     <not-op> = .NOT.
     """
-    subclass_names = []
-    use_names = ['Level_4_Expr']
+    subclass_names = ['Level_4_Expr']
+    use_names = []
     def match(string):
         return UnaryOpBase.match(\
             pattern.not_op.named(),Level_4_Expr,string)
     match = staticmethod(match)
     
-class Level_4_Expr(RBinaryOpBase):
+class Level_4_Expr(BinaryOpBase):
     """
     <level-4-expr> = [ <level-3-expr> <rel-op> ] <level-3-expr>
     <rel-op> = .EQ. | .NE. | .LT. | .LE. | .GT. | .GE. | == | /= | < | <= | > | >=
     """
-    subclass_names = []
-    use_names = ['Level_3_Expr']
+    subclass_names = ['Level_3_Expr']
+    use_names = []
     def match(string):
-        return RBinaryOpBase.match(\
+        return BinaryOpBase.match(\
             Level_3_Expr,pattern.rel_op.named(),Level_3_Expr,string)
     match = staticmethod(match)
     
-class Level_3_Expr(RBinaryOpBase):
+class Level_3_Expr(BinaryOpBase):
     """
     <level-3-expr> = [ <level-3-expr> <concat-op> ] <level-2-expr>
     <concat-op>    = //
     """
-    subclass_names = []
-    use_names =['Level_3_Expr','Level_2_Expr']
+    subclass_names = ['Level_2_Expr']
+    use_names =['Level_3_Expr']
     def match(string):
-        return RBinaryOpBase.match(\
+        return BinaryOpBase.match(\
             Level_3_Expr,pattern.concat_op.named(),Level_2_Expr,string)
     match = staticmethod(match)
 
-class Level_2_Expr(RBinaryOpBase):
+class Level_2_Expr(BinaryOpBase):
     """
     <level-2-expr> = [ [ <level-2-expr> ] <add-op> ] <add-operand>
     <level-2-expr> = [ <level-2-expr> <add-op> ] <add-operand>
@@ -436,9 +469,9 @@
                  | -
     """
     subclass_names = ['Level_2_Unary_Expr']
-    use_names = ['Level_2_Expr','Add_Operand']
+    use_names = ['Level_2_Expr']
     def match(string):
-        return RBinaryOpBase.match(\
+        return BinaryOpBase.match(\
             Level_2_Expr,pattern.add_op.named(),Add_Operand,string)
     match = staticmethod(match)
 
@@ -446,36 +479,34 @@
     """
     <level-2-unary-expr> = [ <add-op> ] <add-operand>
     """
-    subclass_names = []
-    use_names = ['Add_Operand']
-    def match(string):
-        return UnaryOpBase.match(\
-            pattern.add_op.named(),Add_Operand,string)
+    subclass_names = ['Add_Operand']
+    use_names = []
+    def match(string): return UnaryOpBase.match(pattern.add_op.named(),Add_Operand,string)
     match = staticmethod(match)
 
-class Add_Operand(RBinaryOpBase):
+class Add_Operand(BinaryOpBase):
     """
     <add-operand> = [ <add-operand> <mult-op> ] <mult-operand>
     <mult-op>  = *
                  | /
     """
-    subclass_names = []
+    subclass_names = ['Mult_Operand']
     use_names = ['Add_Operand','Mult_Operand']
     def match(string):
-        return RBinaryOpBase.match(\
+        return BinaryOpBase.match(\
             Add_Operand,pattern.mult_op.named(),Mult_Operand,string)
     match = staticmethod(match)
     
-class Mult_Operand(LBinaryOpBase):
+class Mult_Operand(BinaryOpBase):
     """
     <mult-operand> = <level-1-expr> [ <power-op> <mult-operand> ]
     <power-op> = **
     """
-    subclass_names = []
-    use_names = ['Level_1_Expr','Mult_Operand']
+    subclass_names = ['Level_1_Expr']
+    use_names = ['Mult_Operand']
     def match(string):
-        return LBinaryOpBase.match(\
-            Level_1_Expr,pattern.power_op.named(),Mult_Operand,string)
+        return BinaryOpBase.match(\
+            Level_1_Expr,pattern.power_op.named(),Mult_Operand,string,right=False)
     match = staticmethod(match)
     
 class Level_1_Expr(UnaryOpBase):
@@ -483,10 +514,11 @@
     <level-1-expr> = [ <defined-unary-op> ] <primary>
     <defined-unary-op> = . <letter> [ <letter> ]... .
     """
-    subclass_names = []
-    use_names = ['Primary']
+    subclass_names = ['Primary']
+    use_names = []
     def match(string):
-        if pattern.non_defined_binary_op.match(string): return
+        if pattern.non_defined_binary_op.match(string):
+            raise NoMatchError,`string`
         return UnaryOpBase.match(\
             pattern.defined_unary_op.named(),Primary,string)
     match = staticmethod(match)
@@ -503,7 +535,8 @@
                 | ( <expr> )
     """
     subclass_names = ['Parenthesis', 'Constant', 'Designator','Array_Constructor','Structure_Constructor',
-                      'Function_Reference', 'Type_Param_Inquiry', 'Type_Param_Name']
+                      'Function_Reference', 'Type_Param_Inquiry', 'Type_Param_Name', 
+                       ]
 
 class Type_Param_Name(Base):
     """
@@ -526,8 +559,8 @@
     """
     <structure-constructor-2> = [ <keyword> = ] <component-data-source>
     """
-    subclass_names = []
-    use_names = ['Keyword', 'Component_Data_Source']
+    subclass_names = ['Component_Data_Source']
+    use_names = ['Keyword']
     def match(string): return KeywordValueBase.match(Component_Data_Source, string)
     match = staticmethod(match)
 
@@ -579,8 +612,8 @@
     """
     <component-spec> = [ <keyword> = ] <component-data-source>
     """
-    subclass_names = []
-    use_names = ['Keyword','Component_Data_Source']
+    subclass_names = ['Component_Data_Source']
+    use_names = ['Keyword']
     def match(string): return KeywordValueBase.match(Component_Data_Source, string)
     match = staticmethod(match)
 
@@ -588,8 +621,8 @@
     """
     <component-spec-list> = <component-spec> [ , <component-spec> ]...
     """
-    subclass_names = []
-    use_names = ['Component_Spec']
+    subclass_names = ['Component_Spec']
+    use_names = []
     def match(string): return SequenceBase.match(r',', Component_Spec, string)
     match = staticmethod(match)
 
@@ -646,8 +679,8 @@
     """
     <ac-value-list> = <ac-value> [ , <ac-value> ]...
     """
-    subclass_names = []
-    use_names = ['Ac_Value']
+    subclass_names = ['Ac_Value']
+    use_names = []
     def match(string): return SequenceBase.match(r',', Ac_Value, string)
     match = staticmethod(match)
 
@@ -786,7 +819,7 @@
                       | * <char-length>
     """
     subclass_names = []
-    use_names = ['Scalar_Int_Initialization_Expr','Char_Length']
+    use_names = ['Char_Length','Scalar_Int_Initialization_Expr']
 
     def match(string):
         if string[0]+string[-1] != '()':
@@ -898,28 +931,16 @@
             return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1])
         return '%s(%r, %r, %r)' % (self.__class__.__name__, self.items[0],self.items[1],self.items[2])
 
-class Char_Length(Base):
+class Char_Length(BracketBase):
     """
     <char-length> = ( <type-param-value> )
                     | <scalar-int-literal-constant>
     """
-    subclass_names = []
-    use_names = ['Type_Param_Value','Scalar_Int_Literal_Constant']
-    def match(string):
-        if string[0]+string[-1] == '()':
-            return '(',Type_Param_Value(string[1:-1].strip()),')'
-        return Scalar_Int_Literal_Constant(string),
+    subclass_names = ['Scalar_Int_Literal_Constant']
+    use_names = ['Type_Param_Value']
+    def match(string): return BracketBase.match('()',Type_Param_Value, string)
     match = staticmethod(match)
-    init = Base.init_list
-    def tostr(self):
-        if len(self.items)==1: return str(self.items[0])
-        return '%s%s%s' % tuple(self.items)
-    def torepr(self):
-        if len(self.items)==1:
-            return '%s(%r)' % (self.__class__.__name__, self.items[0])
-        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.items[0],self.items[1],self.items[2])
 
-
 class Scalar_Int_Expr(Base):
     """
     <scalar-int-expr> = <expr>
@@ -939,7 +960,7 @@
                        | :
     """
     subclass_names = ['Scalar_Int_Expr']
-    use_names = ['Scalar_Int_Expr']
+    use_names = []
     def match(string):
         if string in ['*',':']: return string,
         return
@@ -961,8 +982,8 @@
     """
     <type-param-spec> = [ <keyword> = ] <type-param-value>
     """
-    subclass_names = []
-    use_names = ['Keyword','Type_Param_Value']
+    subclass_names = ['Type_Param_Value']
+    use_names = ['Keyword']
     def match(string): return KeywordValueBase.match(Type_Param_Value, string)
     match = staticmethod(match)
 
@@ -970,8 +991,8 @@
     """
     <type-param-spec-list> = <type-param-spec> [ , <type-param-spec> ]...
     """
-    subclass_names = []
-    use_names = ['Type_Param_Spec']
+    subclass_names = ['Type_Param_Spec']
+    use_names = []
     def match(string): return SequenceBase.match(',', Type_Param_Spec, string)
     match = staticmethod(match)
 
@@ -1044,7 +1065,7 @@
     <array-section> = <data-ref> [ ( <substring-range> ) ]
     """
     subclass_names = ['Data_Ref']
-    use_names = ['Data_Ref','Substring_Range']
+    use_names = ['Substring_Range']
     def match(string): return CallBase.match(Data_Ref, Substring_Range, string)
     match = staticmethod(match)
 
@@ -1060,18 +1081,15 @@
         lhs,rhs = line.split(':',1)
         lhs = lhs.rstrip()
         rhs = rhs.lstrip()
+        lhs_obj, rhs_obj = None, None
         if lhs:
             for k in Base.findall(lhs):
                 lhs = lhs.replace(k,repmap[k])
             lhs_obj = Scalar_Int_Expr(lhs)
-        else:
-            lhs_obj = None
         if rhs:
             for k in Base.findall(rhs):
                 rhs = rhs.replace(k,repmap[k])
             rhs_obj = Scalar_Int_Expr(rhs)
-        else:
-            rhs_obj = None
         return lhs_obj, rhs_obj
     match = staticmethod(match)
     def init(self, lhs, rhs):
@@ -1104,47 +1122,13 @@
     subclass_names = ['Int_Literal_Constant', 'Real_Literal_Constant','Complex_Literal_Constant',
                       'Logical_Literal_Constant','Char_Literal_Constant','Boz_Literal_Constant']
 
-class Int_Literal_Constant(NumberBase):
-    """
-    <int-literal-constant> = <digit-string> [ _ <kind-param> ]
-    """
-    subclass_names = []
-    def match(string):
-        return NumberBase.match(pattern.abs_int_literal_constant_named, string)
-    match = staticmethod(match)
-
-class Signed_Int_Literal_Constant(NumberBase):
-    """
-    <signed-int-literal-constant> = [ <sign> ] <int-literal-constant>
-    """
-    subclass_names = ['Int_Literal_Constant'] # never used because sign is included in pattern
-    def match(string):
-        return NumberBase.match(pattern.abs_signed_int_literal_constant_named, string)
-    match = staticmethod(match)
-
 class Scalar_Int_Literal_Constant(Base):
     """
     <scalar-int-literal-constant> = <int-literal-constant>
     """
     subclass_names = ['Int_Literal_Constant']
 
-class Real_Literal_Constant(NumberBase):
-    """
-    """
-    subclass_names = []
-    def match(string):
-        return NumberBase.match(pattern.abs_real_literal_constant_named, string)
-    match = staticmethod(match)
 
-class Signed_Real_Literal_Constant(NumberBase):
-    """
-    <signed-real-literal-constant> = [ <sign> ] <real-literal-constant>
-    """
-    subclass_names = ['Real_Literal_Constant'] # never used
-    def match(string):
-        return NumberBase.match(pattern.abs_signed_real_literal_constant_named, string)
-    match = staticmethod(match)
-
 class Complex_Literal_Constant(Base):
     """
     <complex-literal-constant> = ( <real-part>, <imag-part> )
@@ -1178,43 +1162,7 @@
     """
     subclass_names = ['Signed_Int_Literal_Constant','Signed_Real_Literal_Constant','Named_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]=='"':
-            abs_a_n_char_literal_constant_named = pattern.abs_a_n_char_literal_constant_named2
-        else:
-            abs_a_n_char_literal_constant_named = pattern.abs_a_n_char_literal_constant_named1
-        line, repmap = string_replace_map(string)
-        m = abs_a_n_char_literal_constant_named.match(line)
-        if not m: return
-        kind_param = m.group('kind_param')
-        line = m.group('value')
-        for k in Base.findall(line):
-            line = line.replace(k,repmap[k])
-        return line, kind_param
-    match = staticmethod(match)
-    init = Base.init_list
-    def tostr(self):
-        if self.items[1] is None: return self.items[0]
-        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(NumberBase):
-    """
-    <logical-literal-constant> = .TRUE. [ _ <kind-param> ]
-                                 | .FALSE. [ _ <kind-param> ]
-    """
-    subclass_names = []
-    def match(string):
-        return NumberBase.match(pattern.abs_logical_literal_constant_named, string)    
-    match = staticmethod(match)
-
 class Boz_Literal_Constant(Base):
     """
     <boz-literal-constant> = <binary-constant>
@@ -1237,36 +1185,15 @@
     """
     subclass_names = ['Name']
     
-class Function_Reference(Base):
+class Function_Reference(CallBase):
     """
     <function-reference> = <procedure-designator> ( [ <actual-arg-spec-list> ] )
     """
     subclass_names = []
     use_names = ['Procedure_Designator','Actual_Arg_Spec_List']
     def match(string):
-        if string[-1] != ')': return None
-        line, repmap = string_replace_map(string)
-        i = line.rfind('(')
-        if i == -1: return
-        lhs = line[:i].lstrip()
-        if not lhs: return
-        rhs = line[i+1:-1].strip()
-        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 = Procedure_Designator(lhs)
-        if rhs:
-            rhs_obj = Actual_Arg_Spec_List(rhs)
-        else:
-            rhs_obj = None
-        return lhs_obj,'(',rhs_obj,')'
+        return CallBase.match(Procedure_Designator, Actual_Arg_Spec_List, string)
     match = staticmethod(match)
-    init = Base.init_list
-    def tostr(self):
-        if self.items[2] is None: return '%s()' % (self.items[0])
-        return '%s(%s)' % (self.items[0],self.items[2])
-    torepr = Base.torepr_list
 
 
 class Procedure_Designator(BinaryOpBase):
@@ -1287,7 +1214,7 @@
     <part-ref> = <part-name> [ ( <section-subscript-list> ) ]
     """
     subclass_names = ['Part_Name']
-    use_names = ['Part_Name','Section_Subscript_List']
+    use_names = ['Section_Subscript_List']
     def match(string): return CallBase.match(Part_Name, Section_Subscript_List, string)
     match = staticmethod(match)
 
@@ -1295,8 +1222,8 @@
     """
     <section-subscript-list> = <section-subscript> [ , <section-subscript> ]...
     """
-    subclass_names = []
-    use_names = ['Section_Subscript']
+    subclass_names = ['Section_Subscript']
+    use_names = []
     def match(string): return SequenceBase.match(',', Section_Subscript, string)
     match = staticmethod(match)
 
@@ -1394,8 +1321,8 @@
     """
     <data-ref> = <part-ref> [ % <part-ref> ]...
     """
-    subclass_names = []
-    use_names = ['Part_Ref']
+    subclass_names = ['Part_Ref']
+    use_names = []
     def match(string): return SequenceBase.match('%', Part_Ref, string)
     match = staticmethod(match)
 
@@ -1403,8 +1330,8 @@
     """
     <actual-arg-spec-list> = <actual-arg-spec> [ , <actual-arg-spec> ]...
     """
-    subclass_names = []
-    use_names = ['Actual_Arg_Spec']
+    subclass_names = ['Actual_Arg_Spec']
+    use_names = []
     def match(string): return SequenceBase.match(r',', Actual_Arg_Spec, string)
     match = staticmethod(match)
 
@@ -1412,8 +1339,8 @@
     """
     <actual-arg-spec> = [ <keyword> = ] <actual-arg>
     """
-    subclass_names = []
-    use_names = ['Keyword','Actual_Arg']
+    subclass_names = ['Actual_Arg']
+    use_names = ['Keyword']
     def match(string): return KeywordValueBase.match(Actual_Arg, string)
     match = staticmethod(match)
 
@@ -1423,16 +1350,16 @@
     """
     subclass_names = ['Name']
 
-class Type_Name(Base):
+class Type_Name(Name):
     """
     <type-name> = <name>
     <type-name> shall not be DOUBLEPRECISION or the name of intrinsic type
     """
     subclass_names = []
-    use_names = ['Name']
+    use_names = []
     def match(string):
         if pattern.abs_intrinsic_type_name.match(string): return
-        return Name(string)
+        return Name.match(string)
     match = staticmethod(match)
     
 class Actual_Arg(Base):
@@ -1443,7 +1370,7 @@
                  | <proc-component-ref>
                  | <alt-return-spec>
     """
-    subclass_names = ['Expr','Variable','Procedure_Name','Proc_Component_Ref','Alt_Return_Spec']
+    subclass_names = ['Procedure_Name','Proc_Component_Ref','Alt_Return_Spec', 'Variable', 'Expr']
 
 class Alt_Return_Spec(Base):
     """
@@ -1497,14 +1424,71 @@
 Base_classes = {}
 for clsname in dir():
     cls = eval(clsname)
-    if isinstance(cls, ClassType) and issubclass(cls, Base):
+    if isinstance(cls, ClassType) and issubclass(cls, Base) and not cls.__name__.endswith('Base'):
         Base_classes[cls.__name__] = cls
 
+
+# Optimize subclass_names tree:
+def _rpl_list(clsname):
+    cls = Base_classes[clsname]
+    if cls.__dict__.has_key('match'): return [clsname]
+    l = []
+    for n in getattr(cls,'subclass_names',[]):
+        l1 = _rpl_list(n)
+        for n1 in l1: 
+            if n1 not in l:
+                l.append(n1)
+    return l
+
+for cls in Base_classes.values():
+    if not hasattr(cls, 'subclass_names'): continue
+    opt_subclass_names = []
+    for n in cls.subclass_names:
+        for n1 in _rpl_list(n):
+            if n1 not in opt_subclass_names:  opt_subclass_names.append(n1)
+    if not opt_subclass_names==cls.subclass_names:
+        #print cls.__name__,':',', '.join(cls.subclass_names),'->',', '.join(opt_subclass_names)
+        cls.subclass_names[:] = opt_subclass_names
+    #else:
+    #    print cls.__name__,':',opt_subclass_names
+
+if 0:
+
+    def _deep_subclass_names(clsname, l=[]):
+        cls = Base_classes[clsname]
+        subclass_names = getattr(cls,'subclass_names',[])
+        if clsname not in l:
+            l.append(clsname)
+        for n in subclass_names:
+            if n in l: continue
+            l.append(n)
+            _deep_subclass_names(n,l)
+
+        return l
+
+    Base_deps = {}
+    for cls in Base_classes.values():
+        l = []
+        _deep_subclass_names(cls.__name__,l)
+        Base_deps[cls.__name__] = l
+
+    def _sort_deps(lhs,rhs):
+        if lhs==rhs: return 0
+        rhs_deps = Base_deps[rhs]
+        lhs_deps = Base_deps[lhs]
+        if lhs in rhs_deps: return -1
+        if rhs in lhs_deps: return 1
+        return cmp(len(lhs_deps),len(rhs_deps))
+
+    for clsname,deps in Base_deps.items():
+        deps.sort(_sort_deps)
+        print clsname,deps
+
+# Initialize Base.subclasses dictionary:
 for clsname, cls in Base_classes.items():
     subclass_names = getattr(cls, 'subclass_names', None)
     if subclass_names is None:
-        if clsname[-4:]!='Base':
-            print '%s class is missing subclass_names list' % (clsname)
+        print '%s class is missing subclass_names list' % (clsname)
         continue
     try:
         l = Base.subclasses[clsname]

Modified: trunk/numpy/f2py/lib/parser/test_expressions.py
===================================================================
--- trunk/numpy/f2py/lib/parser/test_expressions.py	2006-10-25 09:05:57 UTC (rev 3396)
+++ trunk/numpy/f2py/lib/parser/test_expressions.py	2006-10-25 10:41:11 UTC (rev 3397)
@@ -72,15 +72,15 @@
 
     def check_char_length(self):
         cls = Char_Length
-        a = cls('1')
-        assert isinstance(a,cls),`a`
-        assert_equal(str(a),'1')
-        assert_equal(repr(a),"Char_Length(Int_Literal_Constant('1', None))")
-
         a = cls('(1)')
         assert isinstance(a,cls),`a`
         assert_equal(str(a),'(1)')
+        assert_equal(repr(a),"Char_Length('(', Int_Literal_Constant('1', None), ')')")
 
+        a = cls('1')
+        assert isinstance(a,Int_Literal_Constant),`a`
+        assert_equal(str(a),'1')
+
         a = cls('(*)')
         assert isinstance(a,cls),`a`
         assert_equal(str(a),'(*)')
@@ -215,7 +215,7 @@
         a = cls('f()')
         assert isinstance(a,cls),`a`
         assert_equal(str(a),'f()')
-        assert_equal(repr(a),"Function_Reference(Name('f'), '(', None, ')')")
+        assert_equal(repr(a),"Function_Reference(Name('f'), None)")
 
         a = cls('f(2,k=1,a)')
         assert isinstance(a,cls),`a`
@@ -302,7 +302,7 @@
         a = cls('t()')
         assert isinstance(a,cls),`a`
         assert_equal(str(a),'t()')
-        assert_equal(repr(a),"Structure_Constructor(Name('t'), None)")
+        assert_equal(repr(a),"Structure_Constructor(Type_Name('t'), None)")
 
         a = cls('t(s=1, a)')
         assert isinstance(a,cls),`a`
@@ -726,7 +726,7 @@
         a = cls('a(b)')
         assert isinstance(a,cls),`a`
         assert_equal(str(a),'a(b)')
-        assert_equal(repr(a),"Derived_Type_Spec(Name('a'), Name('b'))")
+        assert_equal(repr(a),"Derived_Type_Spec(Type_Name('a'), Name('b'))")
 
         a = cls('a(b,c,g=1)')
         assert isinstance(a,cls),`a`
@@ -745,9 +745,9 @@
     def check_simple(self):
         cls = Type_Name
         a = cls('a')
-        assert isinstance(a,Name),`a`
+        assert isinstance(a,cls),`a`
         assert_equal(str(a),'a')
-        assert_equal(repr(a),"Name('a')")
+        assert_equal(repr(a),"Type_Name('a')")
 
         self.assertRaises(NoMatchError,cls,'integer')
         self.assertRaises(NoMatchError,cls,'doubleprecision')




More information about the Numpy-svn mailing list