Exemple #1
0
 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);
 }
Exemple #2
0
 public static function addNamespace($name, $ns)
 {
     if (array_key_exists($name, self::$namespaces)) {
         throw ExceptionFactory::createDuplicatedPrefix(__FILE__, __LINE__, $name, $ns);
     }
     self::$namespaces[$name] = $ns;
 }
Exemple #3
0
 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;
 }
Exemple #4
0
 protected function openFile()
 {
     if (!is_readable($this->name)) {
         throw ExceptionFactory::createOpenFile(__FILE__, __LINE__, $this->getFileName(), 'reading');
     }
     $this->filePointer = fopen($this->name, 'r');
 }
Exemple #5
0
 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);
 }
Exemple #6
0
 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);
     }
 }
Exemple #7
0
 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);
 }
Exemple #8
0
 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;
     }
 }
Exemple #9
0
 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);
 }
Exemple #10
0
 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());
     }
 }
Exemple #11
0
 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);
 }