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 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 Error:
    def __init__(self, sErrorMessage):
        self.sErrorMessage = sErrorMessage
    # ----------------------------------------------------
    def sGetError(self):
        return self.__str__()
    # ----------------------------------------------------
    def __str__(self):
        return self.sErrorMessage 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 CompilerDirective(BasicNonStatement):
    def __init__(self, sCompilerDirective, loc):
        BasicNonStatement.__init__(self, sCompilerDirective, loc) class PreDirective(BasicNonStatement):
    def __init__(self, sPreDirective, loc):
        BasicNonStatement.__init__(self, sPreDirective, loc) class CommentLine(BasicNonStatement):
    def __init__(self, sComment, loc=None):
        BasicNonStatement.__init__(self, sComment, loc) class IfOnly(BasicStatement):
    def __init__(self, sLabel=None, loc=None, sIf="IF", sParOpen='(',
                 oIfCond=None, sParClose=')', oStatement=None, nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sIf        = sIf
        self.l          = [sIf, sParOpen, oIfCond, sParClose, oStatement]
    # --------------------------------------------------------------------------
    # Returns the object representing the condition of an if-then statement
    def GetCondition(self): return self.l[2]
    # --------------------------------------------------------------------------
    # Returns the statement which is part of the if (without then) statement
    def GetStatement(self): return self.l[4]
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage):
        varUsage.AddVariable(self.l[2], "read", self)
        self.l[4].GetVarUsage(varUsage)
        
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.l[0]),nIndentNext=1)
        l.append(self.l[1])
        stylesheet.ToList(self.l[2], l)
        l.append(self.l[3],nIndentNext=1)
        stylesheet.ToList(self.l[4], l) class If(BasicNamedStatement):
    def __init__(self, sLabel=None, sName=None, loc=None, sIf="IF", nIndent=0,
                 sParOpen='(', oIfCond=None, sParClose=')', sThen='THEN'):
        BasicNamedStatement.__init__(self, sLabel, sName, loc, nIndent,
                                     isDeclaration=0)
        self.l = [sIf, sParOpen,  oIfCond, sParClose, sThen]
    # --------------------------------------------------------------------------
    # Returns the object representing the condition of an if-then statement
    def GetCondition(self): return self.l[2]
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage):
        varUsage.AddVariable(self.l[2], "read", self)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicNamedStatement.ToList(self, stylesheet, l, bAddSpace=1)
        l.append(stylesheet.sKeyword(self.l[0]), nIndentNext=1)
        l.append(self.l[1])
        stylesheet.ToList(self.l[2], l)
        l.append(self.l[3], nIndentNext=1)
        l.append(stylesheet.sKeyword(self.l[4])) class ElseIf(BasicStatement):
    def __init__(self, sLabel=None, loc=None, sElse=None, sIf=None, nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.lElseIf = [sElse, sIf]
        self.lExpr   = []
        self.sThen   = None
        self.sName   = None
    # --------------------------------------------------------------------------
    def AddExpr(self, sParOpen, expr, sParClose):
        self.lExpr = [sParOpen, expr, sParClose]
    # --------------------------------------------------------------------------
    def SetThen(self, sThen): self.sThen = sThen
    # --------------------------------------------------------------------------
    def SetName(self, sName): self.sName = sName
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage):
        varUsage.AddVariable(self.lExpr[1], "read", self)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.lElseIf[0]), nIndentNext=1)
        l.append(stylesheet.sKeyword(self.lElseIf[1]), nIndentNext=1)
        l.append(self.lExpr[0])
        stylesheet.ToList(self.lExpr[1], l)
        l.append(self.lExpr[2], nIndentNext=1)
        if self.sThen:
            l.append(stylesheet.sKeyword(self.sThen))
        if self.sName:
            l.append(self.sName, nIndent=1) class Else(BasicStatement):
    def __init__(self, sLabel=None, loc=None, sElse="ELSE", nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sElse = sElse
        self.sName = None
    # --------------------------------------------------------------------------
    def SetName(self, sName): self.sName = sName
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage): return
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sElse))
        if self.sName: l.append(self.sName, nIndent=1) class EndIf(BasicStatement):
    def __init__(self, sLabel=None, loc=None, sEnd="END", sIf="IF", nIndent=0):
        BasicStatement.__init__(self, sLabel, loc,nIndent, isDeclaration=0)
        self.lEndIf = [sEnd, sIf]
        self.sName  = None
    # --------------------------------------------------------------------------
    def SetName(self, sName): self.sName = sName
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage): return
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(self.lEndIf[0]           )
        l.append(self.lEndIf[1], nIndent=1)
        if self.sName: l.append(self.sName, nIndent=1) class ArithmeticIf(BasicStatement):
    # Stores an arithmetic if statement
    def __init__(self, sLabel=None, loc=None, sIf="IF", sParOpen='(',
                 ifCond=None, sParClose=')', nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sIf       = sIf
        self.sParOpen  = sParOpen
        self.ifCond    = ifCond
        self.sParClose = sParClose
        self.lLabels   = DoubleList()
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage):
        varUsage.AddVariable(self.ifCond, "read", self)
    # --------------------------------------------------------------------------
    def AppendLabel(self, sLabel, sComma=None):
        self.lLabels.append(sLabel, sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sIf), nIndentNext=1)
        l.append(self.sParOpen)
        stylesheet.ToList(self.ifCond, l)
        l.append(self.sParClose, nIndentNext=1)
        self.lLabels.ToList(stylesheet, l) class ControlLessDo(BasicNamedStatement):
    # Stores a Do loop without loop control
    def __init__(self, sLabel=None, sName=None, loc=None,
                 sDo="DO", sDoLabel=None, nIndent=0):
        self.sDo       = sDo
        self.sDoLabel  = sDoLabel
        self.lLoopData = []
        BasicNamedStatement.__init__(self, sLabel, sName, loc, nIndent,
                                     isDeclaration=0)
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage): return
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicNamedStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sDo))
        if self.sDoLabel:
            l.append(self.sDoLabel, nIndent=1) class Cycle(Exit):
    # Stores a cycle statement which can have a do-construct name
    # (which is basically the same as an exit statement)
    def __init__(self, sLabel=None, loc=None, sCycle='CYCLE',
                 sCycleLabel=None, nIndent=0):
        Exit.__init__(self, sLabel, loc, sCycle, sCycleLabel, nIndent) class Do(BasicNamedStatement):

    # Stores a Do-loop statement
    #
    # sLabel -- Label of the Do statement (this is NOT the label
    #           used in the DO loop, e.g.: 100 DO 200 i=1, 10
    #           This is the label 100, not the label 200
    #
    # sName -- Name of the do statement
    #
    def __init__(self, sLabel=None, sName=None, loc=None,
                 sDo="DO", sDoLabel=None, sOptComma=None, nIndent=0,
                 var=None, sFrom=None, sTo=None):
        self.sDo       = sDo
        self.sOptComma = sOptComma
        self.lLoopData = []
        self.sDoLabel  = sDoLabel
        BasicNamedStatement.__init__(self, sLabel, sName, loc, nIndent,
                                     isDeclaration=0)
        if var: self.SetVariable(var,"=")
        if sFrom: self.SetFrom(sFrom,",")
        if sTo: self.SetTo(sTo)
    # --------------------------------------------------------------------------
    def SetVariable(self, var, sEqual): self.lLoopData.extend([var, sEqual])
    # --------------------------------------------------------------------------
    def SetFrom(self, f, sComma): self.lLoopData.extend([f, sComma])
    # --------------------------------------------------------------------------
    def SetTo  (self, t): self.lLoopData.append(t)
    # --------------------------------------------------------------------------
    def SetStep(self, sComma, s): self.lLoopData.extend([sComma, s])
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage):
        varUsage.AddVariable(self.lLoopData[0], "write",self)   # the do variable is written
        varUsage.AddVariable(self.lLoopData[2], "read", self)
        varUsage.AddVariable(self.lLoopData[4], "read", self)
        if len(self.lLoopData)>5:
            varUsage.AddVariable (self.lLoopData[6], "read", self)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicNamedStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sDo), nIndentNext=1)
        if self.sDoLabel:
            l.append(self.sDoLabel, nIndentNext=1)
        if self.sOptComma: l.append(self.sOptComma)
        stylesheet.ToList(self.lLoopData[0], l)               # var
        l.indent(1)
        l.append(self.lLoopData[1], nIndentNext=1)            # =
        stylesheet.ToList(self.lLoopData[2], l)               # from
        l.append(self.lLoopData[3], nIndentNext=1)            # ,
        stylesheet.ToList(self.lLoopData[4], l)               # to
        if len(self.lLoopData)>5:
            l.append(self.lLoopData[5],nIndentNext=1)         # ,
            stylesheet.ToList(self.lLoopData[6], l)           # step class DoWhile(BasicNamedStatement):
    # Stores a Do-While loop
    def __init__(self, sLabel=None, sName=None, loc=None,
                 sDo="DO", sDoLabel=None, sOptComma=None, sWhile="WHILE",
                 sParOpen='(', nIndent=0):
        self.sDo       = sDo
        self.sOptComma = sOptComma
        self.sDoLabel  = sDoLabel
        self.sWhile    = sWhile
        self.sParOpen  = sParOpen
        self.exp       = None
        self.sParClose = None
        BasicNamedStatement.__init__(self, sLabel, sName, loc, nIndent,
                                     isDeclaration=0)
    # --------------------------------------------------------------------------
    def SetExpression(self, exp, sParClose=')'):
        self.exp       = exp
        self.sParClose = sParClose
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage):
        varUsage.AddVariable(self.exp, "read", self)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicNamedStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sDo))
        if self.sDoLabel:  l.append(self.sDoLabel, nIndent=1)
        if self.sOptComma: l.append(self.sOptComma)
        l.append(stylesheet.sKeyword(self.sWhile), nIndent=1)
        l.append(self.sParOpen)
        stylesheet.ToList(self.exp, l)
        l.append(self.sParClose) class EndDo(BasicStatement):

    # Stores an EndDo statement which can have a do-construct name
    #
    # sLabel -- Label of the statement (5 digit number as a string)
    #
    def __init__(self, sLabel=None, loc=None, sEnd='END', sDo='DO',  nIndent=0):
        self.lEndDo  = [sEnd, sDo]
        self.sName = None
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
    # --------------------------------------------------------------------------
    def SetName(self, sName): self.sName = sName
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage): return
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.lEndDo[0]), nIndentNext=1)
        l.append(stylesheet.sKeyword(self.lEndDo[1]))
        if self.sName:
            l.append(self.sName) class Exit(BasicStatement):
    def __init__(self, sLabel=None, loc=None, sExit="EXIT", sExitLabel=None,
                 nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sExit      = sExit
        self.sExitLabel = sExitLabel
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage): return
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        if self.sExitLabel:
            BasicStatement.ToList(self, stylesheet, l)
            l.append(stylesheet.sKeyword(self.sExit), nIndentNext=1)
            l.append(self.sExitLabel)
        else:
            BasicStatement.ToList(self, stylesheet, l)
            l.append(stylesheet.sKeyword(self.sExit)) class Select(BasicNamedStatement):

    # Stores a select statement
    #
    # sLabel -- Label of the select statement (this is NOT the label
    #           used in the DO loop, e.g.: 100 DO 200 i=1, 10
    #           This is the label 100, not the label 200
    #
    # sName -- Name of the do statement
    #
    def __init__(self, sLabel=None, sName=None, loc=None,
                 sSelect="SELECT", sCase="CASE", sParOpen='(',
                 exp=None, sParClose=')', nIndent=0):
        BasicNamedStatement.__init__(self, sLabel, sName, loc, nIndent,
                                     isDeclaration=0)
        self.sSelect   = sSelect
        self.sCase     = sCase
        self.sParOpen  = sParOpen
        self.exp       = exp
        self.sParClose = sParClose
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicNamedStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sSelect), nIndentNext=1)
        l.append(stylesheet.sKeyword(self.sCase),   nIndentNext=1)
        l.append(self.sParOpen)
        self.exp.ToList(stylesheet, l)
        l.append(self.sParClose) class Case(BasicStatement):

    # Stores a Case statement 
    #
    def __init__(self, sLabel=None, loc=None, sCase='CASE',  nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sCase     = sCase
        self.sName     = None
        self.sDefault  = None           # for DEFAULT
        self.sParOpen  = None
        self.sParClose = None
        self.lSelector = DoubleList()
    # --------------------------------------------------------------------------
    def SetName(self, sName): self.sName = sName
    # --------------------------------------------------------------------------
    def SetParOpen(self, sParOpen='('): self.sParOpen=sParOpen
    # --------------------------------------------------------------------------
    def SetParClose(self, sParClose=')'): self.sParClose=sParClose
    # --------------------------------------------------------------------------
    # Sets either the selector to 'DEFAULT' or to '(obj)'.
    def AddSelector(self, obj=None, sComma=None, sDefault=None):
        if sDefault:
            self.sDefault = sDefault
        else:
            self.lSelector.append(obj, sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(self.sCase, nIndentNext=1)
        if self.sDefault:
            l.append(self.sDefault)
        else:
            l.append(self.sParOpen)
            self.lSelector.ToList(stylesheet, l)
            l.append(self.sParClose)
        if self.sName: l.append(self.sName, nIndentNext=1) class EndSelect(BasicStatement):

    # Stores an EndSelect statement which can have a select-construct name
    #
    # sLabel -- Label of the statement (5 digit number as a string)
    #
    def __init__(self, sLabel=None, loc=None, sEnd='END', sSelect='CASE',  nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.lEndCase  = [sEnd, sSelect]
        self.sName     = None
    # --------------------------------------------------------------------------
    def SetName(self, sName): self.sName = sName
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.lEndCase[0]), nIndentNext=1)
        l.append(stylesheet.sKeyword(self.lEndCase[1]))
        if self.sName:
            l.append(self.sName, nIndent=1) 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 Allocate(BasicStatement):

    # Stores a return statement.
    def __init__(self, sLabel=None, loc=None, sOp='ALLOCATE',sParOpen='(',
                 nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sOp             = sOp
        self.sParOpen        = sParOpen
        self.lVars           = DoubleList()
        self.lOptions        = DoubleList()
        self.sParClose       = ")"
    # --------------------------------------------------------------------------
    def SetParClose(self, sParClose): self.sParClose = sParClose
    # --------------------------------------------------------------------------
    # Adds a variable to allocate to the allocate statement. Parameters:
    #
    # var -- Variable to add
    #
    # sSeparator -- String which separates a variable from the next. Usual a
    #               comma, but the ')' is stored here as well.
    def AddVariable(self, var, sSeparator=None):
        self.lVars.append(var, sSeparator)
    # --------------------------------------------------------------------------
    # Appends an option (stat, errmsg, or source) to the statement. Parameters:
    #
    # sName -- Name of the option
    #
    # sEqual -- The '=' character
    #
    # obj -- A scalar int variable
    #
    # sSeparator -- String which separates an option from the next. Usual a
    #               comma, but the ')' can be stored here as well.
    def AddOption(self, sName, sEqual, obj, sSeparator=None):
        self.lOptions.append( OptionString(sName, sEqual, obj), sSeparator )
    # --------------------------------------------------------------------------
    # Creates a list of strings which represents this statement. Parameters:
    #
    # stylesheet -- The stylesheet to use during layout
    def ToList(self, stylesheet=None,l=[]):
        BasicStatement.ToList(self, stylesheet, l)
        l.extend([stylesheet.sKeyword(self.sOp), self.sParOpen]) # 'allocate', '('
        self.lVars.ToList(stylesheet, l)
        self.lOptions.ToList(stylesheet, l)
        l.append(self.sParClose) class Assignment(BasicStatement):

    # Stores an assignment or pointer assignment statement:
    # assignment-stmt is variable = expr   or
    # pointer-assignment-stmt is
    #     data-pointer-object [ (bounds-spec-list) ] => data-target or
    #     data-pointer-object (bounds-remapping-list ) => data-target or
    #     proc-pointer-object => proc-target
    # This object is not only used as a real statement e.g. it is used
    # in the Parameter object as well). If the flag bNoIndent is set
    # the object will not add indentation in ToList!!
    def __init__(self, sLabel=None, loc=None, nIndent=0, lhs=None,
                 sEqual='=', rhs=None, bNoIndent=None):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.lhs       = lhs
        self.sEqual    = sEqual
        self.rhs       = rhs
        self.bNoIndent = bNoIndent
    # --------------------------------------------------------------------------
    # Define the left hand side of an assignment
    def SetLeftHandSide (self, ls): self.lhs=ls
    # --------------------------------------------------------------------------
    def SetRightHandSide(self, rs): self.rhs=rs
    # --------------------------------------------------------------------------
    def SetEqualSign(self, eq): self.eq = eq
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage, sType="read", obj=None, loc=None):
        varUsage.AddVariable(self.rhs, "read",  obj=self)
        varUsage.AddVariable(self.lhs, "write", obj=self)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet,l):
        if not self.bNoIndent:
            BasicStatement.ToList(self, stylesheet, l)
        stylesheet.ToList(self.lhs, l)
        # one space before and after the =
        l.append(self.sEqual, nIndent=1, nIndentNext=1)
        stylesheet.ToList(self.rhs, l) class Call(FunctionCall, BasicStatement):
    def __init__(self, sLabel=None, loc=None, sCall="CALL", sName=None,
                 nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        FunctionCall.__init__(self, sName)
        self.sCall = sCall
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sCall), nIndentNext=1)
        FunctionCall.ToList(self, stylesheet, l) class Continue(BasicStatement):

    # Stores a continue statement (with a label)
    #
    # sLabel -- Label of the statement (5 digit number as a string)
    #
    def __init__(self, sLabel=None, loc=None, sCont="CONTINUE", nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sCont = sCont
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sCont)) class Deallocate(Allocate):

    # Stores a deallocate statement.
    def __init__(self, sLabel=None, loc=None, sOp='DEALLOCATE',sParOpen='(',
                 nIndent=0):
        Allocate.__init__(self, sLabel=None, loc=loc, sOp=sOp,
                          sParOpen='(', nIndent=0) class Goto(BasicStatement):

    # Stores a goto statement (with a label)
    #
    # sLabel -- Label of the statement (5 digit number as a string)
    #
    # sGotoLabel -- The label to go to
    def __init__(self, sLabel=None, loc=None, sGo="GO", sTo="TO",
                 sGotoLabel=None, nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sGo        = sGo
        self.sTo        = sTo
        self.sGotoLabel = sGotoLabel
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.extend([stylesheet.sKeyword(self.sGo), stylesheet.sKeyword(self.sTo)])
        l.append(self.sGotoLabel, nIndent=1) class ComputedGoto(BasicStatement):

    # Stores a goto statement (with a label)
    #
    # sLabel -- Label of the statement (5 digit number as a string)
    #
    # sGotoLabel -- The label to go to
    def __init__(self, sLabel=None, loc=None, sGo="GO", sTo="TO",
                 sParOpen="(", nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sGo        = sGo
        self.sTo        = sTo
        self.sParOpen   = sParOpen
        self.sParClose  = ""
        self.sComma     = ""
        self.lLabels    = DoubleList()
        self.oExp       = None
    # --------------------------------------------------------------------------
    def AddLabel(self, sLabel, sComma=None):
        self.lLabels.append(sLabel, sComma)
    # --------------------------------------------------------------------------
    def SetParClose(self, sParClose): self.sParClose =sParClose
    # --------------------------------------------------------------------------
    def AddComma(self, sComma): self.sComma = sComma
    # --------------------------------------------------------------------------
    def SetExp(self, oExp): self.oExp = oExp
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.extend([stylesheet.sKeyword(self.sGo), stylesheet.sKeyword(self.sTo)])
        l.append(self.sParOpen, nIndent=1)
        self.lLabels.ToList(stylesheet, l)
        l.append(self.sParClose)
        if self.sComma:
            l.append(self.sComma)
        self.oExp.ToList(stylesheet, l) class Nullify(BasicStatement):
    def __init__(self, sLabel=None, loc=None, sNullify="NULLIFY",
                 sParOpen='(', nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sNullify  = sNullify
        self.sParOpen  = sParOpen
        self.sParClose = None
        self.lPointers = DoubleList()
    # --------------------------------------------------------------------------
    def SetParClose(self, sParClose=')'): self.sParClose=')'
    # --------------------------------------------------------------------------
    def AddExpression(self, exp, sComma=None):
        self.lPointers.append(exp, sComma)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.extend([stylesheet.sKeyword(self.sNullify), self.sParOpen])
        self.lPointers.ToList(stylesheet, l)
        l.append(self.sParClose) class OptionString(BasicRepr):
    def __init__(self, lhs, sEqual, rhs):
        self.l=[lhs, sEqual, rhs]
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage, sType="read", obj=None, loc=None):
        varUsage.AddVariable(self.l[2], sType, obj, loc)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        stylesheet.ToList(self.l[0], l)
        l.append(self.l[1])
        stylesheet.ToList(self.l[2], l) class Pause(Stop):
    # Stores a pause statement - which is similar to a stop statement
    def __init__(self, sLabel=None, loc=None, sPause="PAUSE", nIndent=0):
        Stop.__init__(self, sLabel, loc, sPause, nIndent) class Return(BasicStatement):

    # Stores a return statement.
    def __init__(self, sLabel=None, loc=None, sReturn="RETURN", nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sReturn  = sReturn
        self.retvalue = None
    # --------------------------------------------------------------------------
    def SetReturnValue(self, obj):
        self.retvalue = obj
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage):
        if self.retvalue:
            selt.retvalue.GetVarUsage(varUsage)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        if self.retvalue:
            l.append(stylesheet.sKeyword(self.sReturn), nIndentNext=1)
            stylesheet.ToList(self.retvalue, l)
        else:
            l.append(stylesheet.sKeyword(self.sReturn)) class Stop(BasicStatement):
      # Stores a stop statement.
    def __init__(self, sLabel=None, loc=None, sStop="STOP", nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sStop    = sStop
        self.stopcode = None
    # --------------------------------------------------------------------------
    def SetStopCode(self, obj):
        self.stopcode = obj
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        if self.stopcode:
            l.append(stylesheet.sKeyword(self.sStop), nIndentNext=1)
            stylesheet.ToList(self.stopcode, l)
        else:
            l.append(stylesheet.sKeyword(self.sStop)) class Include(BasicStatement):
    def __init__(self, loc=None, sInclude="include", sFilename=None, nIndent=0):
        BasicStatement.__init__(self, None, loc, nIndent)
        self.sInclude  = sInclude
        self.sFilename = sFilename
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(self.sInclude)
        l.append(self.sFilename, nIndent=1) class StatementFunction(BasicStatement):

    def __init__(self, sLabel=None, loc=None, nIndent=0, lhs=None,
                 sEqual=None, rhs=None, bNoIndent=None):
        BasicStatement.__init__(self, sLabel, loc, nIndent)
        self.lhs       = lhs
        self.sEqual    = sEqual
        self.rhs       = rhs
        self.bNoIndent = bNoIndent
    # --------------------------------------------------------------------------
    # Define the left hand side of an assignment
    def SetLeftHandSide (self, ls): self.lhs=ls
    # --------------------------------------------------------------------------
    def SetRightHandSide(self, rs): self.rhs=rs
    # --------------------------------------------------------------------------
    def SetEqualSign(self, eq): self.eq = eq
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        if not self.bNoIndent:
            BasicStatement.ToList(self, stylesheet, l)
        stylesheet.ToList(self.lhs, l)
        l.indent(1)
        l.append(self.sEqual, nIndentNext=1)
        stylesheet.ToList(self.rhs, l) class Backspace(Rewind):
    # Stores a backspace statement - which is basically identical to a rewind
    def __init__(self,  sLabel=None, loc=None, nIndent=0,
                 sBackspace="BACKSPACE"):
        Rewind.__init__(self, sLabel ,loc, nIndent, sRewind=sBackspace) class Close(BasicIOList):
    # Stores a close statement
    def __init__(self, sLabel=None, loc=None, nIndent=0,
                 sClose="CLOSE", sParOpen='(', nUnit=None):
        BasicIOList.__init__(self, sLabel, loc, nIndent, sClose, sParOpen)
        if nUnit:
            self.AddIOOpt(nUnit) class Endfile(Rewind):
    # Stores a endfile statement - which is basically identical to a rewind
    def __init__(self,  sLabel=None, loc=None, nIndent=0,
                 sEndfile="ENDFILKE"):
        Rewind.__init__(self, sLabel ,loc, nIndent, sRewind=sEndfile) class Format(BasicStatement):

    # Stores a format statement.
    def __init__(self, sLabel=None, loc=None, sFormat="FORMAT", nIndent=0):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sFormat = sFormat
        self.l       = []
    # --------------------------------------------------------------------------
    def append(self, e): self.l.append(e)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.extend([stylesheet.sKeyword(self.sFormat)]+self.l[:]) class Inquire(Read):
    # Stores an inquire statement. Inquire, read and writes are basically
    # identical.
    def __init__(self, sLabel=None, loc=None, nIndent=0,
                 sInquire="INQUIRE", sParOpen=None):
        Read.__init__(self, sLabel, loc, nIndent, sInquire, sParOpen) class Open(BasicIOList):
    # Stores an open statement
    def __init__(self, sLabel=None, loc=None, nIndent=0, sOpen="OPEN",
                 sParOpen='(', nUnit=None):
        BasicIOList.__init__(self, sLabel, loc, nIndent, sOpen, sParOpen,
                             opt=nUnit) class Print(BasicStatement):

    # Stores a return statement.
    def __init__(self, sLabel=None, loc=None, sPrint="PRINT", nIndent=0,
                 format=None):
        BasicStatement.__init__(self, sLabel, loc, nIndent, isDeclaration=0)
        self.sPrint  = sPrint
        self.format  = format
        if format:
            self.sComma  = ","              # First comma after format
        else:
            self.sComma  = None             # First comma after format
        self.lIO     = DoubleList()
    # --------------------------------------------------------------------------
    def AddIOExpression(self, e, sComma=None): self.lIO.append(e, sComma)
    # --------------------------------------------------------------------------
    def SetComma(self, sComma): self.sComma=sComma
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage, sType="read", obj=None, loc=None):
        for i in self.lIO.GetMainList():
            varUsage.AddVariable(i, sType, obj, loc)
    # --------------------------------------------------------------------------
    def SetFormat(self, format):
        self.format = format
        self.sComma = ","
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicStatement.ToList(self, stylesheet, l)
        l.append(stylesheet.sKeyword(self.sPrint),nIndentNext=1)
        if type(self.format)==StringType:
            l.append(self.format)
        elif type(self.format)==IntType:
            l.append(`self.format`)
        else:
            stylesheet.ToList(self.format, l)
        if not self.sComma: return 
        l.append(self.sComma)
        self.lIO.ToList(stylesheet, l) class Read(BasicIOList):
    # Stores a read statement
    def __init__(self, sLabel=None, loc=None, nIndent=0,
                 sRead="READ", sParOpen=None,
                 nUnit=None, var=None):
        BasicIOList.__init__(self, sLabel, loc, nIndent, sRead, sParOpen)
        self.lIOExp    = DoubleList()
        self.sFormat   = None
        self.sComma    = None
        if nUnit:
            if not sParOpen: self.SetParOpen()
            self.AddIOOpt("%s"%nUnit)
            self.SetParClose()
        if var:
            self.AddIOExpression(var)
    # --------------------------------------------------------------------------
    def SetFormat(self, sFormat, sComma=None):
        self.sFormat = sFormat
        self.sComma  = sComma
    # --------------------------------------------------------------------------
    def AddIOExpression(self, exp, sComma=None):
        # To simplify manually creating statements, a comma is automatically
        # added, if only expressions are specified here (except for the first
        # call).
        if type(exp)==type(1): exp=`exp`
        if sComma==None and \
               len(self.lIOExp.lGetSecondaryList())==len(self.lIOExp)-1:
            self.lIOExp.append(",", exp)
        else:
            self.lIOExp.append(exp, sComma)
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage, sType="read", obj=None, loc=None):
        for i in self.lIOExp.GetMainList():
            varUsage.AddVariable(i, "write", obj, loc)
        BasicIOList.GetVarUsage(self, varUsage, sType, obj, loc)
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicIOList.ToList(self, stylesheet, l)
        l.append(' ')
        if self.sFormat:
            l.append(self.sFormat, nIndent=1)
            if self.sComma:
                l.append(self.sComma)
        self.lIOExp.ToList(stylesheet, l) class Rewind(BasicIOList):
    # Stores a rewind statement
    def __init__(self,  sLabel=None, loc=None, nIndent=0, sRewind="REWIND"):
        BasicIOList.__init__(self, sLabel, loc, nIndent, sRewind,sParOpen=None)
        self.sUnitNumber = None
    # --------------------------------------------------------------------------
    def AddUnitNumber(self, sUnitNumber): self.sUnitNumber = sUnitNumber
    # --------------------------------------------------------------------------
    def ToList(self, stylesheet, l):
        BasicIOList.ToList(self, stylesheet, l)
        if self.sUnitNumber:
            l.append(self.sUnitNumber, nIndent=1) class Write(Read):
    # Stores a write statement. Read and writes are basically identical,
    # except that read can have a format instead of a () expression
    def __init__(self, sLabel=None, loc=None, nIndent=0,
                 sWrite="WRITE", sParOpen=None, nUnit=None):
        Read.__init__(self, sLabel, loc, nIndent,
                      sRead=sWrite, sParOpen=sParOpen, nUnit=nUnit)
    # --------------------------------------------------------------------------
    def GetVarUsage(self, varUsage, sType="read", obj=None, loc=None):
        for i in self.lIOExp.GetMainList():
            varUsage.AddVariable(i, "read", obj, loc)
        BasicIOList.GetVarUsage(self, varUsage, sType, obj, loc)
import string
import sys
from   traceback             import print_exception
from   Scanner.Token         import Token
from   Tools.Error           import NotYetImplemented, Error
from   AOR.AttributeString   import AttributeString
from   AOR.SpecialStatements import CompilerDirective, PreDirective,           \
                                    CommentLine
from   AOR.If                import IfOnly, If, ElseIf, Else, EndIf,           \
                                    ArithmeticIf
from   AOR.Do                import ControlLessDo, Cycle, Do, DoWhile, EndDo,  \
                                    Exit
from   AOR.Select            import Select, Case, EndSelect
from   AOR.ProgUnit          import EndProgUnit
from   AOR.Statements        import Allocate, Assignment, Call, Continue,      \
                                    Deallocate, Goto, ComputedGoto, Nullify,   \
                                    OptionString, Pause, Return, Stop
from   AOR.Declaration       import Include, StatementFunction
from   AOR.IO                import Backspace, Close, Endfile, Format, Inquire,\
                                    Open, Print, Read, Rewind, Write
    from Test.ParseExecutionTest import RunAllTests
        # ==============================================
        tok = self.GetNextToken()
        assert tok[0]==Token.tok_SEPARATOR
        tok = self.GetNextToken()
        while 1:
            tok = self.ParseStatements(tok,
                                       dEnd = {"ELSE"  :self.ParseElseOrElseIf,
                                               "ELSEIF":self.ParseElseOrElseIf,
                                               "END"   :self.ParseEndOrEndif,
                                               "ENDIF" :self.ParseEndOrEndif},
                                       nIndentModifier=1)
            if self.sub[-1].__class__==EndIf: break
            if not tok:
                raise Error("Line %d, column %d: Problem with If statement" %
                            (self.scanner.GetLinenumber(),
                             self.scanner.GetColumnnumber()))
        # Return none, since the If statement was already added (at the
        # beginning of this method). This is necessary to ensure that
        # the statements which are part of the if (or else-if or then) block
        # are added after the do statement!
        return tok, None
                
    # --------------------------------------------------------------------------
    # Parses an expression list like "a, (b(i), i=1, 2)"
    def ParseIOExpressionList(self, obj, tok):
        while tok[0]!=Token.tok_SEPARATOR:
            tok, exp = self.ParseExpression(tok)
            if tok[1]==",":
                obj.AddIOExpression(exp, tok[1])
                tok = self.GetNextToken()
            else:
                obj.AddIOExpression(exp)
        return tok, obj
    # --------------------------------------------------------------------------
    # print-stmt is PRINT format [ , output-item-list ]
    # format is default-char-expr or label or *
    def ParsePrint(self, tok, loc=None, sLabel=None, sName=None):
        pr = Print(sLabel, loc, tok[1], self.nIndent)
        tok = self.GetNextToken()
        if tok[1]=="*":
            pr.SetFormat(tok[1])
            tok = self.GetNextToken()
        elif tok[0]==Token.tok_NUMBER:
            pr.SetFormat(int(tok[1]))
            tok = self.GetNextToken()
        else:
            tok, obj = self.ParseExpression(tok)
            pr.SetFormat(obj)
        if tok[1]!=",":
            assert tok[0]==Token.tok_SEPARATOR
            return self.GetNextToken(), pr
        pr.SetComma(tok[1])
        tok, pr = self.ParseIOExpressionList(pr, self.GetNextToken())
        assert tok[0]==Token.tok_SEPARATOR
        return self.GetNextToken(), pr
    # --------------------------------------------------------------------------
    # Parses a statement with the format 'keyword ([a=]b,[c=]d)'
    def ParseBasicIOStatement(self, cl, tok, loc=None, sLabel=None, sName=None):
        rewind = cl(sLabel, loc, self.nIndent, tok[1])
        tok = self.GetNextToken()
        if tok[1]=='(':
            rewind.SetParOpen(tok[1])
            tok = self.ParseIOControlSpec(self.GetNextToken(), rewind)
            assert tok[1]==')'
            rewind.SetParClose(tok[1])
        else:
            rewind.AddUnitNumber(tok[1])
        return self.GetNextToken(), rewind
    # --------------------------------------------------------------------------
    # rewind-stmt REWIND file-unit-number or REWIND ( position-spec-list )
    # position-spec is [ UNIT = ] file-unit-number  or IOMSG = iomsg-variable
    #               or IOSTAT = scalar-int-variable or ERR = label
    def ParseRewind(self, tok, loc=None, sLabel=None, sName=None):
        tok, rew = self.ParseBasicIOStatement(Rewind, tok, loc, sLabel, sName)
        assert tok[0]==Token.tok_SEPARATOR
        return self.GetNextToken(), rew
    # --------------------------------------------------------------------------
    # backspace-stmt is BACKSPACE file-unit-number
    #                or BACKSPACE ( position-spec-list )
    def ParseBackspace(self, tok, loc=None, sLabel=None, sName=None):
        tok, back=self.ParseBasicIOStatement(Backspace, tok, loc, sLabel, sName)
        assert tok[0]==Token.tok_SEPARATOR
        return self.GetNextToken(), back
    # --------------------------------------------------------------------------
    # endfile-stmt is ENDFILE file-unit-number or ENDFILE ( position-spec-list )
    def ParseEndfile(self, tok, loc=None, sLabel=None, sName=None):
        tok, endfile=self.ParseBasicIOStatement(Endfile, tok, loc, sLabel, sName)
        assert tok[0]==Token.tok_SEPARATOR
        return self.GetNextToken(), endfile
    # --------------------------------------------------------------------------
    # open-stmt is OPEN ( connect-spec-list )
    def ParseOpen(self, tok, loc=None, sLabel=None, sName=None):
        # Check if open is a variable name - this test works only if the
        # variable is a scalar! (you can declare a variable 'open(20)', and
        # then use it as "open(20) = 1"  - arrrrgh!
        var     = self.sub.GetVariable(tok[1], bAutoAdd=0)
        tokNext = self.GetNextToken()
        if var:
            if tokNext[1]!='(':
                self.scanner.UnGet(tokNext)
                return self.ParseAssignment(tok, loc=loc, sLabel=sLabel,
                                            sName=sName)
        o   = Open(sLabel, loc, self.nIndent, tok[1], tokNext[1])
        tok = self.ParseIOControlSpec(self.GetNextToken(), o)
        assert tok[1]==')'
        o.SetParClose(tok[1])
        assert self.GetNextToken()[0]==Token.tok_SEPARATOR
        return self.GetNextToken(), o
    # --------------------------------------------------------------------------
    # read-stmt is READ ( io-control-spec-list ) [ input-item-list ]
    #           or READ format [ , input-item-list ]
    def ParseRead(self, tok, loc=None, sLabel=None, sName=None):
        tokPar = self.GetNextToken()
        if tokPar[1]=='(':
            read  = Read(sLabel, loc, self.nIndent, tok[1],tokPar[1])
            tok   = self.GetNextToken()
            tok   = self.ParseIOControlSpec(tok, read)
            read.SetParClose(tok[1])
            tok=self.GetNextToken()
        else:

            read  = Read(sLabel, loc, self.nIndent, tok[1])