[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