1. Pascal / Говнокод #4646

    +106

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    procedure FirstStep (var Text: string);
    // Удаление комментариев <!--...-->, переводов строк, раскрытие тегов <br>, удаление парных пробелов:
    var
      P:     Integer;
      State: Integer;
      Idx:   Integer;
      Cnt:   Integer;
      NL:    Boolean;
    begin
      State := 0;
      P     := 1;
      NL    := True;
      while P <= Length (Text) do
      begin
        if Text[P] in [#9,#10,#13] then Text[P] := ' ';
        case State of
          0: case Text[P] of
               '<': State := 1;
               ' ': begin
                      Idx := P;
                      State := 9;
                    end; { }
               else NL := False;
             end; {case}
          1: case Text[P] of
               '!': State := 2;
               'b': State := 7;
               else
               begin
                 Dec (P);
                 State := 10;
               end; {else}
             end; {case}
          2: if Text[P] <> '-' then
             begin
               Dec (P);
               State := 10;
             end else State := 3;
          3: if Text[P] = '-' then
             begin
               Idx   := P - 3;
               State := 4;
             end else
             begin
               Dec (P);
               State := 10;
             end; {if}
          4: if Text[P] = '-' then State := 5;
          5: if Text[P] = '-' then State := 6 else State := 4;
          6: if Text[P] = '>' then
             begin
               Delete (Text, Idx, P - Idx + 1);
               P := Idx - 1;
               while (P >= 1) and (Text[P] = ' ') do Dec (P);
               State := 0;
             end else State := 4;
          7: if Text[P] = 'r' then State := 8 else State := 0;
          8: begin
               if Text[P] = '>' then
               begin
                 Text[P-3] := #13;
                 Text[P-2] := #10;
                 Delete (Text, P - 1, 2);
                 Dec (P, 2);
                 NL := True;
               end; {if}
               State := 0;
             end; {8}
          9: if Text[P] <> ' ' then
             begin
               Cnt := P - Idx;
               if NL then
               begin
                 Delete (Text, Idx, Cnt);
                 Dec (Idx);
               end else if Cnt > 1 then Delete (Text, Idx, Cnt - 1);
               P := Idx;
               State := 0;
             end; {if}
          10: if Text[P] = '>' then State := 0;
        end; {case}
        Inc (P);
      end; {while}
    end; {proc FirstStep}

    Кусок парсера HTML.

    Запостил: Arigato, 16 Ноября 2010

    Комментарии (38) RSS

    • показать все, что скрытоНу и напишите по-другому, и выложите сюда.
      Ответить
      • "-1". Ну-ну.
        Ответить
      • тоесть Вы реально думаете, что парсер должен содержать строки " 'b': State := 7;" ?:)))))))
        Ответить
        • Можно захватывать до первого пробела, "/", ">" и т.д. и разбирать, что захватил.
          Меньше строк было бы, и скорее всего я бы так и сделал.
          (правда не захватывал бы больше определенного количества символов).

          Этот код отнимает минимальное количество памяти и решает свою задачу.

          Так что не соглашусь, что это говно.
          Ответить
          • Во-первых что такое 7?
            Во-вторых если мы пишем универсальный парсер, то откуда там 'b'?
            а если мы пишем выцарапывание конкретного тэга -- то вообще проше юзать регулярки.
            ни за что не поверю что прирост производительности от стейт-машины так принципиален в таком случае.
            Ответить
            • Семь? это состояние.
              Вот тут лажа, надо константы завести.

              Быстродействие надо проверить (что будет быстрее: регулярка или это), так что тут промолчу.
              Ответить
              • Думаю, это будет быстрее. Вот только вопросы к Delete возникли, как бы он всю картину не подпортил...
                Ответить
                • Да это минус, соглашусь. Я бы новый текст формировал.
                  Ответить
              • регулярка в 100 раз проще, и жертвовать простотой ради производительности надо не всегда.
                Ваш КО
                Ответить
                • согласен. Как кто-то тут сказал: "не надо говнокодить в угоду оптимизации".

                  Просто код уже написан. Если работает и со скоростью нормально, то можно оставить.
                  Ответить
                • Тут не перл ветка, так что с регулярками идите в ветку регуляризатора перла.
                  Ответить
                  • действительно! на дельфи надо делать к в 73м году. Зачем нам регуляки?
                    Ответить
                    • как это ни ужасно - мне приходится согласиться с Arigato, брысь учить про конечные автоматы
                      Ответить
                      • регулярки и построены на конечных автоматах. Зачем реализовывать то, что уже сделано?

                        Что бы было быстрее? Так тут не будет серьезного прироста.

                        Если бы этот горе-парсер был универсальным -- ручная реализация автомата имела бы смысл (регуляркой задачу было бы просто не решить), но он умеет только BR и комменты выцеплять. А такая задача регуляркой решается быстрее и проще.
                        Ответить
                        • неубедительно
                          этот говноавтомат можно поправить
                          а Ваш быдлоспособ - только переписать на PHP
                          :-P
                          Ответить
                          • зачем?
                            если вдруг понадобится сделать полноценный парсер HTML, да что б понимал как xml-based там и smgl-based версии?
                            тогда говноавтомат надо переписывать (почти) с ноля.

                            этот автомат решает простую-и-тупую задачу сложным путем.
                            я говорю: простую-и-тупую задачу лучше решить простым-и-тупым путем.

                            а Вы говорите: "а вдруг задача неимоверно усложнится?"
                            Ответить
                            • таки марш смотреть как устроены автоматы
                              Ответить
                              • Вы реальне думаете, что я не знаю про конечные автоматы?
                                Я что, похож на PHP разработчика?
                                Ответить
                                • судя по кол-ву мессаг в обсуждении - весьма похоже на то :-)
                                  Ответить
                                  • Не, а вот в самом деле, к чему было твоё посылание учить автоматы?
                                    Ответить
                                    • можно провести эксперимент: распечатать этот код и выяснить на каком расстоянии подопытные смогут узнать в нем конечный автомат :)
                                      Ответить
                        • > регулярки и построены на конечных автоматах. Зачем реализовывать то, что уже сделано?
                          позволю себе вмешаться и уточнить: напомнить, что регулярки описывают только класс регулярных языков. А для парсеров лучше годятся (лево-)контекстные грамматики
                          Ответить
                          • исправлюсь:

                            известные мне ___имплементации___ регулярных выражений построены на конечных автоматах, обычно недетерменированных.

                            так лучше?)
                            Ответить
                            • да все было нормально, я про то, что регулярные грамматики лучше для парсеров не использовать
                              Ответить
              • внезапно, перечисляемый тип
                Ответить
          • кстати, "-1" сделал Вам не я.
            Ответить
            • Я совершенно не обращаю внимания на минусы. Так что даже если б Вы поставили -- я б не обиделся)
              Ответить
            • -1 сделал я, для баланса. А то было -2:0.
              Ответить
              • именно так и ставится большинство оценок)
                Ответить
                • Не знаю, тут в каком-то обсуждении сайта кто-то проговорился, что он для эксперимента минусовал нормальные коменты, и потом эти коменты обрастали минусами за счёт стадного инстинкта.
                  Ответить
                  • бывало и плюсовались не за что.
                    но гляжу в дополнение ко всему тут пубертанты балуются, минусуя вообще всем подряд
                    Ответить
      • Ну можно магию убрать.
        Заменить метки case на константы типа stateNo, stateBracket, stateBold (заведя перечислимый тип для начала).

        Ааа, вот говно: Delete (Text, Idx, P - Idx + 1);
        Из-за него разбор будет делаться за квадратное время.
        Ответить
        • Это вырезается комментарий. Интересно, какой иной вариант вырезать коммент вы предложите?
          Ответить
          • Не обрабатывать часть строки до конца комента, продолжая определять текущий терминал после конца комента - К.О.
            Ответить
        • +1 про магик-намберы.
          про Delete
          а над этим обычно задумываются, когда кто-то подсовывает огромменый скрипт, и потом все смотрят, а что же тормозит?!
          тоже +1.
          Ответить
    • О как это напоминает мой код обработки текстов, когда регулярных выражений не знал :D
      Ответить

    Добавить комментарий