Пример #1
1
function yay_parse(string $source, Directives $directives = null, BlueContext $blueContext = null) : string
{
    if ($gc = gc_enabled()) {
        gc_disable();
    }
    // important optimization!
    static $globalDirectives = null;
    if (null === $globalDirectives) {
        $globalDirectives = new ArrayObject();
    }
    $directives = $directives ?: new Directives();
    $blueContext = $blueContext ?: new BlueContext();
    $cg = (object) ['ts' => TokenStream::fromSource($source), 'directives' => $directives, 'cycle' => new Cycle($source), 'globalDirectives' => $globalDirectives, 'blueContext' => $blueContext];
    foreach ($cg->globalDirectives as $d) {
        $cg->directives->add($d);
    }
    traverse(midrule(function (TokenStream $ts) use($directives, $blueContext) {
        $token = $ts->current();
        tail_call:
        if (null === $token) {
            return;
        }
        // skip when something looks like a new macro to be parsed
        if ('macro' === (string) $token) {
            return;
        }
        // here we do the 'magic' to match and expand userland macros
        $directives->apply($ts, $token, $blueContext);
        $token = $ts->next();
        goto tail_call;
    }), consume(chain(token(T_STRING, 'macro')->as('declaration'), optional(repeat(rtoken('/^·\\w+$/')))->as('tags'), lookahead(token('{')), commit(chain(braces()->as('pattern'), operator('>>'), braces()->as('expansion')))->as('body'), optional(token(';'))), CONSUME_DO_TRIM)->onCommit(function (Ast $macroAst) use($cg) {
        $scope = Map::fromEmpty();
        $tags = Map::fromValues(array_map('strval', $macroAst->{'tags'}));
        $pattern = new Pattern($macroAst->{'declaration'}->line(), $macroAst->{'body pattern'}, $tags, $scope);
        $expansion = new Expansion($macroAst->{'body expansion'}, $tags, $scope);
        $macro = new Macro($tags, $pattern, $expansion, $cg->cycle);
        $cg->directives->add($macro);
        // allocate the userland macro
        // allocate the userland macro globally if it's declared as global
        if ($macro->tags()->contains('·global')) {
            $cg->globalDirectives[] = $macro;
        }
    }))->parse($cg->ts);
    $expansion = (string) $cg->ts;
    if ($gc) {
        gc_enable();
    }
    return $expansion;
}
Пример #2
0
 /**
  * Match token and delete it
  *
  * @param  string  $token
  * @param  string  $str
  * @return string|void
  */
 function match($token, &$str)
 {
     if (preg_match($token, $str, $match)) {
         $str = consume($str, $match[0]);
         return $match;
     }
 }
Пример #3
0
function main()
{
    if (!isset($_SERVER['argv'][1])) {
        die('You must provide an argument of either "consume" or "produce"');
    }
    if ($_SERVER['argv'][1] == 'produce') {
        produce();
    }
    if ($_SERVER['argv'][1] == 'consume') {
        consume();
    }
}
Пример #4
0
<?php

use Cake\Datasource\ConnectionManager;
use Cake\Utility\Hash;
ConnectionManager::config(Hash::merge(['default' => ['className' => 'Cake\\Database\\Connection', 'driver' => 'Cake\\Database\\Driver\\Mysql', 'persistent' => false, 'host' => env('DATABASE_DEFAULT_HOST') ?: 'localhost', 'username' => env('DATABASE_DEFAULT_USER') ?: 'my_app', 'password' => env('DATABASE_DEFAULT_PASS') ?: 'secret', 'database' => env('DATABASE_DEFAULT_NAME') ?: 'my_app', 'prefix' => false, 'encoding' => strtolower(str_replace('-', '', read('App.encoding'))), 'timezone' => read('App.timezone'), 'quoteIdentifiers' => false], 'test' => ['className' => 'Cake\\Database\\Connection', 'driver' => 'Cake\\Database\\Driver\\Mysql', 'persistent' => false, 'host' => env('DATABASE_TEST_HOST') ?: 'localhost', 'username' => env('DATABASE_TEST_USER') ?: 'my_app', 'password' => env('DATABASE_TEST_PASS') ?: 'secret', 'database' => env('DATABASE_TEST_NAME') ?: 'test_myapp', 'prefix' => false, 'encoding' => strtolower(str_replace('-', '', read('App.encoding'))), 'timezone' => read('App.timezone'), 'quoteIdentifiers' => false]], consume('Datasources')));
Пример #5
0
<?php

