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

numpy-svn at scipy.org numpy-svn at scipy.org
Sat Dec 23 07:56:43 CST 2006


Author: pearu
Date: 2006-12-23 07:56:35 -0600 (Sat, 23 Dec 2006)
New Revision: 3490

Modified:
   trunk/numpy/f2py/lib/parser/Fortran2003.py
   trunk/numpy/f2py/lib/parser/pattern_tools.py
   trunk/numpy/f2py/lib/parser/test_Fortran2003.py
Log:
Cont. implementing F2000 parser.

Modified: trunk/numpy/f2py/lib/parser/Fortran2003.py
===================================================================
--- trunk/numpy/f2py/lib/parser/Fortran2003.py	2006-12-23 07:08:57 UTC (rev 3489)
+++ trunk/numpy/f2py/lib/parser/Fortran2003.py	2006-12-23 13:56:35 UTC (rev 3490)
@@ -99,23 +99,21 @@
 ##         self._item.reader.put_item(self._item)
 ##         return
 
-    def init_list(self, *items):
+    def init(self, *items):
         self.items = items
         return
+    def torepr(self):
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
+    def compare(self, other):
+        return cmp(self.items,other.items)
 
-    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 __str__(self): return self.tostr()
 
     def __repr__(self): return self.torepr()
 
     def __cmp__(self, other):
         if self is other: return 0
-        if not isinstance(other, self.__class__): return -1
+        if not isinstance(other, self.__class__): return cmp(self.__class__, other.__class__)
         return self.compare(other)
 
     def tofortran(self, tab='', isfix=None):
@@ -184,19 +182,22 @@
             # check names of start and end statements:
             start_stmt = content[0]
             end_stmt = content[-1]
-            if isinstance(end_stmt, endcls) and hasattr(end_stmt, 'name') and hasattr(start_stmt, 'name'):
-                if end_stmt.name is not None:
-                    if start_stmt.name != end_stmt.name:
+            if isinstance(end_stmt, endcls) and hasattr(end_stmt, 'get_name') and hasattr(start_stmt, 'get_name'):
+                if end_stmt.get_name() is not None:
+                    if start_stmt.get_name() != end_stmt.get_name():
                         end_stmt._item.reader.error('expected <%s-name> is %s but got %s. Ignoring.'\
-                                                    % (end_stmt.type.lower(), start_stmt.name, end_stmt.name))
+                                                    % (end_stmt.get_type().lower(), start_stmt.get_name(), end_stmt.get_name()))
                 else:
-                    end_stmt.name = start_stmt.name
+                    end_stmt.set_name(start_stmt.get_name())
         return content,
     match = staticmethod(match)
 
     def init(self, content):
         self.content = content
         return
+    def compare(self, other):
+        return cmp(self.content,other.content)
+
     def tostr(self):
         return self.tofortran()
     def torepr(self):
@@ -258,14 +259,8 @@
     """
     <unary-op-base> = <unary-op> <rhs>
     """
-    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)
+        return '%s %s' % tuple(self.items)
     def match(op_pattern, rhs_cls, string):
         m = op_pattern.match(string)
         if not m: return
@@ -275,9 +270,8 @@
         op = string[:m.end()].rstrip().upper()
         return op, rhs_cls(rhs)
     match = staticmethod(match)
-    def compare(self, other):
-        return cmp((self.op,self.rhs),(other.op,other.rhs))
 
+
 class BinaryOpBase(Base):
     """
     <binary-op-base> = <lhs> <op> <rhs>
@@ -309,17 +303,8 @@
         rhs_obj = rhs_cls(repmap(rhs))
         return lhs_obj, op, 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)
-    def compare(self, other):
-        return cmp((self.op,self.lhs,self.rhs),(other.op,other.lhs,other.rhs))
+        return '%s %s %s' % tuple(self.items)
 
 class SeparatorBase(Base):
     """
@@ -344,9 +329,6 @@
             return
         return lhs_obj, rhs_obj
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
-        return
     def tostr(self):
         s = ''
         if self.items[0] is not None:
@@ -356,7 +338,6 @@
         if self.items[1] is not None:
             s += ' %s' % (self.items[1])
         return s
-    def torepr(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
 
 class KeywordValueBase(Base):
     """
@@ -386,40 +367,31 @@
             return lhs, rhs_cls(rhs)
         return lhs_cls(lhs),rhs_cls(rhs)
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
-        return
     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(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
 
 class BracketBase(Base):
     """
     <bracket-base> = <left-bracket-base> <something> <right-bracket>
     """
-    def match(brackets, cls, string):
+    def match(brackets, cls, string, require_cls=True):
         i = len(brackets)/2
         left = brackets[:i]
         right = brackets[-i:]
         if string.startswith(left) and string.endswith(right):
             line = string[i:-i].strip()
-            if not line: return
+            if not line:
+                if require_cls:
+                    return
+                return left,None,right
             return left,cls(line),right
         return
     match = staticmethod(match)
-    def init(self,left,item,right):
-        self.left = left
-        self.item = item
-        self.right = right
-        return
     def tostr(self):
-        if self.item is None:
-            return '%s%s' % (self.left, self.right)
-        return '%s%s%s' % (self.left, self.item, self.right)
-    def torepr(self): return '%s(%r, %r, %r)' % (self.__class__.__name__, self.left, self.item, self.right)
-    def compare(self, other):
-        return cmp((self.left,self.item,self.right),(other.left,other.item,other.right))
+        if self.items[1] is None:
+            return '%s%s' % (self.items[0], self.items[2])
+        return '%s%s%s' % tuple(self.items)
 
 class NumberBase(Base):
     """
@@ -430,17 +402,11 @@
         if m is None: return
         return m.group('value').upper(),m.group('kind_param')
     match = staticmethod(match)
-    def init(self, value, kind_param):
-        self.value = value
-        self.kind_param = kind_param
-        return
     def tostr(self):
-        if self.kind_param is None: return str(self.value)
-        return '%s_%s' % (self.value, self.kind_param)
-    def torepr(self):
-        return '%s(%r, %r)' % (self.__class__.__name__, self.value, self.kind_param)
+        if self.items[1] is None: return str(self.items[0])
+        return '%s_%s' % tuple(self.items)
     def compare(self, other):
-        return cmp(self.value, other.value)
+        return cmp(self.items[0], other.items[0])
 
 class CallBase(Base):
     """
@@ -472,15 +438,9 @@
             return
         return lhs, None
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
-        return
     def tostr(self):
         if self.items[1] is None: return '%s()' % (self.items[0])
         return '%s(%s)' % (self.items[0], self.items[1])
-    def torepr(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
-    def compare(self, other):
-        return cmp(self.items,other.items)
 
 class CALLBase(CallBase):
     """
@@ -577,19 +537,21 @@
         return stmt_type, None
     match = staticmethod(match)
     def init(self, stmt_type, stmt_name):
+        self.items = [stmt_type, stmt_name]
         self.type, self.name = stmt_type, stmt_name
         return
+    def get_name(self): return self.items[1]
+    def get_type(self): return self.items[0]
+    def set_name(self, name):
+        self.items[1] = name
     def tostr(self):
-        if self.name is not None:
-            return 'END %s %s' % (self.type, self.name)
-        return 'END %s' % (self.type)
+        if self.items[1] is not None:
+            return 'END %s %s' % tuple(self.items)
+        return 'END %s' % (self.items[0])
     def torepr(self):
         return '%s(%r, %r)' % (self.__class__.__name__, self.type, self.name)
-    def compare(self, other):
-        return cmp((self.type,self.name),(other.type,other.name))
 
-def _ensure_single_spaces(string):
-    return ' '.join([s for s in string.split(' ') if s])
+def isalnum(c): return c.isalnum() or c=='_'
 
 class WORDClsBase(Base):
     """
@@ -608,8 +570,10 @@
             if string[:len(pattern)].upper()!=pattern: return
             line = string[len(pattern):]
             if not line: return pattern, None
-            if 'a'<=line[0].lower()<='z' or line[0]=='_': return
+            if isalnum(line[0]): return
             line = line.lstrip()
+            if check_colons and line.startswith('::'):
+                line = line[2:].lstrip()
             if not line:
                 if require_cls: return
                 return pattern, None
@@ -623,24 +587,25 @@
         else:
             pattern_value = m.group().upper()
         if not line: return pattern_value, None
-        if 'a'<=line[0].lower()<='z' or line[0]=='_': return
+        if isalnum(line[0]): return
         line = line.lstrip()
+        if check_colons and line.startswith('::'):
+            line = line[2:].lstrip()
         if not line:
             if require_cls: return
             return pattern_value, None
         if cls is None: return
         return pattern_value, cls(line)
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
-        return
     def tostr(self):
         if self.items[1] is None: return str(self.items[0])
         s = str(self.items[1])
         if s and s[0] in '(*':
             return '%s%s' % (self.items[0], s)
         return '%s %s' % (self.items[0], s)
-    def torepr(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
+    def tostr_a(self): # colons version of tostr
+        if self.items[1] is None: return str(self.items[0])
+        return '%s :: %s' % (self.items[0], self.items[1])
 
 ###############################################################################
 ############################### SECTION  1 ####################################
@@ -1041,15 +1006,9 @@
             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 Signed_Int_Literal_Constant(NumberBase): # R405
     """
@@ -1145,11 +1104,7 @@
         r,i = string[1:-1].split(',')
         return Real_Part(r.strip()), Imag_Part(i.strip())
     match = staticmethod(match)
-    def init(self,real,imag):
-        self.real, self.imag = real, imag
-        return
-    def tostr(self): return '(%s, %s)' % (self.real, self.imag)
-    def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.real, self.imag)
+    def tostr(self): return '(%s, %s)' % tuple(self.items)
 
 class Real_Part(Base): # R422
     """
@@ -1217,13 +1172,10 @@
             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 Length_Selector(Base): # R425
     """
@@ -1245,14 +1197,9 @@
         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(BracketBase): # R426
     """
@@ -1285,15 +1232,9 @@
         line = repmap(line)
         return line, kind_param
     match = staticmethod(match)
-    def init(self, value, kind_param):
-        self.value = value
-        self.kind_param = kind_param
-        return
     def tostr(self):
-        if self.kind_param is None: return str(self.value)
-        return '%s_%s' % (self.kind_param, self.value)
-    def torepr(self):
-        return '%s(%r, %r)' % (self.__class__.__name__, self.value, self.kind_param)
+        if self.items[1] is None: return str(self.items[0])
+        return '%s_%s' % (self.items[1], self.items[0])
 
 class Logical_Literal_Constant(NumberBase): # R428
     """
@@ -1343,8 +1284,6 @@
         if line[0]+line[-1]!='()': return
         return attr_specs, name, Type_Param_Name_List(line[1:-1].strip())
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
     def tostr(self):
         s = 'TYPE'
         if self.items[0] is not None:
@@ -1354,7 +1293,6 @@
         if self.items[2] is not None:
             s += '(%s)' % (self.items[2])
         return s
