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

numpy-svn at scipy.org numpy-svn at scipy.org
Sun Oct 22 16:42:53 CDT 2006


Author: pearu
Date: 2006-10-22 16:42:46 -0500 (Sun, 22 Oct 2006)
New Revision: 3378

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: implementingg Fortran expression parser cont.

Modified: trunk/numpy/f2py/lib/parser/expressions.py
===================================================================
--- trunk/numpy/f2py/lib/parser/expressions.py	2006-10-21 09:55:23 UTC (rev 3377)
+++ trunk/numpy/f2py/lib/parser/expressions.py	2006-10-22 21:42:46 UTC (rev 3378)
@@ -1,15 +1,15 @@
 #!/usr/bin/env python
 """
+Fortran expressions.
 
-Copyright 2006 Pearu Peterson all rights reserved,
-Pearu Peterson <pearu at cens.ioc.ee>
+-----
 Permission to use, modify, and distribute this software is given under the
 terms of the NumPy License. See http://scipy.org.
 
 NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
-
-$Date: $
-Pearu Peterson
+Author: Pearu Peterson <pearu at cens.ioc.ee>
+Created: Oct 2006
+-----
 """
 
 import re
@@ -30,103 +30,27 @@
     def __str__(self): return '.%s.' % (self.letters)
     def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.letters)
 
-class NoChildAllowed:
-    pass
-class NoChildAllowedError(Exception):
-    pass
 class NoMatchError(Exception):
     pass
 
+class NoSubClasses:
+    pass
 
-## class Designator(Primary):
-##     """
-##     <designator> = <object-name>
-##                    | <array-element>
-##                    | <array-section>
-##                    | <structure-component>
-##                    | <substring>
-##     <array-element> = <data-ref>
-##     <array-section> = <data-ref> [ ( <substring-range> ) ]
-##     <data-ref> = <part-ref> [ % <part-ref> ]...
-##     <part-ref> = <part-name> [ ( <section-subscript-list> ) ]
-##     <substring> = <parent-string> ( <substring-range> )
-##     <parent-string> = <scalar-variable-name>
-##                       | <array-element>
-##                       | <scalar-structure-component>
-##                       | <scalar-constant>
-##     <substring-range> = [ <scalar-int-expr> ] : [ <scalar-int-expr> ]
-##     <structure-component> = <data-ref>
-##     """
-
-
-
-## class LiteralConstant(Constant):
-##     """
-##     <constant> = <int-literal-constant>
-##                  | <real-literal-constant>
-##                  | <complex-literal-constant>
-##                  | <logical-literal-constant>
-##                  | <char-literal-constant>
-##                  | <boz-literal-constant>
-##     """
-
-## class SignedIntLiteralConstant(LiteralConstant):
-##     """
-##     <signed-int-literal-constant> = [ <sign> ] <int-literal-constant>
-##     <sign> = + | -
-##     """
-##     match = re.compile(r'\A[+-]\s*\d+\Z').match
-
-##     def init(self, string):
-##         Base.init(self, string)
-##         self.content = [string[0], IntLiteralConstant(string[1:].lstrip())]
-##         return
-##     def tostr(self):
-##         return '%s%s' % tuple(self.content)
-
-## class NamedConstant(Constant):
-##     """
-##     <named-constant> = <name>
-##     """
-
-## class Name(Designator, NamedConstant, NoChildAllowed):
-##     """
-##     <name> = <letter> [ <alpha-numeric-character> ]...
-##     """
-##     match = re.compile(r'\A'+name_pat+r'\Z',re.I).match
-
-## class IntLiteralConstant(SignedIntLiteralConstant, NoChildAllowed):
-##     """
-##     <int-literal-constant> = <digit-string> [ _ <kind-param> ]
-##     <kind-param> = <digit-string>
-##                  | <scalar-int-constant-name>
-##     <digit-string> = <digit> [ <digit> ]...
-##     """
-##     match = compose_pattern([digit_string_pat, '_', kind_param_pat],r'\s*')
-
-##     compose_pattern('int-literal-constant','digit-string','_','kind-param')
-
-## class DigitString(IntLiteralConstant, NoChildAllowed):
-##     """
-##     <digit-string> = <digit> [ <digit> ]...
-##     """
-##     match = re.compile(r'\A\d+\Z').match
-
-
 class Base(object):
 
     subclasses = {}
 
     def __new__(cls, string):
-        if hasattr(cls,'match'):
-            match = cls.match
-            result = match(string)
+        match = cls.__dict__.get('match', None)
+        if match is not None:
+            result = cls.match(string)
         else:
             result = None
         if isinstance(result, tuple):
             obj = object.__new__(cls)
             obj.string = string
-            obj.init(*result)
+            if cls.__dict__.has_key('init'):
+                obj.init(*result)
             return obj
         elif isinstance(result, Base):
             return result
@@ -140,6 +64,8 @@
             raise AssertionError,`result`
         raise NoMatchError,'%s: %r' % (cls.__name__, string)
 
+    default_match = staticmethod(lambda string: None)
+
     findall = staticmethod(re.compile(r'(_F2PY_STRING_CONSTANT_\d+_|F2PY_EXPR_TUPLE_\d+)').findall)
     
     def match_binary_operand_right(lhs_cls, op_pattern, rhs_cls, string):
@@ -148,9 +74,9 @@
         if t is None: return
         lhs, op, rhs = t
         for k in Base.findall(lhs):
-            lhs = lhs.replace(k, repman[k])
+            lhs = lhs.replace(k, repmap[k])
         for k in Base.findall(rhs):
-            rhs = rhs.replace(k, repman[k])
+            rhs = rhs.replace(k, repmap[k])
         lhs_obj = lhs_cls(lhs)
         rhs_obj = rhs_cls(rhs)
         return lhs_obj, t[1], rhs_obj
@@ -163,9 +89,9 @@
         lhs, op, rhs = t
         if lhs: 
             for k in Base.findall(lhs):
-                lhs = lhs.replace(k, repman[k])
+                lhs = lhs.replace(k, repmap[k])
         for k in Base.findall(rhs):
-            rhs = rhs.replace(k, repman[k])
+            rhs = rhs.replace(k, repmap[k])
         rhs_obj = rhs_cls(rhs)
         if lhs:
             lhs_obj = lhs_cls(lhs)
@@ -180,9 +106,9 @@
         if t is None: return
         lhs, op, rhs = t
         for k in Base.findall(lhs):
-            lhs = lhs.replace(k, repman[k])
+            lhs = lhs.replace(k, repmap[k])
         for k in Base.findall(rhs):
-            rhs = rhs.replace(k, repman[k])
+            rhs = rhs.replace(k, repmap[k])
         lhs_obj = lhs_cls(lhs)
         rhs_obj = rhs_cls(rhs)
         return lhs_obj, t[1], rhs_obj
