Класс парсера
Предлагаю обсудить класс парсера, размещен на
http://sources.codenet.ru/download.php?id=615&cid=5&o=2&my=0
Парсер рулит!
Порадовало наличие sin, cos, ... etc.
Сам код парсера глобально на выходных рассмотрю.
P.S. Самому парсер нужен был недавно, но я его так и не написал :(
P.S2 при некорректном вводе выражении программа вылетает с фатальной шибкой.
P.S2 при некорректном вводе выражении программа вылетает с фатальной шибкой.
Например какого выражения?
Предлагаю обсудить класс парсера, размещен на
http://sources.codenet.ru/download.php?id=615&cid=5&o=2&my=0
Гмс.... а на основе патерна State Machine слабо ? :)
Гмс.... а на основе патерна State Machine слабо ? :)
Что значит слабо? Я предлагаю решение задачи разбора выражения - реально востребованной задачи... У меня это сделано на основе алгоритма перевода выражения в обратную польскую запись (см. http://algolist.manual.ru/maths/misc/revpn.php). На delphikingdom.ru эта же задача решена на основе рекурсивного алгоритма, разработан аналогичный класс на Object Pascal...
Если у тебя есть решение рассматриваемой задачи на основе конечного автомата - освети этот вопрос, укажи недостатки и преимущества подхода, о котором говоришь. Мне же фраза "паттерн State Machine" ни о чем не говорит.
P.S. Выяснил причину аварийного завершения программы - нужно в classes.h найти директиву компилятора
#define TEST 1 и заменить ее на
#define TEST 0.
(Т.е. отключить тестовый режим, когда в строку фиксированной длины записывается обратная польская запись для выражения).
Если польская запись превосходила длину строки, программа завершалась аварийно.
Что значит слабо? Я предлагаю решение задачи разбора выражения - реально востребованной задачи... У меня это сделано на основе алгоритма перевода выражения в обратную польскую запись (см. http://algolist.manual.ru/maths/misc/revpn.php). На delphikingdom.ru эта же задача решена на основе рекурсивного алгоритма, разработан аналогичный класс на Object Pascal...
Если у тебя есть решение рассматриваемой задачи на основе конечного автомата - освети этот вопрос, укажи недостатки и преимущества подхода, о котором говоришь. Мне же фраза "паттерн State Machine" ни о чем не говорит.
P.S. Выяснил причину аварийного завершения программы - нужно в classes.h найти директиву компилятора
#define TEST 1 и заменить ее на
#define TEST 0.
(Т.е. отключить тестовый режим, когда в строку фиксированной длины записывается обратная польская запись для выражения).
Если польская запись превосходила длину строки, программа завершалась аварийно.
Что значит слабо?
Такс... ставлю точки на I : ничего личного - просто бизнес.
P.S. Слово бизнес в данном выражении не надо понимать буквально.
Я предлагаю решение задачи разбора выражения - реально востребованной задачи...
Какое никакое но все таки решение. Особенно порадовали комментарии типа : "начало огромного switch". Ты б лучше
написал : "просто огромный switch". :D
У меня это сделано на основе алгоритма перевода выражения в обратную польскую запись (см.
http://algolist.manual.ru/maths/misc/revpn.php).
Замечательно конечно... но есть гораздо более простые и эффективные пути .... и строчек кода получится примерно в
5 раз меньше.
На delphikingdom.ru эта же задача решена на основе рекурсивного алгоритма, разработан аналогичный класс на Object
Pascal...
Если у тебя есть решение рассматриваемой задачи на основе конечного автомата - освети этот вопрос, укажи
недостатки и преимущества подхода, о котором говоришь.
Хотел было начать дискуссию.... но решил сразу перейти на ее конец : посвети себе сам на преимущества и недостатки
объектно-ориентрованного подхода... постарайся быть объективным.... и ты увидишь совсем другой мир...
Мне же фраза "паттерн State Machine" ни о чем не говорит.
присоедняю файл..смотри.....
P.S. Выяснил причину аварийного завершения программы - нужно в classes.h найти директиву компилятора
#define TEST 1 и заменить ее на
#define TEST 0.
(Т.е. отключить тестовый режим, когда в строку фиксированной длины записывается обратная польская запись для
выражения).
Если польская запись превосходила длину строки, программа завершалась аварийно.
Вообщем все достаточно банально..... ты просто закодировал ( то есть по сути переписал плохим почерком ) известный
алгоритм.... это называется кодирование..... а ведь есть еще разработка........ если ты САМОСТОЯТЕЛЬНО решишь эту задачу на основе паттерна StateMachine : можешь считать что ты перешел на следуюший уровень.....
Какое никакое но все таки решение. Особенно порадовали комментарии типа : "начало огромного switch". Ты б лучше
написал : "просто огромный switch". :D
Комментарии помогают понять смысл. Какая разница, как они написаны?
Замечательно конечно... но есть гораздо более простые и эффективные пути .... и строчек кода получится примерно в
5 раз меньше.
Искал - но не нашел. Нашел лишь относительно компактные программы, у которых нет таких возможностей, использовать их в сторонних разработках без адаптации трудно. Здесь же класс, вызываешь конструктор - и у тебя уже есть польская запись ("байт-код"), задаешь значения переменных, вызываешь Get() - и получи ответ. При желании можно даже свои функции подключить...
Хотел было начать дискуссию.... но решил сразу перейти на ее конец : посвети себе сам на преимущества и недостатки
объектно-ориентрованного подхода... постарайся быть объективным.... и ты увидишь совсем другой мир...
Это очень большая тема
присоедняю файл..смотри.....
Это не ты один из авторов статьи?
Вообщем все достаточно банально..... ты просто закодировал ( то есть по сути переписал плохим почерком ) известный
алгоритм.... это называется кодирование..... а ведь есть еще разработка........ если ты САМОСТОЯТЕЛЬНО решишь эту задачу на основе паттерна StateMachine : можешь считать что ты перешел на следуюший уровень.....
Разработка и кодирование взаимодополняют друг друга. Когда есть реально востребованная разработка, в которой нужно использовать тот же парсер, достаточно просто сложить программу из кубиков, в которых это уже реализовано... Так делает каждый программист...
Да, я переделал этот алгоритм (есть его аналог на delphikingdom.ru на Delphi), но как раз его ядро - которое формирует польскую запись, принципиально отличается от того, что было сделано в проекте на "Королевстве". Ядро реализует другой подход, нерекурсивный. И наверняка работает быстрее... Хотя это возможно не так важно.
где ваша программа в несколько тысяч строк? Покажите - может быть тогда поверю, что у меня плохой почерк.
где ваша программа в несколько тысяч строк?
Гмс.... несколько лет назад я написал граф.станцию контроля воздушного пространтсва( про которую от отдного подполковника услышал много всеьма лестных для меня отзывов )....там было около 15 тысячи строк.....показать не могу......пришлось стереть свою домашнюю копию под нажимом ..... ну вообщем ты понял :D :D :D....
В общем, пишите если нужна исправленная версия.
В общем, пишите если нужна исправленная версия.
Будет очень здорово если Вы сделаете ее ввиде DLL, которая будет експортировать одну функцию
типа double Calc(LPSTR str, int* ErrCode);
str - собственно мат.строка
ErrCode - код ошибки (неверная строка, деление на ноль...)
Будет очень здорово если Вы сделаете ее ввиде DLL, которая будет експортировать одну функцию
типа double Calc(LPSTR str, int* ErrCode);
str - собственно мат.строка
ErrCode - код ошибки (неверная строка, деление на ноль...)
Это нереально... Во первых, в dll можно помещать лишь методы класса, а это не очень удобно для использования. Во-вторых, как задавать значения параметров арифмет.выражения, как добавлять функции пользователя? Эти методы будут недоступны. В-третьих, в случае ошибки исключ. ситуации уже не обработать, для этого придется анализировать код возврата и т.д., тогда как в классе парсера исключение генерируется им самим, программе нужно только его отловить в блоке try-catch и вывести на экран . Это лежит в русле Объектно-Ориентир. Программир (ООП).
Мне кажется, что класс парсера в том виде какой он есть, достаточно просто подключить и использовать в своих программах.
В DLL-библиотеки, как мне кажется, стоит помещать группу сложных и связанных тематически функций, в которые достаточно передать параметры и получить код возврата. Например, функции прогноза временных рядов по различным методам - гармонических весов, экспоненциального сглаживания, скользящего среднего, модели авторегрессии, Бокса-Дженкинса,
Это очень большая тема, с достаточно сложными алгоритмами. Здесь применение DLL оправдано, поскольку для каждого метода и модели есть набор своих параметров, алгоритмы гораздо сложнее (по сравнению с парсером) и могут быть собраны в одном месте.
Спасибо за исчерпывающий ответ.
Согласен.
Спасибо за исчерпывающий ответ.
Если кто-то увлекается прогнозированием, моделированием времен. рядов, предлагаю сотрудничать. Я реализовал часть методов и моделей, их можно собрать в DLL.
Поэтому для компиляции проекта в среде Visual Studio необходимо указать в свойствах проекта использование библиотеки MFC. Предварительно она должна быть установлена.
Делаем так. Выбираем Project->Settings->(вкладка General). Из списка "Microsoft Foundation Classes" выбираем "Use MFC in a Static Library" или "Use MFC in a Shared DLL". В зависимости от того, какие компоненты MFC-библиотеки установлены.
После этого проект должен работать.
По поводу использования класса могу сказать следующее: вот пример кода для вычисления выражения.
Пусть в char *formula помещена формула в виде строки.
try
{
CExpr2Parser *ep=new CExpr2Parser;
ep->Translate(formula);// создание т.н. "байт-кода"
for (i=0;i<ep->GetVarCount();i++)
{
// с помощью ep->GetName(i) можно получить имя переменной
ep->SetVars(i,2); // устанавливаем i-тую переменнуую равную 2
}
double d=ep->Get(); // в d - результат вычисления выражения
delete ep;
}
catch (CException *e)
{
// сообщить об ошибке, если она возникла
e->ReportError(MB_OK,0);
e->Delete();
}