2009-01-28 15 views
8

Tengo varias funciones en mi programa que se ven así:Haciendo un C++ aplicación de secuencias de comandos

void foo(int x, int y) 

Ahora quiero mi programa para tomar una cadena que parece:

foo(3, 5) 

y ejecutar las función correspondiente. ¿Cuál es la forma más directa de implementar esto?

Cuando digo directo, me refiero razonablemente extensible y elegante, pero no debería tomar demasiado tiempo para codificar.

Editar:

Durante el uso de un lenguaje de programación real sería, por supuesto, resolver mi problema, todavía me gustaría saber si hay una forma rápida de implementar esto en C++ puro.

Respuesta

5

también me gustaría ir por la respuesta lenguaje de script.

Usando C++ puro, probablemente usaría un generador de analizador sintáctico, que obtendrá las reglas de token y gramática, y me dará un código C que puede analizar exactamente el lenguaje de llamadas de función dado, y me proporciona un árbol de sintaxis esa llamada. flex se puede utilizar para tokenizar una entrada, y bison se puede utilizar para analizar los tokens y transformarlos en un árbol de sintaxis.Alternativamente a ese enfoque, Boost Spirit se puede utilizar para analizar el lenguaje de llamadas de función también. Nunca he usado ninguna de estas herramientas, pero he trabajado en programas que las usan, por lo que sé algo de lo que usaría en caso de que tuviera que resolver ese problema.

En casos muy simples, usted podría cambiar su sintaxis para esto:

func_name arg1, arg2 

continuación, puede utilizar:

std::istringstream str(line); 
std::string fun_name; str >> fun_name; 
map[fun_name](tokenize_args(str)); 

El mapa habría una

std::map<std::string, boost::function<void(std::vector<std::string>)> > map; 

lo cual llenarse con las funciones al comienzo de su programa. tokenize_args simplemente separaría los argumentos y devolvería un vector de ellos como cadenas. Por supuesto, esto es muy primitivo, pero creo que es razonable si lo único que quieres es una forma de llamar a una función (por supuesto, si realmente quieres soporte de script, este enfoque no será suficiente).

+0

Me gustaría ir a boost :: spirit, ya que aprenderá mucho sobre los analizadores sintácticos y sobre la metaprogramación de plantillas. – lothar

8

Puedes echar un vistazo al Lua.

+0

mira Lua - ¿para hacer QUÉ ??? Esa página es inútil para describir cómo insertar el idioma. Incluso la página 3 del manual (http://www.lua.org/manual/5.1/manual.html#3) está más cerca pero no ayuda al OP. – jim

+0

"Usar lua" se está convirtiendo en una reacción instintiva a preguntas similares. – artificialidiot

10

Puede incrustar Python de manera bastante simple, y eso le daría una forma realmente poderosa y extensible para crear un script de su programa. Se puede utilizar el siguiente para facilidad (más o menos) exponga el código C++ para Python:

Yo personalmente uso Boost Python y estoy contento con él, pero es lento de compilar y puede ser difícil de depurar.

+1

SWIG es muy bueno y muy flexible. – vrdhn

3

Como Daniel dijo:

lenguajes de script como Lua y Python serían los lenguajes de script más utilizados para la unión de juntas bibliotecas de C++.

Tendrá que agregar una interfaz de script a su aplicación de C++. La creación de esta interfaz obviamente depende del lenguaje de script que elija.

1

Si solo desea llamar a una función por nombre literal, puede usar las funciones específicas del vinculador.

En sistemas operativos que cumplen con POSIX (como Linux), puede usar dlopen() y dlsym(). Simplemente analiza la cadena de entrada y calcula el nombre y los argumentos de la función. Luego puede pedirle al vinculador que encuentre la función por nombre usando dlsym().

En Windows, sin embargo, estas funciones no están disponibles (a menos que exista algo de entorno POSIX, como Cygwin). Pero puedes usar la API de Windows.

Usted puede echar un vistazo aquí para más detalles sobre estas cosas: http://en.wikipedia.org/wiki/Dynamic_loading

0

¿Su sistema tiene que "tomar una cadena"? Puede exponer interfaces COM (o CORBA, o lo que sea) en su aplicación y hacer que lo que esté generando estos comandos llame a su aplicación directamente.

1

C++ Reflection [2] de Fabio Lombardelli proporciona una reflexión completa para C++ a través de técnicas de metaprogramación de plantillas. Si bien es totalmente compatible con los estándares de C++, se requiere que el programador para anotar las clases con el fin forthem a ser el reflejo

http://cppreflect.sourceforge.net/

de lo contrario te gustaría una tabla de funciones puntero de codificación creo

2

CERN proporciona CINT, un intérprete de C/C++ que se puede incrustar en la aplicación para proporcionar funciones de creación de scripts.

Cuestiones relacionadas