@@ -194,12 +120,33 @@
         if t is None: return
         lhs, op, rhs = t
         for k in Base.findall(rhs):
-            rhs = rhs.replace(k, repman[k])
+            rhs = rhs.replace(k, repmap[k])
         assert not lhs,`lhs`
         rhs_obj = rhs_cls(rhs)
         return t[1], rhs_obj
     match_unary_operand = staticmethod(match_unary_operand)
 
+    def match_list_of(subcls, string):
+        line, repmap = string_replace_map(string)
+        lst = []
+        for p in line.split(','):
+            p = p.strip()
+            for k in Base.findall(p):
+                p = p.replace(k,repmap[k])
+            lst.append(subcls(p))
+        return tuple(lst)
+    match_list_of = staticmethod(match_list_of)
+
+    def init_list(self, *items):
+        self.items = items
+        return
+
+    def tostr_list(self):
+        return ', '.join(map(str,self.items))
+
+    def torepr_list(self):
+        return '%s(%s)' % (self.__class__.__name__,', '.join(map(repr,self.items)))
+
     def init_binary_operand(self, lhs, op, rhs):
         self.lhs = lhs
         self.op = op
@@ -229,6 +176,9 @@
     def tostr_primary(self):
         return str(self.primary)
 
+    def tostr_string(self):
+        return str(self.string)
+
     def torepr_binary_operand(self):
         return '%s(%r, %r, %r)' % (self.__class__.__name__,self.lhs, self.op, self.rhs)
 
@@ -241,6 +191,15 @@
     def torepr_primary(self):
         return '%s(%r)' % (self.__class__.__name__,self.primary)
 
+    def torepr_string(self):
+        return '%s(%r)' % (self.__class__.__name__,self.string)
+
+    def tostr_number(self):
+        if self.items[1] is None: return str(self.items[0])
+        return '%s_%s' % (self.items[0],self.items[1])
+    def torepr_number(self):
+        return '%s(%r,%r)' % (self.__class__.__name__, self.items[0],self.items[1])
+
     def __str__(self):
         if self.__class__.__dict__.has_key('tostr'):
             return self.tostr()
