Exemple #1
0
def merge_adjacent_comment_lines(lines):
    """Given a list of numered Fortran source code lines, i.e., pairs of the
       form (n, code_line) where n is a line number and code_line is a line
       of code, merge_adjacent_comment_lines() merges sequences of lines that are
       indicated to be comment lines.
    """

    i = 0
    while i < len(lines) - 1:
        lnum, line = lines[i]
        if line_is_comment(line):
            j = i + 1
            while j < len(lines) and line_is_comment(lines[j][1]):
                line += lines[j][1]
                lines.pop(j)
                # pop() removes a line so lines[j] now refers to the next line

            lines[i] = (lnum, line)
        i += 1

    return lines
Exemple #2
0
def separate_trailing_comments(lines: List[str]) -> List[Tuple[int, str]]:
    """Given a list of Fortran source code linesseparate_trailing_comments()
       removes partial-line comments and returns the resulting list of lines.
    """
    i = 0
    while i < len(lines):
        code_line = lines[i]
        if not line_is_comment(code_line):
            (code_part, comment_part) = split_trailing_comment(code_line)
            if comment_part is not None:
                lines[i] = code_part
        i += 1

    return lines
Exemple #3
0
def type_of_line(line):
    """Given a line of code, type_of_line() returns a string indicating
       what kind of code it is."""

    if line_is_comment(line):
        return "comment"
    elif line_is_executable(line):
        return "exec_stmt"
    elif line_is_pgm_unit_end(line):
        return "pgm_unit_end"
    else:
        if line_is_pgm_unit_start(line):
            return "pgm_unit_start"
        else:
            return "other"
Exemple #4
0
def merge_continued_lines(lines):
    """Given a list of numered Fortran source code lines, i.e., pairs of the
       form (n, code_line) where n is a line number and code_line is a line
       of code, merge_continued_lines() merges sequences of lines that are
       indicated to be continuation lines.
    """

    # Before a continuation line L1 is merged with the line L0 before it (and
    # presumably the one L1 is continuing), ensure that L0 is not a comment.
    # If L0 is a comment, swap L0 and L1.
    chg = True
    while chg:
        chg = False
        i = 0
        while i < len(lines) - 1:
            ln0, ln1 = lines[i], lines[i + 1]
            if line_is_comment(ln0[1]) and line_is_continuation(ln1[1]):
                # swap the code portions of lines[i] and lines[i+1]
                lines[i], lines[i + 1] = (ln0[0], ln1[1]), (ln1[0], ln0[1])
                chg = True
            i += 1

    # Merge continuation lines
    chg = True
    while chg:
        chg = False
        i = 0
        while i < len(lines):
            line = lines[i]
            if line_is_continuation(line[1]):
                assert i > 0
                (prev_linenum, prev_line_code) = lines[i - 1]
                curr_line_code = line[1].lstrip()[
                    1:
                ]  # remove continuation  char
                merged_code = prev_line_code.rstrip() + curr_line_code.lstrip()

                lines[i - 1] = (prev_linenum, merged_code)
                lines.pop(i)
                chg = True
            i += 1

    return lines
Exemple #5
0
def separate_trailing_comments(lines: List[str]) -> List[Tuple[int, str]]:
    """Given a list of numbered Fortran source code lines, i.e., pairs of the
       form (n, code_line) where n is a line number and code_line is a line
       of code, separate_trailing_comments() behaves as follows: for each
       pair (n, code_line) where code_line can be broken into two parts -- a
       code portion code_part and a trailing comment portion comment_part, such
       that code_part and comment_part are both non-empty, it replaces the
       pair (n, code_line) by two pairs (n, comment_part) and (n, code_part).
       The return value is the resulting list of numbered lines.
    """

    i = 0
    while i < len(lines):
        (n, code_line) = lines[i]
        if not line_is_comment(code_line):
            (code_part, comment_part) = split_trailing_comment(code_line)
            if comment_part is not None:
                lines[i] = (n, comment_part)
                lines.insert(i + 1, (n, code_part))
        i += 1

    return lines