-    def torepr(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
 
 class Type_Name(Name): # C424
     """
@@ -1368,38 +1306,25 @@
         return Name.match(string)
     match = staticmethod(match)
 
-class Type_Attr_Spec(Base): # R431
+class Type_EXTENDS_Parent_Type_Name(CALLBase):
     """
+    <..> = EXTENDS ( <parent-type-name> )
+    """
+    subclass_names = []
+    use_names = ['Parent_Type_Name']
+    def match(string): return CALLBase.match('EXTENDS', Parent_Type_Name, string)
+    match = staticmethod(match)
+
+class Type_Attr_Spec(STRINGBase): # R431
+    """
     <type-attr-spec> = <access-spec>
                        | EXTENDS ( <parent-type-name> )
                        | ABSTRACT
                        | BIND (C)
     """
-    subclass_names = ['Access_Spec']
-    use_names = ['Parent_Type_Name']
-    def match(string):
-        if len(string)==8 and string.upper()=='ABSTRACT': return 'ABSTRACT',None
-        if string[:4].upper()=='BIND':
-            line = string[4:].lstrip()
-            if not line: return
-            if line[0]+line[-1]!='()': return
-            if line[1:-1].strip().upper()=='C': return 'BIND','C'
-            return
-        if string[:7].upper()=='EXTENDS':
-            line = string[7:].lstrip()
-            if not line: return
-            if line[0]+line[-1]!='()': return
-            line = line[1:-1].strip()
-            if not line: return
-            return 'EXTENDS', Parent_Type_Name(line)
+    subclass_names = ['Access_Spec', 'Type_EXTENDS_Parent_Type_Name', 'Language_Binding_Spec']
+    def match(string): return STRINGBase.match('ABSTRACT', string)
     match = staticmethod(match)
-    def init(self,*args):
-        self.items = args
-    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(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
 
 class Private_Or_Sequence(Base): # R432
     """
@@ -1447,19 +1372,14 @@
         if kind_selector: kind_selector = Kind_Selector(kind_selector)
         return kind_selector, Type_Param_Attr_Spec(l1), Type_Param_Decl_List(l2)
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
     def tostr(self):
         s = 'INTEGER'
         if self.items[0] is not None:
-            s += '%s, %s :: %s' % (self.items[0], self.items[1], self.items[2])
+            s += '%s, %s :: %s' % tuple(self.items)
         else:
-            s += ', %s :: %s' % (self.items[1], self.items[2])
+            s += ', %s :: %s' % tuple(self.items[1:])
         return s
-    def torepr(self):
-        return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))        
 
-
 class Type_Param_Decl(BinaryOpBase): # R436
     """
     <type-param-decl> = <type-param-name> [ = <scalar-int-initialization-expr> ]
@@ -1584,9 +1504,6 @@
             assert newline=='',`newline`
         return name, array_spec, char_length, init
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
-        return
     def tostr(self):
         s = str(self.items[0])
         if self.items[1] is not None:
@@ -1596,8 +1513,6 @@
         if self.items[3] is not None:
             s += ' ' + str(self.items[3])
         return s
-    def torepr(self):
-        return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
 
 class Component_Array_Spec(Base): # R443
     """
@@ -1620,13 +1535,9 @@
             return '=', Initialization_Expr(string[2:].lstrip())
         return
     match = staticmethod(match)
-    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 tostr(self): return '%s %s' % tuple(self.items)
 
+
 class Proc_Component_Def_Stmt(StmtBase): # R445
     """
     <proc-component-def-stmt> = PROCEDURE ( [ <proc-interface> ] ) , <proc-component-attr-spec-list> :: <proc-decl-list>
@@ -1634,21 +1545,33 @@
     subclass_names = []
     use_names = ['Proc_Interface', 'Proc_Component_Attr_Spec_List', 'Proc_Decl_List']
 
-class Proc_Component_Attr_Spec(Base): # R446
+class Proc_Component_PASS_Arg_Name(CALLBase):
     """
+    <proc-component-PASS-arg-name> = PASS ( <arg-name> )
+    """
+    subclass_names = []
+    use_names = ['Arg_Name']
+    def match(string): return CALLBase.match('PASS', Arg_Name, string)
+    match = staticmethod(match)
+
+class Proc_Component_Attr_Spec(STRINGBase): # R446
+    """
     <proc-component-attr-spec> = POINTER
                                  | PASS [ ( <arg-name> ) ]
                                  | NOPASS
                                  | <access-spec>
     """
-    subclass_names = []
-    use_names = ['Arg_Name', 'Access_Spec']
+    subclass_names = ['Access_Spec', 'Proc_Component_PASS_Arg_Name']
+    def match(string): return STRINGBase.match(['POINTER','PASS','NOPASS'], string)
+    match = staticmethod(match)
 
 class Private_Components_Stmt(StmtBase): # R447
     """
     <private-components-stmt> = PRIVATE
     """
     subclass_names = []
+    def match(string): return StringBase.match('PRIVATE', string)
+    match = staticmethod(match)
 
 class Type_Bound_Procedure_Part(Base): # R448
     """
@@ -1660,11 +1583,13 @@
     subclass_names = []
     use_names = ['Contains_Stmt', 'Binding_Private_Stmt', 'Proc_Binding_Stmt']
 
-class Binding_Private_Stmt(StmtBase): # R449
+class Binding_Private_Stmt(StmtBase, STRINGBase): # R449
     """
     <binding-private-stmt> = PRIVATE
     """
     subclass_names = []
+    def match(string): return StringBase.match('PRIVATE', string)
+    match = staticmethod(match)
 
 class Proc_Binding_Stmt(Base): # R450
     """
@@ -1674,36 +1599,49 @@
     """
     subclass_names = ['Specific_Binding', 'Generic_Binding', 'Final_Binding']
 
-class Specific_Binding(Base): # R451
+class Specific_Binding(StmtBase): # R451
     """
     <specific-binding> = PROCEDURE [ ( <interface-name> ) ] [ [ , <binding-attr-list> ] :: ] <binding-name> [ => <procedure-name> ]
     """
     subclass_names = []
     use_names = ['Interface_Name', 'Binding_Attr_List', 'Binding_Name', 'Procedure_Name']
 
-class Generic_Binding(Base): # R452
+class Generic_Binding(StmtBase): # R452
     """
     <generic-binding> = GENERIC [ , <access-spec> ] :: <generic-spec> => <binding-name-list>
     """
     subclass_names = []
     use_names = ['Access_Spec', 'Generic_Spec', 'Binding_Name_List']
 
-class Binding_Attr(Base): # R453
+class Binding_PASS_Arg_Name(CALLBase):
     """
+    <binding-PASS-arg-name> = PASS ( <arg-name> )
+    """
+    subclass_names = []
+    use_names = ['Arg_Name']
+    def match(string): return CALLBase.match('PASS', Arg_Name, string)
+    match = staticmethod(match)
+
+class Binding_Attr(STRINGBase): # R453
+    """
     <binding-attr> = PASS [ ( <arg-name> ) ]
                      | NOPASS
                      | NON_OVERRIDABLE
                      | <access-spec>
     """
-    subclass_names = []
-    use_names = ['Arg_Name', 'Access_Spec']
+    subclass_names = ['Access_Spec', 'Binding_PASS_Arg_Name']
+    def match(string): return STRINGBase.match(['PASS', 'NOPASS', 'NON_OVERRIDABLE'], string)
+    match = staticmethod(match)
 
-class Final_Binding(Base): # R454
+class Final_Binding(StmtBase, WORDClsBase): # R454
     """
     <final-binding> = FINAL [ :: ] <final-subroutine-name-list>
     """
     subclass_names = []
     use_names = ['Final_Subroutine_Name_List']
+    def match(string): return WORDClsBase.match('FINAL',Final_Subroutine_Name_List,string,check_colons=True, require_cls=True)
+    match = staticmethod(match)
+    tostr = WORDClsBase.tostr_a
 
 class Derived_Type_Spec(CallBase): # R455
     """
@@ -1769,18 +1707,33 @@
     subclass_names = []
     use_names = ['Enum_Def_Stmt', 'Enumerator_Def_Stmt', 'End_Enum_Stmt']
 
-class Enum_Def_Stmt(StmtBase): # R461
+class Enum_Def_Stmt(STRINGBase): # R461
     """
     <enum-def-stmt> = ENUM, BIND(C)
     """
     subclass_names = []
+    def match(string):
+        if string[:4].upper()!='ENUM': return
+        line = string[4:].lstrip()
+        if not line.startswith(','): return
+        line = line[1:].lstrip()
+        if line[:4].upper()!='BIND': return
+        line = line[4:].lstrip()
+        if not line or line[0]+line[-1]!='()': return
+        line = line[1:-1].strip()
+        if line!='C' or line!='c': return
+        return 'ENUM, BIND(C)',
+    match = staticmethod(match)
 
-class Enumerator_Def_Stmt(StmtBase): # R462
+class Enumerator_Def_Stmt(StmtBase, WORDClsBase): # R462
     """
     <enumerator-def-stmt> = ENUMERATOR [ :: ] <enumerator-list>
     """
     subclass_names = []
     use_names = ['Enumerator_List']
+    def match(string): return WORDClsBase.match('ENUMERATOR',Enumerator_List,string,check_colons=True, require_cls=True)
+    match = staticmethod(match)
+    tostr = WORDClsBase.tostr_a
 
 class Enumerator(BinaryOpBase): # R463
     """
@@ -1839,15 +1792,12 @@
         line = repmap(line)
         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])
+        return '%s :: %s' % self.items
 
 # R467: <left-square-bracket> = [
 # R468: <right-square-bracket> = ]
@@ -1876,9 +1826,7 @@
         s2 = repmap(line[j+1:].lstrip())
         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): # R471
     """
@@ -1896,9 +1844,7 @@
         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 Ac_Do_Variable(Base): # R472
     """
@@ -1951,16 +1897,11 @@
         if entity_decls is None: return
         return type_spec, attr_specs, entity_decls
     match = staticmethod(match)
-    def init(self, *args):
-        self.type_spec, self.attr_specs, self.entity_decls = args
-        return
     def tostr(self):
-        if self.attr_specs is None:
-            return '%s :: %s' % (self.type_spec, self.entity_decls)
+        if self.items[1] is None:
+            return '%s :: %s' % (self.items[0], self.items[2])
         else:
-            return '%s, %s :: %s' % (self.type_spec, self.attr_specs, self.entity_decls)
-    def torepr(self):
-        return '%s(%r, %r, %r)' % (self.__class__.__name__, self.type_spec, self.attr_specs, self.entity_decls)
+            return '%s, %s :: %s' % self.items
 
 class Declaration_Type_Spec(Base): # R502
     """
@@ -1988,9 +1929,7 @@
             return 'CLASS', Derived_Type_Spec(line)
         return
     match = staticmethod(match)
-    init = Base.init_list
-    def tostr(self): return '%s(%s)' % tuple(map(str,self.items))
-    def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1])
+    def tostr(self): return '%s(%s)' % self.items
 
 class Dimension_Attr_Spec(CALLBase): # R503.d
     """
@@ -2073,21 +2012,15 @@
             assert newline=='',`newline`
         return name, array_spec, char_length, init
     match = staticmethod(match)
-    def init(self, *args):
-        self.name, self.array_spec, self.char_length, self.init = args
-        return
     def tostr(self):