@@ -414,33 +373,707 @@
     <type-param-inquiry> = <designator> % <type-param-name>
     """
 
+
+
+class Array_Constructor(Primary):
+    """
+    <array-constructor> = (/ <ac-spec> /)
+                          | <left-square-bracket> <ac-spec> <right-square-bracket>
+
+    """
+    def match(string):
+        if string[:2]+string[-2:]=='(//)':
+            return '(/',Ac_Spec(string[2:-2].strip()),'/)'
+        if string[:1]+string[-1:]=='[]':
+            return '[',Ac_Spec(string[1:-1].strip()),']'
+        return
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self): return ''.join(map(str,self.items))
+    def torepr(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
+
+class Ac_Spec(Base):
+    """
+    <ac-spec> = <type-spec> ::
+                | [ <type-spec> :: ] <ac-value-list>
+    """
+    def match(string):
+        if string.endswith('::'):
+            return Type_Spec(string[:-2].rstrip()),None
+        line, repmap = string_replace_map(string)
+        i = line.find('::')
+        if i==-1:
+            return None, Ac_Value_List(string)
+        ts = line[:i].rstrip()
+        line = line[i+2:].lstrip()
+        for k in Base.findall(ts):
+            ts = ts.replace(k,repmap[k])
+        for k in Base.findall(line):
+            line = line.replace(k,repmap[k])
+        return Type_Spec(ts),Ac_Value_List(line)
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self):
+        if self.items[0] is None:
+            return str(self.items[1])
+        if self.items[1] is None:
+            return str(self.items[0]) + ' ::'
+        return str(self.items[0]) + ' :: ' + str(self.items[1])
+    def torepr(self):
+        return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1])
+
+class Ac_Value_List(Base):
+    """
+    <ac-value-list> = <ac-value> [ , <ac-value> ]...
+    """
+    def match(string):
+        return Base.match_list_of(Ac_Value, string)
+    match = staticmethod(match)
+    init = Base.init_list
+    tostr = Base.tostr_list
+    torepr = Base.torepr_list
+
+class Ac_Value(Base):
+    """
+    <ac-value> = <expr>
+                 | <ac-implied-do>
+    """
+    extra_subclasses = [Expr]
+
+class Ac_Implied_Do(Ac_Value):
+    """
+    <ac-implied-do> = ( <ac-value-list> , <ac-implied-do-control> )
+    """
+    def match(string):
+        if string[0]+string[-1] != '()': return
+        line, repmap = string_replace_map(string[1:-1].strip())
+        i = line.rfind('=')
+        if i==-1: return
+        j = line[:i].rfind(',')
+        assert j!=-1
+        s1 = line[:j].rstrip()
+        s2 = line[j+1:].lstrip()
+        for k in Base.findall(s1):
+            s1 = s1.replace(k,repmap[k])
+        for k in Base.findall(s2):
+            s2 = s2.replace(k,repmap[k])
+        return Ac_Value_List(s1),Ac_Implied_Do_Control(s2)
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self): return '(%s, %s)' % tuple(self.items)
+    def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.items[0],self.items[1])
+
+class Ac_Implied_Do_Control(Base):
+    """
+    <ac-implied-do-control> = <ac-do-variable> = <scalar-int-expr> , <scalar-int-expr> [ , <scalar-int-expr> ]    
+    """
+    def match(string):
+        i = string.find('=')
+        if i==-1: return
+        s1 = string[:i].rstrip()
+        line, repmap = string_replace_map(string[i+1:].lstrip())
+        t = line.split(',')
+        if not (2<=len(t)<=3): return
+        t = [Scalar_Int_Expr(s.strip()) for s in t]
+        return Ac_Do_Variable(s1), t
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self): return '%s = %s' % (self.items[0], ', '.join(map(str,self.items[1])))
+    def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.items[0],self.items[1])
+
+class Scalar_Int_Expr(Base):
+    """
+    <scalar-int-expr> = <expr>
+    """
+    extra_subclasses = [Expr]
+
+class Ac_Do_Variable(Base):
+    """
+    <ac-do-variable> = <scalar-int-variable>
+    <ac-do-variable> shall be a named variable    
+    """
+
+class Type_Spec(Base):
+    """
+    <type-spec> = <intrinsic-type-spec>
+                  | <derived-type-spec>
+    """
+
+class Intrinsic_Type_Spec(Type_Spec):
+    """
+    <intrinsic-type-spec> = INTEGER [ <kind-selector> ]
+                            | REAL [ <kind-selector> ]
+                            | DOUBLE COMPLEX
+                            | COMPLEX [ <kind-selector> ]
+                            | CHARACTER [ <char-selector> ]
+                            | LOGICAL [ <kind-selector> ]
+
+    Extensions:
+                            | DOUBLE PRECISION
+                            | BYTE
+    """
+    def match(string):
+        if string[:7].upper()=='INTEGER':
+            t = string[:7].upper()
+            line = string[7:].lstrip()
+            if line: return t,Kind_Selector(line)
+            return t,None
+        elif string[:4].upper()=='REAL':
+            t = string[:4].upper()
+            line = string[4:].lstrip()
+            if line: return t,Kind_Selector(line)
+            return t,None
+        elif string[:7].upper()=='COMPLEX':
+            t = string[:7].upper()
+            line = string[7:].lstrip()
+            if line: return t,Kind_Selector(line)
+            return t,None
+        elif string[:7].upper()=='LOGICAL':
+            t = string[:7].upper()
+            line = string[7:].lstrip()
+            if line: return t,Kind_Selector(line)
+            return t,None
+        elif string[:9].upper()=='CHARACTER':
+            t = string[:9].upper()
+            line = string[9:].lstrip()
+            if line: return t,Char_Selector(line)
+        elif string[:6].upper()=='DOUBLE':
+            line = string[6:].lstrip().upper()
+            if line=='COMPLEX':
+                return 'DOUBLE COMPLEX',None
+            if line=='PRECISION':
+                return 'DOUBLE PRECISION',None
+        elif string.upper()=='BYTE':
+            return 'BYTE',None
+        return
+    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 Kind_Selector(Base):
+    """
+    <kind-selector> = ( [ KIND = ] <scalar-int-initialization-expr> )
+    Extensions:
+                      | * <char-length>
+    """
+    def match(string):
+        if string[0]+string[-1] != '()':
+            if not string.startswith('*'): return
+            return '*',Char_Length(string[1:].lstrip())
+        line = string[1:-1].strip()
+        if line[:4].upper()=='KIND':
+            line = line[4:].lstrip()
+            if not line.startswith('='): return
+            line = line[1:].lstrip()
+        return '(',Scalar_Int_Initialization_Expr(line),')'
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self):
+        if len(self.items)==2: return '%s%s' % tuple(self.items)
+        return '%sKIND = %s%s' % tuple(self.items)
+    
+    def torepr(self):
+        if len(self.items)==2:
+            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_Selector(Base):
+    """
+    <char-selector> = <length-selector>
+                      | ( LEN = <type-param-value> , KIND = <scalar-int-initialization-expr> )
+                      | ( <type-param-value> , [ KIND = ] <scalar-int-initialization-expr> )
+                      | ( KIND = <scalar-int-initialization-expr> [ , LEN = <type-param-value> ] )
+    """
+    def match(string):
+        if string[0]+string[-1] != '()': return
+        line, repmap = string_replace_map(string[1:-1].strip())
+        if line[:3].upper()=='LEN':
+            line = line[3:].lstrip()
+            if not line.startswith('='): return
+            line = line[1:].lstrip()
+            i = line.find(',')
+            if i==-1: return
+            v = line[:i].rstrip()
+            line = line[i+1:].lstrip()
+            if line[:4].upper()!='KIND': return
+            line = line[4:].lstrip()
+            if not line.startswith('='): return
+            line = line[1:].lstrip()
+            for k in Base.findall(v): v = v.replace(k,repmap[k])
+            for k in Base.findall(line): line = line.replace(k,repmap[k])
+            return Type_Param_Value(v), Scalar_Int_Initialization_Expr(line)
+        elif line[:4].upper()=='KIND':
+            line = line[4:].lstrip()
+            if not line.startswith('='): return
+            line = line[1:].lstrip()
+            i = line.find(',')
+            if i==-1: return None,Scalar_Int_Initialization_Expr(line)
+            v = line[i+1:].lstrip()
+            line = line[:i].rstrip()
+            if v[:3].upper()!='LEN': return
+            v = v[3:].lstrip()
+            if not v.startswith('='): return
+            v = v[1:].lstrip()
+            return Type_Param_Value(v), Scalar_Int_Initialization_Expr(line)
+        else:
+            i = line.find(',')
+            if i==-1: return
+            v = line[:i].rstrip()
+            line = line[i+1:].lstrip()
+            if line[:4].upper()=='KIND':
+                line = line[4:].lstrip()
+                if not line.startswith('='): return
+                line = line[1:].lstrip()
+            return Type_Param_Value(v), Scalar_Int_Initialization_Expr(line)
+        return
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self):
+        if self.items[0] is None:
+            return '(KIND = %s)' % (self.items[1])
+        return '(LEN = %s, KIND = %s)' % (self.items[0],self.items[1])
+    def torepr(self):
+        return '%s(%r, %r)' % (self.__class__.__name__, self.items[0],self.items[1])
+    
+class Lenght_Selector(Char_Selector):
+    """
+    <length-selector> = ( [ LEN = ] <type-param-value> )
+                        | * <char-length> [ , ]
+    """
+    def match(string):
+        if string[0]+string[-1] == '()':
+            line = string[1:-1].strip()
+            if line[:3].upper()=='LEN':
+                line = line[3:].lstrip()
+                if not line.startswith('='): return
+                line = line[1:].lstrip()
+            return '(',Type_Param_Value(line),')'
+        if not string.startswith('*'): return
+        line = string[1:].lstrip()
+        if string[-1]==',': line = line[:-1].rstrip()
+        return '*',Char_Length(line)
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self):
+        if len(self.items)==2: return '%s%s' % tuple(self.items)
+        return '%sLEN = %s%s' % tuple(self.items)
+    def torepr(self):
+        if len(self.items)==2:
+            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):
+    """
+    <char-length> = ( <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),
+    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])
+
+
+Scalar_Int_Expr = Expr
+Scalar_Int_Initialization_Expr = Expr
+
+class Type_Param_Value(Base):
+    """
+    <type-param-value> = <scalar-int-expr>
+                       | *
+                       | :
+    """
+    extra_subclasses = [Scalar_Int_Expr]
+    def match(string):
+        if string in ['*',':']: return string,
+        return
+    match = staticmethod(match)
+    def init(self, value): self.value = value
+    def tostr(self): return str(self.value)
+    def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.value)
+
+class Derived_Type_Spec(Type_Spec):
+    """
+    <derived-type-spec> = <type-name> [ ( <type-param-spec-list> ) ]
+    <type-param-spec> = [ <keyword> = ] <type-param-value>
+    """
+
 class Constant(Primary):
     """
     <constant> = <literal-constant>
                  | <named-constant>
     """
