Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

как выполнить строковое логическое выражение?

71K
27 мая 2011 года
Atarion
2 / / 27.05.2011
int d=12 & 15;
прекрастно работает. я получу результат чему равно 12 И 5
Но что если мне неизвестно заранее логическое действие? или выражение конструируется на этапе выполнения?
int d=Convert.ToInt32("12 &15");

вот так выполнить - выдает ошибку! как можно решить эту проблему?
278
27 мая 2011 года
Alexander92
1.1K / / 04.08.2008
Если вы хотите получить аналог eval(), существующий в JS или PHP, то в C / C++ такой встроенной возможности нет. Дописывайте сами парсер строковых логических выражений, по-другому никак.
71K
27 мая 2011 года
Atarion
2 / / 27.05.2011
то есть? что за парсер?
244
27 мая 2011 года
UAS
2.0K / / 19.07.2006
Любой парсер. Если выражение без скобок, то можете конечный автомат построить для разбора выражения, а если будете ещё и группировку скобками делать, то описываете магазинный автомат для данной грамматики.

Запугал, кажись :D Но это единственный разумный подход, если неизвестно кол-во операторов, значений и т.д.
Ну или можно в лоб парсером, если формат выражения один и тот же.
278
27 мая 2011 года
Alexander92
1.1K / / 04.08.2008
Погуглите "C++ eval", много интересного найти можно. :)
297
27 мая 2011 года
koodeer
1.2K / / 02.05.2009
Судя по Convert.ToInt32 - это C#. Вообще, достало, что в этом разделе топикстартеры не указывают используемый язык.

Atarion, какой сложности выражения будут? Для простых легко свой парсер написать, для сложных есть разные подходы.
360
27 мая 2011 года
P*t*
474 / / 15.02.2007
Мне кажется, Atarion-а пугает само слово "парсер". Не лишним будет сказать, что здесь парсер - это часть программы (может быть в виде функции, может быть в виде класса, зависит от реализации), которая будет принимать выражение (в виде строки) и вычислять его значение.
Нужно либо писать свое нечто, либо искать нечто уже существующее и разбираться в нем.
В конечном итоге использование может выглядеть примерно так:
 
Код:
MyParser p = new MyParser();
p.variable("A", 12);
p.variable("B", 15);
int res = p.calculate("A & B");
278
28 мая 2011 года
Alexander92
1.1K / / 04.08.2008
Кажись, мне сегодня вечером было нечего делать... :)

[ATTACH]5167[/ATTACH]

Реализация на C++. Пример использования - в файле main.cpp.

Краткое описание.
Парсер арифметических и битовых выражений со скобками. Поддерживаются следующие операторы:
  • +, -, *, /
  • &, ^, |, ~
  • >>, <<
  • %
Внутреннее представление операнды имеет тип double. При выполнении заведомо целочисленных операций (битовые операции и нахождение остатка от деления) операнды приводятся к типу long.
5
29 мая 2011 года
hardcase
4.5K / / 09.08.2005
Цитата: Alexander92
Кажись, мне сегодня вечером было нечего делать... :)

Адская жесть. И не лень было столько совершенно ненужного кода ваять? Вот реализация на PEG. На комбинаторах было бы еще короче.

278
29 мая 2011 года
Alexander92
1.1K / / 04.08.2008
Красиво, не спорю. Но сомневаюсь, что без наворотов, предлагаемых Nemerle, можно реализовать существенно короче. Не согласны?

P.S. "Ненужный код", по сути, в вашем варианте заключен вот здесь:
Цитата:

Код:
[PegGrammar( Options = EmitDebugSources, start,
grammar
{
  any                   = ['\u0000'..'\uFFFF'];
  s : void              = ' '*;
  num                   : int = ['0'..'9']+ s;
  parenthesesExpr       : int = "("s expr ")"s;
  unaryExpr             : int = (("-" / "+")s)* (num / parenthesesExpr);
  multiplicationExpr    : int = unaryExpr ( ("*" / "/")s unaryExpr)*;
  additionExpr          : int = multiplicationExpr ( ("+" / "-")s multiplicationExpr)*;
  expr                  : int = additionExpr;
  start                 : int = s expr !any;
})]


А по сути ведь все сохранено. Если этот блок расписать, как раз мой вариант и получится.

5
29 мая 2011 года
hardcase
4.5K / / 09.08.2005
Цитата: Alexander92
Красиво, не спорю. Но сомневаюсь, что без наворотов, предлагаемых Nemerle, можно реализовать существенно короче. Не согласны?

А каков смысл отказываться от инструмента, который идеально подходит под задачу? (Для C# я использовал бы Coco/R, в C++ - boost::spirit). Тем более что этот PegGrammar - не магия компилятора, а всего лишь макрос.

Цитата: Alexander92

P.S. "Ненужный код", по сути, в вашем варианте заключен вот здесь:

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

Цитата: Alexander92
А по сути ведь все сохранено. Если этот блок расписать, как раз мой вариант и получится.

Вот только нафига писать руками код который вполне может изготовить машина?

278
29 мая 2011 года
Alexander92
1.1K / / 04.08.2008
Цитата: hardcase
Вот только нафига писать руками код который вполне может изготовить машина?



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

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог