За weekend на хабре появились три статьи по разбору математических выражений: Компилятор выражений, Парсер математических выражений и Вычисление значения выражения и один комментарий, в котором код на прологе по краткости и выразительности рвет примеры в этих статьях.
Ниже я покажу, как использовать стандартные средства платформы и языка для достижения того же результата, а именно вычислению выражений.
На конференции PDC2008 Anders Hejlsberg сделал доклад, в котором проследил эволюцию языка C#. Он рассмотрел уже существующие версии и сделал обзор будущих: в 4ой версии разработчиков ждет возможность разбавить строгую систему типов возможностями из динамических языков, а к пятой версии компилятор будет полностью переписан под управляемый код, и его можно будет использовать как сервис (compiler as a service).
Для тех программистов, которые мечтают опробовать эту идеологию (compiler as a service) уже сейчас, будет приятной новостью то, что они могут это сделать. Дело в том, что компилятор nemerle написан на nemerle, и его можно использовать как простую библиотеку. Стоит так же отметить то, что в этом случае в процессе его работы не будет создано на диске никаких файлов, только если Вы не хотите обратного. Ниже — пример кода, который использует компилятор как библиотеку и который эффективно решает проблему разбора/вычислений выражений=)
Думаю, что любому программисту, владеющим C# этот код понятен, отдельно отмечу только, что module — синоним static class, double->double — тип функции, аналог Func<double,double>, а using System.Console раскрывает System.Console так, что его статические методы «превращаются» в глобальные функции/процедуры, то есть вызов WriteLine(function(2.0)) это на самом деле вызов Console.WriteLine(function(2.0)).
Другой возможностью попробовать будущее на вкус является платформа mono. Я долго ждал выхода версии 2.2 и удивлен, что на хабре про её выход еще никто не написал. Мои ожидания были основаны на заметке, которую Miguel De Icaza опубликовал в своем блоге в сентябре, в нем он анонсировал, что в следующей версии mono (теперь она уже текущая) добавиться REPL, который в свою очередь основан на идеологии compiler as service. Ниже — код на C# под mono, аналогичный коду на Nemerle:
P.S.
Отдельно хочется отметить, то что и Nemerle, и Mono являются open source проектами. Эту особенность я использовал при создании этой заметки, а именно, исчерпывающей документации по использования compile as a service в Nemerle и Mono я не нашел, но зато быстро смог найти всю интересующую меня информацию, изучая исходные коды.
Ниже я покажу, как использовать стандартные средства платформы и языка для достижения того же результата, а именно вычислению выражений.
На конференции PDC2008 Anders Hejlsberg сделал доклад, в котором проследил эволюцию языка C#. Он рассмотрел уже существующие версии и сделал обзор будущих: в 4ой версии разработчиков ждет возможность разбавить строгую систему типов возможностями из динамических языков, а к пятой версии компилятор будет полностью переписан под управляемый код, и его можно будет использовать как сервис (compiler as a service).
Для тех программистов, которые мечтают опробовать эту идеологию (compiler as a service) уже сейчас, будет приятной новостью то, что они могут это сделать. Дело в том, что компилятор nemerle написан на nemerle, и его можно использовать как простую библиотеку. Стоит так же отметить то, что в этом случае в процессе его работы не будет создано на диске никаких файлов, только если Вы не хотите обратного. Ниже — пример кода, который использует компилятор как библиотеку и который эффективно решает проблему разбора/вычислений выражений=)
using System;
using System.Console;
using Nemerle.Evaluation.Evaluator;
module Program
{
Main() : void
{
def function = EvaluateExpression("x => x + 1.0") :> double->double;
WriteLine(function(2.0));
}
}
Думаю, что любому программисту, владеющим C# этот код понятен, отдельно отмечу только, что module — синоним static class, double->double — тип функции, аналог Func<double,double>, а using System.Console раскрывает System.Console так, что его статические методы «превращаются» в глобальные функции/процедуры, то есть вызов WriteLine(function(2.0)) это на самом деле вызов Console.WriteLine(function(2.0)).
Другой возможностью попробовать будущее на вкус является платформа mono. Я долго ждал выхода версии 2.2 и удивлен, что на хабре про её выход еще никто не написал. Мои ожидания были основаны на заметке, которую Miguel De Icaza опубликовал в своем блоге в сентябре, в нем он анонсировал, что в следующей версии mono (теперь она уже текущая) добавиться REPL, который в свою очередь основан на идеологии compiler as service. Ниже — код на C# под mono, аналогичный коду на Nemerle:
using System;
using Mono.CSharp;
public class Program
{
public static void Main(string[] args)
{
var function =
Evaluator.Evaluate ("new System.Converter<double,double>(x=>x+1.0);")
as Converter<double,double>;
Console.WriteLine(function(2.0));
}
}
P.S.
Отдельно хочется отметить, то что и Nemerle, и Mono являются open source проектами. Эту особенность я использовал при создании этой заметки, а именно, исчерпывающей документации по использования compile as a service в Nemerle и Mono я не нашел, но зато быстро смог найти всю интересующую меня информацию, изучая исходные коды.