Synopsis - Synopsis/Processors/Comments/Filter.py

File: Synopsis/Processors/Comments/Filter.py

      1#
      2# Copyright (C) 2005 Stefan Seefeld
      3# All rights reserved.
      4# Licensed to the public under the terms of the GNU LGPL (>= 2),
      5# see the file COPYING for details.
      6#
      7
      8from Synopsis.Processor import Processor
      9from Synopsis import ASG
     10import re
     11
     12class Filter(Processor, ASG.Visitor):
     13    """Base class for comment filters."""
     14
     15    def process(self, ir, **kwds):
     16
     17        self.set_parameters(kwds)
     18
     19        self.ir = self.merge_input(ir)
     20
     21        for d in ir.asg.declarations:
     22            d.accept(self)
     23
     24        return self.output_and_return_ir()
     25
     26
     27    def visit_declaration(self, decl):
     28
     29        comments = decl.annotations.get('comments', [])
     30        comments[:] = [c is not None and self.filter_comment(c) or None
     31                       for c in comments]
     32
     33    visit_builtin = visit_declaration
     34
     35    def filter_comment(self, comment):
     36        """Filter comment."""
     37
     38        return comment
     39
     40
     41class CFilter(Filter):
     42    """A class that filters C-style comments."""
     43
     44    comment = r'/[\*]+[ \t]*(?P<text>.*)(?P<lines>(\n[ \t]*.*)*?)(\n[ \t]*)?[\*]+/'
     45    # Match lines with and without asterisk.
     46    # Preserve space after asterisk so empty lines are formatted correctly.
     47    line = r'\n[ \t]*([ \t]*[\*]+(?=[ \t\n]))*(?P<text>.*)'
     48
     49    def __init__(self, **kwds):
     50        """Compiles the regular expressions"""
     51
     52        Filter.__init__(self, **kwds)
     53        self.comment = re.compile(CFilter.comment)
     54        self.line = re.compile(CFilter.line)
     55
     56    def filter_comment(self, comment):
     57        """Finds comments in the C format. The format is  /* ... */.
     58        It has to cater for all five line forms: "/* ...", " * ...", " ...",
     59        " */" and the one-line "/* ... */".
     60        """
     61
     62        text = []
     63        mo = self.comment.search(comment)
     64        while mo:
     65            text.append(mo.group('text'))
     66            lines = mo.group('lines')
     67            if lines:
     68                mol = self.line.search(lines)
     69                while mol:
     70                    text.append(mol.group('text'))
     71                    mol = self.line.search(lines, mol.end())
     72            mo = self.comment.search(comment, mo.end())
     73        return '\n'.join(text)
     74
     75
     76class SSFilter(Filter):
     77    """A class that selects only // comments."""
     78
     79    ss = r'^[ \t]*// ?(.*)$'
     80
     81    def __init__(self, **kwds):
     82        "Compiles the regular expressions"
     83
     84        Filter.__init__(self, **kwds)
     85        self.ss = re.compile(SSFilter.ss, re.M)
     86
     87
     88    def filter_comment(self, comment):
     89        """"""
     90
     91        return '\n'.join(self.ss.findall(comment))
     92
     93
     94class SSDFilter(Filter):
     95    """A class that selects only //. comments."""
     96
     97    ssd = r'^[ \t]*//\. ?(.*)$'
     98
     99    def __init__(self, **kwds):
    100        "Compiles the regular expressions"
    101
    102        Filter.__init__(self, **kwds)
    103        self.ssd = re.compile(SSDFilter.ssd, re.M)
    104
    105
    106    def filter_comment(self, comment):
    107        """"""
    108
    109        return '\n'.join(self.ssd.findall(comment))
    110
    111
    112class SSSFilter(Filter):
    113    """A class that selects only /// comments."""
    114
    115    sss = r'^[ \t]*/// ?(.*)$'
    116
    117    def __init__(self, **kwds):
    118        "Compiles the regular expressions"
    119
    120        Filter.__init__(self, **kwds)
    121        self.sss = re.compile(SSSFilter.sss, re.M)
    122
    123
    124    def filter_comment(self, comment):
    125        """"""
    126
    127        return '\n'.join(self.sss.findall(comment))
    128
    129
    130class QtFilter(Filter):
    131    """A class that finds Qt style comments. These have two styles: //! ...
    132    and /*! ... */. The first means "brief comment" and there must only be
    133    one. The second type is the detailed comment."""
    134
    135    brief = r"[ \t]*//!(.*)"
    136    detail = r"[ \t]*/\*!(.*)\*/[ \t\n]*"
    137
    138    def __init__(self, **kwds):
    139        "Compiles the regular expressions"
    140
    141        Filter.__init__(self, **kwds)
    142        self.brief = re.compile(QtFilter.brief)
    143        self.detail = re.compile(QtFilter.detail, re.S)
    144
    145
    146    def filter_comment(self, comment):
    147        "Matches either brief or detailed comments."
    148
    149        mo = self.brief.match(comment)
    150        if mo:
    151            return mo.group(1)
    152        else:
    153            mo = self.detail.match(comment)
    154            if mo:
    155                return mo.group(1)
    156        return ''
    157
    158
    159class JavaFilter(Filter):
    160    """A class that selects java /** style comments"""
    161
    162    java = r'/\*\*[ \t]*(?P<text>.*)(?P<lines>(\n[ \t]*\*.*)*?)(\n[ \t]*)?\*/'
    163    line = r'\n[ \t]*\*[ \t]*(?P<text>.*)'
    164
    165
    166    def __init__(self):
    167        "Compiles the regular expressions"
    168
    169        self.java = re.compile(JavaFilter.java)
    170        self.line = re.compile(JavaFilter.line)
    171
    172
    173    def filter_comment(self, comment):
    174      """Finds comments in the java format. The format is  /** ... */, and
    175      it has to cater for all four line forms: "/** ...", " * ...", " */" and
    176      the one-line "/** ... */".
    177      """
    178
    179      text_list = []
    180      mo = self.java.search(comment)
    181      while mo:
    182         text_list.append(mo.group('text'))
    183         lines = mo.group('lines')
    184         if lines:
    185            mol = self.line.search(lines)
    186            while mol:
    187               text_list.append(mol.group('text'))
    188               mol = self.line.search(lines, mol.end())
    189         mo = self.java.search(comment, mo.end())
    190      return '\n'.join(text_list)
    191
    192

Generated on Thu Apr 16 16:27:12 2009 by
synopsis (version devel)