На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Закрыто archimed7592 11-03-2008: Лимит страниц. Продолжаем Delphi vs C++

Страницы: (117) « Первая ... 56 57 [58] 59 60 ...  116 117  ( Перейти к последнему сообщению )  
> Delphi vs C++ , Часть 1
    Цитата daevaorn @
    а как же!

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

      недавно писал парсер для сложных вормул. код показать не могу ибо комерческий. Но именно там реализация самого парсера связана только с реализацией скоббок и простых операций типа +,-,/,* а функции реализовывались вообще отдельно и добавление их к персеру выглядит как ..
      CRSFormulaParser<CComVariant>::CreateCustomLexem<CRSCustomSUMLexem> ("SUM");

      как видиш код парсера собсто не трогается для добавления новой функции.
        Опять не то.

        Мне нужен был чисто синтаксический анализатор из арифметического парсера! Могу даже сказать зачем: для анализа пользовательских функций, чтобы на этапе загрузки проверять их корректность. Так вот, как мне это реализовать, не переписывая полностью парсер (как он реализован я писал) и не создавая новых функций?
          Smike, но ты ведь не написал, как конкретно ты его реализовавал.. Если, к примеру, отображать формулу в стек, используя инверсную польскую запись, то все ошибки выявятся ещо на этапе формирования стека. Никаких отдельных проверок просто не нужно.
            Никаких стеков нет, выражение вычисляется на этапе анализа.
              Цитата Smike @
              Никаких стеков нет, выражение вычисляется на этапе анализа.

              Ну опятьже если вщять мой пример.. то непосредственное хранение значений и различные операции непосредственно со значениями делает первый шаблонный параметр.. CRSFormulaParser<CComVariant>
              фактически чтобы значения не вычислялись, а только лиш анализировался код мне нужно написать класс
              CMnePofigChtoSoMnoiDelayut которые ничего не делает с пустыми операторами и использовать CRSFormulaParser<CMnePofigChtoSoMnoiDelayut>
                Цитата Smike @
                Мне нужен был чисто синтаксический анализатор из арифметического парсера! Могу даже сказать зачем: для анализа пользовательских функций, чтобы на этапе загрузки проверять их корректность. Так вот, как мне это реализовать, не переписывая полностью парсер (как он реализован я писал) и не создавая новых функций?

                Да, в принципе, не сложно. Парсер разделяется на два класса - собственно парсер выражений, и класс-вычислитель. Второй передается первому в качестве шаблонного параметра. И все это выглядит примерно так:
                ExpandedWrap disabled
                  class TagPlus {;}
                  class TagMinus {;}
                  class TagMul {;}
                  class TagDiv {;}
                  class TagNegate {;}
                  class TagSin {;}
                  class TagCos {;}
                  class TagLg {;}
                  class TagLn {;}
                   
                  class Evaluator
                  {
                  public:
                     static template<typename Tag> T1 EvalUnary(const Tag& t, double arg);
                     static template<typename Tag> T1 EvalBinary(const Tag& t, double arg1, double arg2);
                   
                  };
                   
                  class DummyEvaluator
                  {
                  public:
                     static template<typename Tag> T1 EvalUnary(const Tag& t, double arg) {return 0;}
                     static template<typename Tag> T1 EvalBinary(const Tag& t, double arg1, double arg2) {return 0;}
                   
                  };
                   
                  double Evaluator::EvalUnary(const TagNegate&, double arg) {return - arg;}
                  double Evaluator::EvalUnary(const TagSin&, double arg) {return sin(arg);}
                  // ...
                  double Evaluator::EvalBinary(const TagPlus&, double arg1, double arg2) {return arg1 + arg2;}
                  double Evaluator::EvalBinary(const TagMinus&, double arg1, double arg2) {return arg1 - arg2;}
                   
                   
                  template<class Eval> class Parser
                  {
                  public:
                     double ParseExpression( ... )
                     {
                        //...
                        case '+':
                            result = Eval::EvalBinary(TagPlus(), arg1, arg2);
                            break;
                        case '-':
                            result = Eval::EvalBinary(TagMinus(), arg1, arg2);
                            break;
                     };
                  };
                   
                  //...
                  // Синтаксический анализ
                  try
                  {
                     Parser<DummyEvaluator> p("1 + 2");
                     p.ParseExpression();
                  }
                  //...
                  // Вычисление
                  try
                  {
                     Parser<Evaluator> p("1 + 2");
                     std::cout << p.ParseExpression();
                  }
                  Flex Ferrum
                  :P мои мысли читаеш однако :D
                    Цитата Flex Ferrum @

                    Да, в принципе, не сложно. Парсер разделяется на два класса - собственно парсер выражений, и класс-вычислитель. Второй передается первому в качестве шаблонного параметра. И все это выглядит примерно так:

                    Это вполне реальный вариант, в том числе и на Дельфи, но он требует написания дополнительного кода и заглушек. А вот такого элегантного решения в C++, как я сделал в Delphi, пока не видно.
                      Для расширения функционала парсера тебе здесь нужно всего лишь:
                      1. Добавить новый тег, который должен вычисляться (например, TagASin)
                      2. Добавить в парсер распознаватель соответствующего выражения.
                      3. Реализовать метод
                      ExpandedWrap disabled
                        double Evaluator::EvalUnary(const TagASin&, double arg) {return asin(arg);}
                        Цитата Smike @
                        А вот такого элегантного решения в C++, как я сделал в Delphi, пока не видно.

                        Элегантность твоего решения я не понял ибо делфи не знаю, но чем тебе плюсовый вариант не понравился тоже мне не ясно. Какой еще код заглушки. Просто пустой класс - это не код :P
                          Цитата Smike @
                          А вот такого элегантного решения в C++, как я сделал в Delphi, пока не видно.

                          Гы гы гы... :) А вот что ты будешь делать, если тебе потребуется изменить логику собственно вычисления? Например, логировать вычисляемые операции. Тоже, собственно, в зависимости от условий? :)
                            Цитата Smike @
                            А вот такого элегантного решения в C++, как я сделал в Delphi, пока не видно.

                            :lol: :lol: :lol:
                              Цитата Smike @
                              А вот такого элегантного решения в C++, как я сделал в Delphi, пока не видно.

                              Осталось определиться с мерилом элегантности... :)
                                Цитата Smike @
                                Мне нужен был чисто синтаксический анализатор из арифметического парсера!

                                Смайк, какая разница? :blink:
                                Разбор либо заканчивается ошибкой в выражении, либо удачен, а вычисление выражения должно идти отдельным этапом.

                                Цитата Smike @
                                А вот такого элегантного решения в C++, как я сделал в Delphi, пока не видно.

                                Ты смеёшься? В чём элегантность? Макросы(и вообще препроцессор) - это элегантность? 0_о
                                #if, #else, #ifdef, #ifndef, #endif, #define, #undef, #include тебе в помощь...
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (117) « Первая ... 56 57 [58] 59 60 ...  116 117
                                Закрыто archimed7592 11-03-2008: Лимит страниц. Продолжаем Delphi vs C++



                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0767 ]   [ 15 queries used ]   [ Generated: 9.08.25, 23:15 GMT ]