use Cake\Core\Plugin;
use Cake\Mailer\Email;
$emailFrom = read('App.email', 'no-reply@' . env('HTTP_HOST'));
$emailFrom = [$emailFrom => $emailFrom];
$emailProfiles = ['default' => ['from' => $emailFrom, 'sender' => $emailFrom, 'replyTo' => $emailFrom, 'layout' => 'default', 'template' => null, 'viewRender' => 'Cake\\View\\View', 'theme' => null, 'helpers' => ['Html'], 'emailFormat' => 'both', 'transport' => 'default']];
if (Plugin::loaded('Gourmet/Email')) {
    $emailProfiles['default']['layout'] = 'Gourmet/Email.default';
    $emailProfiles['default']['helpers'][] = 'Gourmet/Email.Email';
}
foreach (consume('Email.profiles', []) as $emailProfile => $emailProfileConfig) {
    $emailProfiles[$emailProfile] = $emailProfileConfig + $emailProfiles['default'];
}
Email::config($emailProfiles);
$emailTransports = ['default' => ['className' => 'Smtp', 'host' => 'localhost', 'port' => 1025, 'timeout' => 30, 'client' => null, 'tls' => null]];
foreach (consume('Email.transports', []) as $emailTransport => $emailTransportConfig) {
    $emailTransports[$emailTransport] = $emailTransportConfig + $emailTransports['default'];
}
Email::configTransport($emailTransports);
unset($emailFrom, $emailProfiles, $emailProfile, $emailProfileConfig, $emailTransport, $emailTransports, $emailTransportConfig);
Пример #6
0
 private function mutate(TokenStream $ts, Ast $context, Cycle $cycle, Directives $directives, BlueContext $blueContext) : TokenStream
 {
     if ($this->constant) {
         return $ts;
     }
     static $states, $parser;
     $states = $states ?? new Stack();
     $parser = $parser ?? traverse(token(Token::CLOAKED), consume(chain(rtoken('/^··\\w+$/')->as('expander'), either(parentheses(), braces())->as('args')))->onCommit(function (Ast $result) use($states) {
         $cg = $states->current();
         $expander = $result->expander;
         if (\count($result->args) === 0) {
             $cg->this->fail(self::E_EMPTY_EXPANDER_SLICE, (string) $expander, $expander->line());
         }
         $context = Map::fromKeysAndValues(['scope' => $cg->cycle->id(), 'directives' => $cg->directives, 'blueContext' => $cg->blueContext]);
         $expansion = TokenStream::fromSlice($result->args);
         $mutation = $cg->this->mutate(clone $expansion, $cg->context, $cg->cycle, $cg->directives, $cg->blueContext);
         $mutation = $cg->this->lookupExpander($expander)($mutation, $context);
         $cg->ts->inject($mutation);
     }), consume(chain(rtoken('/^·\\w+|···\\w+$/')->as('label'), operator('···'), optional(parentheses()->as('delimiters')), braces()->as('expansion')))->onCommit(function (Ast $result) use($states) {
         $cg = $states->current();
         $context = $cg->this->lookupContext($result->label, $cg->context, self::E_UNDEFINED_EXPANSION);
         $expansion = TokenStream::fromSlice($result->expansion);
         $delimiters = $result->delimiters;
         // normalize single context
         if (array_values($context) !== $context) {
             $context = [$context];
         }
         foreach (array_reverse($context) as $i => $subContext) {
             $mutation = $cg->this->mutate(clone $expansion, (new Ast(null, $subContext))->withParent($cg->context), $cg->cycle, $cg->directives, $cg->blueContext);
             if ($i !== 0) {
                 foreach ($delimiters as $d) {
                     $mutation->push($d);
                 }
             }
             $cg->ts->inject($mutation);
         }
     }), consume(rtoken('/^(T_\\w+·\\w+|·\\w+|···\\w+)$/')->as('label'))->onCommit(function (Ast $result) use($states) {
         $cg = $states->current();
         $context = $cg->this->lookupContext($result->label, $cg->context, self::E_UNDEFINED_EXPANSION);
         if ($context instanceof Token) {
             $cg->ts->inject(TokenStream::fromSequence($context));
         } elseif (is_array($context) && \count($context)) {
             $tokens = [];
             array_walk_recursive($context, function (Token $token) use(&$tokens) {
                 $tokens[] = $token;
             });
             $cg->ts->inject(TokenStream::fromSlice($tokens));
         }
     }));
     $cg = (object) ['ts' => $ts, 'context' => $context, 'directives' => $directives, 'cycle' => $cycle, 'this' => $this, 'blueContext' => $blueContext];
     $states->push($cg);
     $parser->parse($cg->ts);
     $states->pop();
     $cg->ts->reset();
     if ($this->cloaked) {
         traverse(consume(token(Token::CLOAKED))->onCommit(function (Ast $result) use($cg) {
             $cg->ts->inject(TokenStream::fromSourceWithoutOpenTag((string) $result->token()));
         }))->parse($cg->ts);
         $cg->ts->reset();
     }
     return $cg->ts;
 }
