File: Synopsis/Processors/Comments/Filter.py 1
2
3
4
5
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
46
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)