行例:
1. class XXX : public YYY, ZZZ { //正常表达,其中class可为struct,public可为protected,部分空格可有可无,或为TAB,或随意换行。2. class XXX{ //不从任何父类继承3. class XXX:public YYY //:前后或没空格,或只一个父类,或大括号在下一行
{4. class XXX //换行且加了空格
: public YYY现在
$fctx = file_get_contents ($f); //读入整个文件到一行了,用preg_match_all的话可以吗?
或
$lines = file ($f);
foreach ($lines as $ln)
{
if (!preg_match ('/\bclass\b/', $ln, $matches)) //??????这一行想极不知怎么写
{
}
}
#include "FramedFilter.hh"
#endifclass ADUFromMP3Source: public FramedFilter {
public:
static ADUFromMP3Source* createNew(UsageEnvironment& env,
FramedSource* inputSource,
Boolean includeADUdescriptors = True);
分析是想取出ADUFromMP3Source和FramedFilter
#ifndef _FRAMED_FILTER_HH
#include "FramedFilter.hh"
#endifclass ADUFromMP3Source: public FramedFilter {
public:
static ADUFromMP3Source* createNew(UsageEnvironment& env,
FramedSource* inputSource,
Boolean includeADUdescriptors = True);
HTML;
preg_match_all('/class\s*([^\s:\{]*):\s*(?:public|protected)?\s*([^\s:\{]*)\s*\{/isU',$fctx,$m);
print_r($m);Array
(
[0] => Array
(
[0] => class ADUFromMP3Source: public FramedFilter {
) [1] => Array
(
[0] => ADUFromMP3Source
) [2] => Array
(
[0] => FramedFilter
))
function walkfile(&$file)
{
global $classes;
global $all_cnt;
global $allkeys;
$pval = null; $fctx = file_get_contents ($file);
if (!preg_match_all('/class\s*([^\s:\{]*):\s*(?:public|protected)?\s*([^\s:\{]*)\s*\{/isU',$fctx,$m))
return;
for ($i=0; $i<count($m[0]); $i++)
{
$key = trim ($m[2][$i]); //parent class
$val = trim ($m[1][$i]); //subclass //process parent class
if (isset ($allkeys[$key])) //found parent
{
if (!is_array ($allkeys[$key]))
$allkeys[$key] = array ();
if (!isset($allkeys[$key][$val]))
$allkeys[$key][$val] = '';
$pval = &$allkeys[$key][$val];
}
else //not found parent
{
$classes[$key] = array ($val=>'');
$allkeys[$key] = &$classes[$key];
$pval = &$classes[$key][$val];
}
//process sub class
if (isset ($allkeys[$val])) //found subclass
{
if (is_array ($allkeys[$val])) //merge parent to this subclass array
{
if (!is_array ($pval))
$pval = array ();
$pval = array_merge ($pval, $allkeys[$val]);
}
$allkeys[$val] = null;//set the old array to null
$allkeys[$val] = &$pval;//new refrence
}
else //not found subclass
{
$allkeys[$val] = &$pval;
} printf ("class $val : public $key\r\n");
$all_cnt++;
}
}哪位帮忙优化一下呀,我写完程序也贴出来
<?php
$all_cnt = 0;
$classes = array ();// array('aa'=>null, 'bb'=>array('cc'=>'')) : null: has deleted. '': valid
$allkeys = array ();//class=>addr eg. 'cc'=>&$classes['bb']['cc']function outtree (&$parent, $tab)
{
ksort ($parent);
foreach ($parent as $left => &$right)
{
if (is_null ($right)) continue;
printf ("$tab$left\r\n");
is_array ($right) && outtree ($right, $tab."\t");
}
}function walkfile(&$file)
{
global $classes;
global $all_cnt;
global $allkeys;
$pval = null; $fctx = file_get_contents ($file);
if (!preg_match_all('/class\s*([^\s:\{]*):\s*(?:public|protected)?\s*([^\s:\{]*)\s*\{/isU',$fctx,$m))
return;
for ($i=0; $i<count($m[0]); $i++)
{
$key = trim ($m[2][$i]); //parent class
$val = trim ($m[1][$i]); //subclass //process parent class
if (isset ($allkeys[$key])) //found parent
{
(!is_array ($allkeys[$key])) && ($allkeys[$key] = array ());
(!isset($allkeys[$key][$val])) && ($allkeys[$key][$val] = '');
$pval = &$allkeys[$key][$val];
}
else //not found parent
{
$classes[$key] = array ($val=>'');
$allkeys[$key] = &$classes[$key];
$pval = &$classes[$key][$val];
}
//process sub class
if (isset ($allkeys[$val])) //found subclass
{
if (is_array ($allkeys[$val])) //merge parent to this subclass array
{
(!is_array ($pval)) && ($pval = array ());
$pval = array_merge ($pval, $allkeys[$val]);
}
$allkeys[$val] = null;//set the old array to null
$allkeys[$val] = &$pval;//new refrence
}
else //not found subclass
{
$allkeys[$val] = &$pval;
}
//printf ("class $val : public $key\r\n");
$all_cnt++;
}
}function walkdir(&$dir)
{
if (!($h = opendir ($dir))) return;
while (false !== ($f = readdir ($h)))
{
if ($f=="." || $f=="..") continue;
$f = "$dir/$f";
is_dir ($f) && walkdir ($f);
!is_dir ($f) && preg_match ('/\.(h|hh|hpp|cpp|cxx)$/', $f) && walkfile ($f);
}
closedir ($h);
}//function main ($argc, $argv)
$argc != 2 && die ("need 2 args\n");
walkdir ($argv[1]);
outtree ($classes, "");
printf ("allcnt=$all_cnt.\r\n");
?>
奇怪,明明还提示可输入有XXX个字符,但又提示回复内容过长。
运行 ./class_tree.php /root/live的输出结果:BufferedPacket
ADUBufferedPacket
AMRBufferedPacket
H264BufferedPacket
JPEGBufferedPacket
LATMBufferedPacket
MPEG4GenericBufferedPacket
QCELPBufferedPacket
QTGenericBufferedPacket
BufferedPacketFactory
ADUBufferedPacketFactory
AMRBufferedPacketFactory
H264BufferedPacketFactory
JPEGBufferedPacketFactory
LATMBufferedPacketFactory
MPEG4GenericBufferedPacketFactory
QCELPBufferedPacketFactory
QTGenericBufferedPacketFactory
DelayQueueEntry
AlarmHandler
DelayQueue
HashTable
BasicHashTable
Medium
AVIFileSink
DarwinInjector
MPEG1or2Demux
MPEG1or2FileServerDemux
MPEG2TransportStreamIndexFile
MediaSession
MediaSink
BasicUDPSink
DummySink
FileSink
AMRAudioFileSink
H264VideoFileSink
RTPSink
MultiFramedRTPSink
AudioRTPSink
AC3AudioRTPSink
AMRAudioRTPSink
GSMAudioRTPSink
MP3ADURTPSink
MPEG1or2AudioRTPSink
MPEG4LATMAudioRTPSink
MPEG4GenericRTPSink
SimpleRTPSink
VideoRTPSink
DVVideoRTPSink
H263plusVideoRTPSink
H264VideoRTPSink
JPEGVideoRTPSink
MPEG1or2VideoRTPSink
MPEG4ESVideoRTPSink
TCPStreamSink
MediaSource
FramedSource
AMRAudioSource
AMRAudioFileSource
AMRDeinterleaver
AudioInputDevice
WAVAudioFileSource
WindowsAudioInputDevice_common
BasicUDPSource
ByteStreamMemoryBufferSource
ByteStreamMultiFileSource
DeviceSource
FramedFileSource
ADTSAudioFileSource
ByteStreamFileSource
MP3FileSource
MP3HTTPSource
FramedFilter
AC3AudioStreamFramer
ADUFromMP3Source
DVVideoStreamFramer
EndianSwap16
H263plusVideoStreamFramer
H264FUAFragmenter
HostFromNetworkOrder16
MP3ADUTranscoder
MP3ADUinterleaverBase
MP3ADUdeinterleaver
MP3ADUinterleaver
MP3FromADUSource
MP3Transcoder
MPEG1or2AudioStreamFramer
MPEG2IFrameIndexFromTransportStream
MPEG2TransportStreamFramer
MPEG2TransportStreamTrickModeFilter
MPEGVideoStreamFramer
H264VideoStreamFramer
H264VideoStreamDiscreteFramer
MPEG1or2VideoStreamFramer
MPEG1or2VideoStreamDiscreteFramer
MPEG4VideoStreamFramer
MPEG4VideoStreamDiscreteFramer
NetworkFromHostOrder16
PCMFromuLawAudioSource
QCELPDeinterleaver
uLawFromPCMAudioSource
JPEGVideoSource
MPEG1or2DemuxedElementaryStream
MPEG2TransportStreamMultiplexor
MPEG2TransportStreamFromESSource
MPEG2TransportStreamFromPESSource
RTPSource
MultiFramedRTPSource
AC3AudioRTPSource
DVVideoRTPSource
H261VideoRTPSource
H263plusVideoRTPSource
H264VideoRTPSource
JPEGVideoRTPSource
MP3ADURTPSource
MPEG1or2AudioRTPSource
MPEG1or2VideoRTPSource
MPEG4ESVideoRTPSource
MPEG4GenericRTPSource
MPEG4LATMAudioRTPSource
QuickTimeGenericRTPSource
RawAMRRTPSource
RawQCELPRTPSource
SimpleRTPSource
QuickTimeFileSink
RTCPInstance
RTSPClient
RTSPClientForDarwinInjector
RTSPServer
RTSPServerSupportingHTTPStreaming
DynamicRTSPServer
SIPClient
ServerMediaSession
ServerMediaSubsession
OnDemandServerMediaSubsession
FileServerMediaSubsession
AC3AudioFileServerMediaSubsession
ADTSAudioFileServerMediaSubsession
AMRAudioFileServerMediaSubsession
DVVideoFileServerMediaSubsession
H263plusVideoFileServerMediaSubsession
H264VideoFileServerMediaSubsession
MP3AudioFileServerMediaSubsession
MPEG1or2VideoFileServerMediaSubsession
MPEG2TransportFileServerMediaSubsession
MPEG4VideoFileServerMediaSubsession
allcnt=163.
只是最近常接触N万行的C++新工程,有感于C++软件都是过度设计的,不打个树出来我就要手工统计。所以才写这么个东西。
现在的情况是
1.有派生的均有输出
2.支持中间插任意空
3.不支持多派生
4.不支持没派生希望能支持没派生
btw,你是说
2. class XXX{ //不从任何父类继承
这样的类没匹配到?
$fctx= <<<HTML
#ifndef _FRAMED_FILTER_HH
#include "FramedFilter.hh"
#endifclass ADUFromMP3Source:public aa,bb,cc{
public:
static ADUFromMP3Source* createNew(UsageEnvironment& env,
FramedSource* inputSource,
Boolean includeADUdescriptors = True);class ADUFromMP3Source:protected xxx{
public:
static ADUFromMP3Source* createNew(UsageEnvironment& env,
FramedSource* inputSource,
Boolean includeADUdescriptors = True);class ADUFromMP3Source{
public:
static ADUFromMP3Source* createNew(UsageEnvironment& env,
FramedSource* inputSource,
Boolean includeADUdescriptors = True);HTML;
preg_match_all('/class\s*([^\s:\{]*)\s*(?:(?::\s*public|:\s*protected)([^:\{]*))?\s*\{/isU',$fctx,$m);
print_r($m);
现在 用了你改的:'/class\s*([^\s:\{]*)\s*(?:(?::\s*public|:\s*protected)?\s*([^\s:\{]*))?\s*\{/sU'
#!/usr/bin/php
<?php
$all_cnt = 0;
$classes = array ();// array('aa'=>null, 'bb'=>array('cc'=>'')) : null: has deleted. '': valid
$allkeys = array ();//class=>addr eg. 'cc'=>&$classes['bb']['cc']function outtree (&$parent, $tab)
{
ksort ($parent);
foreach ($parent as $left => &$right)
{
if (is_null ($right)) continue;
printf ("$tab$left\r\n");
is_array ($right) && outtree ($right, $tab."\t");
}
}function walkfile(&$file)
{
global $classes;
global $all_cnt;
global $allkeys;
$pval = null; $fctx = file_get_contents ($file);
if (!preg_match_all('/class\s*([^\s:\{]*)\s*(?:(?::\s*public|:\s*protected)?\s*([^\s:\{]*))?\s*\{/sU',$fctx,$m))
return;
//print_r ($m);// exit (0);
for ($i=0; $i<count($m[0]); $i++)
{
$key = trim ($m[2][$i]); //parent class
$val = trim ($m[1][$i]); //subclass
($val=='') && ($val=$key) && ($key='ROOT'); //exchang key<==>value //process parent class
if (isset ($allkeys[$key])) //found parent
{
(!is_array ($allkeys[$key])) && ($allkeys[$key] = array ());
(!isset($allkeys[$key][$val])) && ($allkeys[$key][$val] = '');
$pval = &$allkeys[$key][$val];
}
else //not found parent
{
$classes[$key] = array ($val=>'');
$allkeys[$key] = &$classes[$key];
$pval = &$classes[$key][$val];
}
//process sub class
if (isset ($allkeys[$val])) //found subclass
{
if (is_array ($allkeys[$val])) //merge parent to this subclass array
{
(!is_array ($pval)) && ($pval = array ());
$pval = array_merge ($pval, $allkeys[$val]);
}
$allkeys[$val] = null;//set the old array to null
$allkeys[$val] = &$pval;//new refrence
}
else //not found subclass
{
$allkeys[$val] = &$pval;
}
//printf ("class $val : public $key\r\n");
$all_cnt++;
}
}function walkdir(&$dir)
{
if (!($h = opendir ($dir))) return;
while (false !== ($f = readdir ($h)))
{
if ($f=="." || $f=="..") continue;
$f = "$dir/$f";
is_dir ($f) && walkdir ($f);
!is_dir ($f) && preg_match ('/\.(h|hh|hpp|cpp|cxx)$/', $f) && walkfile ($f);
}
closedir ($h);
}//function main ($argc, $argv)
$argc != 2 && die ("need 2 args\n");
walkdir ($argv[1]);
outtree ($classes, "");
printf ("allcnt=$all_cnt.\r\n");
?>运行结果是264个类,检查过了是对的。哈,OK了,谢谢!