-        s = str(self.name)
-        if self.array_spec is not None:
-            s += '(' + str(self.array_spec) + ')'
-        if self.char_length is not None:
-            s += '*' + str(self.char_length)
-        if self.init is not None:
-            s += ' ' + str(self.init)
+        s = str(self.items[0])
+        if self.items[1] is not None:
+            s += '(' + str(self.items[1]) + ')'
+        if self.items[2] is not None:
+            s += '*' + str(self.items[2])
+        if self.items[3] is not None:
+            s += ' ' + str(self.items[3])
         return s
-    def torepr(self):
-        return '%s(%r, %r, %r, %r)' \
-               % (self.__class__.__name__, self.name, self.array_spec, self.char_length, self.init)
     
 class Object_Name(Base): # R505
     """
@@ -2109,12 +2042,7 @@
             return '=', Initialization_Expr(string[2:].lstrip())
         return
     match = staticmethod(match)
-    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 tostr(self): return '%s %s' % self.items
 
 class Null_Init(STRINGBase): # R507
     """
@@ -2160,13 +2088,9 @@
         if not line.startswith('='): return
         return Scalar_Char_Initialization_Expr(line[1:].lstrip()),
     match = staticmethod(match)
-    def init(self, name):
-        self.name = name
     def tostr(self):
-        if self.name is None: return 'BIND(C)'
-        return 'BIND(C, NAME = %s)' % (self.name)
-    def torepr(self):
-        return '%s(%r)' % (self.__class__.__name__, self.name)
+        if self.items[0] is None: return 'BIND(C)'
+        return 'BIND(C, NAME = %s)' % (self.items[0])
 
 class Array_Spec(Base): # R510
     """
@@ -2250,9 +2174,6 @@
         line = line[:-1].rstrip()
         return Explicit_Shape_Spec_List(line), None
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
-        return
     def tostr(self):
         s = ''
         if self.items[0] is not None:
@@ -2261,7 +2182,6 @@
             s += str(self.items[1]) + ' : '
         s += '*'
         return s
-    def torepr(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
     
 class Intent_Spec(STRINGBase): # R517
     """
@@ -2273,12 +2193,15 @@
     def match(string): return STRINGBase.match(pattern.abs_intent_spec, string)
     match = staticmethod(match)
 
-class Access_Stmt(StmtBase): # R518
+class Access_Stmt(StmtBase, WORDClsBase): # R518
     """
     <access-stmt> = <access-spec> [ [ :: ] <access-id-list> ]
     """
     subclass_names = []
     use_names = ['Access_Spec', 'Access_Id_List']
+    def match(string): return WORDClsBase.match(['PUBLIC', 'PRIVATE'],Access_Id_List,string,check_colons=True, require_cls=False)
+    match = staticmethod(match)
+    tostr = WORDClsBase.tostr_a
 
 class Access_Id(Base): # R519
     """
@@ -2287,34 +2210,68 @@
     """
     subclass_names = ['Use_Name', 'Generic_Spec']
 
-class Allocatable_Stmt(StmtBase): # R520
+class Object_Name_Deferred_Shape_Spec_List_Item(CallBase):
     """
+    <..> =  <object-name> [ ( <deferred-shape-spec-list> ) ]
+    """
+    subclass_names = ['Object_Name']
+    use_names = ['Deferred_Shape_Spec_List']
+    def match(string): return CallBase.match(Object_Name, Deferred_Shape_Spec_List, string, require_rhs=True)
+    match = staticmethod(match)
+    
+class Allocatable_Stmt(StmtBase, WORDClsBase): # R520
+    """
     <allocateble-stmt> = ALLOCATABLE [ :: ] <object-name> [ ( <deferred-shape-spec-list> ) ] [ , <object-name> [ ( <deferred-shape-spec-list> ) ] ]...
     """
     subclass_names = []
-    use_names = ['Object_Name', 'Deferred_Shape_Spec_List']
-
-class Asynchronous_Stmt(StmtBase): # R521
+    use_names = ['Object_Name_Deferred_Shape_Spec_List_Item_List']
+    def match(string):
+        return WORDClsBase.match('ALLOCATABLE', Object_Name_Deferred_Shape_Spec_List_Item_List, string,
+                                 check_colons=True, require_cls=True)
+    match = staticmethod(match)
+    
+class Asynchronous_Stmt(StmtBase, WORDClsBase): # R521
     """
     <asynchronous-stmt> = ASYNCHRONOUS [ :: ] <object-name-list>
     """
     subclass_names = []
     use_names = ['Object_Name_List']
+    def match(string): return WORDClsBase.match('ASYNCHRONOUS',Object_Name_List,string,check_colons=True, require_cls=True)
+    match = staticmethod(match)
 
+
 class Bind_Stmt(StmtBase): # R522
     """
     <bind-stmt> = <language-binding-spec> [ :: ] <bind-entity-list>
     """
     subclass_names = []
     use_names = ['Language_Binding_Spec', 'Bind_Entity_List']
+    def match(string):
+        i = string.find('::')
+        if i==-1:
+            i = string.find(')')
+            if i==-1: return
+            lhs. rhs = string[:i], string[i+1:]
+        else:
+            lhs, rhs = string.split('::',1)
+        lhs = lhs.rstrip()
+        rhs = rhs.lstrip()
+        if not lhs or not rhs: return
+        return Language_Binding_Spec(lhs), Bind_Entity_List(rhs)
+    match = staticmethod(match)
+    def tostr(self):
+        return '%s :: %s' % self.items
 
-class Bind_Entity(Base): # R523
+
+class Bind_Entity(BracketBase): # R523
     """
     <bind-entity> = <entity-name>
                     | / <common-block-name> /
     """
     subclass_names = ['Entity_Name']
     use_names = ['Common_Block_Name']
+    def match(string): return BracketBase.match('//',Common_Block_Name, string)
+    match = staticmethod(match)
 
 class Data_Stmt(StmtBase): # R524
     """
@@ -2362,8 +2319,19 @@
     """
     <data-stmt-value> = [ <data-stmt-repeat> * ] <data-stmt-constant>
     """
-    subclass_names = []
-    use_names = ['Data_Stmt_Repeat', 'Data_Stmt_Constant']
+    subclass_names = ['Data_Stmt_Constant']
+    use_names = ['Data_Stmt_Repeat']
+    def match(string):
+        line, repmap = string_replace_map(string)
+        s = line.split('*')
+        if len(s)!=2: return
+        lhs = repmap(s[0].rstrip())
+        rhs = repmap(s[1].lstrip())
+        if not lhs or not rhs: return
+        return Data_Stmt_Repeat(lhs), Data_Stmt_Constant(rhs)
+    match = staticmethod(match)
+    def tostr(self):
+        return '%s * %s' % self.items    
 
 class Data_Stmt_Repeat(Base): # R531
     """
@@ -2417,13 +2385,8 @@
         if not decls: return
         return decls,
     match = staticmethod(match)
-    def init(self, items):
-        self.items = items
-        return
     def tostr(self):
-        return 'DIMENSION :: ' + ', '.join(['%s(%s)' % ns for ns in self.items])
-    def torepr(self):
-        return '%s(%r)' % (self.__class__.__name__, self.items)
+        return 'DIMENSION :: ' + ', '.join(['%s(%s)' % ns for ns in self.items[0]])
 
 class Intent_Stmt(StmtBase): # R536
     """
@@ -2431,14 +2394,33 @@
     """
     subclass_names = []
     use_names = ['Intent_Spec', 'Dummy_Arg_Name_List']
+    def match(string):
+        if string[:6].upper()!='INTENT': return
+        line = string[6:].lstrip()
+        if not line or not line.startswith('('): return
+        i = line.rfind(')')
+        if i==-1: return
+        spec = line[1:i].strip()
+        if not spec: return
+        line = line[i+1:].lstrip()
+        if line.startswith('::'):
+            line = line[2:].lstrip()
+        if not line: return
+        return Intent_Spec(spec), Dummy_Arg_Name_List(line)
+    match = staticmethod(match)
+    def tostr(self):
+        return 'INTENT(%s) :: %s' % self.items
 
-class Optional_Stmt(StmtBase): # R537
+class Optional_Stmt(StmtBase, WORDClsBase): # R537
     """
     <optional-stmt> = OPTIONAL [ :: ] <dummy-arg-name-list>
     """
     subclass_names = []
     use_names = ['Dummy_Arg_Name_List']
-
+    def match(string): return WORDClsBase.match('OPTIONAL',Dummy_Arg_Name_List,string,check_colons=True, require_cls=True)
+    match = staticmethod(match)
+    tostr = WORDClsBase.tostr_a
+    
 class Parameter_Stmt(StmtBase, CALLBase): # R538
     """
     <parameter-stmt> = PARAMETER ( <named-constant-def-list> )
@@ -2457,13 +2439,16 @@
     def match(string): return KeywordValueBase.match(Named_Constant, Initialization_Expr, string)
     match = staticmethod(match)
     
-class Pointer_Stmt(StmtBase): # R540
+class Pointer_Stmt(StmtBase, WORDClsBase): # R540
     """
     <pointer-stmt> = POINTER [ :: ] <pointer-decl-list>
     """
     subclass_names = []
     use_names = ['Pointer_Decl_List']
-
+    def match(string): return WORDClsBase.match('POINTER',Pointer_Decl_List,string,check_colons=True, require_cls=True)
+    match = staticmethod(match)
+    tostr = WORDClsBase.tostr_a
+    
 class Pointer_Decl(CallBase): # R541
     """
     <pointer-decl> = <object-name> [ ( <deferred-shape-spec-list> ) ]
@@ -2474,21 +2459,27 @@
     def match(string): return CallBase.match(Object_Name, Deferred_Shape_Spec_List, string, require_rhs=True)
     match = staticmethod(match)
 
-class Protected_Stmt(StmtBase): # R542
+class Protected_Stmt(StmtBase, WORDClsBase): # R542
     """
     <protected-stmt> = PROTECTED [ :: ] <entity-name-list>
     """
     subclass_names = []
     use_names = ['Entity_Name_List']
+    def match(string): return WORDClsBase.match('PROTECTED',Entity_Name_List,string,check_colons=True, require_cls=True)
+    match = staticmethod(match)
+    tostr = WORDClsBase.tostr_a
 
-class Save_Stmt(StmtBase): # R543
+class Save_Stmt(StmtBase, WORDClsBase): # R543
     """
     <save-stmt> = SAVE [ [ :: ] <saved-entity-list> ]
     """
     subclass_names = []
     use_names = ['Saved_Entity_List']
+    def match(string): return WORDClsBase.match('SAVE',Saved_Entity_List,string,check_colons=True, require_cls=False)
+    match = staticmethod(match)
+    tostr = WORDClsBase.tostr_a
 
-class Saved_Entity(Base): # R544
+class Saved_Entity(BracketBase): # R544
     """
     <saved-entity> = <object-name>
                      | <proc-pointer-name>
@@ -2496,6 +2487,8 @@
     """
     subclass_names = ['Object_Name', 'Proc_Pointer_Name']
     use_names = ['Common_Block_Name']
