Кресты / Говнокод #27961 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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
rule_t block_r = ch_p('{') >> *(~ch_p('}') | (~ch_p('{') >> block_r));
	rule_t bin_r = str_p("0b") >> bin_p[assign(m)];
	rule_t hex_r = str_p("0x") >> hex_p[assign(m)];
	rule_t dec_r = uint_p[assign(m)];
  rule_t id_r = alpha_p >> *(alnum_p | ch_p('_') | ch_p('.'));
  rule_t string_r = ch_p('"') >> (*(~ch_p('"')))[assign(s)] >> ch_p('"');
  rule_t channel_r = str_p("channel") >> *(space_p) >> id_r[assign(s)][assign_a(ch.name,s)][push_back_a(lstJSVars_,s)] >> *(space_p) >> ch_p('{') >>
    *(space_p 
			| (str_p("mode") >> *(space_p) >> ch_p('=') >> *(space_p) >> 
        	(str_p("in")[assign_a(ch.mode,(int)channel::IN)] | str_p("out")[assign_a(ch.mode,(int)channel::OUT)]) >> *(space_p) >> ch_p(';'))
			| (str_p("number") >> *(space_p) >> ch_p('=') >> *(space_p) >> int_p[assign(ch.number)] >> *(space_p) >> ch_p(';')) 
			| (str_p("channel") >> *(space_p) >> ch_p('=') >> *(space_p) >> int_p[assign(ch.ch)] >> *(space_p) >> ch_p(';')) 
			| (str_p("gain") >> *(space_p) >> ch_p('=') >> *(space_p) >> int_p[assign(ch.gain)] >> *(space_p) >> ch_p(';')) 
			| (str_p("type") >> *(space_p) >> ch_p('=') >> *(space_p) >>
					(str_p("analog")[assign_a(ch.type,(int)channel::ANALOG)] | str_p("discrete")[assign_a(ch.type,(int)channel::DISCRETE)]) >> *(space_p) >> ch_p(';'))
			| (str_p("mask") >> *(space_p) >> ch_p('=') >> *(space_p) >> 
					(bin_r[assign_a(ch.mask,m)] | hex_r[assign_a(ch.mask,m)] | dec_r[assign_a(ch.mask,m)]) >> *(space_p) >> ch_p(';'))
    ) >>
    ch_p('}') >> *(space_p) >> ch_p(';'); 
  rule_t device_r = str_p("device_info") >> *(space_p) >> id_r[assign(dev_info_.name)] >> *(space_p) >> ch_p('{') >>
    *(space_p | 
      (str_p("device") >> *(space_p) >> ch_p('=') >> *(space_p) >> string_r[assign_a(dev_info_.dev,s)] >> *(space_p) >> ch_p(';')) | 
      (str_p("blocking") >> *(space_p) >> ch_p('=') >> *(space_p) >> 
        (str_p("true")[assign_a(dev_info_.blocking,true)] | str_p("false")[assign_a(dev_info_.blocking,false)]) >> *(space_p) >> ch_p(';')) |
      (str_p("freq_ch") >> *(space_p) >> ch_p('=') >> *(space_p) >> int_p[assign(dev_info_.freq_ch)] >> *(space_p) >> ch_p(';')) | 
      (str_p("freq_sel_ch") >> *(space_p) >> ch_p('=') >> *(space_p) >> int_p[assign(dev_info_.freq_sel_ch)] >> *(space_p) >> ch_p(';')) |
      (str_p("speed") >> *(space_p) >> ch_p('=') >> *(space_p) >> int_p[assign(dev_info_.speed)] >> *(space_p) >> ch_p(';')) | 
      channel_r[assign_a(v,ch)][push_back_a(lstChannels_,v)]
    ) >>
    ch_p('}') >> *(space_p) >> ch_p(';');
  rule_t var_r = (str_p("var") >> *(space_p) >> id_r[assign(s)][push_back_a(lstJSVars_,s)] >>*(~ch_p(';')) >> ch_p(';'))[assign(s)][push_back_a(lstVars,s)];
  rule_t function_r = str_p("function") >> *(~ch_p('`'));
	//rule_t function_r = str_p("function") >> *(~ch_p('{')) >> block_r;
  rule_t script_r = str_p("script") >> *(space_p) >> ch_p('{') >>
    *(space_p |
      var_r[assign(s)][push_back_a(lstJSVars_,s)] |
      (function_r[assign(s)][push_back_a(lstFunc,s)] >> *(space_p) >> ch_p('`'))
    ) >>
    ch_p('}') >> *(space_p) >> ch_p(';');

