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 sf in self.ir.files.values():
22 self.visit_sourcefile(sf)
23
24 for d in ir.asg.declarations:
25 d.accept(self)
26
27 return self.output_and_return_ir()
28
29
30 def visit_declaration(self, decl):
31
32 comments = decl.annotations.get('comments', [])
33 comments[:] = [c is not None and self.filter_comment(c) or None
34 for c in comments]
35
36 visit_builtin = visit_declaration
37 visit_sourcefile = visit_declaration
38
39 def filter_comment(self, comment):
40 """Filter comment."""
41
42 return comment
43
44
45class CFilter(Filter):
46 """A class that filters C-style comments."""
47
48 comment = r'/[\*]+[ \t]*(?P<text>.*)(?P<lines>(\n[ \t]*.*)*?)(\n[ \t]*)?[\*]+/'
49
50
51 line = r'\n[ \t]*([ \t]*[\*]+(?=[ \t\n]))*(?P<text>.*)'
52
53 def __init__(self, **kwds):
54 """Compiles the regular expressions"""
55
56 Filter.__init__(self, **kwds)
57 self.comment = re.compile(CFilter.comment)
58 self.line = re.compile(CFilter.line)
59
60 def filter_comment(self, comment):
61 """Finds comments in the C format. The format is /* ... */.
62 It has to cater for all five line forms: "/* ...", " * ...", " ...",
63 " */" and the one-line "/* ... */".
64 """
65
66 text = []
67 mo = self.comment.search(comment)
68 while mo:
69 text.append(mo.group('text'))
70 lines = mo.group('lines')
71 if lines:
72 mol = self.line.search(lines)
73 while mol:
74 text.append(mol.group('text'))
75 mol = self.line.search(lines, mol.end())
76 mo = self.comment.search(comment, mo.end())
77 return '\n'.join(text)
78
79
80class SSFilter(Filter):
81 """A class that selects only // comments."""
82
83 ss = r'^[ \t]*// ?(.*)$'
84
85 def __init__(self, **kwds):
86 "Compiles the regular expressions"
87
88 Filter.__init__(self, **kwds)
89 self.ss = re.compile(SSFilter.ss, re.M)
90
91
92 def filter_comment(self, comment):
93 """"""
94
95 return '\n'.join(self.ss.findall(comment))
96
97
98class SSDFilter(Filter):
99 """A class that selects only //. comments."""
100
101 ssd = r'^[ \t]*//\. ?(.*)$'
102
103 def __init__(self, **kwds):
104 "Compiles the regular expressions"
105
106 Filter.__init__(self, **kwds)
107 self.ssd = re.compile(SSDFilter.ssd, re.M)
108
109
110 def filter_comment(self, comment):
111 """"""
112
113 return '\n'.join(self.ssd.findall(comment))
114
115
116class SSSFilter(Filter):
117 """A class that selects only /// comments."""
118
119 sss = r'^[ \t]*/// ?(.*)$'
120
121 def __init__(self, **kwds):
122 "Compiles the regular expressions"
123
124 Filter.__init__(self, **kwds)
125 self.sss = re.compile(SSSFilter.sss, re.M)
126
127
128 def filter_comment(self, comment):
129 """"""
130
131 return '\n'.join(self.sss.findall(comment))
132
133
134class QtFilter(Filter):
135 """A class that finds Qt style comments. These have two styles: //! ...
136 and /*! ... */. The first means "brief comment" and there must only be
137 one. The second type is the detailed comment."""
138
139 brief = r"[ \t]*//!(.*)"
140 detail = r"[ \t]*/\*!(.*)\*/[ \t\n]*"
141
142 def __init__(self, **kwds):
143 "Compiles the regular expressions"
144
145 Filter.__init__(self, **kwds)
146 self.brief = re.compile(QtFilter.brief)
147 self.detail = re.compile(QtFilter.detail, re.S)
148
149
150 def filter_comment(self, comment):
151 "Matches either brief or detailed comments."
152
153 mo = self.brief.match(comment)
154 if mo:
155 return mo.group(1)
156 else:
157 mo = self.detail.match(comment)
158 if mo:
159 return mo.group(1)
160 return ''
161
162
163class JavaFilter(Filter):
164 """A class that selects java /** style comments"""
165
166 java = r'/\*\*[ \t]*(?P<text>.*)(?P<lines>(\n[ \t]*\*.*)*?)(\n[ \t]*)?\*/'
167 line = r'\n[ \t]*\*[ \t]*(?P<text>.*)'
168
169
170 def __init__(self):
171 "Compiles the regular expressions"
172
173 self.java = re.compile(JavaFilter.java)
174 self.line = re.compile(JavaFilter.line)
175
176
177 def filter_comment(self, comment):
178 """Finds comments in the java format. The format is /** ... */, and
179 it has to cater for all four line forms: "/** ...", " * ...", " */" and
180 the one-line "/** ... */".
181 """
182
183 text_list = []
184 mo = self.java.search(comment)
185 while mo:
186 text_list.append(mo.group('text'))
187 lines = mo.group('lines')
188 if lines:
189 mol = self.line.search(lines)
190 while mol:
191 text_list.append(mol.group('text'))
192 mol = self.line.search(lines, mol.end())
193 mo = self.java.search(comment, mo.end())
194 return '\n'.join(text_list)
195
196
Generated on Tue Jul 20 09:07:11 2010 by
synopsis (version devel)