public static function parse(Scanner $scanner) { $file = $scanner->getFile(); // Must be / $char = $file->nextChar(); // Unexpected char if ($char != '/') { // Unexpected EOF if ($char === false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Unexpected char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), $char); } } // Must be > $char = $file->nextChar(); // We have a problem here if ($char != '>') { // Illegal space if ($scanner->isSpace($char)) { throw ExceptionFactory::createIllegalSpace(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Unexpected EOF } elseif ($char === false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Unexpected char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), $char); } } // Next lookAhead $scanner->setLookAhead(Token::T_OPEN_TAG | Token::T_CLOSE_TAG | Token::T_TEXT); // T_CLOSE token found return new Token(Token::T_CLOSE); }
public static function addNamespace($name, $ns) { if (array_key_exists($name, self::$namespaces)) { throw ExceptionFactory::createDuplicatedPrefix(__FILE__, __LINE__, $name, $ns); } self::$namespaces[$name] = $ns; }
public function build() { // Instantiate the component $component = $this->buildOpenTag(); foreach ($this->attributes as $key => $attr) { // Id must be a unique T_ATTRIBUTE if ($attr->getValue() == 'id') { // If component's id is not set yet if (is_null($component->getId())) { $component->setId($this->values[$key]->getValue()); // Add the id into the Symbols Table if (!Symbols::addId($component->getId(), $component)) { throw ExceptionFactory::createDuplicatedId(__FILE__, __LINE__, $this->file->getFileName(), $this->file->getCurrentLine(), $component->getId()); } } else { // Duplicated T_ATTRIBUTE id throw ExceptionFactory::createDuplicatedTagId(__FILE__, __LINE__, $this->file->getFileName(), $this->file->getCurrentLine()); } // It's not an id continue; } // Set other properties $component->{$attr->getValue()} = $this->values[$key]->getValue(); } // Clean up the old parameters $this->cleanUp(); return $component; }
protected function openFile() { if (!is_readable($this->name)) { throw ExceptionFactory::createOpenFile(__FILE__, __LINE__, $this->getFileName(), 'reading'); } $this->filePointer = fopen($this->name, 'r'); }
public function testCreateFileDoesNotExistException() { $ioException = new IOException('source.php', 8, 'File: source.phpml doesn\'t exist'); $exception = ExceptionFactory::createFileDoesNotExist('source.php', 8, 'source.phpml'); $this->assertSame($ioException->getFile(), $exception->getFile()); $this->assertSame($ioException->getLine(), $exception->getLine()); $this->assertSame($ioException->getMessage(), $exception->getMessage()); $this->assertInstanceOf('PHPML\\Exception\\IOException', $exception); }
public function __get($prop) { // Does this property exist? if (array_key_exists($prop, $this->properties)) { return $this->properties[$prop]; } else { throw ExceptionFactory::createGetUnexpectedProperty(__FILE__, __LINE__, $this, $prop); } }
public static function parse(Scanner $scanner) { $file = $scanner->getFile(); $char = $file->nextChar(); $state = 0; $value = ''; $pos = 0; while (true) { switch ($state) { case 0: // Ex: "value" if ($char == '"') { $state = 1; $pos = $file->find('"'); // Ex: 'value' } elseif ($char == "'") { $state = 2; $pos = $file->find("'"); // Exception } else { // Unexpected EOF if ($char == false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Unexpected Char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), $char); } } break; case 1: // Char " not found if ($pos === false) { throw ExceptionFactory::createCannotFindChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), '"'); } // Get the value $value .= $scanner->forward($pos); // Bypass " $scanner->forward(1); break 2; case 2: // Char ' not found if ($pos === false) { throw ExceptionFactory::createCannotFindChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), "'"); } // Get the value $value .= $scanner->forward($pos); // Bypass ' $scanner->forward(1); break 2; } } // Next lookAhead $scanner->setLookAhead(Token::T_ATTRIBUTE | Token::T_END | Token::T_CLOSE); // T_VALUE token found return new SimpleToken(Token::T_VALUE, $value); }
public function nextToken() { if ($this->file->isEOF()) { return false; } switch ($this->lookAhead) { case Token::T_TEXT | Token::T_OPEN_TAG: $registeredNamespaces = Symbols::getRegisteredNamespaces(); array_walk($registeredNamespaces, function (&$ns) { $ns = "<{$ns}:"; }); $pos = $this->file->find($registeredNamespaces); // Nothing found if ($pos === false) { return new SimpleToken(Token::T_TEXT, $this->forward()); // Has T_TEXT to get } elseif ($pos > 0) { $this->lookAhead = Token::T_OPEN_TAG | Token::T_CLOSE_TAG; return new SimpleToken(Token::T_TEXT, $this->forward($pos)); // T_OPEN_TAG } else { return OpenTagParser::parse($this); } break; case Token::T_ATTRIBUTE | Token::T_END | Token::T_CLOSE: // Get the next char to verify the next token $char = $this->nextChar(); $this->file->goBack(); // T_ATTRIBUTE if ($this->isLetter($char)) { return AttributeParser::parse($this); // T_END } elseif ($char == '>') { return EndParser::parse($this); // T_CLOSE } elseif ($char == '/') { return CloseParser::parse($this); // Exception } else { // Unexpected EOF if ($char === false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $this->file->getFileName(), $this->file->getCurrentLine()); // Unexpected Char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $this->file->getFileName(), $this->file->getCurrentLine(), $char); } } break; case Token::T_VALUE: // Get the next char to verify the next token $char = $this->nextChar(); $this->file->goBack(); // T_VALUE if ($char == '"' || $char == "'") { return ValueParser::parse($this); // Exception } else { // Unexpected EOF if ($char == false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $this->file->getFileName(), $this->file->getCurrentLine()); // Unexpected Char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $this->file->getFileName(), $this->file->getCurrentLine(), $char); } } break; case Token::T_OPEN_TAG | Token::T_CLOSE_TAG | Token::T_TEXT: $registeredOpenNamespaces = Symbols::getRegisteredNamespaces(); $registeredCloseNamespaces = $registeredOpenNamespaces; array_walk($registeredOpenNamespaces, function (&$ns) { $ns = "<{$ns}:"; }); array_walk($registeredCloseNamespaces, function (&$ns) { $ns = "</{$ns}:"; }); // Try to find T_OPEN_TAG $posOpenTag = $this->file->find($registeredOpenNamespaces); // Try to find T_CLOSE_TAG $posCloseTag = $this->file->find($registeredCloseNamespaces); // Nothing found if ($posOpenTag === false && $posCloseTag === false) { // There are some characters to parse if ($this->nextChar() !== false) { $this->file->goBack(); return new SimpleToken(Token::T_TEXT, $this->forward()); } // Nothing to parse, we're done // EOF return; // Both found } elseif ($posOpenTag !== false && $posCloseTag !== false) { // T_OPEN_TAG comes first if ($posOpenTag < $posCloseTag) { // We have T_TEXT if ($posOpenTag > 0) { $this->lookAhead = Token::T_OPEN_TAG | Token::T_CLOSE_TAG; return new SimpleToken(Token::T_TEXT, $this->forward($posOpenTag)); } // T_CLOSE_TAG comes first } else { // We have T_TEXT if ($posCloseTag > 0) { $this->lookAhead = Token::T_OPEN_TAG | Token::T_CLOSE_TAG; return new SimpleToken(Token::T_TEXT, $this->forward($posCloseTag)); } } // T_OPEN_TAG found } elseif ($posOpenTag !== false) { // We have T_TEXT if ($posOpenTag > 0) { $this->lookAhead = Token::T_OPEN_TAG | Token::T_CLOSE_TAG; return new SimpleToken(Token::T_TEXT, $this->forward($posOpenTag)); } // We have T_OPEN_TAG return OpenTagParser::parse($this); // T_CLOSE_TAG found } else { // We have T_TEXT if ($posCloseTag > 0) { $this->lookAhead = Token::T_OPEN_TAG | Token::T_CLOSE_TAG; return new SimpleToken(Token::T_TEXT, $this->forward($posCloseTag)); } // We have T_CLOSE_TAG return CloseTagParser::parse($this); } break; case Token::T_OPEN_TAG | Token::T_CLOSE_TAG: $registeredOpenNamespaces = Symbols::getRegisteredNamespaces(); $registeredCloseNamespaces = $registeredOpenNamespaces; array_walk($registeredOpenNamespaces, function (&$ns) { $ns = "<{$ns}:"; }); array_walk($registeredCloseNamespaces, function (&$ns) use(&$registeredOpenNamespaces) { $ns = "</{$ns}:"; $registeredOpenNamespaces[] = $ns; }); $pos = $this->file->find($registeredOpenNamespaces); // Nothing found if ($pos === false) { return false; } $this->file->saveState(); $this->forward(1); $char = $this->file->nextChar(); $this->file->restoreState(); if ($this->isLetter($char)) { return OpenTagParser::parse($this); } else { return CloseTagParser::parse($this); } break; } }
public static function parse(Scanner $scanner) { $file = $scanner->getFile(); $char = $file->nextChar(); $state = 0; $value = ''; while (true) { switch ($state) { case 0: // T_ATTRIBUTE begins with [a-zA-Z] or _ if ($scanner->isLetter($char) || $char == '_') { $state = 1; $value .= $char; $char = $file->nextChar(); // Exception } else { // Unexpected EOF if ($char == false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Unexpected Char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), $char); } } break; case 1: // The second char can be [a-zA-Z0-9] or _ if ($scanner->isAlpha($char) || $char == '_') { $state = 1; $value .= $char; $char = $file->nextChar(); // Space indicates the end of the T_ATTRIBUTE // But we have to eat the next = char } elseif ($scanner->isSpace($char)) { $state = 2; $char = $scanner->nextChar(); // If the next char is =, we're done } elseif ($char == '=') { break 2; // Exception } else { // Unexpected EOF if ($char == false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Unexpected Char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), $char); } } break; case 2: // If the next char is =, we're done if ($char == '=') { break 2; // Exception } else { // Unexpected EOF if ($char == false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Unexpected Char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), $char); } } break; } } // Next lookAhead $scanner->setLookAhead(Token::T_VALUE); // T_ATTRIBUTE token found return new SimpleToken(Token::T_ATTRIBUTE, $value); }
protected function verifyStack() { // If the stack is not empty, we have a problem if (!$this->stack->isEmpty()) { // Get the first remaining token into the stack and throw an exception throw ExceptionFactory::createTagNotClosed(__FILE__, __LINE__, $this->scanner->getFile()->getFileName(), $this->stack->top()); } }
public static function parse(Scanner $scanner) { $file = $scanner->getFile(); $char = $file->nextChar(); $state = 0; $ns = ''; $name = ''; while (true) { switch ($state) { case 0: // Must start with < if ($char == '<') { $state = 1; $char = $file->nextChar(); // Exception } else { // Unexpected EOF if ($char == false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Unexpected Char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), $char); } } break; case 1: // The first char after < can be [a-zA-Z] or _ if ($scanner->isLetter($char) || $char == '_') { $state = 2; $ns .= $char; $char = $file->nextChar(); // Exception } else { // Unexpected EOF if ($char == false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Unexpected Char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), $char); } } break; case 2: // From the second char after < onwards can be [a-zA-Z0-9] or _ if ($scanner->isAlpha($char) || $char == '_') { $state = 2; $ns .= $char; $char = $file->nextChar(); // If the next char is :, we already have the namespace } elseif ($char == ':') { $state = 3; $char = $file->nextChar(); // Exception } else { // Unexpected EOF if ($char == false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Unexpected Char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), $char); } } break; case 3: // The first char after : can be [a-zA-Z] or _ if ($scanner->isLetter($char) || $char == '_') { $state = 4; $name .= $char; $char = $file->nextChar(); // Exception } else { // Unexpected EOF if ($char == false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Illegal space after : } elseif ($scanner->isSpace($char)) { throw ExceptionFactory::createIllegalSpace(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Unexpected Char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), $char); } } break; case 4: // From the second char after : onwards can be [a-zA-Z0-9] or _ if ($scanner->isAlpha($char) || $char == '_') { $state = 4; $name .= $char; $char = $file->nextChar(); // If the next char is \s, we got the name } elseif ($scanner->isSpace($char)) { break 2; // If the next char is >, we got the T_END } elseif ($char == '>') { $file->goBack(); break 2; // Exception } else { // Unexpected EOF if ($char == false) { throw ExceptionFactory::createUnexpectedEOF(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine()); // Unexpected Char } else { throw ExceptionFactory::createUnexpectedChar(__FILE__, __LINE__, $file->getFileName(), $file->getCurrentLine(), $char); } } break; } } // Next lookAhead $scanner->setLookAhead(Token::T_ATTRIBUTE | Token::T_END | Token::T_CLOSE); // T_REGISTER if ($ns == 'php' && $name == 'Register') { return new TagToken(Token::T_REGISTER, $ns, $name); } // T_OPEN_TAG token found return new TagToken(Token::T_OPEN_TAG, $ns, $name); }