Есть ли способ преобразования строки в чистый код в C ++? - PullRequest
11 голосов
/ 05 мая 2009

Я знаю, что можно читать из файла .txt, а затем преобразовывать различные его части в строковые, char и int значения, но возможно ли взять строку и использовать ее в качестве реального кода в программе?


Код:

string codeblock1="cout<<This is a test;";
string codeblock2="int array[5]={0,6,6,3,5};}";
int i;
cin>>i;
if(i)
{
execute(codeblock1);
}
else
{
execute(codeblock2);
}

Где execute - это функция, которая преобразует текст в реальный код (я не знаю, существует ли на самом деле функция с именем execute, я использую ее для целей моего примера).

Ответы [ 9 ]

8 голосов
/ 05 мая 2009

В C ++ нет простого способа сделать это. Эта функция доступна на языках более высокого уровня, таких как Python, Lisp, Ruby и Perl (обычно с некоторыми вариациями функции eval). Однако даже в этих языках эта практика не одобряется, поскольку она может привести к очень нечитаемому коду.

Важно, чтобы вы спросили себя (и, возможно, ответили нам), почему вы хотите это сделать?

Или вы хотите знать только, возможно ли это? Если это так, то хоть и волосатым способом. Вы можете написать исходный файл C ++ (сгенерировать в нем все, что вы хотите, если это действительно C ++), затем скомпилировать его и связать с вашим кодом. Конечно, все это можно делать автоматически, если компилятор доступен вам во время выполнения (а вы просто запускаете его с system). Я знаю человека, который однажды сделал это для какой-то тяжелой оптимизации. Это не красиво, но можно заставить работать.

3 голосов
/ 05 мая 2009

Многие языки сценариев предлагают такую ​​функцию, вплоть до eval в LISP - но C и C ++ не предоставляют компилятор во время выполнения.

В спецификации нет ничего, что мешало бы вам создавать и исполнять произвольный машинный язык, например:

char code[] = { 0x2f, 0x3c, 0x17, 0x43 }; // some machine code of some sort
typedef void (FuncType*)();               // define a function pointer type
FuncType func = (FuncType)code;           // take the address of the code
func();                                   // and jump to it!

но из-за соображений безопасности в большинстве сред происходит сбой, если вы попытаетесь это сделать. (Многие вирусы работают, убеждая обычные программы сделать что-то подобное.)

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

Если вы хотите запустить код в своем собственном пространстве памяти, вы можете вызвать компилятор для создания библиотеки DLL (или .so, в зависимости от вашей платформы), а затем связать ее с DLL и перейти в нее.

3 голосов
/ 05 мая 2009

Вы можете создать функцию, анализировать любые строки и создавать из них структуру данных. Это известно как дерево разбора. Впоследствии вы можете проверить свое дерево разбора и сгенерировать необходимые динамические структуры для выполнения логической задачи. Дерево разбора впоследствии преобразуется в исполняемое представление во время выполнения.

Все компиляторы делают именно это. Они берут ваш код и производят машинный код на основе этого. В вашем конкретном случае вы хотите, чтобы язык писал код для себя. Обычно это делается в контексте генератора кода и является частью более крупного процесса сборки. Если вы напишете программу для анализа вашего языка (для этой операции используйте гибкость и бизон), которая генерирует код, вы можете достичь желаемых результатов.

1 голос
/ 05 мая 2009

Во-первых, я хотел сказать, что я никогда сам не реализовывал что-то подобное, и я могу быть далеко, однако вы пробовали класс CodeDomProvider в System.CodeDom.Compiler пространстве имен? Я чувствую, что классы в System.CodeDom могут предоставить вам ту функциональность, которую вы ищете.

Конечно, это будет код .NET, а не любая другая платформа

Go здесь для образца

0 голосов
/ 01 июня 2009

Не легко, потому что C ++ - это скомпилированный язык. Несколько человек указали несколько способов заставить его работать - либо запустить компилятор, либо включить компилятор или интерпретатор в вашу программу. Если вы хотите пойти по пути переводчика, вы можете сэкономить много работы, используя существующий проект с открытым исходным кодом, такой как Lua

0 голосов
/ 05 мая 2009

Похоже, вы пытаетесь создать «C ++ Script», которого, насколько я знаю, не существует. C ++ - это скомпилированный язык . Это означает, что он всегда должен быть скомпилирован в собственный байт-код перед выполнением. Вы можете обернуть код как функцию, запустить его через компилятор, а затем динамически выполнить полученную DLL, но вы не получите доступа к чему-либо, что скомпилированная DLL обычно не получит.

Вам лучше попытаться сделать это в Java, JavaScript, VBScript или .NET, которые на той или иной стадии являются интерпретируемыми языками . Большинство этих языков либо имеют функцию eval или execute только для этого, либо могут быть просто include d в виде текста.

Конечно, выполнение блоков кода не самая безопасная идея - это сделает вас уязвимым для всех видов атак на выполнение данных.

Я бы порекомендовал создать язык сценариев, который соответствует целям вашего приложения. Это дало бы пользователю ограниченный набор инструкций по соображениям безопасности и позволило бы вам взаимодействовать с существующей программой гораздо более динамично, чем скомпилированный внешний блок.

0 голосов
/ 05 мая 2009

Один из способов сделать это - Boost Python . Вы не будете использовать C ++ в этот момент, но это хороший способ позволить пользователю использовать язык сценариев для взаимодействия с существующей программой. Я знаю, что это не совсем то, что вы хотите, но, возможно, это может помочь.

0 голосов
/ 05 мая 2009

Это вроде как возможно, но не с простым C / C ++. Вам понадобится слой под ним, такой как LLVM.

Выезд c-repl и ccons

0 голосов
/ 05 мая 2009

Да, вам просто нужно собрать компилятор (и, возможно, компоновщик), и вы там.

Несколько языков, таких как Python, могут быть встроены в C / C ++, так что это может быть вариантом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...