+    def match(string): return BracketBase.match('//',CommonBlockName, string)
+    match = staticmethod(match)
 
 class Proc_Pointer_Name(Base): # R545
     """
@@ -2505,25 +2498,31 @@
 
 class Target_Stmt(StmtBase): # R546
     """
-    <target-stmt> = TARGET [ :: ] <object-name> [ ( <array-spec> ) ] [ , <object-name> [ ( <array-spec> ) ]]
+    <target-stmt> = TARGET [ :: ] <object-name> [ ( <array-spec> ) ] [ , <object-name> [ ( <array-spec> ) ] ]...
     """
     subclass_names = []
     use_names = ['Object_Name', 'Array_Spec']
 
-class Value_Stmt(StmtBase): # R547
+class Value_Stmt(StmtBase, WORDClsBase): # R547
     """
     <value-stmt> = VALUE [ :: ] <dummy-arg-name-list>
     """
     subclass_names = []
     use_names = ['Dummy_Arg_Name_List']
+    def match(string): return WORDClsBase.match('VALUE',Dummy_Arg_Name_List,string,check_colons=True, require_cls=True)
+    match = staticmethod(match)
+    tostr = WORDClsBase.tostr_a
 
-class Volatile_Stmt(StmtBase): # R548
+class Volatile_Stmt(StmtBase, WORDClsBase): # R548
     """
     <volatile-stmt> = VOLATILE [ :: ] <object-name-list>
     """
     subclass_names = []
     use_names = ['Object_Name_List']
-
+    def match(string): return WORDClsBase.match('VOLATILE',Object_Name_List,string,check_colons=True, require_cls=True)
+    match = staticmethod(match)
+    tostr = WORDClsBase.tostr_a
+    
 class Implicit_Stmt(StmtBase, WORDClsBase): # R549
     """
     <implicit-stmt> = IMPLICIT <implicit-spec-list>
@@ -2576,13 +2575,9 @@
         if not ('A'<=lhs<=rhs<='Z'): return
         return lhs,rhs
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
-        return
     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(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
 
 class Namelist_Stmt(StmtBase): # R552
     """
@@ -2622,11 +2617,7 @@
         if not l.items: return
         return obj, l
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
-        return
     def tostr(self): return '(%s, %s)' % tuple(self.items)
-    def torepr(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
 
 class Equivalence_Object(Base): # R556
     """
@@ -2697,18 +2688,14 @@
             items.append((name, lst))
         return items,
     match = staticmethod(match)
-    def init(self, items):
-        self.items = items
-        return
     def tostr(self):
         s = 'COMMON'
-        for (name, lst) in self.items:
+        for (name, lst) in self.items[0]:
             if name is not None:
                 s += ' /%s/ %s' % (name, lst)
             else:
                 s += ' // %s' % (lst)
         return s
-    def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.items)
 
 class Common_Block_Object(CallBase): # R558
     """
@@ -2898,22 +2885,17 @@
             rhs_obj = Subscript(repmap(rhs))
         return lhs_obj, rhs_obj, stride_obj
     match = staticmethod(match)
-    def init(self, lhs, rhs, stride):
-        self.lhs, self.rhs, self.stride =lhs, rhs, stride
-        return
     def tostr(self):
         s = ''
-        if self.lhs is not None:
-            s += str(self.lhs) + ' :'
+        if self.items[0] is not None:
+            s += str(self.items[0]) + ' :'
         else:
             s += ':'
-        if self.rhs is not None:
-            s += ' ' + str(self.rhs)
-        if self.stride is not None:
-            s += ' : ' + str(self.stride)
+        if self.items[1] is not None:
+            s += ' ' + str(self.items[1])
+        if self.items[2] is not None:
+            s += ' : ' + str(self.items[2])
         return s
-    def torepr(self):
-        return '%s(%r, %r, %r)' % (self.__class__.__name__,self.lhs, self.rhs, self.stride)        
 
 class Stride(Base): # R621
     """
@@ -2974,14 +2956,17 @@
     """
     subclass_names = ['Expr']
 
-class Allocation(Base):# R628
+class Allocation(CallBase):# R628
     """
-    <allocation> = <allocate-object> [ <allocate-shape-spec-list> ]
+    <allocation> = <allocate-object> [ ( <allocate-shape-spec-list> ) ]
                  | <variable-name>
     """
-    subclass_names = ['Variable_Name']
-    use_names = ['Allocate_Object', 'Allocate_Shape_Spec_List']
-
+    subclass_names = ['Variable_Name', 'Allocate_Object']
+    use_names = ['Allocate_Shape_Spec_List']
+    def match(string):
+        return CallBase.match(Allocate_Object, Allocate_Shape_Spec_List, string, require_rhs = True)
+    match = staticmethod(match)
+    
 class Allocate_Object(Base): # R629
     """
     <allocate-object> = <variable-name>
@@ -3111,8 +3096,24 @@
             pattern.defined_unary_op.named(),Primary,string)
     match = staticmethod(match)
 
-#R703: <defined-unary-op> = . <letter> [ <letter> ]... . 
+class Defined_Unary_Op(STRINGBase): # R703
+    """
+    <defined-unary-op> = . <letter> [ <letter> ]... . 
+    """
+    subclass_names = ['Defined_Op']
 
+
+class Defined_Op(STRINGBase): # R703, 723
+    """
+    <defined-op> = . <letter> [ <letter> ]... . 
+    """
+    subclass_names = []
+    def match(string):
+        if pattern.non_defined_binary_op.match(string):
+            raise NoMatchError,'%s: %r' % (Defined_Unary_Op.__name__, string)
+        return STRINGBase.match(pattern.abs_defined_op, string)
+    match = staticmethod(match)
+
 class Mult_Operand(BinaryOpBase): # R704
     """
     <mult-operand> = <level-1-expr> [ <power-op> <mult-operand> ]
@@ -3261,7 +3262,11 @@
                                    string)
     match = staticmethod(match)
 
-#R723: <defined-binary-op> = . <letter> [ <letter> ]... .
+class Defined_Unary_Op(STRINGBase): # R723
+    """
+    <defined-unary-op> = . <letter> [ <letter> ]... . 
+    """
+    subclass_names = ['Defined_Op']
 
 class Logical_Expr(Base): # R724
     """
@@ -3343,13 +3348,16 @@
     use_names = ['Data_Pointer_Object', 'Bounds_Spec_List', 'Data_Target', 'Bounds_Remapping_List',
                  'Proc_Pointer_Object', 'Proc_Target']
 
-class Data_Pointer_Object(Base): # R736
+class Data_Pointer_Object(BinaryOpBase): # R736
     """
     <data-pointer-object> = <variable-name>
                             | <variable> % <data-pointer-component-name>
     """
     subclass_names = ['Variable_Name']
     use_names = ['Variable', 'Data_Pointer_Component_Name']
+    def match(string):
+        return BinaryOpBase.match(Variable, r'%', Data_Pointer_Component_Name, string)            
+    match = staticmethod(match)
 
 class Bounds_Spec(SeparatorBase): # R737
     """
@@ -3408,6 +3416,20 @@
     """
     subclass_names = []
     use_names = ['Mask_Expr', 'Where_Assignment_Stmt']
+    def match(string):
+        if string[:5].upper()!='WHERE': return
+        line, repmap = string_replace_map(string[5:].lstrip())
+        if not line.startswith('('): return
+        i = line.find(')')
+        if i==-1: return
+        stmt = repmap(line[i+1:].lstrip())
+        if not stmt: return
+        expr = repmap(line[1:i].strip())
+        if not expr: return
+        return Mask_Expr(expr), Where_Assignment_Stmt(stmt)
+    match = staticmethod(match)
+    def tostr(self): return 'WHERE (%s) %s' % tuple(self.items)
+    
 
 class Where_Construct(Base): # R744
     """
@@ -3432,6 +3454,17 @@
     subclass_names = []
     use_names = ['Where_Construct_Name', 'Mask_Expr']
 
+    def match(string):
+        if string[:5].upper()!='WHERE': return
+        line = string[5:].lstrip()
+        if not line: return
+        if line[0]+line[-1] != '()': return
+        line = line[1:-1].strip()
+        if not line: return
+        return Mask_Expr(line),
+    match = staticmethod(match)
+    def tostr(self): return 'WHERE (%s)' % tuple(self.items)
+
 class Where_Body_Construct(Base): # R746
     """
     <where-body-construct> = <where-assignment-stmt>
@@ -3458,13 +3491,31 @@
     """
     subclass_names = []
     use_names = ['Mask_Expr', 'Where_Construct_Name']
-
-class Elsewhere_Stmt(StmtBase): # R750
+    def match(string):
+        if string[:9].upper()!='ELSEWHERE': return
+        line = string[9:].lstrip()
+        if not line.startswith('('): return
+        i = line.rfind(')')
+        if i==-1: return
+        expr = line[1:i].strip()
+        if not expr: return
+        line = line[i+1:].rstrip()
+        if line:
+            return Mask_Expr(expr), Where_Construct_Name(line)
+        return Mask_Expr(expr), None
+    match = staticmethod(match)
+    def tostr(self):
+        if self.items[1] is None: return 'ELSEWHERE(%s)' % (self.items[0])
+        return 'ELSEWHERE(%s) %s' % self.items
+        
+class Elsewhere_Stmt(StmtBase, WORDClsBase): # R750
     """
     <elsewhere-stmt> = ELSEWHERE [ <where-construct-name> ]
     """
     subclass_names = []
     use_names = ['Where_Construct_Name']
+    def match(string): return WORDClsBase.match('ELSEWHERE', Where_Construct_Name, string)
+    match = staticmethod(match)
 
 class End_Where_Stmt(EndStmtBase): # R751
     """
@@ -3485,12 +3536,14 @@
     subclass_names = []
     use_names = ['Forall_Construct_Stmt', 'Forall_Body_Construct', 'End_Forall_Stmt']
 
-class Forall_Construct_Stmt(StmtBase): # R753
+class Forall_Construct_Stmt(StmtBase, WORDClsBase): # R753
     """
     <forall-construct-stmt> = [ <forall-construct-name> : ] FORALL <forall-header>
     """
     subclass_names = []
     use_names = ['Forall_Construct_Name', 'Forall_Header']
+    def match(string): return WORDClsBase.match('FORALL', Forall_Header, string, require_cls = True)
+    match = staticmethod(match)
 
 class Forall_Header(Base): # R754
     """
@@ -3539,6 +3592,19 @@
     """
     subclass_names = []
     use_names = ['Forall_Header', 'Forall_Assignment_Stmt']
+    def match(string):
+        if string[:6].upper()!='FORALL': return
+        line, repmap = string_replace_map(string[6:].lstrip())
+        if not line.startswith(')'): return
+        i = line.find(')')
+        if i==-1: return
+        header = repmap(line[1:i].strip())
+        if not header: return
+        line = repmap(line[i+1:].lstrip())
+        if not line: return
+        return Forall_Header(header), Forall_Assignment_Stmt(line)
+    match = staticmethod(match)
+    def tostr(self): return 'FORALL %s %s' % self.items
 
 ###############################################################################
 ############################### SECTION  8 ####################################