Пример #7
0
 private function mutate(TokenStream $ts, Ast $context) : TokenStream
 {
     $cg = (object) ['ts' => clone $ts, 'context' => $context];
     if ($this->unsafe && !$this->hasTag('·unsafe')) {
         hygienize($cg->ts, $this->cycle->id());
     }
     if ($this->constant) {
         return $cg->ts;
     }
     traverse(either(token(Token::CLOAKED), consume(chain(rtoken('/^·\\w+$/')->as('expander'), parentheses()->as('args')))->onCommit(function (Ast $result) use($cg) {
         $expander = $this->lookupExpander($result->expander);
         $args = [];
         foreach ($result->args as $arg) {
             if ($arg instanceof Token) {
                 $key = (string) $arg;
                 if (preg_match('/^·\\w+|T_\\w+·\\w+|···\\w+$/', $key)) {
                     $arg = $cg->context->{$key};
                 }
             }
             if (is_array($arg)) {
                 array_push($args, ...$arg);
             } else {
                 $args[] = $arg;
             }
         }
         $mutation = $expander(TokenStream::fromSlice($args), $this->cycle->id());
         $cg->ts->inject($mutation);
     }), consume(chain(rtoken('/^·\\w+|···\\w+$/')->as('label'), operator('···'), braces()->as('expansion')))->onCommit(function (Ast $result) use($cg) {
         $index = (string) $result->label;
         $context = $cg->context->{$index};
         if ($context === null) {
             $this->fail(self::E_EXPANSION, $index, $result->label->line(), json_encode(array_keys($cg->context->all()[0]), self::PRETTY_PRINT));
         }
         $expansion = TokenStream::fromSlice($result->expansion);
         // normalize single context
         if (array_values($context) !== $context) {
             $context = [$context];
         }
         foreach (array_reverse($context) as $i => $subContext) {
             $mutation = $this->mutate($expansion, (new Ast(null, $subContext))->withParent($cg->context));
             $cg->ts->inject($mutation);
         }
     }), consume(rtoken('/^(T_\\w+·\\w+|·\\w+|···\\w+)$/'))->onCommit(function (Ast $result) use($cg) {
         $expansion = $cg->context->{(string) $result->token()};
         if ($expansion instanceof Token) {
             $cg->ts->inject(TokenStream::fromSequence($expansion));
         } elseif (is_array($expansion) && \count($expansion)) {
             $tokens = [];
             array_walk_recursive($expansion, function (Token $token) use(&$tokens) {
                 $tokens[] = $token;
             });
             $cg->ts->inject(TokenStream::fromSlice($tokens));
         }
     }), any()))->parse($cg->ts);
     $cg->ts->reset();
     if ($this->cloaked) {
         traverse(either(consume(token(Token::CLOAKED))->onCommit(function (Ast $result) use($cg) {
             $cg->ts->inject(TokenStream::fromSourceWithoutOpenTag((string) $result->token()));
         }), any()))->parse($cg->ts);
         $cg->ts->reset();
     }
     return $cg->ts;
 }
