За последние 24 часа нас посетили 18463 программиста и 1612 роботов. Сейчас ищут 1984 программиста ...

Проблема со скобочками

Тема в разделе "Сделайте за меня", создана пользователем NewbiSavage, 16 фев 2016.

  1. NewbiSavage

    NewbiSavage Новичок

    С нами с:
    13 дек 2015
    Сообщения:
    28
    Симпатии:
    0
    Всем доброго дня.

    В общем нужен скрипт который открывает php файл и проверяет наличие закрывающих скобок, так же он должен выдавать номер строки с ошибкой и кол-во таких строк. Пока что собрал вот такой кусок, как сделать чтобы был вывод строк с ошибками?


    Код (PHP):
    1. function php_check_syntax ($delievery){
    2. @$code = file_get_contents($delievery)
    3. if ($code == false) {
    4.         throw new Exception('File '.$delievery.' does not exist');
    5.     }
    6.      
    7.     // первый этап проверки
    8.     $braces = 0;
    9.     $inString = 0;
    10.     foreach ( token_get_all($code) as $token ) {
    11.         if ( is_array($token) ) {
    12.             switch ($token[0]) {
    13.                 case T_CURLY_OPEN:
    14.                 case T_DOLLAR_OPEN_CURLY_BRACES:
    15.                 case T_START_HEREDOC: ++$inString; break;
    16.                 case T_END_HEREDOC:   --$inString; break;
    17.             }
    18.         }
    19.         else if ($inString & 1) {
    20.             switch ($token) {
    21.                 case '`':
    22.                 case '"': --$inString; break;
    23.             }
    24.         }
    25.         else {
    26.             switch ($token) {
    27.                 case '`':
    28.                 case '"': ++$inString; break;
    29.  
    30.                 case '{': ++$braces; break;
    31.                 case '}':
    32.                     if ($inString) {
    33.                         --$inString;
    34.                     }
    35.                     else {
    36.                         --$braces;
    37.                         if ($braces < 0) {
    38.                             throw new Exception('Braces problem!');
    39.                         }
    40.                     }
    41.                 break;
    42.             }
    43.         }
    44.     }
    45.      
    46.     if ($braces) {
    47.         throw new Exception('Braces problem!');
    48.     }
    49.      
    50.     $res = false;  
    Подсказка от модератора:
    Любой код или текст конфигурации пишите между тегом [code=php] и [/code].
    Используйте отступы в коде для форматирования текста.
    Это помогает быстрее понять вас, увеличивает шанс на получение ответа.
    Что выделять? Например: PHP, HTML, CSS, JavaScript, SQL, XML, .htaccess, ini, регулярные выражения, код шаблонизаторов, любая другая разметка, результаты array/object dump и т. д.
     
  2. mr.akv

    mr.akv Активный пользователь

    С нами с:
    31 мар 2015
    Сообщения:
    1.604
    Симпатии:
    206
    Поставить IDE, госспаде, и не изобретать ненужных вещей
     
  3. NewbiSavage

    NewbiSavage Новичок

    С нами с:
    13 дек 2015
    Сообщения:
    28
    Симпатии:
    0
    Не думаю что преподу понравиться такой поворот.

    Возможно как-то можно значительно сократить код с помощью регулярных выражений?
     
  4. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    можно сократить с помощью php =) но препод поймёт, что это не твоё решение. Но я тебе дам подсказку, найдёшь - молодец. Пхп умеет понимать и разбирать пхп.
     
  5. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Это круто, но, боюсь, задача не преследует целью именно разбор пхп у парня. Препод увидит решение такое и скажет "окей, тогда не пхп, пусть будет *.срр файл".

    Это модификация классической задачи со скобками из разряда задач на разбор выражений/работы с текстом, не более.
     
  6. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    strpos() быстрее.
    У вас какая-то неимоверная логика для тривиальной задачи.
    Читаете текст. Встретили в строке открывающий символ - записали в массив номер строки. Встретили закрывающий - удалили последнюю запись. Нет в массиве открытых скобок? - Записали ошибку в лог. По окончании вывели массив незакрытых скобок и закрывающих без открытых. Никаких экспешенов там не надо. Если надо, то можно использовать стандартный вывод ошибок самого интерпритатора.
     
  7. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    У него там логика учитывает то, что скобочка может находиться, например, внутри строки или SQL_запроса. Хоть автор вряд ли в курсе, потому что код скопипижжен из коммента в документации пыхи. Причем из коммента 8-летней давности, ойвей.
    Пруф - https://php.net/manual/ru/function.php-check-syntax.php#80627

    Причем скопипижжен, походу, немного через "сломанный телефон". Вряд ли автор в курсе первоисточника.

    И да, Автор, препод, как я, вобьет кусок кода в гугл и погонит вас метлой из аудитории.
     
  8. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    встретили открывающую: плюс один.
    встретили закрывающую: минус один.

    В итоге должно быть ноль.
     
  9. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Это не сработает, если речь идет не только о фигурных, но и об обычных скобках. Потому что пропустит конструкцию

    { ( } )

    Которая не может быть валидной. Они тоже ломают синтаксис на ура.
    И это тоже классическая ошибка в решении классической задачи :)
    Такие вещи делаются через стек. Встретили открывающую скобку любого типа - "положили ее в стек". Встретили закрывающую скобку любого типа, обратились к стеку, вытряхнули из него скобочку последнюю, проверили. Если она
    1) Того же типа, что и встреченная
    2) Открывающая

    То все в порядке, идем дальше. В стеке больше этой скобки нет, она вытряхнута. Если хоть одно условие не совпадает, либо стек пуст - прекращаем разбор, ибо ошибка.
     
  10. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    Ну и хрен с ним. Есть кейсы когда эта скобка должна быть не закрыта разве в тексте?
    where like '{%' какой-нибудь разве что намеренно кривой.
    Тут можно сказать: как прописано условие задачи, такое и решение.
     
  11. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Есть.

    Код (PHP):
    1. echo "{"; 
     
  12. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    Прекрасно.
    Есть в условии задачи что учитываем только синтаксические скобки интерпрЕтатора (двоечник я)? Нет, у тса не увидел. В решении - да увидел.
     
  13. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    стек это прикольно. Вот у Феррары пол года смотрю на его статью про разбивку на токены http://blog.ircmaxell.com/2015/05/tries-and-lexers.html и думаю надо ли мне это знать :D

    Добавлено спустя 46 секунд:
    всё, пизда, надо преподу пузырь заносить чо
     
  14. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Но если чисто бежать по скрипту без учета строковых данных, то получится, что открывающих на одну больше, чем закрывающих. По этому там ведется учет кавычек и апострофов в посте. Но все равно через задницу сделано и неправильно. Будет ошибаться, как я выше описал. Собсно, и коммент, на который я сослался, заминусован.
     
  15. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Во, самое время заебошить токенический лексер
     
  16. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    Мб. Но, на самом деле, даже если учесть { в сраных кавычках, исключение их через strpos или регулярками быстрее сработает.
    Дальше сейчас они напишут про { в комментариях...
     
  17. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Такида. Ну правда, если бы речь была просто о проверке любой строки на скобочки, то тогда да. А так - скобочки скобочкам рознь. Нужно проверить код как код, а не как текст.

    Добавлено спустя 3 минуты 3 секунды:
    Но, даже проверка комментов/проверка строк/проверка запросов реализуется крайне крайне просто и тез гемора. Проблемы как таковой в этом нет вооообще. Та же задача на стек, но чуть поправленная.

    Но я принципиально не буду решение автору давать. Пусть учится. Работать за него тоже никто не будет.

    Достаточно того, что основной принцип описан.

    Добавлено спустя 8 минут 48 секунд:
    З.Ы. Так-то никто не против strpos'а. Через него бежать по коду всяко быстрее, чем посимвольно жевать. Это никто и не оспаривает.
     
  18. NewbiSavage

    NewbiSavage Новичок

    С нами с:
    13 дек 2015
    Сообщения:
    28
    Симпатии:
    0
    Нет, думаю igordata здесь был прав потому что по заданию у меня файл пхп с 4 пропущенными закрывающими кавычками и только в коде, нужно лишь чтобы скрип вывел номер строк где они пропущены и что их 4 .

    За strpos отдельное спасибо!
    Это шайсе надо сделать к завтра, но думаю что справлюсь =)
     
  19. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Ну тогда там решение в одну строку. Буквально. Но, боюсь, препод закозлится, мол "я не это имел ввиду".
     
  20. NewbiSavage

    NewbiSavage Новичок

    С нами с:
    13 дек 2015
    Сообщения:
    28
    Симпатии:
    0
    Небольшое уточнение, ф-ия strpos проверяет вхождения, но как она может отметить скобки с отсутствующими парами?
     
  21. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Никак. Ты программист или где? Алгоритмизируй.
    Если ты про "пхп умеет проверять пхп", то ты ищешь не там.
     
  22. NewbiSavage

    NewbiSavage Новичок

    С нами с:
    13 дек 2015
    Сообщения:
    28
    Симпатии:
    0
    Вот к чему пришел, но теперь нужно сделать так чтобы вывело общее кол-во незакрытых строчек,
    Код (PHP):
    1. <?
    2. $str = @file_get_contents('delivery.php') ; 
    3. if($str === FALSE) { echo 'Such file was not found';}
    4. else {
    5. $arr = explode('
    6. ', $str);
    7. foreach ($arr as $nomStr => $text){
    8.         $left =  explode('{',$text);
    9.         if(count($left)>=2){
    10.                 for($i=1;$i<count($left);$i++){
    11.                         echo '<strong style="color: #009900">braces "{" in string '.($nomStr+1).'</strong>';
    12.                         echo '<br>';
    13.                 }
    14.                 unset($left);
    15.         }    
    16.         $bad =  explode('}',$text);      
    17.         if(count($bad)>=2){
    18.                 for($i=1;$i<count($bad);$i++){
    19.                         echo '<strong style="color:#FF0000">braces  "}" in string'.($nomStr+1).'</strong>';
    20.                         echo '<br>';
    21.                 }
    22.                 unset($bad);           
    23.         }
    24.     }
    25. }
    26. ?>
     
  23. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    не пизди
     
  24. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Индусский код, бро.
    Код (PHP):
    1. if (file_exists('delivery.php')){
    2. //работа с файлом.
    3. }
    О_О

    Бро, решение нереальнейше индусское. Плевать, что не расширяемое, плевать что топорное, но индуизм - это эребор.

    В чем проблема сделать через стек-то? Длина стека к концу работы - количество скобочек. Ты делаешь просто по замеру количества, без учета порядка, ок. Тогда просто вычитай длины...массивов финальных и бери результат по модулю.

    Но, е-мое, генерить массивы - это эребор. Я б на месте препода охренел, увидев такое.
     
  25. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    в том что он и этого не делал, ага