@@ -3637,11 +3703,7 @@
         if line[0]+line[-1]!='()': return
         return Scalar_Logical_Expr(line[1:-1].strip()),
     match = staticmethod(match)
-    def init(self, expr):
-        self.expr = expr
-        return
-    def tostr(self): return 'IF (%s) THEN' % (self.expr)
-    def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.expr)
+    def tostr(self): return 'IF (%s) THEN' % self.items
 
 class Else_If_Stmt(StmtBase): # R804
     """
@@ -3665,14 +3727,10 @@
         if line: return Scalar_Logical_Expr(expr), If_Construct_Name(line)
         return Scalar_Logical_Expr(expr), None
     match = staticmethod(match)
-    def init(self, *args):
-        self.expr, self.iflabel = args
-        return
     def tostr(self):
-        if self.iflabel is None:
-            return 'ELSE IF (%s) THEN' % (self.expr)
-        return 'ELSE IF (%s) THEN %s' % (self.expr, self.iflabel)
-    def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.expr, self.iflabel)
+        if self.items[1] is None:
+            return 'ELSE IF (%s) THEN' % (self.items[0])
+        return 'ELSE IF (%s) THEN %s' % self.items
 
 class Else_Stmt(StmtBase): # R805
     """
@@ -3686,14 +3744,10 @@
         if line: return If_Construct_Name(line),
         return None,
     match = staticmethod(match)
-    def init(self, iflabel):
-        self.iflabel = iflabel
-        return
     def tostr(self):
-        if self.iflabel is None:
+        if self.items[0] is None:
             return 'ELSE'
-        return 'ELSE %s' % (self.expr, self.iflabel)
-    def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.iflabel)
+        return 'ELSE %s' % self.items
 
 class End_If_Stmt(EndStmtBase): # R806
     """
@@ -3721,12 +3775,8 @@
         stmt = repmap(line[i+1:].lstrip())
         return Scalar_Logical_Expr(expr), Action_Stmt_C802(stmt)
     match = staticmethod(match)
-    def init(self, *args):
-        self.expr, self.stmt = args
-        return
-    def tostr(self): return 'IF (%s) %s' % (self.expr, self.stmt)
-    def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.expr, self.stmt)
-    
+    def tostr(self): return 'IF (%s) %s' % self.items
+
 class Case_Construct(Base): # R808
     """
     <case-construct> = <select-case-stmt>
@@ -3738,12 +3788,14 @@
     subclass_names = []
     use_names = ['Select_Case_Stmt', 'Case_Stmt', 'End_Select_Stmt']
 
-class Select_Case_Stmt(StmtBase): # R809
+class Select_Case_Stmt(StmtBase, CALLBase): # R809
     """
     <select-case-stmt> = [ <case-construct-name> : ] SELECT CASE ( <case-expr> )
     """
     subclass_names = []
     use_names = ['Case_Construct_Name', 'Case_Expr']
+    def match(string): return CALLBase.match(pattter.abs_select_case, Case_Expr, string)
+    match = staticmethod(match)
 
 class Case_Stmt(StmtBase): # R810
     """
@@ -3807,12 +3859,14 @@
     subclass_names = []
     use_names = ['Associate_Stmt', 'Block', 'End_Associate_Stmt']
 
-class Associate_Stmt(StmtBase): # R817
+class Associate_Stmt(StmtBase, CALLBase): # R817
     """
     <associate-stmt> = [ <associate-construct-name> : ] ASSOCIATE ( <association-list> )
     """
     subclass_names = []
     use_names = ['Associate_Construct_Name', 'Association_List']
+    def match(string): return CALLBase.match('ASSOCIATE', Association_List, string)
+    match = staticmethod(match)
 
 class Association(BinaryOpBase): # R818
     """
@@ -3865,7 +3919,45 @@
     """
     subclass_names = []
     use_names = ['Type_Spec', 'Select_Construct_Name']
-
+    def match(string):
+        if string[:4].upper()=='TYPE':
+            line = string[4:].lstrip()
+            if not line[:2].upper()=='IS': return
+            line = line[2:].lstrip()
+            kind = 'TYPE IS'
+        elif string[:5].upper()=='CLASS':
+            line = string[5:].lstrip()
+            if line[:2].upper()=='IS':
+                line = line[2:].lstrip()
+                kind = 'CLASS IS'
+            elif line[:7].upper()=='DEFAULT':
+                line = line[7:].lstrip()
+                if line:
+                    if isalnum(line[0]): return
+                    return 'CLASS DEFAULT', None, Select_Construct_Name(line)
+                return 'CLASS DEFAULT', None, None
+            else:
+                return
+        else:
+            return
+        if not line.startswith('('): return
+        i = line.rfind(')')
+        if i==-1: return
+        l = line[1:i].strip()
+        if not l: return
+        line = line[i+1:].lstrip()
+        if line:
+            return kind, Type_Spec(l), Select_Construct_Name(line)
+        return kind, Type_Spec(l), None
+    match = staticmethod(match)
+    def tostr(self):
+        s = str(self.items[0])
+        if self.items[1] is not None:
+            s += ' (%s)' % (self.items[0])
+        if self.items[2] is not None:
+            s += ' %s' % (self.items[2])
+        return s
+    
 class End_Select_Type_Stmt(EndStmtBase): # R824
     """
     <end-select-type-stmt> = END SELECT [ <select-construct-name> ]
@@ -3956,18 +4048,18 @@
         if line: return Label(label), Loop_Control(line)
         return Label(label), None
     match = staticmethod(match)
-    def init(self,*args):
-        self.dolabel, self.loop_control = args
     def tostr(self):
-        if self.loop_control is None: return 'DO %s' % (self.dolabel)
-        return 'DO %s %s' % (self.dolabel, self.loop_control)
+        if self.itens[1] is None: return 'DO %s' % (self.items[0])
+        return 'DO %s %s' % self.items
     
-class Nonlabel_Do_Stmt(StmtBase): # R829
+class Nonlabel_Do_Stmt(StmtBase, WORDClsBase): # R829
     """
     <nonlabel-do-stmt> = [ <do-construct-name> : ] DO [ <loop-control> ]
     """
     subclass_names = []
     use_names = ['Do_Construct_Name', 'Loop_Control']
+    def match(string): return WORDClsBase.match('DO', Loop_Control, string)
+    match = staticmethod(match)
 
 class Loop_Control(Base): # R830
     """
@@ -3992,14 +4084,9 @@
         if not 2<=len(rhs)<=3: return
         return Variable(repmap(var.rstrip())),map(Scalar_Int_Expr, map(repmap,rhs))
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
     def tostr(self):
         if len(self.items)==1: return ', WHILE (%s)' % (self.items[0])
         return ', %s = %s' % (self.items[0], ', '.join(map(str,self.items[1])))
-    def torepr(self):
-        if len(self.items)==1: return '%s(%r)' % (self.__class__.__name__, self.items[0])
-        return '%s(%r, %r)' % (self.__class__.__name__, self.items[0], self.items[1])
     
 class Do_Variable(Base): # R831
     """
@@ -4153,9 +4240,7 @@
         if line[:2].upper() != 'TO': return
         return Label(line[2:].lstrip()),
     match = staticmethod(match)
-    def init(self, value): self.value = value
-    def tostr(self): return 'GO TO %s' % (self.value)
-    def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.value)
+    def tostr(self): return 'GO TO %s' % (self.items[0])
 
 class Computed_Goto_Stmt(StmtBase): # R846
     """
@@ -4163,6 +4248,23 @@
     """
     subclass_names = []
     use_names = ['Label_List', 'Scalar_Int_Expr']
+    def match(string):
+        if string[:2].upper()!='GO': return
+        line = string[2:].lstrip()
+        if line[:2].upper()!='TO': return
+        line = line[2:].lstrip()
+        if not line.startswith('('): return
+        i = line.find(')')
+        if i==-1: return
+        lst = line[1:i].strip()
+        if not lst: return
+        line = line[i+1:].lstrip()
+        if line.startswith(','):
+            line = line[1:].lstrip()
+        if not line: return
+        return Label_List(lst), Scalar_Int_Expr(line)
+    match = staticmethod(match)
+    def tostr(self): return 'GO TO (%s), %s' % self.items
 
 class Arithmetic_If_Stmt(StmtBase): # R847
     """
@@ -4179,13 +4281,9 @@
         labels = line[i+1:].lstrip().split(',')
         if len(labels) != 3: return
         labels = [Label(l.strip()) for l in labels]
-        return Scalar_Numeric_Expr(line[1:i].strip()), labels
+        return (Scalar_Numeric_Expr(line[1:i].strip()),) + tuple(labels)
     match = staticmethod(match)
-    def init(self, *args):
-        self.expr, self.labels = args
-        return
-    def tostr(self): return 'IF (%s) %s' % (self.expr, ', '.join(map(str,self.labels)))
-    def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.expr, ', '.join(map(repr,self.labels)))
+    def tostr(self): return 'IF (%s) %s, %s, %s' % self.items
 
 class Continue_Stmt(StmtBase, STRINGBase): # R848
     """
@@ -4242,14 +4340,16 @@
     """
     subclass_names = ['Char_Variable']
 
-class Open_Stmt(StmtBase): # R904
+class Open_Stmt(StmtBase, CALLBase): # R904
     """
     <open-stmt> = OPEN ( <connect-spec-list> )
     """
     subclass_names = []
     use_names = ['Connect_Spec_List']
-
-class Connect_Spec(Base): # R905
+    def match(string): CALLBase.match('OPEN', Connect_Spec_List, string, require_rhs=True)
+    match = staticmethod(match)
+    
+class Connect_Spec(KeywordValueBase): # R905
     """
     <connect-spec> = [ UNIT = ] <file-unit-number>
                      | ACCESS = <scalar-default-char-expr>
@@ -4274,7 +4374,26 @@
     subclass_names = []
     use_names = ['File_Unit_Number', 'Scalar_Default_Char_Expr', 'Label', 'File_Name_Expr', 'Iomsg_Variable',
                  'Scalar_Int_Expr', 'Scalar_Int_Variable']
+    def match(string):
+        for (k,v) in [\
+            (['ACCESS','ACTION','ASYNCHRONOUS','BLANK','DECIMAL','DELIM','ENCODING',
+              'FORM','PAD','POSITION','ROUND','SIGN','STATUS'], Scalar_Default_Char_Expr),
+            ('ERR', Label),
+            ('FILE',File_Name_Expr),
+            ('IOSTAT', Scalar_Int_Variable),
+            ('IOMSG', Iomsg_Variable),
+            ('RECL', Scalar_Int_Expr),
+            ('UNIT', File_Unit_Number),
+            ]:
+            try:
+                obj = KeywordValueBase.match(k, v, string, upper_lhs = True)
+            except NoMatchError:
+                obj = None
+            if obj is not None: return obj
+        return 'UNIT', File_Unit_Number
+    match = staticmethod(match)
 
+
 class File_Name_Expr(Base): # R906
     """
     <file-name-expr> = <scalar-default-char-expr>
@@ -4287,14 +4406,16 @@
     """
     subclass_names = ['Scalar_Default_Char_Variable']
 