Из системы эмуляции полёта на тренажере.

Запостил: codemeow codemeow, (Updated )

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

  • Это описание кококой-то грамматики? BNF на опереторах C++
    Ответить
      • О, хоспаде, кокой кошмар.

        Хорошо, что я не дописал похожую штуку для петона. Сперва я думал, что будет красиво.
        Ответить
      • Да так то вполне читаемо... Но сама идея парсить код на JS (?!!) врукопашную как-то смущает.
        Ответить
        • >Да так то вполне читаемо...
          а писаемо?
          Ответить
          • > а писаемо?

            Надо руку набить и немного выпить для храбрости... И самое главное -- не смотреть вниз на ошибки конпелятора.

            Если с [action'ами] сильно не выёбываться и правила более-менее внятно называть, то пишется вполне норм.
            Ответить
            • Спрошу прямо, в лоб, по стариковски: а почему нельзя написать это на BNF, и потом сгенерить код? Чтобы шаманить там что-то и восстанавливаться из под ошибок?
              Ответить
              • Ну во-первых внешние тулы тоже красотой не блещут, а во-вторых их вызывать надо, в билд-систему прикручивать. Так что если какой-то мелкий конфиг распарсить -- спирт вполне сойдёт.
                Ответить
                • Тулы может и не блещут, то кажется, что BNF писать проще, не?

                  >мелкий конфиг
                  вооот! Какой-нить "ini" файл я бы и сам на спирите запилил, но ведь тут совсем что-то страшное.

                  Кстати, современные конфиги можно хранить в yaml/toml/xml/json и не писать парсер вооще
                  Ответить
                  • > кажется, что BNF писать проще

                    Дык это и есть BNF, просто обмазанный крестоговном и с ограничениями типичного LL парсера...
                    Ответить
                    • Я имел ввиду BNF не как модель, а как синтаксис.

                      Но я предвзят: спирит я трогал один раз из интереса, а BNF мне часто встречался в описании всяких говноформатов протоколов, и я как-то привык
                      Ответить
                      • На голом BNF далеко не уедешь, один фиг как-то надо мапать его на структуры языка.
                        Ответить
                        • Дык я имел ввиду:
                          * пишешь BNF
                          * тула генерит тебе по нему код

                          Ну как бизон например. Другой вопрос, что код получается говеный, и его нужно обмазывать потом удодным API
                          Ответить
                          • > генерит по нему код

                            И что этот код сможет сделать помимо проверки синтаксиса? Всё равно какие-то расширения BNF нужны в духе экшенов [спирта] или {бизона}. Голый BNF только для документации пригоден.
                            Ответить
                            • Ну ты можешь сделать тулу, которая по BNF сгенерит тебе структуры, заполнит их, а ты потом по ним будешь навигирвоаться.

                              Примерно как бы ты парсил XML со схемой.

                              Это не подойдет для настоящего парсера наверное, но для конфига может.

                              (тут надо спизднуть что-то умное про грамматики и иерархию Хомски, наверное)
                              Ответить
                              • > по ним навигироваться

                                Фублядь, фунахуй... Зачем мне описывать грамматику, которая мапается на какое-то json-подобное говнище, которое потом руками дальше парсить? Если уж юзать инструмент, так по-нормальному...
                                Ответить
                                • ну не совсем json подобное, все таки оно типизировано.

                                  А зачем? Ну если это key value, то чому бы и нет?

                                  Если же ты хочешь настоящий парсер, который умеет найши ошибку, подсветить, и сказать "питух экспектд", то конечно надо вшивать в него умный код, и тут без экшенов не абойтись
                                  Ответить
                                  • > типизировано

                                    А где генератор в голом BNF найдёт типы? Свои какие-то от балды напихает, чтобы мне потом их в осмысленные загонять и доделывать работу руками за него?
                                    Ответить
                                    • Создаст структуры по описанию, как прокси классы по всяким схемам и IDL

                                      ну типа итак
                                      <letter>         ::= "A", "Z", "Ы"

                                      это енум Letter
                                      итд

                                      >тобы мне потом их в осмысленные загонять

                                      Так и было сказано:
                                      >Другой вопрос, что код получается говеный, и его нужно обмазывать потом удодным API

                                      А еще было сказано, что это подходит для конфигов (где все довольно тупо) но не для парсеров.


                                      Блин, какой ты капризный. У меня на работе жабаёбы длиннющщие JSONы вручную парсят какой-то хуйней типа
                                      jsonkal.getObject("hui").getString("zhopa");

                                      и не жужжат
                                      Ответить
                                      • > Блин, какой ты капризный.

                                        Я просто не понимаю, нахуя закручивать шурупы шуроповёртом как отвёрткой, так и не разобравшись, что его можно включить и он будет закручивать всё сам...
                                        Ответить
                                • Зачем? Зачем? Тула генерит кот, который строит АСТ, а ты по нему идёшь и течёш. Правда годится только для КС-грамматик, наверное.

                                  Хотя мне ближе ручной процедурный подход.
                                  Ответить
                                  • > который строит АСТ

                                    Из говна и палок? А если я могу как-то управлять упаковкой распарсенного говна в нужные мне типы, поля и т.п., то это уже расширенный BNF, как в спирте или бизоне.
                                    Ответить
                                    • Какие генераторы, какие АСТ, вы про что?

                                      Хочу я конфиг — беру «pydantic» и теку от строго типизированной конфигурации с нулевым бройлерплейтом:
                                      from pydantic import BaseModel
                                      
                                      
                                      class Settings(BaseModel):
                                          foo: int
                                          bar: str
                                      
                                      
                                      def main():
                                          s1 = Settings.parse_raw('{"foo": 42, "bar": "hello"}')
                                          print(s1)
                                      
                                          s2 = Settings.parse_raw('{"foo": "hello", "bar": "hello"}')
                                          # pydantic.error_wrappers.ValidationError: 1 validation error for Settings
                                          # foo
                                          #   value is not a valid integer (type=type_error.integer)
                                      
                                      
                                      if __name__ == '__main__':
                                          main()

                                      Там даже «parse_file()» есть, если лень файл читать.
                                      Ответить
                                      • А там можно что-нибудь более человеческое вместо json?
                                        Ответить
                                        • А чем тебе json не нравятся? Я тут всю жизнь живу и всем советую.


                                          Можно сделать «parse_obj()», передав туда любой питоний словарик; словарик можешь парсить откуда угодно.
                                          Ответить
                                          • > чем тебе json не нравятся

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

                                            А там ведь даже комментов нету.
                                            Ответить
                                      • А так понял мы не просто о конфигах, а о парсинше во бщем.
                                        Ответить
                                    • Он тебе распарсит, что это за коньструкция и все её параметры. А ты уже в программе пишешь, что с этим делать, какие типы и т.д.

                                      Отделяет синтакс от сёмантики.
                                      Ответить
                                      • > что это за коньструкция и все её параметры

                                        Имена параметров он где возьмёт? Как он поймёт, какие элементы мне надо сохранить, а какие просто кусок синтаксиса? Как он поймёт, какие типы назначить этим параметрам (я не хочу допарсивать каждый инт потом)?

                                        В голом BNF ничего из этого нет, емнип.
                                        Ответить
                                        • Я имею ввиду участников действа. Нопремер в присваивании это выражение слева и выражение справа, выражение слева это имя переменной или разыменование и тюдю
                                          Ответить
                                        • Борманд, есть такой конфиг
                                          name = petuh # это строка
                                          iq = 22 #это число
                                          # это комментарий

                                          ключи известны заранее

                                          Как бы ты его распарсил?
                                          Ответить
                                          • Лучше тебе не знать, как я парсила командлайн в одной из наших утилиток...
                                            Ответить
                                            • А что, гетпоц отменили?

                                              Я писал парсер и лексер для гнуснёвой командлайны на жабе

                                              Ну точнее я просто взял JFlex и там нахучил
                                              Ответить
                                              • На винде то? Там кроме буста вроде и нечем нормально спарсить...
                                                Ответить
                                                • На винде вообще очень трудно что-то спарсить, тут ты прав..

                                                  Именно потому каждая виндовая тула имеет СВОЙ синтаксис для аргументов, и каждый из них отвратителен по своему

                                                  А ты же читал статью "Everyone quotes command line arguments the wrong way" ?
                                                  Ответить
                                          • А вообще, можно попробовать спиртом сразу в крестовую структуру высрать.
                                            Ответить
                  • > и не писать парсер вооще

                    Ну х.з., yaml ещё ничего, но за конфиги в json или xml мне хочется убивать.
                    Ответить
                    • yaml я не люблю. При серьезном уровне вложенности приходится писать код в правом углу моника.

                      Я тут давеча попал на сервер убунту, и а там netplan. Я его исправил, говорю ``netplan try --debug``, а он говорит "хуй", а что хуй не поясняет.

                      Правда ямл не виноват: там оказалось, что он ждал листа (который в ямле через "-" или в скобках) а я ему туда литерал хуйнул.

                      json действительно отвратителен, но к сожалению на нем уже дохуя всего, например докер, и вроде эти ваши VSCode?


                      XML хорошо поддерживает вложенность, есть стандарт для референсов, его можно програмно спарснуть на любом языке, итд.
                      Проблема его только в вербозности. Использовать XML для пары key-value -- тупо.

                      Мне XML легче читать, чем JSON, но это тоже моя деформация
                      Ответить
                      • > yaml я не люблю. При серьезном уровне вложенности приходится писать код в правом углу моника.

                        Python я не люблю. При серьёзном уровне вложенности приходится писать код в правом углу моника.

                        Вообще говоря, он обратно совместим с json. Так что можешь скобочками обмазать в некоторых местах.
                        Ответить
                        • Я и питон не люблю, но там можно выносить куски в функции.
                          А может, и в ямле можно? Я может лалка анскильная?

                          > Так что можешь скобочками обмазать.
                          Спасибо, не хочу.

                          Хачу чтобы чтобы вместо неплана были interfaces как в debian. Там свой говноформат, очень простой
                          Ответить
                          • > А может, и в ямле можно?

                            С натяжкой, там есть ссылки. И если в твоём формате есть какие-то места, на которые парсеру пофиг, то там можно &складывать блоки и *ссылаться на них из других мест.
                            Ответить
        • Да, похоже на жс. Только расширен какими-то доплнительными конь-струкциями channel и device_info. Хотя вместо них можно было взять готовый движок и сделать функции.

          Кстати тут больше никаких операций не определяется, я бы вместо токого дерьма нагородил бы простенький дсльчик.
          Ответить
          • Может, это DSL поверх JS?

            можно как-то так наибать JS, чтоб можно было написать
            device_info {
            
            }

            или нет?
            Ответить
            • На джс незнаю, на тцл это тупо вызов функции девице_инфо.
              device_info {
                  name HACTEHbKA
                  age 12
              }
              Ответить
  • пожалуйста скажите что это автогенерено
    Ответить

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

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8