1 """
   2 	MoinMoin - C++ Source Parser
   3 
   4 	Copyright (c) 2002 by Taesu Pyo <bigflood@hitel.net>
   5 	All rights reserved.
   6 
   7 """
   8 
   9 # Imports
  10 import cgi, string, re, sys
  11 
  12 
  13 #############################################################################
  14 
  15 class ReservedWordFormat:
  16 	def __init__(self,color,bold=1):
  17 		self.color = color
  18 		self.bold = bold
  19 	def formatString(self,word):
  20 		if self.bold:
  21 			return '<font color="%s"><b>%s</b></font>' % (self.color,word)
  22 		else:
  23 			return '<font color="%s">%s</font>' % (self.color,word)
  24 
  25 
  26 class Parser:
  27 	"""
  28 	"""
  29 	formatting_rules = r"""(?P<CommentStart>/[*])
  30 (?P<LineComment>//.*$)
  31 (?P<StringStart>L?")
  32 (?P<Char>'\\.'|'[^\\]')
  33 (?P<Number>[0-9](\.[0-9]*)?(eE[+-][0-9])?[flFLuU]?|0[xX][0-9a-fA-F]+)
  34 (?P<Preprc>^\s*#(.*\\\n)*.*$)
  35 (?P<ID>[a-zA-Z_][0-9a-zA-Z_]*)
  36 (?P<SPChar>[~!%^&*()+=|\[\]:;,.<>/?{}-])"""
  37 	
  38 	reserved_words = ['struct','class','union','enum',
  39 	'int','float','double','signed','unsigned','char','short','void','bool',
  40 	'long','register','auto','operator',
  41 	'static','const','private','public','protected','virtual','explicit',
  42 	'new','delete','this',
  43 	'if','else','while','for','do','switch','case','default','sizeof',
  44 	'dynamic_cast','static_cast','const_cast','reinterpret_cast','typeid',
  45 	'try','catch','throw','throws','return','continue','break','goto']
  46 
  47 	reserved_words2 = ['extern', 'volatile', 'typedef', 'friend',
  48 	'__declspec', 'inline','__asm','thread','naked','dllimport','dllexport',
  49 	'namespace','using', 'template','typename','goto']
  50 
  51 	special_words = ['std','string','vector','map','set','cout','cin','cerr']
  52 
  53 	constant_words = ['true','false','NULL']
  54 
  55 	ID_format = {}
  56 	for w in reserved_words:
  57 		ID_format[w] = ReservedWordFormat('#4040ff')
  58 
  59 	for w in reserved_words2:
  60 		ID_format[w] = ReservedWordFormat('#0080ff')
  61 	
  62 	for w in special_words:
  63 		ID_format[w] = ReservedWordFormat('#0000ff',bold=0)
  64 
  65 	for w in constant_words:
  66 		ID_format[w] = ReservedWordFormat('#008080')
  67 
  68 	ID_def_format = ReservedWordFormat('#000000',bold=0)
  69 
  70 
  71 	def __init__(self, raw, request, **kw):
  72 		self.raw = raw
  73 		self.rawout = kw.get('out', sys.stdout)
  74 		self.line_count = 0
  75 	
  76 	
  77 	def write(self, s):
  78 		self.rawout.write(s)
  79 
  80 
  81 	def format(self, formatter, form):
  82 		""" Send the text.
  83 		"""
  84 		scan_re = re.compile(self.formatting_rules.replace('\n','|'),re.M)
  85 		self.end_comment_re = re.compile(r'[*]/',re.M)
  86 		self.end_string_re = re.compile(r'[^\\]$|[^\\](\\\\)*"',re.M)
  87 
  88 		self.lastpos = 0
  89 		self.line = self.raw
  90 
  91 		self.write('<pre><font face="Lucida,Courier New" color="#C00000">')
  92 
  93 		match = scan_re.search(self.line)
  94 
  95 		while match and self.lastpos < len(self.line):
  96 			# add the match we found
  97 			self.write_no_match(self.line[self.lastpos:match.start()])
  98 			self.lastpos = match.end() + (match.end() == self.lastpos)
  99 
 100 			self.write_match(match)
 101 
 102 			# search for the next one
 103 			match = scan_re.search(self.line, self.lastpos)
 104 
 105 		self.write_no_match(self.line[self.lastpos:])
 106 
 107 		self.write('</font></pre>')
 108 
 109 
 110 	def write_no_match(self,text):
 111 		text = cgi.escape(text)
 112 		text = string.expandtabs(text)
 113 		self.write(text)
 114 
 115 	def write_match(self,match):
 116 		for type, hit in match.groupdict().items():
 117 			if not hit: continue
 118 			apply(getattr(self, 'write_match_' + type), (hit,))
 119 	
 120 
 121 	def write_match_CommentStart(self,hit):
 122 		self.write('<font color="#808080">' + str(hit))
 123 		match = self.end_comment_re.search(self.line, self.lastpos)
 124 		if not match:
 125 			next_lastpos = len(self.line)
 126 		else:
 127 			next_lastpos = match.end() + (match.end() == self.lastpos)
 128 		self.write(self.line[self.lastpos:next_lastpos])
 129 		self.lastpos = next_lastpos
 130 		self.write('</font>')
 131 
 132 	def write_match_StringStart(self,hit):
 133 		self.write('<font color="#004080">' + str(hit))
 134 
 135 		if self.line[self.lastpos] == '"':
 136 			next_lastpos = self.lastpos + 1
 137 		else:
 138 			match = self.end_string_re.search(self.line, self.lastpos)
 139 			if not match:
 140 				next_lastpos = len(self.line)
 141 			else:
 142 				next_lastpos = match.end() + (match.end() == self.lastpos)
 143 		self.write(self.line[self.lastpos:next_lastpos])
 144 		self.lastpos = next_lastpos
 145 		self.write('</font>')
 146 
 147 	def write_match_Char(self,hit):
 148 		self.write('<font color="#004080">%s</font>' % hit)
 149 
 150 	def write_match_LineComment(self,hit):
 151 		self.write('<font color="#808080">%s</font>' % hit)
 152 
 153 	def write_match_Preprc(self,hit):
 154 		self.write('<font color="#804000">%s</font>' % cgi.escape(hit))
 155 
 156 	def write_match_Number(self,hit):
 157 		self.write('<font color="#008080"><B>%s</B></font>' % hit)
 158 
 159 	def write_match_ID(self,hit):
 160 		c = self.ID_format.get(hit,self.ID_def_format)
 161 		self.write(c.formatString(hit))
 162 
 163 	def write_match_SPChar(self,hit):
 164 		self.write('<font color="#0000C0">%s</font>' % cgi.escape(hit))
 165 
 166 
 167 if __name__ == "__main__":
 168 	import os, sys
 169 
 170 	# open C++ source.
 171 	source = open('test.cpp').read()
 172 	Parser(source, None, out = open('test.html', 'wt')).format(None, None)
 173 
 174 	# load HTML page into browser
 175 	if os.name == "nt":
 176 		os.system("explorer test.html")
 177 	else:
 178 		os.system("netscape test.html &")

MoinMoin: ParserMarket/cplusplus.py (last edited 2007-10-29 19:13:25 by localhost)