+
+class Designator(Primary):
+    """
+    <designator> = <object-name>
+                   | <array-element>
+                   | <array-section>
+                   | <structure-component>
+                   | <substring>
+    <array-element> = <data-ref>
+    <array-section> = <data-ref> [ ( <substring-range> ) ]
+    <data-ref> = <part-ref> [ % <part-ref> ]...
+    <part-ref> = <part-name> [ ( <section-subscript-list> ) ]
+    <substring> = <parent-string> ( <substring-range> )
+    <parent-string> = <scalar-variable-name>
+                      | <array-element>
+                      | <scalar-structure-component>
+                      | <scalar-constant>
+    <substring-range> = [ <scalar-int-expr> ] : [ <scalar-int-expr> ]
+    <structure-component> = <data-ref>
+    """
+
+
+class Literal_Constant(Constant):
+    """
+    <literal-constant> = <int-literal-constant>
+                         | <real-literal-constant>
+                         | <complex-literal-constant>
+                         | <logical-literal-constant>
+                         | <char-literal-constant>
+                         | <boz-literal-constant>
+    """
+
+class Int_Literal_Constant(Literal_Constant):
+    """
+    <int-literal-constant> = <digit-string> [ _ <kind-param> ]
+    """
     def match(string):
-        if pattern.abs_constant.match(string):
-            return (string,)
+        m = pattern.abs_int_literal_constant_named.match(string)
+        if m is None: return
+        return m.group('value'),m.group('kind_param')
+    match = staticmethod(match)
+    init = Base.init_list
+    tostr = Base.tostr_number
+    torepr = Base.torepr_number
+
+Scalar_Int_Literal_Constant = Int_Literal_Constant
+
+class Real_Literal_Constant(Literal_Constant):
+    """
+    """
+    def match(string):
+        m = pattern.abs_real_literal_constant_named.match(string)
+        if m is None: return
+        return m.group('value'),m.group('kind_param')
+    match = staticmethod(match)
+    init = Base.init_list
+    tostr = Base.tostr_number
+    torepr = Base.torepr_number
+
+class Complex_Literal_Constant(Literal_Constant):
+    """
+    <complex-literal-constant> = ( <real-part>, <imag-part> )
+    <real-part> = <imag-part> = <signed-int-literal-constant>
+                                | <signed-real-literal-constant>
+                                | <named-constant>
+    """
+    def match(string):
+        if string[0]+string[-1]!='()': return
+        if not pattern.abs_complex_literal_constant.match(string):
+            return
+        r,i = string[1:-1].split(',')
+        return Real_Part(r.strip()), Imag_Part(i.strip())
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self): 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 Real_Part(Base):
+    """
+    <real-part> = <signed-int-literal-constant>
+                  | <signed-real-literal-constant>
+                  | <named-constant>
+    """
+    def match(string):
+        clses = [Int_Literal_Constant, Real_Literal_Constant]
+        if string[0] in '+-':
+            sign = string[0]
+            string = string[1:].lstrip()
+
+        else:
+            sign = None
+            clses.append(Named_Constant)
+        obj = None
+        for cls in clses:
+            try:
+                obj = cls(string)
+            except NoMatchError:
+                pass
+        if obj is None:
+            return
+        return sign, obj
+    match = staticmethod(match)
+    init = Base.init_list
+    def tostr(self):
+        if self.items[0] is None: return str(self.items[1])
+        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 Imag_Part(Real_Part):
+    """
+    <imag-part> = <real-part>
+    """
+    match = staticmethod(Real_Part.match)
+    init = Real_Part.init
+    tostr = Real_Part.tostr
+    torepr = Real_Part.torepr
+
+class Char_Literal_Constant(Literal_Constant):
+    """
+    <char-literal-constant> = [ <kind-param> _ ] ' <rep-char> '
+                              | [ <kind-param> _ ] \" <rep-char> \"
+    """
+    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 m is None: 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(Literal_Constant):
+    """
+    <logical-literal-constant> = .TRUE. [ _ <kind-param> ]
+                                 | .FALSE. [ _ <kind-param> ]
+    """
+    def match(string):
+        m = pattern.abs_logical_literal_constant_named.match(string)
+        if m is None: return
+        return m.group('value'), m.group('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[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):
+    """
+    <boz-literal-constant> = <binary-constant>
+                             | <octal-constant>
+                             | <hex-constant>
+    """
+
+
+class Binary_Constant(Boz_Literal_Constant):
+    """
+    <binary-constant> = B ' <digit> [ <digit> ]... '
+                        | B \" <digit> [ <digit> ]... \"
+    """
+    def match(string):
+        if pattern.abs_binary_constant.match(string): return (string,)
         return
     match = staticmethod(match)
-    init = Base.init_primary
-    tostr = Base.tostr_primary
-    torepr = Base.torepr_primary
+    tostr = Base.tostr_string
+    torepr = Base.torepr_string
 
+class Octal_Constant(Boz_Literal_Constant):
+    """
+    <octal-constant> = O ' <digit> [ <digit> ]... '
+                       | O \" <digit> [ <digit> ]... \"
+    """
+    def match(string):
+        if pattern.abs_octal_constant.match(string): return (string,)
+        return
+    match = staticmethod(match)
+    tostr = Base.tostr_string
+    torepr = Base.torepr_string
+
+class Hex_Constant(Boz_Literal_Constant):
+    """
+    <hex-constant> = Z ' <digit> [ <digit> ]... '
+                     | Z \" <digit> [ <digit> ]... \"
+    """
+    def match(string):
+        if pattern.abs_hex_constant.match(string): return (string,)
+        return
+    match = staticmethod(match)
+    tostr = Base.tostr_string
+    torepr = Base.torepr_string
+
+class Named_Constant(Constant):
+    """
+    <named-constant> = <name>
+    """
+
+
+class Object_Name(Designator):
+    """
+    <object-name> = <name>
+    """
+
+class Function_Reference(Primary):
+    """
+    <function-reference> = <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,')'
+    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(Base):
+    """
+    <procedure-designator> = <procedure-name>
+                           | <proc-component-ref>
+                           | <data-ref> % <binding-name>
+    """
+        
+class Actual_Arg_Spec_List(Base):
+    """
+    <actual-arg-spec-list> = <actual-arg-spec> [ , <actual-arg-spec> ]...
+    """
+    def match(string):
+        return Base.match_list_of(Actual_Arg_Spec, string)
+    match = staticmethod(match)
+    init = Base.init_list
+    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>
+    """    
+    def match(string):
+        if pattern.keyword_equal.match(string):
+            i = string.find('=')
+            assert i!=-1,`string`
+            kw = Keyword(string[:i].rstrip())
+            string = string[i+1:].lstrip()
+        else:
+            kw = None
+        return kw, Actual_Arg(string)
+
+    match = staticmethod(match)
+    def init(self,kw,arg):
+        self.keyword = kw
+        self.actual_arg =arg
+        return
+    def tostr(self):
+        if self.keyword is not None:
+            return '%s = %s' % (self.keyword, self.actual_arg)
+        return str(self.actual_arg)
+    def torepr(self):
+        return '%s(%s, %s)' % (self.__class__.__name__, self.keyword, self.actual_arg)
+
+class Keyword(Base):
+    """
+    <keyword> = <name>
+    """
+
+class Actual_Arg(Actual_Arg_Spec):
+    """
+    <actual-arg> = <expr>
+                 | <variable>
+                 | <procedure-name>
+                 | <proc-component-ref>
+                 | <alt-return-spec>
+    <alt-return-spec> = * <label>
+    <variable> = <designator>
+    <proc-component-ref> = <variable> % <procedure-component-name>
+    """
+    extra_subclasses = [Expr]
+    
+class Procedure_Name(Procedure_Designator, Actual_Arg):
+    """
+    <procedure-name> = <name>
+    """
+    
+class Parenthesis(Primary):
+    """
+    ( <expr> )
+    """
+    def match(string):
+        if string[0]+string[-1]=='()':
+            return '(',Expr(string[1:-1].strip()),')'
+        return None
+    match = staticmethod(match)
+    init = Base.init_binary_operand
+    tostr = Base.tostr_binary_operand
+    torepr = Base.torepr_binary_operand
+
+class Name(Object_Name, Named_Constant, Procedure_Name, Keyword, Ac_Do_Variable):
+    """
+    <name> = <letter> [ <alphanumeric_character> ]...
+    """
+    def match(string):
+        if pattern.abs_name.match(string):
+            return string,
+        return
+    match = staticmethod(match)
+    tostr = Base.tostr_string
+    torepr = Base.torepr_string
+    
 ClassType = type(Base)
 for clsname in dir():
     cls = eval(clsname)
     if isinstance(cls, ClassType) and issubclass(cls, Base):
+        extra_subclasses = cls.__dict__.get('extra_subclasses',[])
+        if extra_subclasses:
+            try:
+                l = Base.subclasses[cls.__name__]
+            except KeyError:
+                Base.subclasses[cls.__name__] = l = []
+            l.extend(extra_subclasses)
         for basecls in cls.__bases__:
+            if basecls is Base: continue
             if issubclass(basecls, Base):
                 try:
                     Base.subclasses[basecls.__name__].append(cls)
                 except KeyError:
                     Base.subclasses[basecls.__name__] = [cls]
-
-
-print Constant('a')
-print `Constant('1')`
-print `Base('+1')`
-print `Base('c-1*a/b')`
+#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-21 09:55:23 UTC (rev 3377)
+++ trunk/numpy/f2py/lib/parser/pattern_tools.py	2006-10-22 21:42:46 UTC (rev 3378)
@@ -21,10 +21,13 @@
     ~p1        -> [ <p1> ]
     ~~p1       -> [ <p1> ]...
     ~~~p1      -> <p1> [ <p1> ]...
-    ~~~~p1     -> <p1> [ <p1> ]...
+    ~~~~p1     -> ~~~p1
     abs(p1)    -> whole string match of <p1>
     p1.named(name) -> match of <p1> has name
     p1.match(string) -> return string match with <p1>
+    p1.flags(<re.I,..>)
+    p1.rsplit(..)
+    p1.lsplit(..)
     """
     _special_symbol_map = {'.': '[.]',
                            '*': '[*]',
@@ -41,19 +44,27 @@
                            '}': '\}',
                            '>': '[>]',
                            '<': '[<]',
+                           '=': '[=]'
                            }
 
-    def __init__(self, label, pattern, optional=0):
+    def __init__(self, label, pattern, optional=0, flags=0):
         self.label = label
         self.pattern = pattern
         self.optional = optional
+        self._flags = flags
         return
 
+    def flags(self, *flags):
+        f = self._flags
+        for f1 in flags:
+            f = f | f1
+        return Pattern(self.label, self.pattern, optional=self.optional, flags=f)
+
     def get_compiled(self):
         try:
             return self._compiled_pattern
         except AttributeError:
-            self._compiled_pattern = compiled = re.compile(self.pattern)
+            self._compiled_pattern = compiled = re.compile(self.pattern, self._flags)
             return compiled
 
     def match(self, string):
@@ -69,10 +80,10 @@
         compiled = self.get_compiled()
         t = compiled.split(string)
         if len(t) < 3: return
-        rhs = t[-1]
-        pattern_match = t[-2]
+        rhs = t[-1].strip()
+        pattern_match = t[-2].strip()
         assert abs(self).match(pattern_match),`pattern_match`
-        lhs = ''.join(t[:-2])
+        lhs = (''.join(t[:-2])).strip()
         return lhs, pattern_match, rhs
 
     def lsplit(self, string):
@@ -85,14 +96,14 @@
         compiled = self.get_compiled()
         t = compiled.split(string) # can be optimized
         if len(t) < 3: return
-        lhs = t[0]
-        pattern_match = t[1]
-        rhs = ''.join(t[2:])
+        lhs = t[0].strip()
+        pattern_match = t[1].strip()
+        rhs = (''.join(t[2:])).strip()
         assert abs(self).match(pattern_match),`pattern_match`
         return lhs, pattern_match, rhs
 
     def __abs__(self):
-        return Pattern(self.label, r'\A' + self.pattern+ r'\Z')
+        return Pattern(self.label, r'\A' + self.pattern+ r'\Z',flags=self._flags)
 
     def __repr__(self):
         return '%s(%r, %r)' % (self.__class__.__name__, self.label, self.pattern)
@@ -101,54 +112,61 @@
         label = '( %s OR %s )' % (self.label, other.label)
         if self.pattern==other.pattern:
             pattern = self.pattern
+            flags = self._flags
         else:
             pattern = '(%s|%s)' % (self.pattern, other.pattern)
-        return Pattern(label, pattern)
+            flags = self._flags | other._flags
+        return Pattern(label, pattern, flags=flags)
 
     def __and__(self, other):
         if isinstance(other, Pattern):
             label = '%s%s' % (self.label, other.label)
             pattern = self.pattern + other.pattern
+            flags = self._flags | other._flags
         else:
             assert isinstance(other,str),`other`
             label = '%s%s' % (self.label, other)
             pattern = self.pattern + other
-        return Pattern(label, pattern)
+            flags = self._flags
+        return Pattern(label, pattern, flags=flags)
 
     def __rand__(self, other):
         assert isinstance(other,str),`other`
         label = '%s%s' % (other, self.label)
         pattern = other + self.pattern
-        return Pattern(label, pattern)
+        return Pattern(label, pattern, flags=self._flags)
 
     def __invert__(self):
         if self.optional:
             if self.optional==1:
-                return Pattern(self.label + '...', self.pattern[:-1] + '*', 2)
+                return Pattern(self.label + '...', self.pattern[:-1] + '*', optional=2,flags=self._flags)
             if self.optional==2:
-                return Pattern('%s %s' % (self.label[1:-4].strip(), self.label), self.pattern[:-1] + '+', 3)
+                return Pattern('%s %s' % (self.label[1:-4].strip(), self.label), self.pattern[:-1] + '+',
+                               optional=3, flags=self._flags)
             return self
         label = '[ %s ]' % (self.label)
         pattern = '(%s)?' % (self.pattern)
-        return Pattern(label, pattern, 1)
+        return Pattern(label, pattern, optional=1, flags=self._flags)
 
     def __add__(self, other):
         if isinstance(other, Pattern):
             label = '%s %s' % (self.label, other.label)
             pattern = self.pattern + r'\s*' + other.pattern
+            flags = self._flags | other._flags
         else:
             assert isinstance(other,str),`other`
             label = '%s %s' % (self.label, other)
             other = self._special_symbol_map.get(other, other)
             pattern = self.pattern + r'\s*' + other
-        return Pattern(label, pattern)
+            flags = self._flags
+        return Pattern(label, pattern, flags = flags)
 
     def __radd__(self, other):
         assert isinstance(other,str),`other`
         label = '%s %s' % (other, self.label)
         other = self._special_symbol_map.get(other, other)
         pattern = other + r'\s*' + self.pattern
-        return Pattern(label, pattern)
+        return Pattern(label, pattern, flags=self._flags)
 
     def named(self, name = None):
         if name is None:
@@ -157,45 +175,54 @@
         else:
             label = '<%s>' % (name)
         pattern = '(?P%s%s)' % (label.replace('-','_'), self.pattern)
-        return Pattern(label, pattern)
+        return Pattern(label, pattern, flags=self._flags)
 
     def rename(self, label):
         if label[0]+label[-1]!='<>':
             label = '<%s>' % (label)
-        return Pattern(label, self.pattern, self.optional)
+        return Pattern(label, self.pattern, optional=self.optional, flags=self._flags)
 
 # Predefined patterns
 
-letter = Pattern('<letter>','[a-zA-Z]')
-name = Pattern('<name>', r'[a-zA-Z]\w*')
+letter = Pattern('<letter>','[A-Z]',flags=re.I)
+name = Pattern('<name>', r'[A-Z]\w*',flags=re.I)
 digit = Pattern('<digit>',r'\d')
 underscore = Pattern('<underscore>', '_')
-hex_digit = Pattern('<hex-digit>',r'[\da-fA-F]')
+binary_digit = Pattern('<binary-digit>',r'[01]')
+octal_digit = Pattern('<octal-digit>',r'[0-7]')
+hex_digit = Pattern('<hex-digit>',r'[\dA-F]',flags=re.I)
 
 digit_string = Pattern('<digit-string>',r'\d+')
-hex_digit_string = Pattern('<hex-digit-string>',r'[\da-fA-F]+')
+binary_digit_string = Pattern('<binary-digit-string>',r'[01]+')
+octal_digit_string = Pattern('<octal-digit-string>',r'[0-7]+')
+hex_digit_string = Pattern('<hex-digit-string>',r'[\dA-F]+',flags=re.I)
 
 sign = Pattern('<sign>',r'[+-]')
-exponent_letter = Pattern('<exponent-letter>',r'[ED]')
+exponent_letter = Pattern('<exponent-letter>',r'[ED]',flags=re.I)
 
-alphanumeric_character = Pattern('<alphanumeric-character>','\w') # [a-z0-9_]
+alphanumeric_character = Pattern('<alphanumeric-character>',r'\w') # [A-Z0-9_]
 special_character = Pattern('<special-character>',r'[ =+-*/\()[\]{},.:;!"%&~<>?,\'`^|$#@]')
 character = alphanumeric_character | special_character
 
 kind_param = digit_string | name
+kind_param_named = kind_param.named('kind-param')
 signed_digit_string = ~sign + digit_string
 int_literal_constant = digit_string + ~('_' + kind_param)
 signed_int_literal_constant = ~sign + int_literal_constant
 
-binary_constant = '[Bb]' + ("'" & digit_string & "'" | '"' & digit_string & '"')
-octal_constant = '[Oo]' + ("'" & digit_string & "'" | '"' & digit_string & '"')
-hex_constant = '[Zz]' + ("'" & hex_digit_string & "'" | '"' & hex_digit_string & '"')
+int_literal_constant_named = digit_string.named('value') + ~ ('_' + kind_param_named)
+
+binary_constant = ('B' + ("'" & binary_digit_string & "'" | '"' & binary_digit_string & '"')).flags(re.I)
+octal_constant = ('O' + ("'" & octal_digit_string & "'" | '"' & octal_digit_string & '"')).flags(re.I)
+hex_constant = ('Z' + ("'" & hex_digit_string & "'" | '"' & hex_digit_string & '"')).flags(re.I)
 boz_literal_constant = binary_constant | octal_constant | hex_constant
 
 exponent = signed_digit_string
 significand = digit_string + '.' + ~digit_string | '.' + digit_string
 real_literal_constant = significand + ~(exponent_letter + exponent) + ~ ('_' + kind_param) | \
                         digit_string + exponent_letter + exponent + ~ ('_' + kind_param)
+real_literal_constant_named = (significand + ~(exponent_letter + exponent) |\
+                               digit_string + exponent_letter + exponent).named('value') +  ~ ('_' + kind_param_named)
 signed_real_literal_constant = ~sign + real_literal_constant
 
 named_constant = name
@@ -203,33 +230,59 @@
 imag_part = real_part
 complex_literal_constant = '(' + real_part + ',' + imag_part + ')'
 
-char_literal_constant = ~( kind_param + '_') + "'.*'" | ~( kind_param + '_') + '".*"'
+a_n_rep_char = Pattern('<alpha-numeric-rep-char>',r'\w')
+rep_char = Pattern('<rep-char>',r'.')
+char_literal_constant = ~( kind_param + '_') + ("'" + ~~rep_char + "'" | '"' + ~~rep_char + '"' )
+a_n_char_literal_constant_named1 = ~( kind_param_named + '_') + (~~~("'" + ~~a_n_rep_char + "'" )).named('value')
+a_n_char_literal_constant_named2 = ~( kind_param_named + '_') + (~~~('"' + ~~a_n_rep_char + '"' )).named('value')
 
-logical_literal_constant = '[.](TRUE|FALSE)[.]' + ~ ('_' + kind_param)
+logical_literal_constant = ('[.](TRUE|FALSE)[.]' + ~ ('_' + kind_param)).flags(re.I)
+logical_literal_constant_named = Pattern('<value>',r'[.](TRUE|FALSE)[.]',flags=re.I).named() + ~ ('_' + kind_param_named)
 literal_constant = int_literal_constant | real_literal_constant | complex_literal_constant | logical_literal_constant | char_literal_constant | boz_literal_constant
 constant = literal_constant | named_constant
 int_constant = int_literal_constant | boz_literal_constant | named_constant
 char_constant = char_literal_constant | named_constant
-abs_constant = abs(constant)
 
+
 power_op = Pattern('<power-op>','[*]{2}')
 mult_op = Pattern('<mult-op>','[*/]')
 add_op = Pattern('<add-op>','[+-]')
 concat_op = Pattern('<concat-op>','[/]{}')
-rel_op = Pattern('<rel-op>','([.](EQ|NE|LT|LE|GT|GE)[.])|[=]{2}|/[=]|[<]|[<][=]|[>]|[=][>]')
-not_op = Pattern('<not-op>','[.]NOT[.]')
-and_op = Pattern('<and-op>','[.]AND[.]')
-or_op = Pattern('<or-op>','[.]OR[.]')
-equiv_op = Pattern('<equiv-op>','[.](EQV|NEQV)[.]')
+rel_op = Pattern('<rel-op>','([.](EQ|NE|LT|LE|GT|GE)[.])|[=]{2}|/[=]|[<]|[<][=]|[>]|[=][>]',flags=re.I)
+not_op = Pattern('<not-op>','[.]NOT[.]',flags=re.I)
+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)
 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
 
-defined_unary_op = Pattern('<defined-unary-op>','[.][a-zA-Z]+[.]')
-defined_binary_op = Pattern('<defined-binary-op>','[.][a-zA-Z]+[.]')
+defined_unary_op = Pattern('<defined-unary-op>','[.][A-Z]+[.]',flags=re.I)
+defined_binary_op = Pattern('<defined-binary-op>','[.][A-Z]+[.]',flags=re.I)
 defined_operator = defined_unary_op | defined_binary_op | extended_intrinsic_operator
 
 label = Pattern('<label>','\d{1,5}')
 
+keyword = name
+keyword_equal = keyword + '='
+
+abs_constant = abs(constant)
+abs_literal_constant = abs(literal_constant)
+abs_int_literal_constant = abs(int_literal_constant)
+abs_int_literal_constant_named = abs(int_literal_constant_named)
+abs_real_literal_constant = abs(real_literal_constant)
+abs_real_literal_constant_named = abs(real_literal_constant_named)
+abs_complex_literal_constant = abs(complex_literal_constant)
+abs_logical_literal_constant = abs(logical_literal_constant)
+abs_char_literal_constant = abs(char_literal_constant)
+abs_boz_literal_constant = abs(boz_literal_constant)
+abs_name = abs(name)
+abs_a_n_char_literal_constant_named1 = abs(a_n_char_literal_constant_named1)
+abs_a_n_char_literal_constant_named2 = abs(a_n_char_literal_constant_named2)
+abs_logical_literal_constant_named = abs(logical_literal_constant_named)
+abs_binary_constant = abs(binary_constant)
+abs_octal_constant = abs(octal_constant)
+abs_hex_constant = abs(hex_constant)
+
 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-21 09:55:23 UTC (rev 3377)
+++ trunk/numpy/f2py/lib/parser/test_expressions.py	2006-10-22 21:42:46 UTC (rev 3378)
@@ -4,36 +4,359 @@
 
 from expressions import *
 
-class test_Base(NumpyTestCase):
+class test_Type_Spec(NumpyTestCase):
 
+    def check_kind_selector(self):
+        cls = Kind_Selector
+        a = cls('(1)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(KIND = 1)')
+        assert_equal(repr(a),"Kind_Selector('(', Int_Literal_Constant('1',None), ')')")
+
+        a = cls('(kind=1+2)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(KIND = 1 + 2)')
+
+        a = cls('* 1')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'*1')
+
+    def check_type_param_value(self):
+        cls = Type_Param_Value
+        a = cls('*')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'*')
+        assert_equal(repr(a),"Type_Param_Value('*')")
+
+        a = cls(':')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),':')
+
+        a = cls('1+2')
+        assert isinstance(a,Level_2_Expr),`a`
+        assert_equal(str(a),'1 + 2')
+
+    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)')
+
+        a = cls('(*)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(*)')
+
+        a = cls('(:)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(:)')
+
+    def check_lenght_selector(self):
+        cls = Lenght_Selector
+        a = cls('( len = *)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(LEN = *)')
+        assert_equal(repr(a),"Lenght_Selector('(', Type_Param_Value('*'), ')')")
+
+        a = cls('*2,')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'*2')
+
+    def check_char_selector(self):
+        cls = Char_Selector
+        a = cls('(len=2, kind=8)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(LEN = 2, KIND = 8)')
+        assert_equal(repr(a),"Char_Selector(Int_Literal_Constant('2',None), Int_Literal_Constant('8',None))")
+
+
+        a = cls('(2, kind=8)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(LEN = 2, KIND = 8)')
+
+        a = cls('(2, 8)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(LEN = 2, KIND = 8)')
+        
+        a = cls('(kind=8)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(KIND = 8)')
+
+        a = cls('(kind=8,len=2)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(LEN = 2, KIND = 8)')
+
+    def check_intrinsic_type_spec(self):
+        cls = Intrinsic_Type_Spec
+        a = cls('INTEGER')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'INTEGER')
+        assert_equal(repr(a), "Intrinsic_Type_Spec('INTEGER', None)")
+
+        a = cls('Integer*2')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'INTEGER*2')
+
+        a = cls('real*2')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'REAL*2')
+
+        a = cls('logical*2')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'LOGICAL*2')
+
+        a = cls('complex*2')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'COMPLEX*2')
+
+        a = cls('character*2')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'CHARACTER*2')
+
+        a = cls('double complex')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'DOUBLE COMPLEX')
+
+        a = cls('double precision')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'DOUBLE PRECISION')
+    
+class test_Array_Constructor(NumpyTestCase):
+
+    def check_ac_implied_do_control(self):
+        cls = Ac_Implied_Do_Control
+        a = cls('n = 3, 5')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'n = 3, 5')
+        assert_equal(repr(a),"Ac_Implied_Do_Control(Name('n'), [Int_Literal_Constant('3',None), Int_Literal_Constant('5',None)])")
+
+        a = cls('n = 3+1, 5, 1')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'n = 3 + 1, 5, 1')
+
+    def check_ac_value_list(self):
+        cls = Ac_Value_List
+        a = cls('a, b')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'a, b')
+        assert_equal(repr(a),"Ac_Value_List(Name('a'), Name('b'))")
+
+        a = cls('a')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'a')
+        
+    def check_ac_implied_do(self):
+        cls = Ac_Implied_Do
+        a = cls('( a, b, n = 1, 5 )')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(a, b, n = 1, 5)')
+        assert_equal(repr(a),"Ac_Implied_Do(Ac_Value_List(Name('a'), Name('b')), Ac_Implied_Do_Control(Name('n'), [Int_Literal_Constant('1',None), Int_Literal_Constant('5',None)]))")
+
+    def check_ac_spec(self):
+        cls = Ac_Spec
+        a = cls('integer ::')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'INTEGER ::')
+        assert_equal(repr(a),"Ac_Spec(Intrinsic_Type_Spec('INTEGER', None), None)")
+
+        a = cls('integer :: a,b')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'INTEGER :: a, b')
+
+        a = cls('a,b')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'a, b')
+
+        a = cls('integer :: a, (a, b, n = 1, 5)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'INTEGER :: a, (a, b, n = 1, 5)')
+
+class test_Constant(NumpyTestCase):
+
     def check_name(self):
         a = Name('a')
         assert isinstance(a,Name),`a`
+        a = Name('a2')
+        assert isinstance(a,Name),`a`
         a = Designator('a')
         assert isinstance(a,Name),`a`
         a = Constant('a')
         assert isinstance(a,Name),`a`
-        a = Base('a')
+        a = Expr('a')
         assert isinstance(a,Name),`a`
-        a = NamedConstant('a')
-        assert isinstance(a,Name),`a`
-        a = Constant('a')
-        assert isinstance(a,Name),`a`
 
     def check_int_literal_constant(self):
-        a = IntLiteralConstant('1')
-        assert isinstance(a,IntLiteralConstant),`a`
-        a = LiteralConstant('1')
-        assert isinstance(a,IntLiteralConstant),`a`
-        a = Constant('1')
-        assert isinstance(a,IntLiteralConstant),`a`
-        a = Base('1')
-        assert isinstance(a,IntLiteralConstant),`a`
-        a = Base('+1')
-        assert isinstance(a,SignedIntLiteralConstant),`a`
-        a = IntLiteralConstant('0')
-        assert isinstance(a,IntLiteralConstant),`a`
-        #a = NamedConstant('1') # raise NoMatch error
+        cls = Int_Literal_Constant
+        a = cls('1')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'1')
+        assert_equal(repr(a),"%s('1',None)" % (cls.__name__))
 
+        a = cls('21_2')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'21_2')
+        assert_equal(repr(a),"%s('21','2')" % (cls.__name__))
+
+        a = cls('21_SHORT')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'21_SHORT')
+
+        a = cls('21_short')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'21_short')
+
+        a = cls('1976354279568241_8')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'1976354279568241_8')
+
+    def check_real_literal_constant(self):
+        cls = Real_Literal_Constant
+        a = cls('12.78')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'12.78')
+        assert_equal(repr(a),"%s('12.78',None)" % (cls.__name__))
+
+        a = cls('12.78_8')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'12.78_8')
+        assert_equal(repr(a),"%s('12.78','8')" % (cls.__name__))
+
+        a = cls('12.')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'12.')
+
+        a = cls('1.6E3')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'1.6E3')
+
+        a = cls('1.6E3_8')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'1.6E3_8')
+
+        a = cls('1.6D3')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'1.6D3')
+
+        a = cls('1.6E-3')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'1.6E-3')
+        a = cls('1.6E+3')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'1.6E+3')
+
+        a = cls('3E4')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'3E4')
+
+        a = cls('.123')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'.123')
+
+        a = cls('1.6E-3')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'1.6E-3')
+
+        a = cls('10.9E7_QUAD')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'10.9E7_QUAD')
+
+        a = cls('10.9e-17_quad')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'10.9e-17_quad')
+
+    def check_complex_literal_constant(self):
+        cls = Complex_Literal_Constant
+        a = cls('(1.0, -1.0)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(1.0, -1.0)')
+        assert_equal(repr(a),"%s(Real_Part(None, Real_Literal_Constant('1.0',None)), Imag_Part('-', Real_Literal_Constant('1.0',None)))" % (cls.__name__))
+
+        a = cls('(3,3.1E6)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(3, 3.1E6)')
+
+        a = cls('(4.0_4, 3.6E7_8)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(4.0_4, 3.6E7_8)')
+
+        a = cls('( 0., PI)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'(0., PI)')
+
+    def check_char_literal_constant(self):
+        cls = Char_Literal_Constant
+        a = cls('NIH_"DO"')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'NIH_"DO"')
+        assert_equal(repr(a),'Char_Literal_Constant(\'"DO"\', \'NIH\')')
+
+        a = cls("'DO'")
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),"'DO'")
+        assert_equal(repr(a),'Char_Literal_Constant("\'DO\'", None)')
+
+        a = cls("'DON''T'")
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),"'DON''T'")
+
+        a = cls('"DON\'T"')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'"DON\'T"')
+
+        a = cls('""')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'""')
+
+        a = cls("''")
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),"''")
+
+        a = cls('"hey ha(ada)\t"')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'"hey ha(ada)\t"')
+
+    def check_logical_literal_constant(self):
+        cls = Logical_Literal_Constant
+        a = cls('.TRUE.')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'.TRUE.')
+        assert_equal(repr(a),"%s('.TRUE.', None)" % (cls.__name__))
+
+        a = cls('.True.')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'.True.')
+
+        a = cls('.FALSE.')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'.FALSE.')
+
+        a = cls('.TRUE._HA')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'.TRUE._HA')
+
+    def check_boz_literal_constant(self):
+        cls = Boz_Literal_Constant
+        bcls = Binary_Constant
+        a = cls('B"01"')
+        assert isinstance(a,bcls),`a`
+        assert_equal(str(a),'B"01"')
+        assert_equal(repr(a),"%s('B\"01\"')" % (bcls.__name__))
+
+        ocls = Octal_Constant
+        a = cls('O"017"')
+        assert isinstance(a,ocls),`a`
+        assert_equal(str(a),'O"017"')
+        assert_equal(repr(a),"%s('O\"017\"')" % (ocls.__name__))
+
+        zcls = Hex_Constant
+        a = cls('Z"01A"')
+        assert isinstance(a,zcls),`a`
+        assert_equal(str(a),'Z"01A"')
+        assert_equal(repr(a),"%s('Z\"01A\"')" % (zcls.__name__))
+    
 if __name__ == "__main__":
     NumpyTest().run()



More information about the Numpy-svn mailing list