Скомпилировать простую строку - PullRequest
8 голосов
/ 01 сентября 2009

Было просто интересно, есть ли в c ++ ИЛИ c # встроенные функции, позволяющие использовать компилятор во время выполнения? Как например, если я хочу перевести:

!print "hello world";

в

MessageBox.Show("hello world");

, а затем сгенерировать исполняемый файл, который затем сможет отобразить вышеуказанное сообщение? Несколько лет назад я видел пример проекта в Интернете, который сделал это, но больше не может его найти.

Ответы [ 6 ]

15 голосов
/ 01 сентября 2009

Это возможно с помощью C #. Взгляните на этот Пример проекта из CodeProject.

Извлечение кода

private Assembly BuildAssembly(string code)
{
    Microsoft.CSharp.CSharpCodeProvider provider = new CSharpCodeProvider();
    ICodeCompiler compiler = provider.CreateCompiler();
    CompilerParameters compilerparams = new CompilerParameters();
    compilerparams.GenerateExecutable = false;
    compilerparams.GenerateInMemory = true;
    CompilerResults results = compiler.CompileAssemblyFromSource(compilerparams, code);
    if (results.Errors.HasErrors)
    {
       StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
       foreach (CompilerError error in results.Errors )
       {
            errors.AppendFormat("Line {0},{1}\t: {2}\n", error.Line, error.Column, error.ErrorText);
       }
       throw new Exception(errors.ToString());
    }
    else
    {
        return results.CompiledAssembly;
    }
}

public object ExecuteCode(string code, string namespacename, string classname, string functionname, bool isstatic, params object[] args)
{
    object returnval = null;
    Assembly asm = BuildAssembly(code);
    object instance = null;
    Type type = null;
    if (isstatic)
    {
        type = asm.GetType(namespacename + "." + classname);
    }
    else
    {
        instance = asm.CreateInstance(namespacename + "." + classname);
        type = instance.GetType();
    }
    MethodInfo method = type.GetMethod(functionname);
    returnval = method.Invoke(instance, args);
    return returnval;
}
5 голосов
/ 01 сентября 2009

В C ++ вы не можете использовать компилятор во время выполнения, но вы можете встроить интерпретатор в ваш проект, например CINT.

3 голосов
/ 01 сентября 2009

Вы всегда можете сделать это грязным способом, с помощью system () и вызова компилятора "gcc ..." или вашего аналога

1 голос
/ 01 сентября 2009

В C # вы можете создать дерево .NET "CodeDom", а затем скомпилировать его с помощью компилятора .NET. Это дает вам полный доступ к большинству функций .NET.

Подробнее см. В пространстве имен System.CodeDom или в справке MSDN для CodeCompileUnit .

1 голос
/ 01 сентября 2009

.NET-framework предоставляет несколько классов, которые дают вам доступ к компиляторам и генераторам кода для C # и VB.NET, в результате чего либо сборка загружается в память, либо простой .exe-файл. См. CSharpCodeProvider и в этой статье .

Кроме того, вы можете просто создать исходные файлы и скомпилировать их вручную (вызовы командной строки (system) для компилятора, make-файлы).

Что касается перевода вашего источника: вам придется использовать механизмы синтаксического анализа, такие как регулярные выражения, здесь, или использовать инструмент компилятора-компилятора, такой как Coco / R, yacc и т. Д. (Обратите внимание, что в C ++ boost::spirit также весьма полезно)

1 голос
/ 01 сентября 2009

Предложение Ника хорошее, но есть альтернатива, которая, возможно, проще реализовать (но может не подходить для всех проектов). Если вы можете предположить, что у вашего пользователя установлен компилятор, вы можете сгенерировать файл и затем скомпилировать его, используя свой компилятор.

...