-class Close_Stmt(StmtBase): # R908
+class Close_Stmt(StmtBase, CALLBase): # R908
     """
     <close-stmt> = CLOSE ( <close-spec-list> )
     """
     subclass_names = []
     use_names = ['Close_Spec_List']
+    def match(string): CALLBase.match('CLOSE', Close_Spec_List, string, require_rhs=True)
+    match = staticmethod(match)
 
-class Close_Spec(Base): # R909
+class Close_Spec(KeywordValueBase): # R909
     """
     <close-spec> = [ UNIT = ] <file-unit-number>
                    | IOSTAT = <scalar-int-variable>
@@ -4305,6 +4426,21 @@
     subclass_names = []
     use_names = ['File_Unit_Number', 'Scalar_Default_Char_Expr', 'Label', 'Iomsg_Variable',
                  'Scalar_Int_Variable']
+    def match(string):
+        for (k,v) in [\
+            ('ERR', Label),
+            ('IOSTAT', Scalar_Int_Variable),
+            ('IOMSG', Iomsg_Variable),
+            ('STATUS', Scalar_Default_Char_Expr),
+            ('UNIT', File_Unit_Number),
+            ]:
+            try:
+                obj = KeywordValueBase.match(k, v, string, upper_lhs = True)
+            except NoMatchError:
+                obj = None
+            if obj is not None: return obj
+        return 'UNIT', File_Unit_Number(string)
+    match = staticmethod(match)
 
 class Read_Stmt(StmtBase): # R910
     """
@@ -4334,13 +4470,9 @@
             return Io_Control_Spec_List(l),None
         return Io_Control_Spec_List(l), Output_Item_List(repmap(line[i+1:].lstrip()))
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
-        return
     def tostr(self):
         if self.items[1] is None: return 'WRITE(%s)' % (self.items[0])
         return 'WRITE(%s) %s' % tuple(self.items)
