Мне нужен быстрый синтаксический анализатор времени выполнения
Мне нужно найти быстрый, легкий анализатор выражений.
В идеале я хочу передать ему список пар имя/значение (например, переменные) и строку, содержащую выражение для оценки. Все, что мне нужно, это значение true/false.
Типы выражений должны быть в строках:
varA == "xyz" and varB==123
В принципе, просто простой логический движок, выражение которого предоставляется во время выполнения.
UPDATE
Как минимум, он должен поддерживать ==,! =, > , > =, <, < =
Что касается скорости, я ожидаю, что по запросу будет выполнено примерно 5 выражений. Мы увидим где-то около 100/запросов в секунду. Наши текущие страницы имеют тенденцию к выполнению менее 50 мс. Обычно в любом выражении участвуют только 2 или 3 переменных. Тем не менее, мне нужно загрузить примерно 30 в парсер до выполнения.
ОБНОВЛЕНИЕ 2012/11/5
Обновление производительности. Мы реализовали nCalc почти 2 года назад. С тех пор мы расширили его использование, так что мы усредняем 40+ выражений, содержащих более 300 переменных на пост-спине. В настоящее время тысячи обратных сообщений, возникающих в секунду, имеют абсолютно нулевое снижение производительности.
Мы также расширили его, включив в него несколько дополнительных функций, опять же без потери производительности. Короче говоря, nCalc отвечал всем нашим потребностям и превзошел наши ожидания.
Ответы
Ответ 1
Вы видели https://ncalc.codeplex.com/ и https://github.com/sheetsync/NCalc?
Он расширяемый, быстрый (например, имеет собственный кеш) позволяет вам предоставлять пользовательские функции и переменные во время выполнения, обрабатывая события EvaluateFunction/EvaluateParameter. Примеры выражений, которые он может анализировать:
Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameters["Pi2"] = new Expression("Pi * Pi");
e.Parameters["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
Debug.Assert(117.07 == e.Evaluate());
Он также обрабатывает unicode и многие типы данных изначально. Он поставляется с файлом antler, если вы хотите изменить грамматик. Существует также вилка, которая поддерживает MEF для загрузки новых функций.
Он также поддерживает логические операторы, строки даты/времени и операторы if.
Ответ 2
Как насчет Быстрая легкая оценка выражений? Он позволяет устанавливать переменные и поддерживает логические операторы.
Если вам нужно что-то более сильное и у вас есть время, вы также можете создать свой собственный язык выражений с помощью Irony.
Ответ 3
Интерпретатор Hisystems поддерживает пользовательские функции, операторы и литералы, представляет собой легкий чистый С# портативный код. В настоящее время он работает на iOS через MonoTouch и должен работать в любой другой среде Mono, а также в окнах. Бесплатно для коммерческого использования. Доступно на GitHub в https://github.com/hisystems/Interpreter.
Ответ 4
Я полностью понимаю, как поздно этот ответ, однако, я хотел бы бросить свое решение, потому что я считаю, что он может добавить больше, чем принятый ответ на использование NCalc, если кто-то хочет использовать выражения на нескольких платформах.
Я создал парсер для С# с планами также реализовать его для Java и Swift в течение следующих нескольких месяцев. Это означало бы, что вы можете оценивать выражения на нескольких платформах без необходимости настройки на платформу.
Выразительный инструмент, и он доступен по адресу:
GitHub или Nuget.
На сайте имеется достаточное количество документации, но для предотвращения гниения ссылки здесь приведен пример того, как его использовать:
Поддержка переменных
var expression = new Expression("1 * [variable]");
var result = expression.Evaluate(new Dictionary<string, object> { ["variable"] = 2);
Функции
var expression = new Expression("sum(1,2,3,4)");
var result = expression.Evaluate();
Он был разработан так, чтобы соответствовать NCalc как можно лучше, но он добавил поддержку таких вещей, как ключевое слово "null".
Ответ 5
самооценка здесь
Я написал генератор генератора парсеров для С# https://github.com/b3b00/csly
вы можете найти пример parseras выражения на моем github. вам может потребоваться настроить его в соответствии с вашими потребностями.