class Token:

  # --- token types ---
  #
  # Basically the token number can be arbitrary numbers. But to make
  # some comparisons more efficient, the numbers are grouped.
  # group 1: everything below TOK_ATTRIBUTESMAX
  #          Tokens which should not be returned individually, but which are
  #          added as 'attribute' to the previous token.
  tok_COMMENT      = 1   # full line or trailing comment
  tok_COMMENTLINE  = 2   # full line or trailing comment
  tok_F90_DIR      = 3   # !cdir, !$omp etc
  tok_CPP_DIR      = 4   # #include #define #ifdef etc
  tok_IGNORED      = 5   # anything after col 72/132
  tok_CONT_MARK    = 6   # & at begin or end in free, char in col 6 in fixed
  TOK_ATTRIBUTESMAX= 9
  tok_UNKNOWN      = 10  # catch-all class
  tok_LABEL        = 20  #
  tok_QUOTE_START  = 21  # first part of multiline quote
  tok_QUOTE_MIDDLE = 22  # entire line in a multiline quote (ie no quote marks)
  tok_QUOTE_END    = 23  # last part of multiline quote
  tok_QUOTE        = 24  # entire quote that fits on one line
  tok_SEPARATOR    = 25  # ;
  tok_NUMBER       = 26  # number literal
  tok_KEYWORD      = 27  #
  tok_IDENTIFIER   = 28  #
  tok_OPERATOR     = 29  # +,-,*,**,.ge. .and. .not. .true. 
  tok_TRUEFALSE    = 30  # .true. or .false.
  tok_SPECIAL      = 31  # (),
  tok_INCLUDE      = 32  # Special tokens, means that the next token must be
                         # read from an include file - the respective scanner
                         # will be the second element of the token
  tok_DIRECTIVE    = 33  # compiler directive
  tok_PREDIRECTIVE = 34  # preprocessor directive class Variable:
    def __init__(self, sName, oVariableData=None):
        self.sName    = sName                     # Potential an AttributeString
        if oVariableData:
            self.oVarData = oVariableData
        else:
            self.oVarData = VariableData(self.sName,{})
    # --------------------------------------------------------------------------
    # Forward this to the actual VariableData instance
    def __getitem__(self, key): return self.oVarData[key]
    # --------------------------------------------------------------------------
    # Forward this to the actual VariableData instance
    def __setitem__(self, key, value):
        return self.oVarData.__setitem__(key, value)
    # --------------------------------------------------------------------------
    # Forward this to the actual VariableData instance
    def __delitem__(self, key):
        return self.oVarData.__delitem__(key)
    # --------------------------------------------------------------------------
    # This is necessary, since for example in a common block an expression
    # like common /xx/ a, b(10) can be used. Now, to store the information
    # that a common block is used, we need acces to the variable b (which is
    # an ArrayRef). To avoid further tests, the same method is implemented
    # for variables as well.
    def oGetVariable(self): return self
    # --------------------------------------------------------------------------
    # Forward this to the actual VariableData instance
    def GetDeclarationAsString(self, stylesheet):
        return self.oVarData.GetDeclarationAsString(stylesheet)
    # --------------------------------------------------------------------------
    def GetAllUsedVariables(self):
        l = self.oVarData.GetAllUsedVariables()
        l.append(self)
        return l
    # --------------------------------------------------------------------------
    # Sets an attributes for the variable. The attribute can be either
    # a string (in which case the value is set to 1), or an object
    # (e.g. dimension, type). This is forwarded to the respective VariableData
    # instance.
    def SetAttribute(self, att, value=1):
        return self.oVarData.SetAttribute(att, value)
    # --------------------------------------------------------------------------
    # Returns a dictionary with all attributes of a variable.
    def GetAttributes(self): return self.oVarData.GetAttributes()
    # --------------------------------------------------------------------------
    def sGetName(self): return self.oVarData.sGetName()
    # --------------------------------------------------------------------------
    def SetName(self, s) : self.oVarData.SetName(s)
    # --------------------------------------------------------------------------
    # Returns a string with the correct declaration of the variable, e.g.
    # '(1:2, 3:, nlat_dyn+3, nlon_dyn,*)'. This is forwarded to the respective
    # VariableData instance.
    def GetDimensionAsString(self): return self.oVarData.GetDimensionAsString()
    # --------------------------------------------------------------------------
    def oCreateDeclarationStatement(self, nIndent=0, bUseInclude=1, bUseModule=1,
                                    sNewName="", bAddInit=0):
        return self.oVarData.oCreateDeclarationStatement(nIndent,
                                                         bUseInclude=bUseInclude,
                                                         bUseModule=bUseModule,
                                                         sNewName=sNewName,
                                                         bAddInit=bAddInit)
    # --------------------------------------------------------------------------
    def bTypeIs(self, sType):
        return self["type"].bIsType(sType)
    # --------------------------------------------------------------------------
    def bIsArray(self): return self.oVarData.bIsArray()
    # --------------------------------------------------------------------------
    # Displays the variable name and all attributes. This is forwarded to the
    # respective VariableData instance.
    def DisplayAll(self): return self.oVarData.DisplayAll()
    # --------------------------------------------------------------------------
    # Needed for layout2d
    def __len__(self): return len(self.sName)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        sCurrentName = self.oVarData.sGetName()
        if string.lower(sCurrentName)==string.lower(self.sName):
            l.append(stylesheet.sVariable(self.sName))
            return
        # The variable has been renamed. If the current name is a normal string,
        # simply replace it with the new name:
        if type(self.sName)==type(''):
            self.sName=sCurrentName
            l.append(sCurrentName)
            return
        # Otherwise sName is an AttributeString. Create a new instance of
        # AttributeString
        self.sName = self.sName.sCreateCopy(sCurrentName)
        l.append(stylesheet.sVariable(self.sName))
    # --------------------------------------------------------------------------
    def __repr__(self): return self.sName
    # -------------------------------------------------------------------------- class AttributeString(str):
    def __init__(self, s):
        str.__init__(self, s)
        # If this object is initialised with an AttributeString,
        # copy the attributes as well
        if isinstance(s, AttributeString):
            self.lPrefix  = s.GetPrefixAttributes()[:]
            self.lPostfix = s.GetPostfixAttributes()[:]
        else:
            self.lPrefix  = []
            self.lPostfix = []
    # --------------------------------------------------------------------------
    # Creates a new attribute string which has the same pre- and postfix
    # attributes, but a new string.
    def sCreateCopy(self, s):
        new = AttributeString(s)
        new.SetPrefixAttributes(self.GetPrefixAttributes())
        new.SetPostfixAttributes(self.GetPostfixAttributes())
        return new
    # --------------------------------------------------------------------------
    # Splits an AttributeString into two strings, the first one containing
    # all prefix attributes, the second one all postfix ones. The parameter
    # n specified the number of character to for the first string.
    def tSplitString(self, n):
        s1 = AttributeString(self[0:n])
        s2 = AttributeString(self[n: ])
        s1.SetPrefixAttributes(self.GetPrefixAttributes())
        s2.SetPostfixAttributes(self.GetPostfixAttributes())
        return s1,s2
    # --------------------------------------------------------------------------
    def SetPrefixAttributes(self,  l) : self.lPrefix = l[:]
    # --------------------------------------------------------------------------
    def SetPostfixAttributes(self, l) : self.lPostfix = l[:]
    # --------------------------------------------------------------------------
    def AppendPrefix(self,  o):
        if type(o)==ListType:
            self.lPrefix.extend(o)
        else:
            self.lPrefix.append(o)
    # --------------------------------------------------------------------------
    def AppendPostfix(self, o):
        if type(o)==ListType:
            self.lPostfix.extend(o)
        else:
            self.lPostfix.append(o)
    # --------------------------------------------------------------------------
    def GetPrefixAttributes(self ): return self.lPrefix
    # --------------------------------------------------------------------------
    def GetPostfixAttributes(self): return self.lPostfix
    # --------------------------------------------------------------------------
    def GetString(self): return str.__str__(self)
    # --------------------------------------------------------------------------
    # We have to overwrite this method so that a new AttributeString is
    # returned!
    def upper(self):
        return self.sCreateCopy(str.__str__(self).upper())
    # --------------------------------------------------------------------------
    # We have to overwrite this method so that a new AttributeString is
    # returned!
    def lower(self):
        return self.sCreateCopy(str.__str__(self).lower())
    # --------------------------------------------------------------------------
    # We have to overwrite this method so that a new AttributeString is
    # returned!
    def capitalize(self):
        return self.sCreateCopy(str.__str__(self).capitalize())
    # --------------------------------------------------------------------------
    #def ToList(self, stylesheet, l): return l.append(str.__str__(self))
    def ToList(self, stylesheet, l): return l.append(self)
    # --------------------------------------------------------------------------
    #def __repr__(self): return str.__str__(self)
    # Debug: output an attribute string with all attributes
    def __repr__(self):
        return "%s-%s-%s"%(`self.lPrefix`,str.__str__(self),`self.lPostfix`) class BasicExpression(BasicRepr):
    def __init__(self, o=None, operator=None, o2=None):
        self.l = DoubleList()
        if o:
            if operator:
                self.l.append(o, operator)
                if o2:
                    self.l.append(o2)
            else:
                self.l.append(o)

    # --------------------------------------------------------------------------
    def append(self, obj, sOperator=None):
        self.l.append(obj, sOperator)
    # --------------------------------------------------------------------------
    # Returns a list of all used variables in this expression
    def GetAllUsedVariables(self):
        l=[]
        for i in self.l.GetMainList():
            if isinstance(i,Variable.Variable):
                l.append(i)
            else:
                l.extend(i.GetAllUsedVariables())
        return l
    # --------------------------------------------------------------------------
    # In this case all variables MUST be read expression, since an expression
    # can't be written.
    def GetVarUsage(self, varUsage, sType="read", obj=None, loc=None):
        for i in self.l.GetMainList():
            varUsage.AddVariable(i, "read", obj, loc)
    # --------------------------------------------------------------------------
    def lGetAsSimpleList(self):
        return self.l.lGetAsSimpleList()
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l2d):
        self.l.ToList(stylesheet, l2d) class OneArraySpec(BasicRepr):
    def __init__(self, lower=None, sColon=None, upper=None):
        self.l = [lower, sColon, upper]
    # --------------------------------------------------------------------------
    def GetAllUsedVariables(self):
        l=[]
        if self.l[0]:
            l.extend(self.l[0].GetAllUsedVariables())
        if self.l[2]:
            l.extend(self.l[2].GetAllUsedVariables())
        return l
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        for i in self.l:
            if i: stylesheet.ToList(i, l) class ArraySpecWithName(BasicRepr):
    def __init__(self, var=None, sName="", arrayspec=None, sParOpen=None):
        self.var           = var
        self.sName         = sName
        if not arrayspec:
            self.arrayspec = ArraySpec()
        else:
            self.arrayspec = arrayspec
        if sParOpen:
            self.arrayspec.SetParOpen(sParOpen)
        else:
            self.arrayspec.SetParOpen("(")
    # --------------------------------------------------------------------------
    def SetAttribute(self, att, value): self.var.SetAttribute(att, value)
    # --------------------------------------------------------------------------
    def SetParOpen(self, sParOpen):
        self.arrayspec.SetParOpen(sParOpen)
    # --------------------------------------------------------------------------
    def SetParClose(self, sParClose):
        self.arrayspec.SetParClose(sParClose)
    # --------------------------------------------------------------------------
    def AddSubscript(self, exp, sComma=None):
        self.arrayspec.AddSubscript(exp, sComma)
    # --------------------------------------------------------------------------
    def GetArraySpec(self): return self.arrayspec
    # --------------------------------------------------------------------------
    def oGetVariable(self): return self.var
    # --------------------------------------------------------------------------
    # Returns a list of all variables used in this array declaration
    def GetAllUsedVariables(self):
        return self.arrayspec.GetAllUsedVariables()
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage, sType="read", obj=None, loc=None):
        # Add the main variable as whatever is appropriate (read or write).
        # e.g: a(i) = b(i) --> a will have sType='write', and b will have
        # sType="read"
        if self.var:
            varUsage.AddVariable(self.var,   sType,  obj, loc)
        varUsage.AddVariable(self.arrayspec, "read", obj, loc)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        if self.var:
            stylesheet.ToList(self.var, l)
        elif self.sName:
            l.append(stylesheet.sKeyword(self.sName))
        self.arrayspec.ToList(stylesheet, l) class Common(BasicStatement):
    def __init__(self, loc, sCommon="COMMON", nIndent=0, sGlobal=None):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sCommon = sCommon
        self.lName   = []               # List of the names of common blocks
        self.lObj    = []               # List of list of objects in c.b.
        self.sGlobal = sGlobal
    # --------------------------------------------------------------------------
    def GetAllUsedVariables(self):
        l=[]
        for i in self.lObj:
            lObjects = i.GetMainList()
            l.extend( map(lambda x: x.oGetVariable(), lObjects) )
        return l
    # --------------------------------------------------------------------------
    # Adds a name of a common block, which is: [ / [ common-block-name ] / ].
    # If the nameless common block is used with //, just don't specify sName,
    # in case that the nameless common block is used without //, calls
    # this function with all parameters = None. Parameters:
    #
    # sComma -- An optional leading comma, e.g.: [[,]/[name]/object-list
    #
    # sSlash1 -- First slash
    #
    # sName -- Name of the common block (if applicable)
    #
    # sSlash2 -- Second ('closing') slash
    def AddCommonBlockName(self, sComma=None, sSlash1=None, sName=None,
                           sSlash2=None):
        self.lName.append( (sComma, CommonBlockName(sSlash1, sName, sSlash2)) )
        self.lObj.append(DoubleList())

    # --------------------------------------------------------------------------
    # Add an object to the last added common block name
    def AddCommonObject(self, obj, sComma=None):
        self.lObj[-1].append(obj, sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        if self.sGlobal:
            BasicStatement.ToList(self, stylesheet, l)
            l.append(stylesheet.sKeyword(self.sGlobal), nIndentNext=1)
            l.append(stylesheet.sKeyword(self.sCommon), nIndentNext=1)
        else:
            BasicStatement.ToList(self, stylesheet, l)
            l.append(stylesheet.sKeyword(self.sCommon), nIndentNext=1)
        n = 0
        for t in self.lName:
            if t[0]: l.append(t[0])
            stylesheet.ToList(t[1], l)
            self.lObj[n].ToList(stylesheet, l)
            n=n+1
    # -------------------------------------------------------------------------- class CrayPointer(BasicStatement):
    def __init__(self, loc, sPointer='POINTER', nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sPointer = sPointer
        self.lPointer = DoubleList()
    # --------------------------------------------------------------------------
    def AddPointer(self, pointer, sComma=None):
        self.lPointer.append(pointer, sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(self.sPointer, nIndentNext=1)
        self.lPointer.ToList(stylesheet, l) class CrayPointerTuple:
    def __init__(self, sParOpen, pointer, sComma, data, sParClose):
        self.l=[sParOpen, pointer, sComma, data, sParClose]
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        l.append(self.l[0])
        stylesheet.ToList(self.l[1], l)
        l.append(self.l[2])
        stylesheet.ToList(self.l[3], l)
        l.append(self.l[4]) class Data(BasicStatement):
    def __init__(self, loc, sData, nIndent):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sData           = sData
        self.lDataStatements = []
    # --------------------------------------------------------------------------
    def AddDataStatement(self, ds):
        self.lDataStatements.append(ds)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sData), nIndentNext=1)
        for i in self.lDataStatements:
            i.ToList(stylesheet, l)
            l.indent(1) class DataStatementSet(BasicRepr):
    def __init__(self, sComma=None):
        self.sComma     = sComma
        self.ObjectList = DoubleList()
        self.DataValue  = None
    # --------------------------------------------------------------------------
    def AddObject(self, obj, sComma=None): self.ObjectList.append(obj, sComma)
    # --------------------------------------------------------------------------
    def AddValueList(self, vl): self.DataValue = vl
    # --------------------------------------------------------------------------
    def AddSecondSlash(self, sSlash): self.sSlash2 = sSlash
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        if self.sComma:
            l.append(self.sComma, nIndentNext=1)
        self.ObjectList.ToList(stylesheet, l)
        self.DataValue.ToList(stylesheet,  l) class DataValueList(BasicRepr):
    def __init__(self, sSlash1='/'):
        self.sSlash1   = sSlash1
        self.sSlash2   = None
        self.ValueList = DoubleList()
    # --------------------------------------------------------------------------
    def AddValue(self, obj, sComma=None): self.ValueList.append(obj, sComma)
    # --------------------------------------------------------------------------
    def AddSlash(self, sSlash): self.sSlash2 = sSlash
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        l.append(self.sSlash1)
        self.ValueList.ToList(stylesheet, l)
        l.append(self.sSlash2) class Declaration(BasicStatement):
    def __init__(self, sType, sComma=None, loc=None, nIndent=0, var=None,
                 attribute=None):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sType        = sType
        self.sComma       = sComma
        self.lAttributes  = DoubleList()
        self.lColons      = []
        self.lVars        = DoubleList()
        if var:
            self.AppendVariable(var)
        if attribute:
            self.AddAttribute(attribute)
    # --------------------------------------------------------------------------
    # Add a variable or an array specification to the list of declaration
    def AddDeclaredVariable(self, var, sComma=None):
        self.lVars.append(var, sComma)
    # --------------------------------------------------------------------------
    # Add an attribute, like 'allocateable', ...
    def AddAttribute(self, sAtt, sComma=None):
        if len(self.lAttributes)==0 and not self.sComma:
            self.sComma=","
        self.lAttributes.append(sAtt, sComma)
    # --------------------------------------------------------------------------
    # Adds the optional double colon of a declaration. Parameters:
    # 
    # c1/c2 -- Each of the two colons (the scanner returns two colons for a ::)
    def AddDoubleColons(self, c1, c2): self.lColons=[c1,c2]
    # --------------------------------------------------------------------------
    # This function is used to construct new declaration statements:
    def AppendVariable(self, v):
        if len(self.lVars)==0:
            self.lColons=[":",":"]
            self.lVars.append(v)
        else:
            self.lVars.append(",", v)
    # --------------------------------------------------------------------------
    def GetAttributes(self):
        return self.lAttributes.GetMainList()
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        stylesheet.ToList(self.sType, l)
        if self.sComma:
            l.append(self.sComma)
        l.indent(1)
        # The if is not really necessary, but without it two spaces
        # would be added in case of an empy attribute list
        if len(self.lAttributes.GetMainList())>0:
            self.lAttributes.ToList(stylesheet, l, bAddSpace=1)
            l.indent(1)
        if self.lColons:
            l.extend(self.lColons)
            l.indent(1)
        self.lVars.ToList(stylesheet, l, bAddSpace=1) class Dimension(BasicStatement):
    def __init__(self, loc, sDim="DIMENSION", nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.lVars   = DoubleList()
        self.sDim    = sDim
        self.lColons = []
    # --------------------------------------------------------------------------
    def AddDoubleColons(self, c1, c2):
        self.lColons=[c1,c2]
    # --------------------------------------------------------------------------
    def AddArraySpec(self, arrayspec, sComma=None):
        self.lVars.append(arrayspec, sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sDim), nIndentNext=1)
        if self.lColons:
            l.extend(self.lColons)
            l.indent(1)
        self.lVars.ToList(stylesheet, l, bAddSpace=1) class Equivalence(BasicStatement):
    def __init__(self, loc, sEq="EQUIVALENCE", nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sEq       = sEq
        self.lObjects  = DoubleList()
    # --------------------------------------------------------------------------
    def AddObject(self, obj, sComma=None):
        self.lObjects.append(obj, sComma)
    # --------------------------------------------------------------------------    
    def GetAllUsedVariables(self):
        l=[]
        for i in self.lObjects.GetMainList():
            l.extend(i.GetAllUsedVariables())
        return l
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sEq))
        self.lObjects.ToList(stylesheet, l) class EquivalenceItem(BasicRepr):
    def __init__(self, sParOpen):
        self.sParOpen  = sParOpen
        self.l         = DoubleList()
        self.sParClose = ''
    # --------------------------------------------------------------------------
    def AddObject(self, obj, sComma=None): self.l.append(obj, sComma)
    # --------------------------------------------------------------------------
    def SetParClose(self, sParClose): self.sParClose = sParClose
    # --------------------------------------------------------------------------
    def GetAllEquivalentVariables(self):
        return self.l.GetMainList()
    # --------------------------------------------------------------------------
    def GetAllUsedVariables(self):
        l=[]
        for i in self.l.GetMainList():
            l.extend(i.GetAllUsedVariables())
        return l
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        l.append(self.sParOpen)
        self.l.ToList(stylesheet, l)
        l.append(self.sParClose) class External(BasicStatement):
   # Stores an external declaration
    def __init__(self, loc, sExternal="EXTERNAL", nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sExternal = sExternal
        self.lColon    = []
        self.l         = DoubleList()
    # --------------------------------------------------------------------------
    def AddDoubleColon(self, sCol1, sCol2): self.lColon=[sCol1,sCol2]
    # --------------------------------------------------------------------------
    def AddExternal(self, ext, sComma=None):
        self.l.append(ext, sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sExternal), nIndentNext=1)
        if self.lColon:
            l.extend(self.lColon)
        self.l.ToList(stylesheet, l) class Implicit(BasicStatement):

    # Stores a parameter declaration
    def __init__(self, sImplicit="IMPLICIT", loc=None, nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sImplicit = sImplicit
        self.sNone     = None
        self.type      = None
        self.l         = DoubleList()
        self.sParOpen  = None
        self.sParClose = None
    # --------------------------------------------------------------------------
    def SetParOpen(self, sParOpen): self.sParOpen = sParOpen
    # --------------------------------------------------------------------------
    def SetParClose(self, sParClose): self.sParClose = sParClose
    # --------------------------------------------------------------------------
    def SetImplicitNone(self, sNone="NONE"): self.sNone=sNone
    # --------------------------------------------------------------------------
    def isNone(self): return self.sNone!=None
    # --------------------------------------------------------------------------
    def SetType(self, type): self.type=type
    # --------------------------------------------------------------------------
    def AddLetter(self, sFrom, sDash=None, sTo=None, sComma=None):
        self.l.append(FromTo(sFrom, sDash, sTo), sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sImplicit),nIndentNext=1)
        if self.sNone:
            l.append(stylesheet.sKeyword(self.sNone))
            return
        stylesheet.ToList(self.type, l)
        l.append(self.sParOpen)
        self.l.ToList(stylesheet, l)
        l.append(self.sParClose) class Intrinsic(BasicStatement):
    # Stores an intrinsic declaration
    def __init__(self, loc, sIntri="INTRINSIC", nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sIntri  = sIntri
        self.lColons = None
        self.l       = DoubleList()
    # --------------------------------------------------------------------------
    def AddDoubleColons(self, c1, c2): self.lColons=[c1,c2]
    # --------------------------------------------------------------------------
    def AddIntrinsic(self, obj, sComma=None): self.l.append(obj, sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sIntri),nIndentNext=1)
        if self.lColons:
            l.extend(self.lColons)
        self.l.ToList(stylesheet, l) class Intent(BasicRepr):
    def __init__(self, sIntent, sParOpen, s, sParClose):
        self.l = [sIntent, sParOpen, s, sParClose]
    # --------------------------------------------------------------------------
    def GetIntent(self): return string.upper(self.l[2])
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        l.extend(self.l[:]) class Namelist(Common):
    def __init__(self, loc, sNamelist="namelist", nIndent=0, sGlobal=None):
        Common.__init__(self, loc=loc, sCommon=sNamelist, nIndent=nIndent,
                        sGlobal=sGlobal)
    # --------------------------------------------------------------------------
    def AddNamelistName(self, sComma=None, sSlash1=None, sName=None,
                        sSlash2=None):
        self.AddCommonBlockName(sComma, sSlash1, sName, sSlash2)
    # --------------------------------------------------------------------------
    # Add an object to the last added namelist
    def AddNamelistObject(self, obj, sComma=None):
        self.AddCommonObject(obj, sComma=None) class ModuleProcedure(BasicStatement):
    def __init__(self, loc, sModule=None, sProcedure="PROCEDURE", nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sModule    = sModule
        self.sProcedure = sProcedure
        self.l          = DoubleList()
    # --------------------------------------------------------------------------
    def AddProcedure(self, obj, sComma=None): self.l.append(obj, sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        if self.sModule:
            l.append(self.sModule,    nIndentNext=1)
            l.append(self.sProcedure, nIndentNext=1)
        else:
            l.append(self.sProcedure, nIndentNext=1)
        self.l.ToList(stylesheet, l) class Parameter(BasicStatement):

    # Stores a parameter declaration
    def __init__(self, loc, sParam="PARAMETER", nIndent=0, sParOpen="("):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sParam    = sParam
        self.l         = DoubleList()
        self.sParOpen  = sParOpen
        self.sParClose = None
    # --------------------------------------------------------------------------
    def AddVarValue(self, var, sEqual, obj, sComma=None):
        a=Assignment(sLabel=None, loc=None, nIndent=0, lhs=var,
                     sEqual=sEqual, rhs=obj, bNoIndent=1)
        self.l.append(a, sComma)
    # --------------------------------------------------------------------------
    def SetParClose(self, sParClose): self.sParClose=sParClose
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sParam))
        l.append(self.sParOpen)
        self.l.ToList(stylesheet, l)
        l.append(self.sParClose) class Pointer(BasicStatement):
    def __init__(self, loc, sPointer='POINTER', nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sPointer = sPointer
        self.lPointer = DoubleList()
        self.lColons  = None
    # --------------------------------------------------------------------------
    def AddDoubleColons(self, c1, c2): self.lColons=[c1,c2]
    # --------------------------------------------------------------------------
    def AddPointer(self, pointer, sComma=None):
        self.lPointer.append(pointer, sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(self.sPointer)
        if self.lColons:
            l.indent(1)
            l.extend(self.lColons)
        l.indent(1)
        self.lPointer.ToList(stylesheet, l) class Private(Public):
    def __init__(self,  loc, sPrivate="PRIVATE", nIndent=0):
        Public.__init__(self, loc, sPrivate, nIndent) class Public(BasicStatement):
    # Stores a public statement declaration
    def __init__(self, loc, sPublic="PUBLIC", nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sPublic = sPublic
        self.lColons = None
        self.l       = DoubleList()
    # --------------------------------------------------------------------------
    def AddDoubleColons(self, c1, c2): self.lColons=[c1,c2]
    # --------------------------------------------------------------------------
    def AddObject(self, obj, sComma=None): self.l.append(obj, sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sPublic), nIndentNext=1)
        if self.lColons:
            l.extend(self.lColons)
        self.l.ToList(stylesheet, l) class Save(BasicStatement):

    # Stores a parameter declaration
    def __init__(self, loc, sSave="SAVE", nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sSave   = sSave
        self.lColons = None
        self.l       = DoubleList()
    # --------------------------------------------------------------------------
    def AddDoubleColons(self, c1, c2): self.lColons=[c1,c2]
    # --------------------------------------------------------------------------
    def AddCommonBlock(self, sSlash1, obj, sSlash2, sComma=None):
        self.l.append(CommonBlockName(sSlash1, obj, sSlash2), sComma)
    # --------------------------------------------------------------------------
    def AddObject(self, obj, sComma=None):
        self.l.append(obj, sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sSave), nIndentNext=1)
        if self.lColons:
            l.extend(self.lColons)
        self.l.ToList(stylesheet, l) class Type(BasicRepr):

    # Constructor. Parameters:
    #
    # sType -- The basic type
    #
    # sType2 -- Used for double precision
    #
    def __init__(self, sType, sType2=None):
        self.sType  = sType
        self.sType2 = sType2
        self.sStar  = None
        self.len    = None
        self.lKind  = []
    # --------------------------------------------------------------------------
    def bIsType(self, sType):
        return string.upper(self.sType)==string.upper(sType)
    # --------------------------------------------------------------------------
    def SetStar(self, sStar): self.sStar = sStar
    # --------------------------------------------------------------------------
    def SetLen(self, l) : self.lKind = [l]
    # --------------------------------------------------------------------------
    def SetParOpen(self, sParOpen): self.lKind.append(sParOpen)
    # --------------------------------------------------------------------------
    def SetParClose(self, sParClose): self.lKind.append(sParClose)
    # --------------------------------------------------------------------------
    # Adds the kind information: Either '(5)', or '(kind=5)'
    def AddKindOrLen(self, sKeyword=None, sEqual=None, obj=None, sComma=None):
        if sKeyword:
            self.lKind.append( (sKeyword, sEqual, obj) )
        else:
            self.lKind.append(obj)
        if sComma: self.lKind.append(sComma)
    # --------------------------------------------------------------------------
    # The tuple t is either (keyword,'=',exp) or a single exp obj. This will
    # return a tuple where the keyword is handled by the stylesheet
    def HandleKeywords(self, t, stylesheet, l):
        if type(t)==TupleType:
            l.append(stylesheet.sKeyword(t[0]))
            l.append(t[1])
            stylesheet.ToList(t[2], l)
        else:
            stylesheet.ToList(t, l)
    # --------------------------------------------------------------------------
    # Convert a basic type into a list.
    def ToList(self, stylesheet, l):
        l.append(stylesheet.sKeyword(self.sType))
        if self.sType2:
            l.append(stylesheet.sKeyword(self.sType2))
        if self.sStar:
            l.append(self.sStar)

        if not self.lKind:
            return
        # E.g. integer *8
        if len(self.lKind)==1:
            stylesheet.ToList(self.lKind[0], l)
        # E.g. (4)  or (KIND=4), since ('KIND','=',4) is a single tuple.
        elif len(self.lKind)==3:
            l.append(self.lKind[0])                             # (
            self.HandleKeywords(self.lKind[1], stylesheet, l)   # 3
            l.append(self.lKind[2])                             # )
        # E.g. (3, len=5)
        else:
            l.append(self.lKind[0])                             # (
            self.HandleKeywords(self.lKind[1],stylesheet, l)    # 4
            l.append(self.lKind[2])                             # ,
            self.HandleKeywords(self.lKind[3], stylesheet, l)   # 5 
            l.append(self.lKind[4], nIndentNext=1)              # ) class Use(BasicStatement):
    # Constructor. Parameters:
    #
    # sub -- progunit Object, used to store variables in
    def __init__(self, loc, sUse="USE", nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sUse        = sUse
        self.lNature     = []
        self.lColons     = []
        self.lOnly       = DoubleList()
        self.lOnlyString = ''
        self.lRename     = DoubleList()
        self.sComma      = None
        self.sName       = None
    # --------------------------------------------------------------------------
    # Returns the name of the module
    def GetName(self): return self.sName
    # --------------------------------------------------------------------------
    # Returns true if this is a 'use only' use statement
    def IsOnly(self): return len(self.lOnly)>0
    # --------------------------------------------------------------------------
    # Returns a list of all imported entries from a module
    def GetOnlyList(self):
        return self.lOnly
    # --------------------------------------------------------------------------
    # Returns true if this has a rename list
    def HasRename(self): return len(self.lRename)>0
    # --------------------------------------------------------------------------
    # Returns a list of tuples (from,to) for all renamed entries
    def GetRenameList(self):
        l=[]
        for i in self.lRename:
            l.append( (i[0], i[1]) )
        return l
    # --------------------------------------------------------------------------
    def SetNature(self, sComma, sNature): self.lNature=[sComma, sNature]
    # --------------------------------------------------------------------------
    # Adds the optional double colon of an use statement. Parameters:
    # 
    # c1/c2 -- Each of the two colons (the scanner returns two colons for a ::)
    def AddDoubleColon(self, c1, c2): self.lColons=(c1,c2)
    # --------------------------------------------------------------------------
    # Sets the module name to import from. Parameter:
    #
    # sName -- Name
    def SetName(self, sName):
        self.sName=sName
    # --------------------------------------------------------------------------
    # Adds the comma which comes before a "ONLY" or a rename list
    def AddComma(self, sComma): self.sComma=sComma
    # --------------------------------------------------------------------------
    # Adds the comma, the 'only' string, and the colon. If this function was
    # called, no rename function  (AddRenameComma/AddRename) should be called.
    def AddOnlyString(self, sOnly="ONLY", sColon=":"):
        self.lOnlyString=[sOnly, sColon]
    # --------------------------------------------------------------------------
    # Adds a 'only' import plus (optionally) a comma
    def AddOnly(self, var, sComma=None): self.lOnly.append(var, sComma)
    # --------------------------------------------------------------------------
    # Adds a rename statement, i.e. the ", from => to" part - including the
    # comma!
    def AddRename(self, sFrom, sArrow, varTo, sComma=None):
        self.lRename.append( RenameVar(sFrom, sArrow, varTo), sComma )
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sUse), nIndentNext=1)
        if self.lNature: l.extend(self.lNature)
        if self.lColons:
            l.extend(self.lColons)
            l.indent(1)
        l.append(self.sName)
        # If it's an 'only' use statement
        if self.sComma: l.append(self.sComma)
        if self.lOnly:
            l.extend(self.lOnlyString)
            self.lOnly.ToList(stylesheet, l)
        else:
            self.lRename.ToList(stylesheet, l) class UserType(BasicRepr):
    # Stores a user defined type
    def __init__(self, sType="TYPE", sParOpen='(', sSubType=None, sParClose=')'):
        self.sTypeString = sType
        self.sParOpen    = sParOpen
        self.type        = sSubType
        self.sParClose   = sParClose
    # --------------------------------------------------------------------------
    def bIsType(self, sType):
        return self.type.bIsType(sType)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        l.append(stylesheet.sKeyword(self.sTypeString))
        l.append(self.sParOpen)
        stylesheet.ToList(self.type, l)
        l.append(self.sParClose) class VariableWithInit(BasicRepr):
    def __init__(self, var, sEqual=None, value=None, dataobj=None):
        self.var = var
        if sEqual:
            self.value  = value
            self.sEqual = sEqual
        else:
            self.value  = dataobj
            self.sEqual = None
    # --------------------------------------------------------------------------
    def GetAllUsedVariables(self):
        return self.var.GetAllUsedVariables()
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        if self.sEqual:
            self.var.ToList(stylesheet, l)
            l.append(self.sEqual)
            self.value.ToList(stylesheet, l)
        else:
            self.var.ToList(stylesheet, l)
            l.indent(1)
            self.value.ToList(stylesheet, l) class VariableWithLen(BasicRepr):
    def __init__(self, var, sStar=None, len=None):
        self.var      = var
        self.sStar    = sStar
        self.len      = len
        self.lAddStar = None
    # --------------------------------------------------------------------------
    def SetParenthesisStar(self, sParOpen='(', sStar='*', sParClose=')'):
        self.lAddStar=[sParOpen, sStar, sParClose]
    # --------------------------------------------------------------------------
    def GetAllUsedVariables(self):
        return self.var.GetAllUsedVariables()
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        
        self.var.ToList(stylesheet, l)
        l.append(self.sStar)
        if self.len:      self.len.ToList(stylesheet, l)
        if self.lAddStar: l.extend(self.lAddStar) class SubroutineStatement(BasicStatement):
    def __init__(self, loc=None, lPrefix=[], sSub="SUBROUTINE", sName="",
                 nIndent=0, oSub = None):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.lPrefix     = lPrefix
        self.sSub        = sSub
        self.sName       = sName
        self.lArgs       = DoubleList()
        self.sParOpen    = None
        self.sParClose   = None
        self.oSub        = oSub
    # --------------------------------------------------------------------------
    def SetParOpen(self, sParOpen): self.sParOpen = sParOpen
    # --------------------------------------------------------------------------
    def SetParClose(self, sParClose): self.sParClose = sParClose
    # --------------------------------------------------------------------------
    def GetName(self): return self.sName
    # --------------------------------------------------------------------------
    def GetPrefix(self): return self.lPrefix
    # --------------------------------------------------------------------------
    def GetArguments(self): return self.lArgs.GetMainList()
    # --------------------------------------------------------------------------
    def AddArgument(self, sName, sComma=None, d=None):
        if self.sParOpen==None: self.sParOpen="("
        self.sParClose = ")"
        if sComma==None and \
               len(self.lArgs.lGetSecondaryList())==len(self.lArgs)-1:
            self.lArgs.append(",", sName)
        else:
            self.lArgs.append(sName, sComma)
            
        if self.oSub:
            self.oSub.AddArgument(sName, sComma=sComma, d=d)
            
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        for i in self.lPrefix:
            l.append(stylesheet.sKeyword(i), nIndentNext=1)
        l.append(stylesheet.sKeyword(self.sSub), nIndentNext=1)
        l.append(self.sName)
        if not self.sParOpen:
            return 
        l.append(self.sParOpen)
        self.lArgs.ToList(stylesheet, l)
        l.append(self.sParClose)
                 
    # -------------------------------------------------------------------------- class InterfaceStatement(BasicStatement):
    def __init__(self, loc=None, sInterface='INTERFACE', sAbstract=None,
                 nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.l = [sAbstract, sInterface]
    # --------------------------------------------------------------------------
    # A GenericSpec can be simply the name, or OPERATOR(operator);
    # READ(FORMATTED), ...
    def AddGenericSpec(self, *s):
        for i in s:
            self.l.append(i)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        if self.l[0]: l.append(stylesheet.sKeyword(self.l[0]), nIndentNext=1)
        l.append(stylesheet.sKeyword(self.l[1]))
        for i in self.l[2:]:
            l.append(i, nIndent=1) class EndInterfaceStatement(BasicStatement):
    def __init__(self, loc=None, sEnd='END', sInterface='INTERFACE', nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.l     = [sEnd, sInterface]
        self.sName = None
    # --------------------------------------------------------------------------
    def SetName(self, sName): self.sName = sName
    # --------------------------------------------------------------------------
    # A GenericSpec can be simply the name, or OPERATOR(operator);
    # READ(FORMATTED), ...
    def AddGenericSpec(self, *s):
        for i in s:
            self.l.append(i)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.l[0]))                 # End
        if len(self.l)>1:
            l.append(stylesheet.sKeyword(self.l[1]), nIndent=1)  # Interface
        if len(self.l)>2:
            l.appen(self.l[1], nIndent=1)                        # name class ProgUnit(Variables, list, BasicRepr):
    # Constructor for a program unit object. Parameter:
    #
    # sType -- Type of the program unit (subroutine, function, program)
    #
    # sName -- Name of unit
    #
    # nLine -- Line number
    #
    # nColumn -- Column number
    #
    def __init__(self, obj=None):
        self._bIsExec         = 0
        Variables.__init__(self)
        if obj:
            self.nLastDeclaration = 1
            list.__init__(self, [obj])
        else:
            self.nLastDeclaration = 0
            list.__init__(self)
        self.contains         = None
        self.oContainedIn     = None
        self.lContains        = []
        self.lCalls           = []
        self.lFuncCalls       = []
        # The StatementIndex contains the index position of all real Fortran
        # statements. Most function will only access these statements (and not
        # comment lines, directive lines, ...), so the default is to return
        # only statements. Separate functions (oGetLine(), lGetLines()) must be
        # used if all statements are needed.
        self.lAllStatements  = []
    # --------------------------------------------------------------------------
    def delete(self, i):
        return self.remove(i)
    # --------------------------------------------------------------------------
    def __getitem__(self, n):
        return self.lAllStatements[n]
    # --------------------------------------------------------------------------
    def oGetLine(self,n):
        return list.__getitem__(self, n)
    # --------------------------------------------------------------------------
    def lGetLines(self,n):
        return self[:]
    # --------------------------------------------------------------------------
    # Renamed from 'append'. If append is overwritten here, this object (for
    # whatever reasons) can't be deepcopied anymore (apparently deepcopy calls
    # append, before setting _bIsExec, so that append fails).
    def AppendStatement(self, d):
        if self._bIsExec:
            list.append(self,d)
        else:
            self.AddDeclaration(d)
        # If its a real statement, add the index to the statement index list
        if d.isStatement():
            self.lAllStatements.append(d)
    # --------------------------------------------------------------------------
    # Adds a declaration (or a list of declarations) at the right place of the
    # program unit.
    def AddDeclaration(self, d):
        # Support for adding a list of declarations
        if type(d)==type([]):
            for i in d:
                self.AddDeclaration(i)
            return
        if len(self)==self.nLastDeclaration:
            list.append(self, d)
            self.nLastDeclaration = len(self)
        else:
            self.insert(self.nLastDeclaration,d)
            self.nLastDeclaration = self.nLastDeclaration+1
    # --------------------------------------------------------------------------
    def SetIsExec(self, b): self._bIsExec = b
    # --------------------------------------------------------------------------
    def bIsExec(self): return self._bIsExec
    # --------------------------------------------------------------------------
    # The name is stored in the first statement, which is the subroutine-,
    # function-, ... -statement
    def sGetName(self): return self[0].GetName()
    # --------------------------------------------------------------------------
    # Return the type of a program unit, i.e.:  'module', 'subroutine',
    # 'program', 'function', 'blockdata'
    def sGetType(self): return self.__class__.__name__.lower()
    # --------------------------------------------------------------------------
    # Inserts a statement before (or after) another statement. This must be a
    # pointer to a statement, not a line number!
    def Insert(self, statement, before=None, after=None):
        # Support lists of statements, so simple statements are treated
        # as 1-element lists.
        if type(statement) != type([]):
            statement = [statement]
            
        if not before:
            if not after:
                self.extend(statement)
                return
            sToFind = after
            nDelta  = 1
        else:
            sToFind = before
            nDelta  = 0

        # First insert in list of all lines
        # ---------------------------------
        nCount = 0
        for i in self:
            if i == sToFind:
                for j in range(len(statement)-1, -1, -1):
                    self.insert(nCount+nDelta, statement[j])
                break
            nCount = nCount + 1
        nCount = 0

        # Then insert in lists of all statements (i.e. without comments etc)
        # ------------------------------------------------------------------
        for i in self.lAllStatements:
            if i == sToFind:
                for j in range(len(statement)-1, -1, -1):
                    if(statement[j].isStatement()):
                        self.lAllStatements.insert(nCount+nDelta, statement[j])
                return
            nCount = nCount + 1
                
        # No insertion point found
        # ------------------------
        self.extend(statement)
        return -nCount
        
    # --------------------------------------------------------------------------
    def AddExecution  (self, e): self.append(e)
    # --------------------------------------------------------------------------
    def AddEnd        (self, e): self.append(e)
    # --------------------------------------------------------------------------
    # Adds an argument of a program unit. Each argument is stored as an id
    # only (pointer to variable object), so that variables can easily be renamed
    def AddArgument(self, sName, d=None, sComma=None):
        if d==None: d={}
        d["argument"]=1
        var=Variables.GetVariable(self, sName, d, bAutoAdd=1)
    # --------------------------------------------------------------------------
    # Adds the actual 'contain' statements
    def SetContainStatement(self, contains):
        self.contains = contains
    # --------------------------------------------------------------------------
    # Appends a contained subroutine/function
    def AddContained(self, obj):
        self.lContains.append(obj)
        obj.SetContainedIn(self)
    # --------------------------------------------------------------------------
    # If this subroutine is contained in another subroutine, a pointer
    # to this other subroutine is stored.
    def SetContainedIn(self, obj): self.oContainedIn = obj
    # --------------------------------------------------------------------------
    def bContains(self): return self.olContains
    # --------------------------------------------------------------------------
    def GetArguments(self): return self[0].GetArguments()
    # --------------------------------------------------------------------------
    def GetPrefix(self): return self[0].GetPrefix()
    # --------------------------------------------------------------------------
    def GetVariable(self, sName, d={}, bAutoAdd=1):
        var =  Variables.GetVariable(self, sName, d=d, bAutoAdd=0)
        if var: return var

        if self.oContainedIn:
            var=self.oContainedIn.GetVariable(sName, bAutoAdd=0)
            
        if not var:
            if bAutoAdd:
                return Variables.GetVariable(self, sName, d=d, bAutoAdd=1)
        return var

    # --------------------------------------------------------------------------
    def GetAttributes(self, sName):
        var=self.GetVariable(sName, bAutoAdd=0)
        if not var: return {}
        return var.GetAttributes()    
    # --------------------------------------------------------------------------
    # lCalls contains a list of all subroutine/function calls, the locations it
    # occurs, and the type ('subroutine'/'function').
    def AddFunctionCall(self, sName, loc):
        self.lFuncCalls.append( (sName, loc) )
    # --------------------------------------------------------------------------
    # lCalls contains a list of all subroutine/function calls, the locations it
    # occurs, and the type ('subroutine'/'function').
    def AddCall(self, sName, loc, type):
        self.lCalls.append( (sName, loc) )
    # --------------------------------------------------------------------------
    def lContainedProgUnits(self): return self.lContains
    # --------------------------------------------------------------------------
    def lGetFunctionCalls(self):   return self.lFuncCalls
    # --------------------------------------------------------------------------
    def lGetCalls(self):           return self.lCalls
    # --------------------------------------------------------------------------
    def lGetAllCalls(self):        return self.lCalls + self.lFuncCalls
    # --------------------------------------------------------------------------
    # Copies the declaration from this program unit to the program unit
    # 'progunit'. If var is specified, only the variable 'var' will be
    # copied, if in addition renamedTo is specified, the variable will be
    # named 'renamedTo' in 'progunit'
    def CopyDeclarationTo(self, progunit, sVar=None, sRenamedTo=None):
        if not sVar:
            for var in self.lGetAllVariables():
                dAttr = var.GetAttributes()
                progunit.AddVariable(var.sGetName(), dAttr)
            return
        if sRenamedTo:
            dAttr=self.GetAttributes(sVar)
            v=progunit.AddVariable(sRenamedTo, dAttr)
            return
        dAttr=self.GetAttributes(sVar)
        progunit.AddVariable(sVar, dAttr)
        
    # --------------------------------------------------------------------------
    # Returns a list of all statements of the program unit (this is basically
    # a copy of the program unit object). If lClasses is specified, only
    # statements which are of a class specified in that list will be returned.
    # Example:
    # from AOR.Statements import Call
    # from AOR.Do import Do, EndDo
    #     for i in objFile:
    #         for j in i.lGetStatements([Call, Do, EndDo]):
    #             print j
    # Parameter:
    #
    # lClasses -- List of statement classes. If this is specified, only
    #             statements belonging to one of the classes of this list
    #             are returned. If this parameter is not specified (or None),
    #             a list of all statements is returned.
    #
    # bExtractIfOnly -- If statements without a then (called ifonly here) have
    #             a statement attached to them. With this flag it can be chosen
    #             whether these statements in ifonly statements are to be
    #             returned or not. The function is probably faster if they are
    #             not to be returned. Example (consider that IfOnly is NOT an
    #             If object!!):
    #             ProgUnit is [if (a.eq.1) call sub(a)]
    #             lGetStatements(...,lClasses=[If, Call])
    #                    -> [call sub(a)]
    #             lGetStatements(...,lClasses=[IfOnly, Call])
    #                    -> [if (a.eq.1) call sub(a)]
    #                       the Call is not returned twice in the list!
    #             lGetStatements(...,lClasses=[If, Call], bExtractIfOnly=0)
    #                    -> []
    #                       because the call statement in the IfOnly statement
    #                       is not returned
    #             lGetStatements(...,lClasses=[IfOnly], bExtractIfOnly=0)
    #                    -> [if (a.eq.1) call sub(a)]
    def lGetStatements(self, lClasses = None, bExtractIfOnly=1):
        if lClasses==None:
            return self[:]
        # Convert to a dictionary for faster access
        d = {}
        for i in lClasses:
            d[i]=1
        # We can use the faster filter function here
        if not bExtractIfOnly:
            return filter(lambda x, d=d: d.get(x.__class__,None), self)
        # Now we have to loop over all statements and check for IfOnly
        l = []
        for i in self:
            if d.get(i.__class__, None):
                l.append(i)
            else:
                if i.__class__==IfOnly:
                    s = i.GetStatement()
                    if d.get(s.__class__, None): l.append(s)
        return l
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        if not self.lContains:
            for i in self:
                l2dDummy = Layout2d()
                stylesheet.ToList(i, l2dDummy)
                l.append(l2dDummy)
            return
        for i in self[:-1]:
            l2dDummy = Layout2d()
            stylesheet.ToList(i, l2dDummy)
            l.append(l2dDummy)
        l2dDummy = Layout2d()
        stylesheet.ToList(self.contains, l2dDummy)
        l.append(l2dDummy)
        for sub in self.lContains:
            stylesheet.ToList(sub, l)
        l2dDummy = Layout2d()
        stylesheet.ToList(self[-1], l2dDummy)
        l.append(l2dDummy)
    # --------------------------------------------------------------------------
    def __repr__(self):
        return self.ToString(DefaultStylesheet()) class EndProgUnit(BasicStatement):

    # Stores an end-{program, subroutine, function} statement:
    # end-program-stmt	is END [ PROGRAM [ program-name ] ]
    # end-subroutine-stmt is END [ SUBROUTINE [ subroutine-name ] ]
    # end-function-stmt	is END [ FUNCTION [ function-name ] ]
    def __init__(self, sLabel=None, loc=None, sEnd="END", nIndent=0, sName=None):
        self.sEnd  = sEnd
        self.sType = None
        self.sName = sName
        BasicStatement.__init__(self, sLabel, loc, nIndent)
    # --------------------------------------------------------------------------
    # Is sName is none, only 'subroutine' will be appended
    def SetName(self, sType, sName=None):
        self.sType = sType
        self.sName = sName
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sEnd))
        if self.sType: l.append(stylesheet.sKeyword(self.sType), nIndent=1)
        if self.sName: l.append(self.sName,                      nIndent=1) class NotYetImplemented(Warning):
    def __init__(self, sWarningMessage, scanner):
        Warning.__init__(self, sWarningMessage)
        self.nLinenumber   = scanner.GetLinenumber()
        self.nColumnnumber = scanner.GetColumnnumber()
    # ----------------------------------------------------
    def __repr__(self):
        return "Line %d, column %d: %s not yet implemented."%\
               (self.nLinenumber, self.nColumnnumber,
                Warning.__repr__(self) ) class Warning:
    def __init__(self, sWarningMessage):
        self.sWarningMessage = sWarningMessage
    # ----------------------------------------------------
    def sGetError(self):
        return `self`
    # ----------------------------------------------------
    def __repr__(self): return self.sWarningMessage
    # ----------------------------------------------------
    def __str__(self):
        return `self`
import string
from   Scanner.Token         import Token
from   AOR.Variable          import Variable
from   AOR.AttributeString   import AttributeString
from   AOR.Expression        import BasicExpression, OneArraySpec, \
                                    ArraySpecWithName
from   AOR.Declaration       import Common, CrayPointer, CrayPointerTuple, \
                                    Data, DataStatementSet, DataValueList, \
                                    Declaration, Dimension, Equivalence, \
                                    EquivalenceItem, External, Implicit, \
                                    Intrinsic, Intent, Namelist,\
                                    ModuleProcedure, Parameter, Pointer, \
                                    Private, Public, Save, \
                                    Type, Use, UserType, VariableWithInit, \
                                    VariableWithLen
from   AOR.Subroutine        import SubroutineStatement
from   AOR.Interface         import InterfaceStatement, EndInterfaceStatement
from   AOR.ProgUnit          import ProgUnit
from   AOR.ProgUnit          import EndProgUnit
from   Tools.Error           import NotYetImplemented, Warning
    from Test.ParseSpecificationTest import RunAllTests
                    save.AddCommonBlock(tok[1], tok2[1], tok3[1])
                    tok = tokComma
            else:
                tokComma  = self.GetNextToken()
                var = self.sub.GetVariable(tok[1], {"save":1}, bAutoAdd=1)
                if tokComma[1]==",":
                    save.AddObject(var, sComma=tokComma[1])
                    tok  = self.GetNextToken()
                else:
                    save.AddObject(var)
                    tok = tokComma
        return self.GetNextToken(), save
                
    # --------------------------------------------------------------------------
    def ParseSubroutineStatement(self, tok, loc, sLabel=None, sName=None):
        tokName = self.GetNextToken()
        subStatement = SubroutineStatement(loc=loc, lPrefix=[],
                                           sSub=tok[1],
                                           sName=tokName[1],
                                           nIndent=self.nIndent)

        tok = self.ParseArguments(self.GetNextToken(), subStatement)
        if tok[1]==",":
            # Following now: BIND ( C [ , NAME = scalar-char-initialization-expr ] )
            raise Error("language-binding-spec currently not supported")

        assert tok[0]==Token.tok_SEPARATOR
        self.sub.AppendStatement(subStatement)
        subStatement.SetEndLocation(self.scanner.GetPreviousLocation())
        # parseEndProgUnit is defined in ParseExecution
        tok = self.ParseStatements(self.GetNextToken(),
                                   dEnd = {'ENDSUBROUTINE' :
                                           self.SpeciParseEndProgUnit,
                                           'END': self.SpeciParseEndProgUnit},
                                   nIndentModifier=1)
        return tok, None
    # --------------------------------------------------------------------------
    # A simple wrapper for ParseEndprogUnit, which is necessary because the
    # parameters for all functions when parsing the specification part are
    # different from the parameters needed in the execution part.
    def SpeciParseEndProgUnit(self, tok, loc, sLabel=None, sName=None):
        return self.ParseEndProgUnit(sLabel=None, keywordtoken=tok, sName=None,
                                     loc=loc)
    # --------------------------------------------------------------------------
    # This method sets all attributes contained in the declaration DECL
    # to the variable VAR, e.g.:  integer, dimension(20) :: a
    # would set the 'dimension' attribute in the variable a
    def SetAllAttributes(self, var, decl):
        for i in decl.GetAttributes():
            if i.__class__ == ArraySpecWithName:
                var.SetAttribute('dimension', i.GetArraySpec())
            elif i.__class__ == Intent:
                var.SetAttribute('intent', i)
            # We have to handle more special attributes for sure!!!
            elif i.__class__ == str or i.__class__ == AttributeString:
                var.SetAttribute(i.lower())
            else:
                i.__class__
                var.SetAttribute(i)
            
    # --------------------------------------------------------------------------
    # type-declaration-stmt is declaration-type-spec [ [ , attr-spec ] ... :: ]
    #                          entity-decl-list
    # entity-decl is object-name [(array-spec)] [*char-length] [initialization]
    def ParseTypeDeclaration(self, tok, loc, sLabel=None, sName=None):
        tokComma, type = self.ParseTypeSpec(tok)
        if tokComma[1]==",":
            decl           = Declaration(sType=type, sComma=tokComma[1],
                                         loc=loc, nIndent=self.nIndent)
        else:
            decl           = Declaration(sType=type, loc=loc, nIndent=self.nIndent)

        # now loop for attributes
        while tokComma[1]==",":
            tok  = self.GetNextToken()
            sAtt = string.upper(tok[1])
            if sAtt=="DIMENSION":
                tok2=self.GetNextToken()
                tokComma,att = self.ParseArraySpec(sName=tok[1],
                                                   tok=tok2)
            elif sAtt=="INTENT":
                tokParOpen = self.GetNextToken()
                assert tokParOpen[1]=="("
                tokIntent = self.GetNextToken()
                tokParClose = self.GetNextToken()
                assert tokParClose[1]==")"
                att = Intent(tok[1], tokParOpen[1], tokIntent[1],
                             tokParClose[1])
                tokComma = self.GetNextToken()
            else:
                tokComma = self.GetNextToken()
                att = tok[1]
            if tokComma[1]==",":
                decl.AddAttribute(att, tokComma[1])
            else:
                decl.AddAttribute(att)

        if tokComma[1]==":":
            decl.AddDoubleColons(tokComma[1], self.GetNextToken()[1])
            tok = self.GetNextToken()
        else:
            tok = tokComma
        # Next: loop over the list of variables
        while 1:
            var = self.sub.GetVariable(tok[1], {'type':type})
            self.SetAllAttributes(var, decl)
            tok = self.GetNextToken()
            if tok and tok[1]=="(":
                tok,arrspec = self.ParseArraySpec(tok=tok, var=var)
                var.SetAttribute('dimension',arrspec.GetArraySpec())
                declvar = arrspec
                var = declvar
            if tok and tok[1]=='*':
                tok1 = self.GetNextToken()
                if tok1[0]==Token.tok_NUMBER:
                    self.scanner.UnGet(tok1)
                    tokNext, len = self.ParseExpression(self.GetNextToken())
                    declvar = VariableWithLen(var, tok[1], len)
                    tok = tokNext
                else: 

                    declvar = VariableWithLen(var, tok[1])