-    def torepr(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
     
 class Print_Stmt(StmtBase): # R912
     """
@@ -4361,13 +4493,9 @@
         if not l: return
         return Format(repmap(line[:i].rstrip())), Output_Item_List(l)
     match = staticmethod(match)
-    def init(self, *args):
-        self.items = args
-        return
     def tostr(self):
         if self.items[1] is None: return 'PRINT %s' % (self.items[0])
         return 'PRINT %s, %s' % tuple(self.items)
-    def torepr(self): return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items)))
     
 class Io_Control_Spec_List(SequenceBase): # R913-list
     """
@@ -4494,13 +4622,15 @@
     subclass_names = []
     use_names = ['Do_Variable', 'Scalar_Int_Expr']
 
-class Dtv_Type_Spec(Base): # R920
+class Dtv_Type_Spec(CALLBase): # R920
     """
     <dtv-type-spec> = TYPE ( <derived-type-spec> )
                       | CLASS ( <derived-type-spec> )
     """
     subclass_names = []
     use_names = ['Derived_Type_Spec']
+    def match(string): CALLStmt.match(['TYPE', 'CLASS'], Derived_Type_Spec, string, require_rhs=True)
+    match = staticmethod(match)
 
 class Wait_Stmt(StmtBase, CALLBase): # R921
     """
@@ -4564,7 +4694,7 @@
     subclass_names = []
     use_names = ['File_Unit_Number', 'Position_Spec_List']
 
-class Position_Spec(Base): # R926
+class Position_Spec(KeywordValueBase): # R926
     """
     <position-spec> = [ UNIT = ] <file-unit-number>
                       | IOMSG = <iomsg-variable>
@@ -4573,7 +4703,22 @@
     """
     subclass_names = []
     use_names = ['File_Unit_Number', 'Iomsg_Variable', 'Scalar_Int_Variable', 'Label']
+    def match(string):
+        for (k,v) in [\
+            ('ERR', Label),
+            ('IOSTAT', Scalar_Int_Variable),
+            ('IOMSG', Iomsg_Variable),
+            ('UNIT', File_Unit_Number),
+            ]:
+            try:
+                obj = KeywordValueBase.match(k, v, string, upper_lhs = True)
+            except NoMatchError:
+                obj = None
+            if obj is not None: return obj
+        return 'UNIT', File_Unit_Number(string)
+    match = staticmethod(match)
 
+
 class Flush_Stmt(StmtBase): # R927
     """
     <flush-stmt> = FLUSH <file-unit-number>
@@ -4582,7 +4727,7 @@
     subclass_names = []
     use_names = ['File_Unit_Number', 'Position_Spec_List']
 
-class Flush_Spec(Base): # R928
+class Flush_Spec(KeywordValueBase): # R928
     """
     <flush-spec> = [ UNIT = ] <file-unit-number>
                    | IOMSG = <iomsg-variable>
@@ -4591,6 +4736,20 @@
     """
     subclass_names = []
     use_names = ['File_Unit_Number', 'Iomsg_Variable', 'Scalar_Int_Variable', 'Label']
+    def match(string):
+        for (k,v) in [\
+            ('ERR', Label),
+            ('IOSTAT', Scalar_Int_Variable),
+            ('IOMSG', Iomsg_Variable),
+            ('UNIT', File_Unit_Number),
+            ]:
+            try:
+                obj = KeywordValueBase.match(k, v, string, upper_lhs = True)
+            except NoMatchError:
+                obj = None
+            if obj is not None: return obj
+        return 'UNIT', File_Unit_Number(string)
+    match = staticmethod(match)
 
 class Inquire_Stmt(StmtBase): # R929
     """
@@ -4600,7 +4759,7 @@
     subclass_names = []
     use_names = ['Inquire_Spec_List', 'Scalar_Int_Variable', 'Output_Item_List']
 
-class Inquire_Spec(Base): # R930
+class Inquire_Spec(KeywordValueBase): # R930
     """
     <inquire-spec> = [ UNIT = ] <file-unit-number>
                      | FILE = <file-name-expr>
@@ -4643,25 +4802,50 @@
     use_names = ['File_Unit_Number', 'File_Name_Expr', 'Scalar_Default_Char_Variable',
                  'Scalar_Default_Logical_Variable', 'Scalar_Int_Variable', 'Scalar_Int_Expr',
                  'Label', 'Iomsg_Variable']
+    def match(string):
+        for (k,v) in [\
+            (['ACCESS','ACTION','ASYNCHRONOUS', 'BLANK', 'DECIMAL', 'DELIM',
+              'DIRECT','ENCODING','FORM','NAME','PAD', 'POSITION','READ','READWRITE',
+              'ROUND', 'SEQUENTIAL', 'SIGN','STREAM','UNFORMATTED','WRITE'],
+             Scalar_Default_Char_Variable),
+            ('ERR', Label),
+            (['EXIST','NAMED','PENDING'], Scalar_Default_Logical_Variable),
+            ('ID', Scalar_Int_Expr),
+            (['IOSTAT','NEXTREC','NUMBER','POS','RECL','SIZE'], Scalar_Int_Variable),
+            ('IOMSG', Iomsg_Variable),
+            ('FILE', File_Name_Expr),
+            ('UNIT', File_Unit_Number),
+            ]:
+            try:
+                obj = KeywordValueBase.match(k, v, string, upper_lhs = True)
+            except NoMatchError:
+                obj = None
+            if obj is not None: return obj
+        return 'UNIT', File_Unit_Number(string)
+        return
+    match = staticmethod(match)
 
-
 ###############################################################################
 ############################### SECTION 10 ####################################
 ###############################################################################
 
-class Format_Stmt(StmtBase): # R1001
+class Format_Stmt(StmtBase, WORDClsBase): # R1001
     """
     <format-stmt> = FORMAT <format-specification>
     """
     subclass_names = []
     use_names = ['Format_Specification']
+    def match(string): WORDClsBase.match('FORMAT', Format_Specification, string, require_cls=True)
+    match = staticmethod(match)
 
-class Format_Specification(Base): # R1002
+class Format_Specification(BracketBase): # R1002
     """
     <format-specification> = ( [ <format-item-list> ] )
     """
     subclass_names = []
     use_names = ['Format_Item_List']
+    def match(string): return BracketBase.match('()', Format_Item_List, string, require_cls=False)
+    match = staticmethod(match)
 
 class Format_Item(Base): # R1003
     """
@@ -4698,6 +4882,96 @@
     """
     subclass_names = []
     use_names = ['W', 'M', 'D', 'E', 'Char_Literal_Constant', 'V_List']
+    def match(string):
+        c = string[0].upper()
+        if c in ['I','B','O','Z','D']:
+            line = string[1:].lstrip()
+            if '.' in line:
+                i1,i2 = line.split('.',1)
+                i1 = i1.rstrip()
+                i2 = i2.lstrip()
+                return c, W(i1), M(i2), None
+            return c,W(line), None, None
+        if c in ['E','G']:
+            line = string[1:].lstrip()
+            if line.count('.')==1:
+                i1,i2 = line.split('.',1)
+                i1 = i1.rstrip()
+                i2 = i2.lstrip()
+                return c, W(i1), D(i2), None
+            elif line.count('.')==2:
+                i1,i2,i3 = line.split('.',2)
+                i1 = i1.rstrip()
+                i2 = i2.lstrip()
+                i3 = i3.lstrip()
+                return c, W(i1), D(i2), E(i3)
+            else:
+                return
+        if c=='L':
+            line = string[1:].lstrip()
+            if not line: return
+            return c, W(line), None, None
+        if c=='A':
+            line = string[1:].lstrip()
+            if not line:
+                return c, None, None, None
+            return c, W(line), None, None
+        c = string[:2].upper()
+        if len(c)!=2: return
+        if c in ['EN','ES']:
+            line = string[2:].lstrip()
+            if line.count('.')==1:
+                i1,i2 = line.split('.',1)
+                i1 = i1.rstrip()
+                i2 = i2.lstrip()
+                return c, W(i1), D(i2), None
+            elif line.count('.')==2:
+                i1,i2,i3 = line.split('.',2)
+                i1 = i1.rstrip()
+                i2 = i2.lstrip()
+                i3 = i3.lstrip()
+                return c, W(i1), D(i2), E(i3)
+            else:
+                return
+        if c=='DT':
+            line = string[2:].lstrip()
+            if not line:
+                return c, None, None, None
+            lst = None
+            if line.endswith(')'):
+                i = line.rfind('(')
+                if i==-1: return
+                l = line[i+1:-1].strip()
+                if not l: return
+                lst = V_List(l)
+                line = line[:i].rstrip()
+            if not line:
+                return c, None, lst, None
+            return c, Char_Literal_Constant(line), lst, None
+        return
+    match = staticmethod(match)
+    def tostr(self):
+        c = selt.items[0]
+        if c in ['I', 'B', 'O', 'Z', 'F', 'D', 'A', 'L']:
+            if self.items[2] is None:
+                return '%s%s' % (c, self.items[1])
+            return '%s%s.%s' % (c, self.items[1], self.items[2])
+        if c in ['E', 'EN', 'ES', 'G']:
+            if self.items[3] is None:
+                return '%s%s.%s' % (c, self.items[1], self.items[2])
+            return '%s%s.%sE%s' % (c, self.items[1], self.items[2], self.items[3])
+        if c=='DT':
+            if self.items[1] is None:
+                if self.items[2] is None:
+                    return c
+                else:
+                    return '%s(%s)' % (c, self.items[2])
+            else:
+                if self.items[2] is None:
+                    return '%s%s' % (c, self.items[1])
+                else:
+                    return '%s%s(%s)' % (c, self.items[1], self.items[2])
+        raise NotImpletenetedError,`c`
 
 class W(Base): # R1006
     """
@@ -4829,12 +5103,14 @@
     use_names = ['Program_Stmt', 'Specification_Part', 'Execution_Part', 'Internal_Subprogram_Part',
                  'End_Program_Stmt']
 
-class Program_Stmt(StmtBase): # R1102
+class Program_Stmt(StmtBase, WORDClsBase): # R1102
     """
     <program-stmt> = PROGRAM <program-name>
     """
     subclass_names = []
     use_names = ['Program_Name']
+    def match(string): return WORDClsBase.match('PROGRAM',Program_Name, string, require_cls = True)
+    match = staticmethod(match)
 
 class End_Program_Stmt(EndStmtBase): # R1103
     """
@@ -4855,12 +5131,14 @@
     subclass_names = []
     use_names = ['Module_Stmt', 'Specification_Part', 'Module_Subprogram_Part', 'End_Module_Stmt']
 
-class Module_Stmt(StmtBase): # R1105
+class Module_Stmt(StmtBase, WORDClsBase): # R1105
     """
     <module-stmt> = MODULE <module-name>
     """
     subclass_names = []
     use_names = ['Module_Name']
+    def match(string): return WORDClsBase.match('MODULE',Module_Name, string, require_cls = True)
+    match = staticmethod(match)
 
 class End_Module_Stmt(EndStmtBase): # R1106
     """
@@ -4895,6 +5173,44 @@
     subclass_names = []
     use_names = ['Module_Nature', 'Module_Name', 'Rename_List', 'Only_List']
 
+    def match(string):
+        if string[:3].upper() != 'USE': return
+        line = string[3:]
+        if not line: return
+        if isalnum(line[0]): return
+        line = line.lstrip()
+        i = line.find('::')
+        nature = None
+        if i!=-1:
+            if line.startswith(','):
+                l = line[1:i].strip()
+                if not l: return
+                nature = Module_Nature(l)
+            line = line[i+2:].lstrip()
+            if not line: return
+        i = line.find(',')
+        if i==-1: return nature, Module_Name(line), '', None
+        name = line[:i].rstrip()
+        if not name: return
+        name = Module_Name(name)
+        line = line[i+1:].lstrip()
+        if not line: return
+        if line[:5].upper()=='ONLY:':
+            line = line[5:].lstrip()
+            if not line:
+                return nature, name, ', ONLY:', None
+            return nature, name, ', ONLY:', Only_List(line)
+        return nature, name, ',', Rename_List(line)
+    match = staticmethod(match)
+    def tostr(self):
+        s = 'USE'
+        if self.items[0] is not None:
+            s += ', %s' % (self.items[0])
+        s += ' :: %s%s' % (self.items[1], self.items[2])
+        if self.items[3] is not None:
+            s += ' %s' % (self.items[3])
+        return s
+        
 class Module_Nature(STRINGBase): # R1110
     """
     <module-nature> = INTRINSIC
@@ -4911,6 +5227,26 @@
     """
     subclass_names = []
     use_names = ['Local_Name', 'Use_Name', 'Local_Defined_Operator', 'Use_Defined_Operator']
+    def match(string):
+        s = string.split('=>', 1)
+        if len(s) != 2: return
+        lhs, rhs = s[0].rstrip(), s[1].lstrip()
+        if not lhs or not rhs: return
+        if lhs[:8].upper()=='OPERATOR' and rhs[:8].upper()=='OPERATOR':
+            l = lhs[8:].lstrip()
+            r = rhs[8:].lstrip()
+            if l and r and l[0]+l[-1]=='()':
+                if r[0]+r[-1] != '()': return
+                l = l[1:-1].strip()
+                r = r[1:-1].strip()
+                if not l or not r: return
+                return 'OPERATOR', Local_Defined_Operator(l), Use_Defined_Operator(r)
+        return None, Local_Name(lhs), Use_Name(rhs)
+    match = staticmethod(match)
+    def tostr(self):
+        if not self.items[0]:
+            return '%s => %s' % self.items[1:]
+        return '%s(%s) => %s(%s)' % (self.items[0], self.items[1],self.items[0], self.items[2])
 
 class Only(Base): # R1112
     """
@@ -4955,6 +5291,17 @@
     """
     subclass_names = []
     use_names = ['Block_Data_Name']
+    def match(string):
+        if string[:5].upper()!='BLOCK': return
+        line = string[5:].lstrip()
+        if line[:4].upper()!='DATA': return
+        line = line[4:].lstrip()
+        if not line: return None,
+        return Block_Data_Name(line),
+    match = staticmethod(match)
+    def tostr(self):
+        if self.items[0] is None: return 'BLOCK DATA'
+        return 'BLOCK DATA %s' % self.items
 
 class End_Block_Data_Stmt(EndStmtBase): # R1118
     """
@@ -5041,44 +5388,26 @@
     """
     subclass_names = []
 
-class Import_Stmt(StmtBase): # R1209
+class Import_Stmt(StmtBase, WORDClsBase): # R1209
     """
     <import-stmt> = IMPORT [ :: ] <import-name-list>
     """
     subclass_names = []
     use_names = ['Import_Name_List']
-    def match(string):
-        start = string[:6].upper()
-        if start != 'IMPORT': return
-        line = string[6:].lstrip()
-        if line.startswith('::'):
-            line = line[2:].lstrip()
-        return Import_Name_List(line),
+    def match(string): return WORDClsBase.match('IMPORT',Import_Name_List,string,check_colons=True, require_cls=True)
     match = staticmethod(match)
-    def init(self, names):
-        self.names = names
-        return
-    def tostr(self): return 'IMPORT :: %s' % (self.names)
-    def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.names)
-
-class External_Stmt(StmtBase): # R1210
+    tostr = WORDClsBase.tostr_a
+    
+class External_Stmt(StmtBase, WORDClsBase): # R1210
     """
     <external-stmt> = EXTERNAL [ :: ] <external-name-list>
     """
     subclass_names = []
     use_names = ['External_Name_List']
-    def match(string):
-        if string[:8].upper() != 'EXTERNAL': return
-        line = string[8:].lstrip()
-        if line.startswith('::'): line = line[2:].lstrip()
-        return External_Name_List(line),
+    def match(string): return WORDClsBase.match('EXTERNAL',External_Name_List,string,check_colons=True, require_cls=True)
     match = staticmethod(match)
-    def init(self, names):
-        self.names = names
-        return
-    def tostr(self): return 'EXTERNAL :: %s' % (self.names)
-    def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.names)
-
+    tostr = WORDClsBase.tostr_a
+    
 class Procedure_Declaration_Stmt(StmtBase): # R1211
     """
     <procedure-declaration-stmt> = PROCEDURE ( [ <proc-interface> ] ) [ [ , <proc-attr-spec> ]... :: ] <proc-decl-list>
@@ -5104,26 +5433,31 @@
     subclass_names = ['Access_Spec', 'Proc_Language_Binding_Spec']
     use_names = ['Intent_Spec']
 
-class Proc_Decl(Base): # R1214
+class Proc_Decl(BinaryOpBase): # R1214
     """
     <proc-decl> = <procedure-entity-name> [ => <null-init> ]
     """
     subclass_names = ['Procedure_Entity_Name']
     use_names = ['Null_Init']
-
+    def match(string): return BinaryOpBase.match(Procedure_Entity_Name,'=>', Null_Init, string)
+    match = staticmethod(match)
+    
 class Interface_Name(Base): # R1215
     """
     <interface-name> = <name>
     """
     subclass_names = ['Name']
 
-class Intrinsic_Stmt(StmtBase): # R1216
+class Intrinsic_Stmt(StmtBase, WORDClsBase): # R1216
     """
     <intrinsic-stmt> = INTRINSIC [ :: ] <intrinsic-procedure-name-list>
     """
     subclass_names = []
     use_names = ['Intrinsic_Procedure_Name_List']
-
+    def match(string): return WORDClsBase.match('INTRINSIC',Intrinsic_Procedure_Name_List,string,check_colons=True, require_cls=True)
+    match = staticmethod(match)
+    tostr = WORDClsBase.tostr_a
+    
 class Function_Reference(CallBase): # R1217
     """
     <function-reference> = <procedure-designator> ( [ <actual-arg-spec-list> ] )
@@ -5152,12 +5486,9 @@
             return Procedure_Designator(repmap(line[:i].rstrip())),None
         return Procedure_Designator(string[4:].lstrip()),None
     match = staticmethod(match)
-    def init(self, *args):
-        self.designator, self.args = args
     def tostr(self):
-        if self.args is None: return 'CALL %s' % (self.designator)
-        return 'CALL %s(%s)' % (self.designator, self.args)
-    def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.designator, self.args)
+        if self.items[1] is None: return 'CALL %s' % (self.items[0])
+        return 'CALL %s(%s)' % self.items
 
 class Procedure_Designator(BinaryOpBase): # R1219
     """
@@ -5196,18 +5527,14 @@
     <alt-return-spec> = * <label>
     """
     subclass_names = []
+    use_names = ['Label']
     def match(string):
         if not string.startswith('*'): return
         line = string[1:].lstrip()
-        if pattern.abs_label.match(line):
-            return line,
-        return
+        if not line: return
+        return Label(line),
     match = staticmethod(match)
-    def init(self, label):
-        self.label = label
-        return
-    def tostr(self): return '*%s' % (self.label)
-    def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.label)
+    def tostr(self): return '*%s' % (self.items[0])
 
 class Function_Subprogram(BlockBase): # R1223
     """
@@ -5272,6 +5599,33 @@
     subclass_names = ['Proc_Language_Binding_Spec']
     use_names = ['Result_Name']
 
+    def match(string):
+        if string[:6].upper()=='RESULT':
+            line = string[6:].lstrip()
+            if not line.startswith('('): return
+            i = line.find(')')
+            if i==-1: return
+            name = line[1:i].strip()
+            if not name: return
+            line = line[i+1:].lstrip()
+            if line: return Result_Name(name), Proc_Language_Binding_Spec(line)
+            return Result_Name(name), None
+        if not string.endswith(')'): return
+        i = string.rfind('(')
+        if i==-1: return
+        name = string[i+1:-1].strip()
+        if not name: return
+        line = string[:i].rstrip()
+        if line[-6:].upper()!='RESULT': return
+        line = line[:-6].rstrip()
+        if not line: return
+        return Result_Name(name), Proc_Language_Binding_Spec(line)
+    match = staticmethod(match)
+    def tostr(self):
+        if self.items[1] is None:
+            return 'RESULT(%s)' % (self.items[0])
+        return 'RESULT(%s) %s' % self.items
+
 class End_Function_Stmt(EndStmtBase): # R1230
     """
     <end-function-stmt> = END [ FUNCTION [ <function-name> ] ]
@@ -5327,22 +5681,17 @@
             binding_spec = Proc_Language_Binding_Spec(repmap(line))
         return prefix, name, dummy_args, binding_spec
     match = staticmethod(match)
-    def init(self, *args):
-        self.prefix, self.name, self.dummy_args, self.binding_spec = args
-        return
+    def get_name(self): return self.items[1]
     def tostr(self):
-        if self.prefix is not None:
-            s = '%s SUBROUTINE %s' % (self.prefix, self.name)
+        if self.items[0] is not None:
+            s = '%s SUBROUTINE %s' % (self.items[0], self.items[1])
         else:
-            s = 'SUBROUTINE %s' % (self.name)
-        if self.dummy_args is not None:
-            s += '(%s)' % (self.dummy_args)
-        if self.binding_spec is not None:
-            s += ' %s' % (self.binding_spec)
+            s = 'SUBROUTINE %s' % (self.items[1])
+        if self.items[2] is not None:
+            s += '(%s)' % (self.items[2])
+        if self.items[3] is not None:
+            s += ' %s' % (self.items[3])
         return s
-    def torepr(self):
-        return '%s(%r, %r, %r, %r)'\
-               % (self.__class__.__name__, self.prefix, self.name, self.dummy_args, self.binding_spec)
 
 class Dummy_Arg(StringBase): # R1233
     """
@@ -5381,13 +5730,9 @@
         if len(string)==6: return None,
         return Scalar_Int_Expr(string[6:].lstrip()),
     match = staticmethod(match)
-    def init(self, value):
-        self.value = value
-        return
     def tostr(self): 
-        if self.value is None: return 'RETURN'
-        return 'RETURN %s' % (self.value)
-    def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.value)
+        if self.items[0] is None: return 'RETURN'
+        return 'RETURN %s' % self.items
 
 class Contains_Stmt(StmtBase, STRINGBase): # R1237
     """
@@ -5404,6 +5749,27 @@
     subclass_names = []
     use_names = ['Function_Name', 'Dummy_Arg_Name_List', 'Scalar_Expr']
 
+    def match(string):
+        i = string.find('=')
+        if i==-1: return
+        expr = string[i+1:].lstrip()
+        if not expr: return
+        line = string[:i].rstrip()
+        if not line or not line.endswith(')'): return
+        i = line.find('(')
+        if i==-1: return
+        name = line[:i].rstrip()
+        if not name: return
+        args = line[i+1:-1].strip()
+        if args:
+            return Function_Name(name), Dummy_Arg_Name_List(args), Scalar_Expr(expr)
+        return Function_Name(name), None, Scalar_Expr(expr)
+    match = staticmethod(match)
+    def tostr(self):
+        if self.items[1] is None:
+            return '%s () = %s' % (self.items[0], self.items[2])
+        return '%s (%s) = %s' % self.items
+
 ###############################################################################
 ################ GENERATE Scalar_, _List, _Name CLASSES #######################
 ###############################################################################

Modified: trunk/numpy/f2py/lib/parser/pattern_tools.py
===================================================================
--- trunk/numpy/f2py/lib/parser/pattern_tools.py	2006-12-23 07:08:57 UTC (rev 3489)
+++ trunk/numpy/f2py/lib/parser/pattern_tools.py	2006-12-23 13:56:35 UTC (rev 3490)
@@ -278,6 +278,8 @@
 defined_binary_op = Pattern('<defined-binary-op>','[.][A-Z]+[.]',flags=re.I)
 defined_operator = defined_unary_op | defined_binary_op | extended_intrinsic_operator
 abs_defined_operator = abs(defined_operator)
+defined_op = Pattern('<defined-op>','[.][A-Z]+[.]',flags=re.I)
+abs_defined_op = abs(defined_op)
 
 non_defined_binary_op = intrinsic_operator | logical_literal_constant
 
@@ -339,6 +341,9 @@
 
 subroutine = Pattern('<subroutine>', r'SUBROUTINE', flags=re.I)
 
+select_case = Pattern('<select-case>', r'SELECT\s*CASE', flags=re.I, value='SELECT CASE')
+abs_select_case = abs(select_case)
+
 def _test():
     assert name.match('a1_a')
     assert abs(name).match('a1_a')

Modified: trunk/numpy/f2py/lib/parser/test_Fortran2003.py
===================================================================
--- trunk/numpy/f2py/lib/parser/test_Fortran2003.py	2006-12-23 07:08:57 UTC (rev 3489)
+++ trunk/numpy/f2py/lib/parser/test_Fortran2003.py	2006-12-23 13:56:35 UTC (rev 3490)
@@ -508,14 +508,14 @@
         a = cls('abstract')
         assert isinstance(a, cls),`a`
         assert_equal(str(a),'ABSTRACT')
-        assert_equal(repr(a),"Type_Attr_Spec('ABSTRACT', None)")
+        assert_equal(repr(a),"Type_Attr_Spec('ABSTRACT')")
 
         a = cls('bind (c )')
-        assert isinstance(a, cls),`a`
+        assert isinstance(a, Language_Binding_Spec),`a`
         assert_equal(str(a),'BIND(C)')
 
         a = cls('extends(a)')
-        assert isinstance(a, cls),`a`
+        assert isinstance(a, Type_EXTENDS_Parent_Type_Name),`a`
         assert_equal(str(a),'EXTENDS(a)')
 
         a = cls('private')
@@ -626,6 +626,19 @@
         assert isinstance(a, cls),`a`
         assert_equal(str(a),'a(1) => NULL')
 
+class test_Final_Binding(NumpyTestCase): # R454
+
+    def check_simple(self):
+        cls = Final_Binding
+        a = cls('final a, b')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'FINAL :: a, b')
+        assert_equal(repr(a),"Final_Binding('FINAL', Final_Subroutine_Name_List(',', (Name('a'), Name('b'))))")
+
+        a = cls('final::a')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'FINAL :: a')
+
 class test_Derived_Type_Spec(NumpyTestCase): # R455
 
     def check_simple(self):
@@ -1009,7 +1022,23 @@
         assert isinstance(a, cls),`a`
         assert_equal(str(a),'a : b, 1 : *')
 
+class test_Access_Stmt(NumpyTestCase): # R518
 
+    def check_simple(self):
+        cls = Access_Stmt
+        a = cls('private')
+        assert isinstance(a, cls),`a`
+        assert_equal(str(a),'PRIVATE')
+        assert_equal(repr(a),"Access_Stmt('PRIVATE', None)")
+
+        a = cls('public a,b')
+        assert isinstance(a, cls),`a`
+        assert_equal(str(a),'PUBLIC :: a, b')
+
+        a = cls('public ::a')
+        assert isinstance(a, cls),`a`
+        assert_equal(str(a),'PUBLIC :: a')
+
 class test_Parameter_Stmt(NumpyTestCase): # R538
 
     def check_simple(self):
@@ -1658,6 +1687,25 @@
         assert_equal(str(a),'a % b')
         assert_equal(repr(a),"Proc_Component_Ref(Name('a'), '%', Name('b'))")
 
+class test_Where_Stmt(NumpyTestCase): # R743
+
+    def check_simple(self):
+        cls = Where_Stmt
+        a = cls('where (a) c=2')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'WHERE (a) c = 2')
+        assert_equal(repr(a),"Where_Stmt(Name('a'), Assignment_Stmt(Name('c'), '=', Int_Literal_Constant('2', None)))")
+
+class test_Where_Construct_Stmt(NumpyTestCase): # R745
+
+    def check_simple(self):
+        cls = Where_Construct_Stmt
+        a = cls('where (a)')
+        assert isinstance(a,cls),`a`
+        assert_equal(str(a),'WHERE (a)')
+        assert_equal(repr(a),"Where_Construct_Stmt(Name('a'))")
+
+
 ###############################################################################
 ############################### SECTION  8 ####################################
 ###############################################################################
@@ -1792,6 +1840,27 @@
 ############################### SECTION 11 ####################################
 ###############################################################################
 
+class test_Use_Stmt(NumpyTestCase): # R1109
+
+    def check_simple(self):
+        cls = Use_Stmt
+        a = cls('use a')
+        assert isinstance(a, cls),`a`
+        assert_equal(str(a),'USE :: a')
+        assert_equal(repr(a),"Use_Stmt(None, Name('a'), '', None)")
+
+        a = cls('use :: a, c=>d')
+        assert isinstance(a, cls),`a`
+        assert_equal(str(a),'USE :: a, c => d')
+
+        a = cls('use :: a, operator(.hey.)=>operator(.hoo.)')
+        assert isinstance(a, cls),`a`
+        assert_equal(str(a),'USE :: a, OPERATOR(.HEY.) => OPERATOR(.HOO.)')
+
+        a = cls('use, intrinsic :: a, operator(.hey.)=>operator(.hoo.), c=>g')
+        assert isinstance(a, cls),`a`
+        assert_equal(str(a),'USE, INTRINSIC :: a, OPERATOR(.HEY.) => OPERATOR(.HOO.), c => g')
+
 class test_Module_Nature(NumpyTestCase): # R1110
 
     def check_simple(self):
@@ -1873,7 +1942,7 @@
         a = cls('* 123')
         assert isinstance(a,cls),`a`
         assert_equal(str(a),'*123')
-        assert_equal(repr(a),"Alt_Return_Spec('123')")
+        assert_equal(repr(a),"Alt_Return_Spec(Label('123'))")
 
 class test_Prefix(NumpyTestCase): # R1227
 
@@ -1988,12 +2057,17 @@
         assert_equal(repr(a),"Contains_Stmt('CONTAINS')")
 
 if 1:
+    nof_needed_tests = 0
+    nof_needed_match = 0
+    total_needs = 0
+    total_classes = 0
     for name in dir():
         obj = eval(name)
         if not isinstance(obj, ClassType): continue
         if not issubclass(obj, Base): continue
         clsname = obj.__name__
         if clsname.endswith('Base'): continue
+        total_classes += 1
         subclass_names = obj.__dict__.get('subclass_names',None)
         use_names = obj.__dict__.get('use_names',None)
         if not use_names: continue
@@ -2002,16 +2076,26 @@
             test_cls = eval('test_%s' % (clsname))
         except NameError:
             test_cls = None
+        total_needs += 1
         if match is None:
             if test_cls is None:
-                print '%s needs match implementation and tests' % (clsname)
+                #print 'Needs tests:', clsname
+                print 'Needs match implementation:', clsname
+                nof_needed_tests += 1
+                nof_needed_match += 1
             else:
-                print '%s needs match implementation' % (clsname)
+                print 'Needs match implementation:', clsname
+                nof_needed_match += 1
         else:
             if test_cls is None:
-                print '%s needs tests' % (clsname)
+                #print 'Needs tests:', clsname
+                nof_needed_tests += 1
         continue
-
-
+    print '-----'
+    print 'Nof match implementation needs:',nof_needed_match,'out of',total_needs
+    print 'Nof tests needs:',nof_needed_tests,'out of',total_needs
+    print 'Total number of classes:',total_classes
+    print '-----'
+    
 if __name__ == "__main__":
     NumpyTest().run()



More information about the Numpy-svn mailing list