Пример #8
0
<?php

use Cake\Cache\Cache;
use Cake\Utility\Hash;
$cacheEngines = ['file' => ['className' => 'Cake\\Cache\\Engine\\FileEngine', 'serialize' => true], 'redis' => ['className' => 'Cake\\Cache\\Engine\\RedisEngine', 'port' => '6379', 'server' => 'localhost']];
$cacheEngine = $cacheEngines['file'];
if (extension_loaded('redis') && class_exists('\\Redis')) {
    $redis = new \Redis();
    if ($rh = $redis->connect($cacheEngines['redis']['server'], $cacheEngines['redis']['port'])) {
        $redis->close();
        $cacheEngine = $cacheEngines['redis'];
    }
}
$cacheConfig = Hash::merge(['_cake_core_' => $cacheEngines['file'] + ['duration' => '+1 year', 'path' => CACHE . 'persistent' . DS], '_cake_model_' => $cacheEngines['file'] + ['duration' => '+1 year', 'path' => CACHE . 'models' . DS], 'default' => $cacheEngine + ['duration' => '+15 mins'], 'year' => $cacheEngine + ['duration' => '+1 year'], 'month' => $cacheEngine + ['duration' => '+1 month'], 'week' => $cacheEngine + ['duration' => '+1 week'], 'day' => $cacheEngine + ['duration' => '+1 day'], 'asset_compress' => $cacheEngines['file'] + ['duration' => '+1 year', 'path' => CACHE . 'persistent' . DS]], consume('Cache'));
Cache::config($cacheConfig);
unset($cacheConfig, $cacheEngine, $cacheEngines, $redis);
Пример #9
0
<?php

use Cake\Log\Log;
use Cake\Utility\Hash;
$logDefaultConfig = ['className' => 'Cake\\Log\\Engine\\FileLog', 'file' => LOGS . php_sapi_name() . '-debug', 'levels' => []];
$logConfigs = Hash::merge(['debug' => ['levels' => ['notice', 'info', 'debug']] + $logDefaultConfig, 'error' => ['file' => LOGS . php_sapi_name() . '-error', 'levels' => ['warning', 'error', 'critical', 'alert', 'emergency']] + $logDefaultConfig], consume('Log', []));
Log::config($logConfigs);
unset($logDefaultConfig, $logConfigs);
Пример #10
0
 function testConsume()
 {
     $ts = TokenStream::fromSource('<?php A  {X} B {X} C    {x} ');
     $this->parseSuccess($ts, token(T_OPEN_TAG), "T_OPEN_TAG(<?php )");
     traverse(either(consume(chain(token('{'), token(T_STRING), token('}'))), any()))->parse($ts);
     $this->assertEquals('<?php A   B  C     ', (string) $ts);
     $ts = TokenStream::fromSource('<?php A  {-}   B    {-}     ');
     $this->parseSuccess($ts, token(T_OPEN_TAG), "T_OPEN_TAG(<?php )");
     traverse(either(consume(chain(token('{'), token('-'), token('}')), CONSUME_DO_TRIM), any()))->parse($ts);
     $this->assertEquals('<?php A  B    ', (string) $ts);
 }