1. C++ / Говнокод #27961

    +3

    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
    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, 21 Января 2022

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

    • Это описание кококой-то грамматики? BNF на опереторах C++
      Ответить
      • Ура! Нидлес вернулся!!1
        Ответить
      • Спирт, вестимо.
        Ответить
        • Не спирт, а дух:)
          Ответить
        • О, хоспаде, кокой кошмар.

          Хорошо, что я не дописал похожую штуку для петона. Сперва я думал, что будет красиво.
          Ответить
      • Насколько мы поняли - Boost::spirit
        Ответить
        • Да так то вполне читаемо... Но сама идея парсить код на 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. Там свой говноформат, очень простой
                            Ответить
                            • > А может, и в ямле можно?

                              С натяжкой, там есть ссылки. И если в твоём формате есть какие-то места, на которые парсеру пофиг, то там можно &складывать блоки и *ссылаться на них из других мест.
                              Ответить
                              • Есть «JSON-лиггетт-дукат» для курильщиков, в котором можно делать ссылки:

                                https://ru.m.wikipedia.org/wiki/JSON-LD
                                Ответить
                                • JSON LSD

                                  Пиздец, какой-то XML с неймспейсами там замутили...
                                  Ответить
                                  • Как я понял, они RDF (который и так непрост) портировали с синтаксиса XML в синтаксис JSON.
                                    Ответить
          • Да, похоже на жс. Только расширен какими-то доплнительными конь-струкциями channel и device_info. Хотя вместо них можно было взять готовый движок и сделать функции.

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

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

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

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