Skip to content

Commit

Permalink
further improvements on error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
pseewald committed Sep 1, 2016
1 parent 268ccac commit c44b6a7
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 33 deletions.
27 changes: 20 additions & 7 deletions fparse_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,23 @@
flags=re.IGNORECASE)

# FIXME bad ass regex!
VAR_DECL_RE = re.compile(r" *(?P<type>integer(?: *\* *[0-9]+)?|logical|character(?: *\* *[0-9]+)?|real(?: *\* *[0-9]+)?|complex(?: *\* *[0-9]+)?|type) *(?P<parameters>\((?:[^()]+|\((?:[^()]+|\([^()]*\))*\))*\))? *(?P<attributes>(?: *, *[a-zA-Z_0-9]+(?: *\((?:[^()]+|\((?:[^()]+|\([^()]*\))*\))*\))?)+)? *(?P<dpnt>::)?(?P<vars>[^\n]+)\n?", re.IGNORECASE)
VAR_DECL_RE = re.compile(
r" *(?P<type>integer(?: *\* *[0-9]+)?|logical|character(?: *\* *[0-9]+)?|real(?: *\* *[0-9]+)?|complex(?: *\* *[0-9]+)?|type) *(?P<parameters>\((?:[^()]+|\((?:[^()]+|\([^()]*\))*\))*\))? *(?P<attributes>(?: *, *[a-zA-Z_0-9]+(?: *\((?:[^()]+|\((?:[^()]+|\([^()]*\))*\))*\))?)+)? *(?P<dpnt>::)?(?P<vars>[^\n]+)\n?", re.IGNORECASE)

OMP_DIR_RE = re.compile(r"^\s*(!\$omp)", re.IGNORECASE)
OMP_RE = re.compile(r"^\s*(!\$)", re.IGNORECASE)


class FPrettifyParseError(Exception):
"""Exception for unparseable Fortran code"""

def __init__(self, filename, line_nr,
msg=("Parser error - "
"possibly due to incorrect Fortran syntax.")):
super(FPrettifyParseError, self).__init__('{}:{}:{}'.format(
filename, line_nr, msg))


class CharFilter(object):
"""
An iterator to wrap the iterator returned by `enumerate`
Expand Down Expand Up @@ -70,10 +81,13 @@ class InputStream(object):
Class to read logical Fortran lines from a Fortran file.
"""

def __init__(self, infile):
def __init__(self, infile, orig_filename=None):
if not orig_filename:
orig_filename = infile.name
self.line_buffer = deque([])
self.infile = infile
self.line_nr = 0
self.filename = orig_filename

