• Как трансформировать код из 1 вида в другой?

    @kelvin57 Автор вопроса
    ksnk, СПС за помощь) эх... почему сразу прозрение не пришло, слабость в алгоритмах)))
    Написано
  • Как трансформировать код из 1 вида в другой?

    @kelvin57 Автор вопроса
    ksnk, у меня просто уже там и так одинарные кавычки в строках экранируются
    if ($node instanceof Text) {
                $this->php[] = $this->echo(str_replace('\'', '\\\'', $node->data));
    }

    По поводу последнего echo да просто пушим в data пустую строку и всё)
    Так думаю надёжнее чем регулярки и тд... код конечно прям совсем тупой в лоб но это и хорошо, вряд ли какие то подводные камни будут с ним
    Написано
  • Как трансформировать код из 1 вида в другой?

    @kelvin57 Автор вопроса
    ksnk, слушай а я такой пример накатал )) чудовищно конечно, ну зато работает...))
    без регулярок, в принципе в код можно вникнуть там всё по цепочке идёт и довольно логично. что скажешь как решение ?

    почему то мне казалось, что через токенайзер можно сделать что то подобное)

    $data = [
                (object) array(
                    'string' => '
            CHECK
            
            ',
                    'inQuotes' => true,
                ),
                (object) array(
                    'string' => '1 + 3 . \'-\'. 4 . \'=\' . 0',
                    'inQuotes' => false,
                ),
                (object) array(
                    'string' => '
            
            ',
                    'inQuotes' => true,
                ),
                (object) array(
                    'string' => '<h2>',
                    'inQuotes' => true,
                ),
                (object) array(
                    'string' => 'Olololo',
                    'inQuotes' => true,
                ),
                (object) array(
                    'string' => '</h2>',
                    'inQuotes' => true,
                ),
                (object) array(
                    'string' => '
            
            ',
                    'inQuotes' => true,
                ),
                (object) array(
                    'string' => '<h2>',
                    'inQuotes' => true,
                ),
                (object) array(
                    'string' => 'Number is, ',
                    'inQuotes' => true,
                ),
                (object) array(
                    'string' => 'count(["1","2","3"])',
                    'inQuotes' => false,
                ),
                (object) array(
                    'string' => '</h2>',
                    'inQuotes' => true,
                ),
                (object) array(
                    'string' => '
            
            ',
                    'inQuotes' => true,
                ),
                '
            if (rand(0,1)){',
                (object) array(
                    'string' => '
                lol
            ',
                    'inQuotes' => true,
                ),
                '
            }',
            ];
    
    
    
            $res = '';
            $openEcho = false;
            $inQuotes = false;
    
            foreach ($data as $str) {
                if (is_string($str)) {
                    if ($openEcho) {
                        if ($inQuotes) {
                            $res .= "'";
                        }
                        $res .= ";";
                        $openEcho = false;
                    }
                    $res .= $str;
                    continue;
                }
    
                if (!$openEcho) {
                    $openEcho = true;
                    $inQuotes = $str->inQuotes;
                    $res .= "\necho ";
                    if ($str->inQuotes) {
                        $res .= "'";
                    }
                    $res .= $str->string;
    
                } elseif ($str->inQuotes) {
                    if (!$inQuotes) {
                        $res .= ",'";
                        $inQuotes = true;
                    }
                    $res .= $str->string;
    
                } elseif (!$str->inQuotes) {
                    if ($inQuotes) {
                        $res .= "'";
                        $inQuotes = false;
                    }
                    $res .= ",$str->string";
                }
    
            }
    
            echo $res;


    на выходе:
    echo '
    CHECK
    
    ',1 + 3 . '-'. 4 . '=' . 0,'
    
    <h2>Olololo</h2>
    
    <h2>Number is, ',count(["1","2","3"]),'</h2>
    
    ';
    if (rand(0,1)){
    echo '
        lol
    ';
    }
    Написано
  • Как трансформировать код из 1 вида в другой?

    @kelvin57 Автор вопроса
    ksnk, а как это грамотно склеить ?

    например такой массив

    array (
      0 => 
      (object) array(
         'string' => '
    CHECK
    
    ',
         'inQuotes' => true,
      ),
      1 => 
      (object) array(
         'string' => '1 + 3 . \'-\'. 4 . \'=\' . 0',
         'inQuotes' => false,
      ),
      2 => 
      (object) array(
         'string' => '
    
    ',
         'inQuotes' => true,
      ),
      3 => 
      (object) array(
         'string' => '<h2>',
         'inQuotes' => true,
      ),
      4 => 
      (object) array(
         'string' => 'Olololo',
         'inQuotes' => true,
      ),
      5 => 
      (object) array(
         'string' => '</h2>',
         'inQuotes' => true,
      ),
      6 => 
      (object) array(
         'string' => '
    
    ',
         'inQuotes' => true,
      ),
      7 => 
      (object) array(
         'string' => '<h2>',
         'inQuotes' => true,
      ),
      8 => 
      (object) array(
         'string' => 'Number is, ',
         'inQuotes' => true,
      ),
      9 => 
      (object) array(
         'string' => 'count()',
         'inQuotes' => false,
      ),
      10 => 
      (object) array(
         'string' => '</h2>',
         'inQuotes' => true,
      ),
      11 => 
      (object) array(
         'string' => '
    
    ',
         'inQuotes' => true,
      ),
      12 => '
    if (rand(0,1)){',
      13 => 
      (object) array(
         'string' => '
        lol
    ',
         'inQuotes' => true,
      ),
      14 => '
    }',
    )
    Написано
  • Как трансформировать код из 1 вида в другой?

    @kelvin57 Автор вопроса
    Ладно, я уже другой путь выбрал)
    Написано
  • Как трансформировать код из 1 вида в другой?

    @kelvin57 Автор вопроса
    ksnk, получается в компиляции надо 2 прогона:
    1й типа прекомпайл
    2й уже финальный компайл в строку ?
    а так можно в массив например складывать колбеки и метаинформацию что там хранится, и грубо говоря склеивать судя по метаинформации.

    да для эстетики тоже важно что бы компилированый код был хорошо читаем, мало ли отдебажить что то надо и тд... ну и микрооптимизация вызовов echo))) да всё таки это надо делать на этапе компиляции, прост я думал типа как плагин пострпроцесс замутить ) что бы компилятор был до ужаса простецким, а все ништяки уже доп пакетами или спец флагами компилятора
    Написано
  • Как трансформировать код из 1 вида в другой?

    @kelvin57 Автор вопроса
    ksnk, а скинь класс этот отрефакториный) в чём вообше суть я пишу шаблонизатор, мб этот момент надо учитывать на этапе компиляции ? вот кусочек кода как это компилируется по заранее приготовленному AST которое подготовил мой парсер , мб я что то не так делаю)?
    public function compile($node)
        {
    
            if ($node instanceof ForeachBlock) {
                $res = "";
    
                if ($node->fallback) {
                    $res .= "\nif($node->expression) {\n";
                }
    
                $res .= "\nforeach ($node->expression as $node->context) {";
                $res .= $this->compile($node->body);
                $res .= "\n}";
    
                if ($node->fallback) {
                    $res .= "\n} else {";
                    $res .= $this->compile($node->fallback);
                    $res .= "\n}";
                }
    
                return $res;
            }
    
            if ($node instanceof Text) {
                return $this->echo(str_replace('\'', '\\\'', $node->data));
            }
    
    
            if ($node instanceof ExpressionTag) {
                return $this->echo($node->expression, inQuotes: false);
            }
    }
    Написано
  • Как трансформировать код из 1 вида в другой?

    @kelvin57 Автор вопроса
    Хотя вроде и работает. ну вот не знаю, кажется что вряд ли все случаи учитываются... чем проще тем лучше конечно) супер, спасибо!)
    Написано
  • Как трансформировать код из 1 вида в другой?

    @kelvin57 Автор вопроса
    ksnk, В любом случае спасибо за попытку)!
    да явно этот код хрупкий.....
    тут даже это надёжнее будет)
    $phpCode = explode(";\necho ", $phpCode);
    $phpCode = implode(',', $phpCode);


    мб после такого прогона будет проще склеить строки в 1 ?
    так как на выходе у нас получается всего 2 echo, надо убрать ',' если след токен строка, хотя бы так
    <?php 
    echo '
    CHECK
    
    ',1 + 3 . '-'. 4 . '=' . 0,'
    
    ',count(["1","2","3"]),'
    ',rand(0,1),'
    
    ','<h2>','Olololo','</h2>','
    
    ','<h3>','QWErt\'y','</h3>','
    
    
    ','<h2>','Hello, ',$name,'</h2>','
    
    ';
    foreach ([1,2,3] as $item) {
    echo '
        ','<h2>','Number is: ',$item,'</h2>','
    ';
    }
    Написано
  • Как трансформировать код из 1 вида в другой?

    @kelvin57 Автор вопроса
    Работает, но ненадёжно....(
    Надо как то упростить, например если у нас в коде:
    echo '<h2>';
    echo 'Number is: ';
    echo count(["1","2","3"]);
    echo '</h2>';

    то уже ничего не работает, мне кажется тут логика должна быть проще...

    на псевдо коде мб что то в таком направлении ?

    $isEchoOpen = false;
    if(token === echo) {
      if($isEchoOpen) {
        $res.= ',';
      } else {
       $isEchoOpen = true;
       $res .= 'echo ';
      }
    } else {
      if($isEchoOpen) {
        $isEchoOpen = false;
        $res.= ';';
       }
    }
    Написано
  • Как трансформировать код из 1 вида в другой?

    @kelvin57 Автор вопроса
    Алексей Уколов, Видел) ну это монстр (абстрактное дерево и тд. тут вряд ли нужны)...
    во-2 даже с либой хз как это сделать.

    как то это можно через встроенную либу в php, вот пример который убирает все комментарии из кода
    https://www.php.net/manual/ru/tokenizer.examples.php пару строк кода и готово, думаю тут какое то аналогичное решение.
    Написано
  • Как трансформировать код из 1 вида в другой?

    @kelvin57 Автор вопроса
    Думал об этом, но альтернативный синтаксис не годится. Надо именно перегнать из 1 формата в другой.
    Написано