Exemple #6
0
def merge_continued_lines(lines):
    """Given a list of numered Fortran source code lines, i.e., pairs of the
       form (n, code_line) where n is a line number and code_line is a line
       of code, merge_continued_lines() merges sequences of lines that are
       indicated to be continuation lines.
    """

    # Before a continuation line L1 is merged with the line L0 before it (and
    # presumably the one L1 is continuing), ensure that L0 is not a comment.
    # If L0 is a comment, swap L0 and L1.
    chg = True
    swaps = set()
    while chg:
        chg = False
        i = 0
        while i < len(lines) - 1:
            ln0, ln1 = lines[i], lines[i + 1]
            if (line_is_comment(ln0[1]) and line_is_continuation(ln1[1])) \
               or (line_is_continued(ln0[1]) and line_is_comment(ln1[1])):
                if (i, i + 1) not in swaps:
                    # swap the code portions of lines[i] and lines[i+1]
                    lines[i], lines[i + 1] = (ln0[0], ln1[1]), (ln1[0], ln0[1])
                    swaps.add((i, i + 1))  # to prevent infinite loops
                else:
                    # If we get here, there is a pair of adjacent lines that
                    # are about to go into an infinite swap sequence; one of them
                    # must be a comment.  We delete the comment.
                    if line_is_comment(ln0[1]):
                        lines.pop(i)
                    else:
                        assert line_is_comment(ln1[1])
                        lines.pop(i + 1)
                chg = True

            i += 1

    # Merge continuation lines
    chg = True
    while chg:
        chg = False
        i = 0
        while i < len(lines):
            line = lines[i]
            if line_is_continuation(line[1]):
                assert i > 0
                (prev_linenum, prev_line_code) = lines[i - 1]
                curr_line_code = line[1].lstrip()[
                    1:]  # remove continuation  char
                merged_code = prev_line_code.rstrip() + \
                              " " + \
                              curr_line_code.lstrip() + \
                              "\n"
                lines[i - 1] = (prev_linenum, merged_code)
                lines.pop(i)
                chg = True
            elif line_is_continued(line[1]):
                assert i < len(lines) - 1  # there must be a next line
                (next_linenum, next_line_code) = lines[i + 1]
                curr_line_code = line[1].rstrip()[:-1].rstrip(
                )  # remove continuation  char
                merged_code = curr_line_code + " " + next_line_code.lstrip()
                lines[i] = (i, merged_code)
                lines.pop(i + 1)
                chg = True

            i += 1

    return lines
Exemple #7
0
def get_comments(src_file_name: str):
    curr_comment = []
    curr_fn, prev_fn, curr_marker = None, None, None
    in_neck = False
    comments = OrderedDict()
    lineno = 1

    comments["$file_head"] = None
    comments["$file_foot"] = None

    _, f_ext = os.path.splitext(src_file_name)

    with open(src_file_name, "r", encoding="latin-1") as f:
        for line in f:
            if line_is_comment(line) or line.strip() == "":
                curr_comment.append(line)
            else:
                if comments["$file_head"] is None:
                    comments["$file_head"] = curr_comment

                f_start, f_name_maybe = line_starts_subpgm(line)
                if f_start:
                    f_name = f_name_maybe

                    prev_fn = curr_fn
                    curr_fn = f_name

                    if prev_fn is not None:
                        comments[prev_fn]["foot"] = curr_comment

                    comments[curr_fn] = init_comment_map(
                        curr_comment, [], [], OrderedDict())
                    curr_comment = []
                    in_neck = True
                elif line_ends_subpgm(line):
                    curr_comment = []
                elif line_is_continuation(line, f_ext):
                    lineno += 1
                    continue
                else:
                    if in_neck:
                        comments[curr_fn]["neck"] = curr_comment
                        in_neck = False
                        curr_comment = []
                    else:
                        match = re.match(RE_INTERNAL_COMMENT_MARKER, line)
                        if match != None:
                            curr_marker = match.group(1)
                            curr_comment = []
                        elif curr_marker != None:
                            comments[curr_fn]["internal"][
                                curr_marker] = curr_comment
                            curr_marker = None
                            curr_comment = []

            lineno += 1

    # if there's a comment at the very end of the file, make it the foot
    # comment of curr_fn
    if curr_comment != [] and comments.get(curr_fn):
        comments[curr_fn]["foot"] = curr_comment
        comments["$file_foot"] = curr_comment

    if comments["$file_head"] is None:
        comments["$file_head"] = []
    if comments["$file_foot"] is None:
        comments["$file_foot"] = []

    return comments
Exemple #8
0
def discard_comments(lines):
    return [
        line for line in lines
        if not (line_is_comment(line) or line.strip() == "")
    ]