def next_fortran_line(self):
"""Reads a group of connected lines (connected with &, separated by newline or semicolon)
Expand Down Expand Up @@ -126,11 +140,12 @@ def next_fortran_line(self):
# FIXME: does not handle line continuation of
# omp conditional fortran statements
# starting with an ampersand.
raise SyntaxError("unexpected line format:" + repr(line))
raise FPrettifyParseError(
self.filename, self.line_nr, "unexpected line format:")
if match.group("preprocessor"):
if len(lines) > 1:
raise SyntaxError(
"continuation to a preprocessor line not supported " + repr(line))
raise FPrettifyParseError(self.filename, self.line_nr,
"continuation to a preprocessor line not supported")
comments.append(line)
break
core_att = match.group("core")
Expand All @@ -151,5 +166,3 @@ def next_fortran_line(self):
if not continuation:
break
return (joined_line, comments, lines)


44 changes: 18 additions & 26 deletions fprettify.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
import os
import tempfile
import logging
from fparse_utils import (USE_PARSE_RE, VAR_DECL_RE, InputStream,
CharFilter, OMP_RE, OMP_DIR_RE)
from fparse_utils import (USE_PARSE_RE, VAR_DECL_RE, OMP_RE, OMP_DIR_RE,
InputStream, CharFilter, FPrettifyParseError)


# PY2/PY3 compat wrappers:
Expand Down Expand Up @@ -159,16 +159,6 @@ def any(iterable):
ENDFCT_RE, ENDMOD_RE, ENDPROG_RE, ENDINTERFACE_RE, ENDTYPE_RE]


class FortranSyntaxError(Exception):
"""Exception for unparseable Fortran code"""

def __init__(self, filename, line_nr,
msg=("Syntax error - "
"this formatter can not handle invalid Fortran files.")):
super(FortranSyntaxError, self).__init__('{}:{}:{}'.format(
filename, line_nr, msg))


class F90Indenter(object):
"""
Parses encapsulation of subunits / scopes line by line
Expand Down Expand Up @@ -251,7 +241,7 @@ def process_lines_of_fline(self, f_line, lines, rel_ind, rel_ind_con,

if is_new:
if not valid_new:
raise FortranSyntaxError(filename, line_nr)
raise FPrettifyParseError(filename, line_nr)
else:
line_indents = [ind + indents[-1] for ind in line_indents]
old_ind = indents[-1]
Expand All @@ -263,13 +253,13 @@ def process_lines_of_fline(self, f_line, lines, rel_ind, rel_ind_con,

elif is_con:
if not valid_con:
raise FortranSyntaxError(filename, line_nr)
raise FPrettifyParseError(filename, line_nr)
else:
line_indents = [ind + indents[-2] for ind in line_indents]

elif is_end:
if not valid_end:
raise FortranSyntaxError(filename, line_nr)
raise FPrettifyParseError(filename, line_nr)
else:
line_indents = [ind + indents[-2] for ind in line_indents]
indents.pop()
Expand Down Expand Up @@ -337,7 +327,7 @@ def process_lines_of_fline(self, f_line, lines, rel_ind, line_nr):
self._line_indents.append(self._br_indent_list[-1])

if len(self._br_indent_list) > 2 or self._level:
raise SyntaxError(self._filename, self._line_nr)
raise FPrettifyParseError(self._filename, self._line_nr)

def get_lines_indent(self):
"""
Expand Down Expand Up @@ -386,7 +376,7 @@ def __align_line_continuations(self, line, is_decl, indent_size, line_nr):
level += -1
indent_list.pop()
if level < 0:
raise FortranSyntaxError(filename, line_nr)
raise FPrettifyParseError(filename, line_nr)

if pos_ldelim:
pos_ldelim.pop()
Expand All @@ -399,7 +389,7 @@ def __align_line_continuations(self, line, is_decl, indent_size, line_nr):
if what_del_open == r"[":
valid = what_del_close == r"]"
if not valid:
raise FortranSyntaxError(filename, line_nr)
raise FPrettifyParseError(filename, line_nr)
else:
pos_rdelim.append(pos)
rdelim.append(what_del_close)
Expand All @@ -408,7 +398,7 @@ def __align_line_continuations(self, line, is_decl, indent_size, line_nr):
if not REL_OP_RE.match(
line[max(0, pos - 1):min(pos + 2, len(line))]):
if pos_eq > 0:
raise FortranSyntaxError(filename, line_nr)
raise FPrettifyParseError(filename, line_nr)
is_pointer = line[pos + 1] == '>'
pos_eq = pos + 1
# don't align if assignment operator directly before
Expand All @@ -435,18 +425,20 @@ def __align_line_continuations(self, line, is_decl, indent_size, line_nr):
self._level = level


def inspect_ffile_format(infile, indent_size):
def inspect_ffile_format(infile, indent_size, orig_filename=None):
"""
Determine indentation by inspecting original Fortran file
(mainly for finding aligned blocks of DO/IF statements).
Also check if it has f77 constructs.
"""
if not orig_filename:
orig_filename = infile.name

adopt = indent_size <= 0

is_f90 = True
indents = []
stream = InputStream(infile)
stream = InputStream(infile, orig_filename)
prev_offset = 0
first_indent = -1
while 1:
Expand Down Expand Up @@ -704,7 +696,7 @@ def format_single_fline(f_line, whitespace, linebreak_pos, ampersand_sep,
lines_out.append(line[linebreak_pos_ftd[-1]:])

if level != 0:
raise FortranSyntaxError(filename, line_nr)
raise FPrettifyParseError(filename, line_nr)

return lines_out

Expand Down Expand Up @@ -750,7 +742,7 @@ def reformat_ffile(infile, outfile, indent_size=3, whitespace=2,

infile.seek(0)
req_indents, first_indent, is_f90 = inspect_ffile_format(
infile, indent_size)
infile, indent_size, orig_filename)
infile.seek(0)

if not is_f90:
Expand All @@ -763,7 +755,7 @@ def reformat_ffile(infile, outfile, indent_size=3, whitespace=2,

do_indent = True
use_same_line = False
stream = InputStream(infile)
stream = InputStream(infile, orig_filename)
skip_blank = False
in_manual_block = False

Expand Down Expand Up @@ -800,8 +792,8 @@ def reformat_ffile(infile, outfile, indent_size=3, whitespace=2,
else:
in_manual_block = False
if not valid_directive:
raise FortranSyntaxError(orig_filename, stream.line_nr,
FORMATTER_ERROR_MESSAGE)
raise FPrettifyParseError(orig_filename, stream.line_nr,
FORMATTER_ERROR_MESSAGE)

indent = [0] * len(lines)

Expand Down

0 comments on commit c44b6a7

Please sign in to comment.