示例#1
0
 /**
  * Parses a YAML string to a PHP value.
  *
  * @param  string A YAML string
  *
  * @return mixed  A PHP value
  */
 public function parse($value)
 {
     $this->value = $this->cleanup($value);
     $this->currentLineNb = -1;
     $this->currentLine = '';
     $this->lines = explode("\n", $this->value);
     $data = array();
     while ($this->moveToNextLine()) {
         if ($this->isCurrentLineEmpty()) {
             continue;
         }
         // tab?
         if (preg_match('#^\\t+#', $this->currentLine)) {
             throw new InvalidArgumentException(sprintf('A YAML file cannot contain tabs as indentation at line %d (%s).', $this->getRealCurrentLineNb(), $this->currentLine));
         }
         $isRef = $isInPlace = false;
         if (preg_match('#^\\-(\\s+(?P<value>.+?))?\\s*$#', $this->currentLine, $values)) {
             if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#', $values['value'], $matches)) {
                 $isRef = $matches['ref'];
                 $values['value'] = $matches['value'];
             }
             // array
             if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
                 $c = $this->getRealCurrentLineNb() + 1;
                 $parser = new Doctrine_Parser_sfYaml_Parser($c);
                 $parser->refs =& $this->refs;
                 $data[] = $parser->parse($this->getNextEmbedBlock());
             } else {
                 if (preg_match('/^([^ ]+)\\: +({.*?)$/', $values['value'], $matches)) {
                     $data[] = array($matches[1] => Doctrine_Parser_sfYaml_Inline::load($matches[2]));
                 } else {
                     $data[] = $this->parseValue($values['value']);
                 }
             }
         } else {
             if (preg_match('#^(?P<key>[^ ].*?) *\\:(\\s+(?P<value>.+?))?\\s*$#', $this->currentLine, $values)) {
                 $key = Doctrine_Parser_sfYaml_Inline::parseScalar($values['key']);
                 if ('<<' === $key) {
                     if (isset($values['value']) && '*' === substr($values['value'], 0, 1)) {
                         $isInPlace = substr($values['value'], 1);
                         if (!array_key_exists($isInPlace, $this->refs)) {
                             throw new InvalidArgumentException(sprintf('Reference "%s" does not exist on line %s.', $isInPlace, $this->currentLine));
                         }
                     } else {
                         throw new InvalidArgumentException(sprintf('In place substitution must point to a reference on line %s.', $this->currentLine));
                     }
                 } else {
                     if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#', $values['value'], $matches)) {
                         $isRef = $matches['ref'];
                         $values['value'] = $matches['value'];
                     }
                 }
                 // hash
                 if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
                     // if next line is less indented or equal, then it means that the current value is null
                     if ($this->isNextLineIndented()) {
                         $data[$key] = null;
                     } else {
                         $c = $this->getRealCurrentLineNb() + 1;
                         $parser = new Doctrine_Parser_sfYaml_Parser($c);
                         $parser->refs =& $this->refs;
                         $data[$key] = $parser->parse($this->getNextEmbedBlock());
                     }
                 } else {
                     if ($isInPlace) {
                         $data = $this->refs[$isInPlace];
                     } else {
                         $data[$key] = $this->parseValue($values['value']);
                     }
                 }
             } else {
                 // one liner?
                 if (1 == count(explode("\n", rtrim($this->value, "\n")))) {
                     return Doctrine_Parser_sfYaml_Inline::load($this->lines[0]);
                 }
                 throw new InvalidArgumentException(sprintf('Unable to parse line %d (%s).', $this->getRealCurrentLineNb(), $this->currentLine));
             }
         }
         if ($isRef) {
             $this->refs[$isRef] = end($data);
         }
     }
     return empty($data) ? null : $data;
 }