function concat(TokenStream $ts) : TokenStream { $buffer = []; while ($t = $ts->current()) { $str = (string) $t; if (!preg_match('/^\\w+$/', $str)) { throw new YayException("Only valid identifiers are mergeable, '{$t->dump()}' given."); } $buffer[] = $str; $ts->next(); } return TokenStream::fromSequence(new Token(T_STRING, implode('', $buffer))); }
protected function parseDictKey(TokenStream $stream) { $stream->expect(array(Tokens::T_IDENTIFIER, Tokens::T_STRING)); $token = $stream->current(); switch ($token->name) { case Tokens::T_STRING: $key = $this->cleanString($token->value); break; case Tokens::T_IDENTIFIER: default: $key = $token->value; break; } $stream->next(); return $key; }
/** * Parses an attribute from a selector contained in $stream and returns * the resulting AttribNode object. * * @throws SyntaxError When encountered unexpected selector * * @param Node\NodeInterface $selector The selector object whose attribute * is to be parsed. * @param TokenStream $stream The container token stream. * * @return Node\AttribNode */ protected function parseAttrib($selector, $stream) { $attrib = $stream->next(); if ($stream->peek() == '|') { $namespace = $attrib; $stream->next(); $attrib = $stream->next(); } else { $namespace = '*'; } if ($stream->peek() == ']') { return new Node\AttribNode($selector, $namespace, $attrib, 'exists', null); } $op = $stream->next(); if (!in_array($op, array('^=', '$=', '*=', '=', '~=', '|=', '!='))) { throw new SyntaxError(sprintf("Operator expected, got '%s'", $op)); } $value = $stream->next(); if (!$value->isType('Symbol') && !$value->isType('String')) { throw new SyntaxError(sprintf("Expected string or symbol, got '%s'", $value)); } return new Node\AttribNode($selector, $namespace, $attrib, $op, $value); }
function processTokenStream(TokenStream $tokenStream, ConverterStateMachine $stateMachine, $originalFilename) { $name = ''; $value = ''; $stateMachine->currentTokenStream = $tokenStream; while ($tokenStream->hasMoreTokens() == TRUE) { $tokenStream->next($name, $value); $count = 0; $parsedToken = $stateMachine->parseToken($name, $value, $count); //TODO - both of these should be somewhere more logical. if ($name == 'T_CONSTANT_ENCAPSED_STRING') { $value = convertMultiLineString($value); } if ($name == 'T_ENCAPSED_AND_WHITESPACE') { $parsedToken = convertMultiLineString($parsedToken); } $stateMachine->accountForOpenBrackets($name); $stateMachine->accountForQuotes($name); $stateMachine->scopePreStateMagic($name, $value); do { $reprocess = $stateMachine->processToken($name, $value, $parsedToken); if ($count > 5) { throw new \Exception("Stuck converting same token."); } $count++; } while ($reprocess == TRUE); $stateMachine->accountForCloseBrackets($name); $stateMachine->scopePostStateMagic($name, $value); if ($name == 'T_VARIABLE') { //If there's a token that needs to be inserted e.g. 'var' if ($stateMachine->insertToken != FALSE) { $stateMachine->addJS($stateMachine->insertToken); $stateMachine->insertToken = FALSE; } } if (FALSE) { $requiredFile = $stateMachine->getRequiredFile(); if ($requiredFile != NULL) { //echo "Figure out where $requiredFile is from original file path $originalFilename"; //TraitInclude.php' is from original file path TraitExample.php $pathParts = pathinfo($originalFilename); $requireFilePath = $pathParts['dirname'] . '/' . $requiredFile; //$requireFilePath = realpath($requireFilePath); if (PHPToJavascript::$TRACE == TRUE) { echo "Including file [{$requiredFile}] on path [{$requireFilePath}]."; } $code = file_get_contents($requireFilePath); if ($code === FALSE) { throw new \Exception("Could not open file [{$requiredFile}] on path [{$requireFilePath}]."); } $requireTokenStream = new TokenStream($code); processTokenStream($requireTokenStream, $stateMachine, $originalFilename); $stateMachine->addJS("\n//End of require\n"); //TODO Add a new state to tidy up semi-colon after include } } } }
private function parseIdentifier(TokenStream $tokens) { $cur = $tokens->current(); $node = new Node\IdentifierNode($cur->getValue(), $cur); $tokens->next(); return $node; }