Visa ett inlägg
Oläst 2007-11-08, 13:50 #20
blixtsystems blixtsystems är inte uppkopplad
Flitig postare
 
Reg.datum: Mar 2005
Inlägg: 442
blixtsystems blixtsystems är inte uppkopplad
Flitig postare
 
Reg.datum: Mar 2005
Inlägg: 442
Det är inte en huvudloop direkt utan tre klasser som interagerar, annars hade jag redan postat den, men det blir en hel del kod som kan vara relevant.

HHParser.php är huvudklassen som kollar vad det är för format på text filen (vilket pokernätverk den kommer ifrån).
Den relevanta koden där är:
Kod:
	function getFormat(){
 // parser rules to get HH format
 $this->Parser->FSM('/<general>/',$this, 'FormatFound', 'iPoker', 'STOP','FMT');
 $this->Parser->FSM('/PokerStars Game/',$this,'FormatFound', 'Poker Stars', 'STOP','FMT');	
 $this->Parser->FSM('/\*\* Game ID/',$this,'FormatFound', 'MicroGaming', 'STOP','FMT'); 
 $this->Parser->FSM('/Full Tilt Poker Game/',$this,'FormatFound', 'Full Tilt', 'STOP','FMT');	
 $this->Parser->ParseFile(FILE,"FMT", 0, 100);
	}
	function FormatFound($str){
 $this->location=$str;
 $this->addSessionToDB();
 switch($str){
 	case "Poker Stars":
  require("classes/sites/ps.php");
  $this->Data->setMode("PS");
  $this->Site=new PS($this);
  break;
 	case "MicroGaming":
  require("classes/sites/mg.php");
  $this->Data->setMode("MG");
  $this->Site=new MG($this);
  break;	
 	case "Full Tilt":
  require("classes/sites/ft.php");
  $this->Data->setMode("FT");
  $this->Site=new FT($this);
  break;	
 }
	}
parserclass.inc.php innehåller en state machine:
Kod:
<?
/*
Finite State Machine Parser class.
FSM-based text parser framework.
*/

//Parse() result codes
define("FSMSTOP_OK",0); //FSM reached end of text or file.
define("FSMSTOP_UNHANDLED",1);	//FSM stopped because some state is unhandled.
define("FSMSTOP_STOP",2);	//FSM stopped by a handler.

class FSMParser {
	var $FSMArr=array();
	var $STATE;
	/*
 FSM programming 
	*/
	function FSM($expect,$caller,$execute,$arg,$defaultstate,$state=NULL, $start=NULL, $end=NULL, $greed=FALSE, $recurse=NULL){
 $this->FSMArr[]=array("ex"=>$expect,"ca"=>$caller,"do"=>$execute,"ar"=>$arg,"ds"=>$defaultstate,"cs"=>$state, "st"=>$start, "en"=>$end, "gr"=>$greed, "re"=>$recurse);
	}
	/*
 Main loop method.
	*/
	function Parse($text,$state){
 $PTR=0;
 $LEN=strlen($text);
 $RET=FSMSTOP_OK;
 $this->STATE=$state;
 $EN=$LEN;
 $nextState;
 $lastPTR;
 $a=$this->FSMArr;
 $this->FSMArr=array();
 $tok_off=NULL;
 $tok_key=NULL;
 $tok_len=NULL;
 while($PTR<$LEN){
 	if(isset($a)){
  foreach($a as $tkey=>$line){  
  	if( (!$line["cs"]) or ($line["cs"]==$this->STATE) ) {
   if($line["st"] != NULL){
   	$PTR=$line["st"];
   }
   if($line["en"] != NULL){
   	$EN=$line["en"]-$PTR;
   }
   //echo "<br/>STATE: ".$line["cs"]." REGEXP: ".$line["ex"]." RANGE:".$PTR."-".$EN;
   //echo "<br/>".substr($text,$PTR,$EN)."<br/>";
   if(preg_match($line["ex"],substr($text,$PTR,$EN),$matches,PREG_OFFSET_CAPTURE)) {
   	if( (is_null($tok_off)) or ($matches[0][1]<$tok_off) or ( ($matches[0][1]==$tok_off) and (strlen($matches[0][0])>$tok_len) ) ) { 	
     $tok_off=$matches[0][1];
     $tok_len=strlen($matches[0][0]);
     $tok_key=$tkey;
     $STRING=$matches[0][0];
   	} 
   }
   if($line["gr"]==TRUE || $line["re"] == TRUE){
   	$nextState=$line["ds"];
   }
	
  	}
  }
  if(is_null($tok_key)){
  	if(!is_null($nextState)){
   $this->STATE=$nextState;
   $nextState=NULL;
   continue;
  	} else {
   $RET=FSMSTOP_UNHANDLED;
   break;
  	}
  }	
  $PTR+=$tok_off+$tok_len;
  $lastPRT=$PTR;
  $arg=$a[$tok_key]["ar"] != "string" ? $a[$tok_key]["ar"] : $STRING;
  $arr=array($a[$tok_key]["ca"], $a[$tok_key]["do"]);
  $result=call_user_func($arr, $arg);
  $nextState=$result;
  if($a[$tok_key]["re"] != TRUE){
  	$this->STATE=$a[$tok_key]["ds"];
  } else {
  	$this->STATE=$a[$tok_key]["cs"];
  	$nextState=NULL;
  }
  $tok_off=NULL;
  $tok_len=NULL;
  $tok_key=NULL;
 	}
 }
 return $RET;
	}
	/*
 Main loop method - file wrapper.
	*/
	function ParseFile($filename,$state, $offset=0, $end=NULL){
 ini_set('default_socket_timeout',  120);
 return $this->Parse(file_get_contents($filename, FALSE, NULL, $offset, $end),$state);
	}
}
?>
ft.php innehåller parse regler för Full Tilt filer och anropar först FSM funktionen i parserclass ett antal gånger för att bygga en array med states, och sedan kör den:
Kod:
$this->C->Parser->FSM('/(Seat[\r\n'.$this->playerNameChars.':.$,]+\))+/',$this, 'TablePlayers', 'string', 'HANDFORCED','TABLEPLAYERS', NULL, $streets[0]);
//
// 18 rader med olika states för att gå igenom all information
//
$this->C->Parser->FSM('/\r?\n/',$this, 'HandEnd', 'string', 'STOP','HANDEND', $endIndex); 
$this->C->Parser->ParseFile(FILE,"TABLEPLAYERS", $this->offset, $endIndex);
Det få parserclass att läsa in handen och köra reexp uttrycken för att extrahera informationen.

Då alla states är genomgångna så börjar ft.php om från början och bearbetar nästa hand på samma vis.

Tyvärr är det som du ser inte alltför enkelt att ändra så man läser mer eller mindre än en hand åt gången.
Jag kan förvisso läsa in hela filen i ParseFile funktionen i parserclass, men jag måste ändå plocka ut reveant del någonstans.
Resultatet då jag har testat att läsa in hela filen och använda substr för att plocka ur nödvändig del är att den kör lika långt men använder mer minne.
blixtsystems är inte uppkopplad   Svara med citatSvara med citat