def str(self, max_len_first, max_len_following=0): """ Gives this line as a list of strings. The first line with maximum length max_len_first, the following lines of maximum length max_len_following (The default values max_len_following=0 means 'same as first line') For comments, the maximum lengths can be ignored! """ result = ["PARAMETER ("] indent = len(result[0]) max_len_first -= indent + 1 ## we assume it fits on the line if not max_len_following == 0: max_len_following -= indent names = [] for param in self.parameters: names += [param[0], "=", param[1], ","] del names[-1] ## FIXME: maybe there is a really long right hand side in the parameter ## statement. So catch the exeption and in nessacasy split the rh-sides params = tokenizer.join_tokens(names, max_len_first, max_len_following) result[0] += params[0] for line in params[1:]: result.append(indent * " " + line) result[-1] += ")" return [result]
def str(self, max_len_first, max_len_following=0): """ Gives this line as a list of strings. The first line with maximum length max_len_first, the following lines of maximum length max_len_following (The default values max_len_following=0 means 'same as first line') For comments, the maximum lengths can be ignored! """ result = ["EQUIVALENCE "] indent = len(result[0]) max_len_first -= indent + 1 ## we assume it fits on the line if not max_len_following == 0: max_len_following -= indent names = [] for l in self.equ_lists: names += ["(", []] for var_name in l: names[-1] += var_name + [","] del names[-1][-1] params = tokenizer.join_tokens(names, max_len_first, max_len_following) result[0] += params[0] for line in params[1:]: result.append(indent * " " + line) return [result]
def str(self, max_len_first, max_len_following=0): """ Gives this line as a list of strings. The first line with maximum length max_len_first, the following lines of maximum length max_len_following (The default values max_len_following=0 means 'same as first line') For comments, the maximum lengths can be ignored! """ result = ["COMMON /" + self.common_name + "/ "] indent = len(result[0]) max_len_first -= indent ## we assume it fits on the line if not max_len_following == 0: max_len_following -= indent ## for the variable names build a token_list like that: ## ["INT1", ",", "INT2", ",", ... ] var_names = [] for var in self.variable_names: if not self.remove_dimensions: var_names += [var, ","] else: var_names += [tokenizer.tokenize(var)[0], ","] del var_names[-1] vars = tokenizer.join_tokens(var_names, max_len_first, max_len_following) result[0] += vars[0] for line in vars[1:]: result.append(indent * " " + line) return [result]
def __init__(self, tokens): unknown.__init__(self, tokens) self.is_declaration = True self.variables = [] self.type = "declaration" ## we want to buid a list like that: [['TYPE'], ['name1', 'name2', ...] ] ## F90 syntax is easy: if "::" in self.tokens: declaration = tokenizer.split_token_list(self.tokens, ["::"]) declaration[1] = tokenizer.split_token_list(declaration[1], [',']) ## F77 is harder: else: end = 1 if self.tokens[end] == '*': if self.tokens[end + 1] == '(': end += 3 else: end += 2 if self.tokens[end] == '(': end += 2 declaration = [[], []] declaration[0] = self.tokens[:end] declaration[1] = tokenizer.split_token_list( self.tokens[end:], [',']) self.variable_type = tokenizer.join_tokens(declaration[0]) ## now process this list; for i in range(len(declaration[1])): var = variable(declaration[1][i], declaration[0]) self.variables.append(var)
def __init__(self, tokens): unknown.__init__(self, tokens) self.is_declaration = True self.type = "parameter" if not tokens[0].upper() == "PARAMETER" and tokens[1] == "(": raise error.ParsingError("Invalid PARAMETER statement") name_list = tokenizer.split_token_list(tokens[2], [","]) self.parameters = [(i[0], tokenizer.join_tokens(i[2:])) for i in name_list]
def str(self, max_len_first, max_len_following=0): """ Gives this line as a list of strings. The first line with maximum length max_len_first, the following lines of maximum length max_len_following (The default values max_len_following=0 means 'same as first line') For comments, the maximum lengths can be ignored! """ ## F77 style of variable declarations if self.variable_type in ["", "CHARACTER"]: types = [] for var in self.variables: if var.type == "CHARACTER": t = "CHARACTER*" + str(var.char_len) else: t = var.type if not t in types: types.append(t) else: types = [self.variable_type] result = [] for t in types: result.append([t + " "]) indent = len(result[-1][-1]) mlen_first = max_len_first - indent ## we assume it fits on the line if not max_len_following == 0: mlen_following = max_len_following - indent else: mlen_following = max_len_following ## for the variable name build a token_list like that: ## ["INT1", ",", "INT2(10)", ",", ..." variable_names = [] for var in self.variables: if t.startswith("CHARACTER") and var.type == "CHARACTER": if t[t.find('*') + 1:] == var.char_len: variable_names += [var.name + var.dimension, ","] elif var.type == t: variable_names += [var.name + var.dimension, ","] del variable_names[-1] vars = tokenizer.join_tokens(variable_names, mlen_first, mlen_following) result[-1][-1] += vars[0] for line in vars[1:]: result[-1].append(indent * " " + line) return result
def __init__(self, tokens): unknown.__init__(self, tokens) self.is_declaration = True self.type = "common block" self.remove_dimensions = False if not tokens[0].upper( ) == "COMMON" and tokens[1] == "/" and tokens[3] == "/": raise error.ParsingError("Invalid COMMON statement") if "/" in tokens[4:]: raise error.NotImplementedError( "Two common blocks declared in one COMMON statement", False) self.common_name = tokens[2] name_list = tokenizer.split_token_list(tokens[4:], [","]) self.variable_names = [tokenizer.join_tokens(i) for i in name_list]
def str(self, max_len_first, max_len_following=0): """ Gives this line as a of lists of strings. Each list is one 'program line' (that means: actually belongs to one line, but is maybe split over multiple line that have to be joined by appropriate continuation marks). The first line with maximum length max_len_first, the following lines of maximum length max_len_following (The default values max_len_following=0 means 'same as first line') For comments, the maximum lengths can be ignored! """ ## This version indents continuation lines by 1 space if not max_len_following == 0: max_len_following -= 1 result = tokenizer.join_tokens(self.tokens, max_len_first, max_len_following) result[1:] = [(" " + r) for r in result[1:]] return [result]
def new_statement(tokens): """ generic interface to this module: Take a list of tokens and returns a suitable statement-class """ ## a declaration if tokens[0].upper() in [ "INTEGER", "REAL", "LOGICAL", "DOUBLE PRECISION", "CHARACTER" ]: return declaration(tokens) elif tokens[0].upper() == "COMMON": return common_block(tokens) elif tokens[0].upper() == "PARAMETER": return parameter(tokens) elif tokens[0].upper() == "EQUIVALENCE": return equivalence(tokens) else: s = tokenizer.join_tokens(tokens) raise error.NotImplementedError("Unknown statement: " + s) return unknown(tokens)
def __init__(self, decl_token_list, type_token_list=[]): """ decl_token_list: the list of tokens of the (implicit or explicit) declaration, beginnig with the variable name type_token_list: the token list declaring the type in an explicit declaration ( for example INTEGER, REAL*8 or 'INTEGER, DIMENSION(10)' if empty, implicit typing [IMPLICIT REAL*8 (A-H,O-Z)] is assumed """ self.dimension = "" self.type = "" implicit = (type_token_list == []) ## first process the declaration part if not implicit: type_decl = tokenizer.split_token_list(type_token_list, [',']) ## up to now we only consider the type name and a dimension statement ## type name self.type = tokenizer.join_tokens(type_decl[0]) if type_decl[0][0].upper() == "CHARACTER": self.char_len = '1' self.type = "CHARACTER" if "*" in type_decl[0]: i = type_decl[0].index("*") if type_decl[0][i + 1] == '(': self.char_len = tokenizer.join_tokens( type_decl[0][i + 1:i + 3]) else: self.char_len = type_decl[0][i + 1] elif len(type_decl[0]) > 1 and type_decl[0][1] == "(": if type_decl[0][2][0:1] == ["LEN", "="]: self.char_len = int(type_decl[0][2][2]) for i in range(1, len(type_decl)): if type_decl[i][0].upper() == "DIMENSION": if len(type_decl[i]) < 3 or not type_decl[i][1] == '(': raise ParsingError("Invalid DIMENSION statement") else: self.dimension = tokenizer.join_tokens( type_decl[i][1:3]) if type_decl[0][0].upper() == "CHARACTER" and \ type_decl[i][0].upper() == "LEN" and type_decl[i][1] == "=": char_len = typle_decl[i][2] ## now process the variable name self.name = decl_token_list[0] ## is there a dimesion specification following the variable name? ## (if so, it is overriding a possible previos DIMENSION statement if len(decl_token_list) >= 3 and decl_token_list[1] == '(': self.dimension = tokenizer.join_tokens(decl_token_list[1:3]) ## same for character length if self.type == 'CHARACTER' and "*" in decl_token_list: i = decl_token_list.index("*") if decl_token_list[i + 1] == '(': self.char_len = tokenizer.join_tokens(decl_token_list[i + 1:i + 3]) else: self.char_len = decl_token_list[i + 1] ## if needed, do implicit typing if implicit: if self.name[0].upper() in "IJKLMN": self.type = "INTEGER" else: self.type = "REAL*8"