highlighting logic needs improvement
Posted: Wed Jun 07, 2006 10:51 pm
Hey guys,
I'm new to these forums, and fairly new to PHP, so I thought maybe you all could give me a little advice to help me with this problem. I just created an actionscript syntax highlighter for this wiki i'm creating, but it's taking too long for PHP to process all the data sometimes. For example, it takes around 20 seconds to process about 1,000 lines of actionscript code.
I think the problem is that I'm searching through the entire list way too many times, but who knows. Here's what I have so far: (don't be intimidated, the first half of the code are just the KEYWORDS)
* the only variable that needs to be passed into the following function (parse_code) is $out, which is an example Actionscript string*
Inside the CSS file:
.kw1 {color:#ff6600;}
.w6c {color:#808080;}
.w6r {color:#ff0000;}
.w6n {color:#cc66cc;}
.w6s {color:#66cc66;}
PHP:
As you can see, I'm using preg_replace and str_replace way too many times... one time for each keyword, totalling about 600 times. When you run down 1,000 lines of code 600 times... that could take a while.
Can anyone point me in the right direction in terms of shortcuts or better logic? I used a lot of RegEx to save lines of code, so I can explain what the lines are doing if you need me to.
Thanks in advance,
Matt
I'm new to these forums, and fairly new to PHP, so I thought maybe you all could give me a little advice to help me with this problem. I just created an actionscript syntax highlighter for this wiki i'm creating, but it's taking too long for PHP to process all the data sometimes. For example, it takes around 20 seconds to process about 1,000 lines of actionscript code.
I think the problem is that I'm searching through the entire list way too many times, but who knows. Here's what I have so far: (don't be intimidated, the first half of the code are just the KEYWORDS)
* the only variable that needs to be passed into the following function (parse_code) is $out, which is an example Actionscript string*
Inside the CSS file:
.kw1 {color:#ff6600;}
.w6c {color:#808080;}
.w6r {color:#ff0000;}
.w6n {color:#cc66cc;}
.w6s {color:#66cc66;}
PHP:
Code: Select all
<?php
function parse_code($out) {
$as=array(
'KEYWORDS'=>array(
1=>array(
'#include','for','foreach','if','elseif','else','while','do','dowhile',
'endwhile','endif','switch','case','endswitch','return','break','continue','in'
),
2=>array('null','false','true','var','default','function','class','new','_global'),
3=>array(
'#endinitclip','#initclip','__proto__','_accProps','_alpha','_currentframe',
'_droptarget','_focusrect','_framesloaded','_height','_highquality','_lockroot',
'_name','_parent','_quality','_root','_rotation','_soundbuftime','_target','_totalframes',
'_url','_visible','_width','_x','_xmouse','_xscale','_y','_ymouse','_yscale','abs',
'Accessibility','acos','activityLevel','add','addListener','addPage','addProperty',
'addRequestHeader','align','allowDomain','allowInsecureDomain','and','appendChild',
'apply','Arguments','Array','asfunction','asin','atan','atan2','attachAudio','attachMovie',
'attachSound','attachVideo','attributes','autosize','avHardwareDisable','background',
'backgroundColor','BACKSPACE','bandwidth','beginFill','beginGradientFill','blockIndent',
'bold','Boolean','border','borderColor','bottomScroll','bufferLength','bufferTime',
'builtInItems','bullet','Button','bytesLoaded','bytesTotal','call','callee','caller',
'Camera','capabilities','CAPSLOCK','caption','catch','ceil','charAt','charCodeAt',
'childNodes','chr','clear','clearInterval','cloneNode','close','Color','concat',
'connect','condenseWhite','constructor','contentType','ContextMenu','ContextMenuItem',
'CONTROL','copy','cos','createElement','createEmptyMovieClip','createTextField',
'createTextNode','currentFps','curveTo','CustomActions','customItems','data','Date',
'deblocking','delete','DELETEKEY','docTypeDecl','domain','DOWN',
'duplicateMovieClip','duration','dynamic','E','embedFonts','enabled',
'END','endFill','ENTER','eq','Error','ESCAPE','escape','eval',
'exactSettings','exp','extends','finally','findText','firstChild','floor',
'flush','focusEnabled','font','fps','fromCharCode','fscommand',
'gain','ge','get','getAscii','getBeginIndex','getBounds','getBytesLoaded','getBytesTotal',
'getCaretIndex','getCode','getCount','getDate','getDay','getDepth','getEndIndex','getFocus',
'getFontList','getFullYear','getHours','getInstanceAtDepth','getLocal','getMilliseconds',
'getMinutes','getMonth','getNewTextFormat','getNextHighestDepth','getPan','getProgress',
'getProperty','getRGB','getSeconds','getSelected','getSelectedText','getSize','getStyle',
'getStyleNames','getSWFVersion','getText','getTextExtent','getTextFormat','getTextSnapshot',
'getTime','getTimer','getTimezoneOffset','getTransform','getURL','getUTCDate','getUTCDay',
'getUTCFullYear','getUTCHours','getUTCMilliseconds','getUTCMinutes','getUTCMonth','getUTCSeconds',
'getVersion','getVolume','getYear','globalToLocal','goto','gotoAndPlay','gotoAndStop',
'hasAccessibility','hasAudio','hasAudioEncoder','hasChildNodes','hasEmbeddedVideo','hasMP3',
'hasPrinting','hasScreenBroadcast','hasScreenPlayback','hasStreamingAudio','hasStreamingVideo',
'hasVideoEncoder','height','hide','hideBuiltInItems','hitArea','hitTest','hitTestTextNearPos',
'HOME','hscroll','html','htmlText','ID3','ifFrameLoaded','ignoreWhite','implements',
'import','indent','index','indexOf','Infinity','-Infinity','INSERT','insertBefore','install',
'instanceof','int','interface','isActive','isDebugger','isDown','isFinite','isNaN','isToggled',
'italic','join','Key','language','lastChild','lastIndexOf','le','leading','LEFT','leftMargin',
'length','level','lineStyle','lineTo','list','LN10','LN2','load','loadClip','loaded','loadMovie',
'loadMovieNum','loadSound','loadVariables','loadVariablesNum','LoadVars','LocalConnection',
'localFileReadDisable','localToGlobal','log','LOG10E','LOG2E','manufacturer','Math','max',
'MAX_VALUE','maxChars','maxhscroll','maxscroll','mbchr','mblength','mbord','mbsubstring','menu',
'message','Microphone','min','MIN_VALUE','MMExecute','motionLevel','motionTimeOut','Mouse',
'mouseWheelEnabled','moveTo','Movieclip','MovieClipLoader','multiline','muted','name','names','NaN',
'ne','NEGATIVE_INFINITY','NetConnection','NetStream','newline','nextFrame',
'nextScene','nextSibling','nodeName','nodeType','nodeValue','not','Number','Object',
'on','onActivity','onChanged','onClipEvent','onClose','onConnect','onData','onDragOut',
'onDragOver','onEnterFrame','onID3','onKeyDown','onKeyUp','onKillFocus','onLoad','onLoadComplete',
'onLoadError','onLoadInit','onLoadProgress','onLoadStart','onMouseDown','onMouseMove','onMouseUp',
'onMouseWheel','onPress','onRelease','onReleaseOutside','onResize','onRollOut','onRollOver',
'onScroller','onSelect','onSetFocus','onSoundComplete','onStatus','onUnload','onUpdate','onXML',
'or(logischesOR)','ord','os','parentNode','parseCSS','parseFloat','parseInt','parseXML','password',
'pause','PGDN','PGUP','PI','pixelAspectRatio','play','playerType','pop','position',
'POSITIVE_INFINITY','pow','prevFrame','previousSibling','prevScene','print','printAsBitmap',
'printAsBitmapNum','PrintJob','printNum','private','prototype','public','push','quality',
'random','rate','registerClass','removeListener','removeMovieClip','removeNode','removeTextField',
'replaceSel','replaceText','resolutionX','resolutionY','restrict','reverse','RIGHT',
'rightMargin','round','scaleMode','screenColor','screenDPI','screenResolutionX','screenResolutionY',
'scroll','seek','selectable','Selection','send','sendAndLoad','separatorBefore','serverString',
'set','setvariable','setBufferTime','setClipboard','setDate','setFocus','setFullYear','setGain',
'setHours','setInterval','setMask','setMilliseconds','setMinutes','setMode','setMonth',
'setMotionLevel','setNewTextFormat','setPan','setProperty','setQuality','setRate','setRGB',
'setSeconds','setSelectColor','setSelected','setSelection','setSilenceLevel','setStyle',
'setTextFormat','setTime','setTransform','setUseEchoSuppression','setUTCDate','setUTCFullYear',
'setUTCHours','setUTCMilliseconds','setUTCMinutes','setUTCMonth','setUTCSeconds','setVolume',
'setYear','SharedObject','SHIFT','shift','show','showMenu','showSettings',
'silenceLevel','silenceTimeout','sin','size','slice','smoothing','sort','sortOn','Sound','SPACE',
'splice','split','sqrt','SQRT1_2','SQRT2','Stage','start','startDrag','static','status','stop',
'stopAllSounds','stopDrag','String','StyleSheet','styleSheet','substr',
'substring','super','swapDepths','System','TAB','tabChildren','tabEnabled','tabIndex',
'tabStops','tan','target','targetPath','tellTarget','text','textColor','TextField','TextFormat',
'textHeight','TextSnapshot','textWidth','this','throw','time','toggleHighQuality','toLowerCase',
'toString','toUpperCase','trace','trackAsMenu','try','type','typeof','undefined',
'underline','unescape','uninstall','unloadClip','unloadMovie','unLoadMovieNum','unshift','unwatch',
'UP','updateAfterEvent','updateProperties','url','useCodePage','useEchoSuppression','useHandCursor',
'UTC','valueOf','variable','version','Video','visible','void','watch','width',
'with','wordwrap','XML','xmlDecl','XMLNode','XMLSocket'
)
),'SYMBOLS'=>array('(',')','[',']','{','}','!','@','%','&','|','<','>'), # missing '/' and '*'
);
#numbers
$out = ' '.trim($out).' ';
$out = preg_replace("@([^#])([0-9]+)@", '\1:w6n:\2:end2:',$out);
# symbols
for($i=0; $i<count($as['SYMBOLS']); $i++) {
$who = $as['SYMBOLS'][$i];
$out = str_replace($who,':w6s:'.$who.':end2:',$out);
}
# spacing
$out = str_replace(" "," ",$out);
# single-line comments
$out = preg_replace_callback("@[^:]{1}//[\S\s]*\r@U", "fixComment", $out);
# multi-line comments
$out = preg_replace_callback("@/\*[\S\s]*?\*/@U", "fixComment", $out);
# keywords
for($i=0; $i<count($as['KEYWORDS'][3]); $i++) {
$who = $as['KEYWORDS'][3][$i];
$out = preg_replace("@([\W])$who([\W])@",'\1:kw3~'.$who.'::end1:\2',$out);
}
for($i=0; $i<count($as['KEYWORDS'][2]); $i++) {
$who = $as['KEYWORDS'][2][$i];
$out = preg_replace("@([\W])$who([\W])@",'\1:kw2~'.$who.'::end1:\2',$out);
}
for($i=0; $i<count($as['KEYWORDS'][1]); $i++) {
$who = $as['KEYWORDS'][1][$i];
$out = preg_replace("@([\W])$who([\W])@",'\1:kw1:'.$who.':end2:\2',$out);
}
# quotes
$out = preg_replace("@\'([\S\s]*)?\'@U", ':w6r:\0:end2:', $out);
$out = preg_replace("@\"([\S\s]*)?\"@U", ':w6r:\0:end2:', $out);
# make substitutions
$out = str_replace(':kw1:',"<span class='kw1'>",$out);
$out = preg_replace("@:kw2~([\w]*)?:@","<a href='wiki.php?id=\$1'>\$1",$out);
$out = preg_replace("@:kw3~([\w]*)?:@","<a href='wiki.php?id=\$1'>\$1",$out);
$out = str_replace(':w6c:',"<span class='w6c'>",$out);
$out = str_replace(':w6r:',"<span class='w6r'>",$out);
$out = str_replace(':w6n:',"<span class='w6n'>",$out);
$out = str_replace(':w6s:',"<span class='w6s'>",$out);
$out = str_replace(':end2:',"</span>",$out);
$out = str_replace(':end1:',"</a>",$out);
# newlines and tabs
$out = str_replace("\t"," ",$out);
$out = str_replace("\r","<br />",$out);
return $out;
}
function fixComment($m) {
$beg = '';
if(substr($m[0],0,2) != '/*') {
$beg = substr($m[0],0,1);
$m[0] = substr($m[0],1);
}
# remove tags from #numbers and #symbols
$m[0] = str_replace(":w6n:","",$m[0]);
$m[0] = str_replace(":w6s:","",$m[0]);
$m[0] = str_replace(":end2:","",$m[0]);
$swap = ':w6c:';
# replace each character with its entity equivalent
for ($i=0; $i < strlen($m[0]); $i++) {
$swap .= '&#'.ord($m[0][$i]).';';
}
# reverse the important tags
$swap = str_replace(" "," ",$swap);
$swap = str_replace("&","&",$swap);
$swap = str_replace("<","<",$swap);
$swap = str_replace(">",">",$swap);
$swap .= ':end2:'."\r";
return $beg.$swap;
}
?>Can anyone point me in the right direction in terms of shortcuts or better logic? I used a lot of RegEx to save lines of code, so I can explain what the lines are doing if you need me to.
Thanks in advance,
Matt