From 136e5b6a9469e3fa9bb6ee64f5b3a20d2eeb4fc4 Mon Sep 17 00:00:00 2001 From: Alexander Kiryukhin Date: Tue, 28 Aug 2012 18:03:50 +0400 Subject: [PATCH] Alpha of new version --- nyaml.php | 219 +++++++++++++++++++++++++++++++---------------------- test.nyaml | 3 + test.php | 8 ++ 3 files changed, 138 insertions(+), 92 deletions(-) create mode 100644 test.nyaml create mode 100644 test.php diff --git a/nyaml.php b/nyaml.php index 2caf399..6ba2716 100644 --- a/nyaml.php +++ b/nyaml.php @@ -1,106 +1,141 @@ '/[\s|\t]/', + self::T_NEWLINE => '/[\n]/', + self::T_CHAR => '/[a-zA-Zа-яА-Я0-9]/', + self::T_QUOTE => '/[\']/', + self::T_DQUOTE => '/[\"]/' + ); + + /** + * Таблица переходов состояния + * @var array + */ + private $actions = array( + array(self::PARSE_KEY, self::T_CHAR, self::PARSE_KEY), + array(self::PARSE_KEY, self::T_SPACE, self::PARSE_VALUE), + array(self::PARSE_KEY, self::T_NEWLINE, self::PARSE_VALUE), + array(self::PARSE_VALUE, self::T_NEWLINE, self::PARSE_KEY), + array(self::PARSE_VALUE, self::T_SPACE, self::PARSE_VALUE), + array(self::PARSE_VALUE, self::T_CHAR, self::PARSE_VALUE), + array(self::PARSE_KEY, self::T_QUOTE, self::PARSE_KEY_IN_QUOTE), + array(self::PARSE_KEY, self::T_DQUOTE, self::PARSE_KEY_IN_DQUOTE), + array(self::PARSE_VALUE, self::T_QUOTE, self::PARSE_VALUE_IN_QUOTE), + array(self::PARSE_VALUE, self::T_DQUOTE, self::PARSE_VALUE_IN_DQUOTE), + array(self::PARSE_KEY_IN_QUOTE, self::T_QUOTE, self::PARSE_KEY), + array(self::PARSE_KEY_IN_DQUOTE, self::T_DQUOTE, self::PARSE_KEY), + array(self::PARSE_VALUE_IN_QUOTE, self::T_QUOTE, self::PARSE_VALUE), + array(self::PARSE_VALUE_IN_DQUOTE, self::T_DQUOTE, self::PARSE_VALUE), + array(self::PARSE_KEY_IN_QUOTE, self::T_CHAR, self::PARSE_KEY_IN_QUOTE), + array(self::PARSE_KEY_IN_DQUOTE, self::T_CHAR, self::PARSE_KEY_IN_DQUOTE), + array(self::PARSE_VALUE_IN_QUOTE, self::T_CHAR, self::PARSE_VALUE_IN_QUOTE), + array(self::PARSE_VALUE_IN_DQUOTE, self::T_CHAR, self::PARSE_VALUE_IN_DQUOTE), + array(self::PARSE_KEY_IN_QUOTE, self::T_SPACE, self::PARSE_KEY_IN_QUOTE), + array(self::PARSE_KEY_IN_DQUOTE, self::T_SPACE, self::PARSE_KEY_IN_DQUOTE), + array(self::PARSE_VALUE_IN_QUOTE, self::T_SPACE, self::PARSE_VALUE_IN_QUOTE), + array(self::PARSE_VALUE_IN_DQUOTE, self::T_SPACE, self::PARSE_VALUE_IN_DQUOTE), + array(self::PARSE_KEY_IN_QUOTE, self::T_NEWLINE, self::PARSE_KEY_IN_QUOTE), + array(self::PARSE_KEY_IN_DQUOTE, self::T_NEWLINE, self::PARSE_KEY_IN_DQUOTE), + array(self::PARSE_VALUE_IN_QUOTE, self::T_NEWLINE, self::PARSE_VALUE_IN_QUOTE), + array(self::PARSE_VALUE_IN_DQUOTE, self::T_NEWLINE, self::PARSE_VALUE_IN_DQUOTE), + ); + + public function file($fileName) + { //Parse file - return $this->string(file_get_contents($fileName)); + return $this->string(file_get_contents($fileName)); } - public function string($nyaml) { - //Parse string - - //Preprocessing - $nyaml = preg_replace("/(\n|^)\s*\#.*?\n/", "\n", $nyaml); //Cleaning from one-line comments - $nyaml = str_replace("\r", "", $nyaml); //Fix new lines - $nyaml = str_replace("\n\n", "\n", $nyaml); //Cleaning clear lines - $nyaml = trim($nyaml,"\n"); - - $this->lines = explode("\n", $nyaml); - //Parsing - return $this->parse(0); - } - - private function parse($level) { - $return=array(); - $linelevel = $level; - - while (count($this->lines)>0) { - - $line = array_shift($this->lines); - $linelevel = $this->countLevel($line); - - if ($linelevel<$level) { //If next line from root node stop parsing - array_unshift($this->lines, $line); - return $return; - } - if (substr($line,-1,1)==":") { //If new node - $key = substr($line, 0, strlen($line)-1); - $value = $this->parse($linelevel+1); - $return[trim($key)] = $value; - } elseif (strpos($line,":")!==false) { //If key-value pair - list($key, $value) = explode(":", $line, 2); - $return[trim($key)] = $this->parseValue($value); - } else { //If just value - $return[] = trim($line); - } - } - return $return; - } - - private function parseValue($value) { - $value = trim($value); - switch (substr($value,0,1)) { - case "\"": - return substr($value,1,(strlen($value)-2)); - break; - case "'": - return substr($value,1,(strlen($value)-2)); - break; - case "[": - $result = $this->explode(",", substr($value,1,(strlen($value)-2))); - $result = array_map(array($this, "parseValue"), $result); - return $result; - break; - default: - return $value; - } - } - - private function explode($letter, $string) { - //smart exploding string - $quotes = array("\"","'","[","]"); - $quote = ''; + public function string($nyaml) + { $result = array(); - $token = ""; - for ($i = 0; $istate; + $newState = $this->getState($char); + $this->state = $newState; + if (($newState == self::PARSE_KEY) && ($oldState == self::PARSE_VALUE)) { + $result[$key] = $value; + $key = ''; + $value = ''; + + } + if (($newState == self::PARSE_KEY) && ($oldState == self::PARSE_KEY) && ($oldState != self::PARSE_VALUE_IN_QUOTE) && ($oldState != self::PARSE_VALUE_IN_DQUOTE)) { + $key.=$char; + } + if ( ($newState == self::PARSE_VALUE) && ($oldState != self::PARSE_VALUE_IN_QUOTE) && ($oldState != self::PARSE_VALUE_IN_DQUOTE) ) { + $value.=$char; + } + + if (($newState == self::PARSE_KEY_IN_QUOTE) && ($oldState != self::PARSE_KEY)) { + $key.=$char; + } + if (($newState == self::PARSE_KEY_IN_DQUOTE) && ($oldState != self::PARSE_KEY)) { + $key.=$char; + } + + if (($newState == self::PARSE_VALUE_IN_QUOTE) && ($oldState != self::PARSE_VALUE)) { + $value.=$char; + } + if (($newState == self::PARSE_VALUE_IN_DQUOTE) && ($oldState != self::PARSE_VALUE)) { + $value.=$char; } } - if ($token!='') { - $result[] = $token; - } + + $result[$key] = $value; return $result; } - private function countLevel($string) { - //Counting level by indenting - return (strlen($string) - strlen(ltrim($string,"\t "))); + public function getState($char) + { + $currentTerm = null; + foreach ($this->terms as $key => $term) { + if (preg_match($term, $char)) { + $currentTerm = $key; + } + } + if ($currentTerm === null) { + throw new Exception('Parse error'); + } + foreach ($this->actions as $action) { + if (( $action[0] == $this->state ) && ( $action[1] == $currentTerm )) { + + return $action[2]; + } + } } + } diff --git a/test.nyaml b/test.nyaml new file mode 100644 index 0000000..ac55a4a --- /dev/null +++ b/test.nyaml @@ -0,0 +1,3 @@ +node1 value 1 +'node 2' value 2 +'node 3' "value 3" \ No newline at end of file diff --git a/test.php b/test.php new file mode 100644 index 0000000..b57b514 --- /dev/null +++ b/test.php @@ -0,0 +1,8 @@ +file('test.nyaml')); +