Traducir el código fuente a un idioma extranjero

Tengo un sitio web educativo que enseña programación a niños (de 12 a 15 años).

Como no todos hablan inglés en el código fuente de las soluciones, usamos nombres de funciones y variables en francés. Sin embargo, estamos planeando traducir el contenido a otros idiomas (alemán, español, inglés). Para hacerlo, me gustaría traducir el código fuente lo más rápido posible. En su mayoría tenemos código C / C ++.

La solución que planeo usar:

  1. extraer todos los nombres de variables / funciones del código fuente, con su posición en el archivo (donde se declaran, se usan, se llaman ...)
  2. eliminar todas las palabras clave del idioma y las funciones de la biblioteca
  3. pedirle al traductor que proporcione traducciones para los nombres restantes
  4. reemplazar los nombres en el archivo

¿Existe ya algún código / proyecto de fuente abierta que pueda hacer eso? (Para los puntos 1,2, 4 y XNUMX)

Si no lo hay, el punto más difícil en el primero: usar un analizador C / C ++ para construir un árbol sintáctico y luego extraer las variables con su posición parece el camino a seguir. ¿Tienes otras ideas?

Gracias por cualquier consejo.

Editar: Como se señaló en un comentario, también tendré que ocuparme de los comentarios, pero solo hay algunos de ellos: la solución completa ya se explica en texto plano y luego mostramos el código fuente con la variable / función autoexplicable nombres. El código fuente rara vez tiene más de 30/40 líneas y los buenos nombres deben hacerlo comprensible sin comentarios si ya sabe lo que hace el código.

Información adicional : para las personas interesadas, el sitio web es una plataforma de formación para las Olimpíadas Internacionales de Informática y C / C ++ (al menos el mínimo necesario para el concurso de programación) no es tan difícil de aprender para un niño de 12 años.

preguntado el 27 de agosto de 11 a las 15:08

Intente poner el código directamente en el traductor de Google. Hace un buen trabajo traduciendo solo palabras. Las cosas que hace que se traduzcan "accidentalmente" podrían resolverse ejecutando el código a través de algo que los reemplace con sustitutos conocidos. -

Algunos cuestionarían la decisión de usar C / C ++ para enseñar a niños de esa edad, pero escribí C cuando tenía 15 años y no sufrí ningún daño, hasta donde yo sé. (Escribir Pascal a una edad más temprana me perjudicó más, porque no tenía ninguna guía de pronunciación para las muchas palabras clave allí. Me tomó años dejar de pronunciar "comenzar" como si fuera el primer ministro israelí). -

No creo que sea una buena idea. Una palabra extranjera correcta es mejor que una palabra nativa incorrecta. El traductor tendrá 0 contexto para seguir al traducir. Muchas palabras tienen homónimos, ¿cómo se resolvería eso? No traduciría la fuente, la dejaría como está. Además, los niños de 12 a 15 años ya están aprendiendo inglés en la escuela. -

@Karl Knechtel: Usé C / C ++ aquí como atajo. En la práctica se puede considerar que estamos enseñando C ++ con CI / O (para velocidad) y con clases limitadas a struct (+ algunos métodos como < operator). El punto no es ser "C" o "C ++", sino hacer algo de C ++ con lo mejor de cada lenguaje y con un objetivo: codificar desafíos algorítmicos rápidamente, con un código corto y sin ningún error. -

WTF trabajo, ¿tiene principiantes haciendo donde la velocidad de E / S importa? -

4 Respuestas

¿Estás seguro de que necesitas un árbol de sintaxis completo para esto? Creo que bastaría con hacer un análisis léxico para encontrar los identificadores, que es mucho más fácil. Luego, excluya las palabras clave e identificadores que también aparecen en los archivos de encabezado que se incluyen.

En principio, es posible que desee que diferentes variables con el mismo nombre en inglés se traduzcan a diferentes palabras en francés / alemán, pero para el uso educativo, el riesgo de que esto surja probablemente sea lo suficientemente pequeño como para ignorarlo al principio. Puede eludir el problema escribiendo las fuentes originales con algunos prefijos cuasi húngaros que eliminen la ambigüedad y luego eliminarlos con el mismo mecanismo de traducción para mostrarlos a los usuarios finales de habla inglesa.

Asegúrese de que los traductores vean el nombre que están traduciendo. con contexto completo antes de elegir una traducción.

Respondido 27 ago 11, 19:08

De hecho, los códigos fuente son pequeños (pero hay muchos) y las variables siempre están bien nombradas, en particular: nunca el mismo nombre si tiene un significado diferente, no hay variables de una letra ... Y sí, el traductor tendrá un nombre completo contexto, esta herramienta de traducción está aquí para ayudarlo. - Loïc Février

Realmente creo que puedes usar sonido metálico (libclang) para analizar sus fuentes y hacer lo que quiera (ver aquí para más información), la buena noticia es que tienen enlaces de Python, lo que te facilitará la vida si quieres acceder a un servicio de traducción o algo por el estilo.

Respondido 27 ago 11, 20:08

Realmente no necesita un analizador de C / C ++, solo un simple lexer que le brinda elementos del código uno por uno. Entonces obtienes una gran cantidad de {, [, 213, ) etc que simplemente ignora y escribe en el archivo de resultados. Traduces todo lo que consista solo en letras (excepto palabras clave) y las pones en la salida.

Ahora que lo pienso, es tan simple como esto:

bool is_letter(char c)
{
    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
bool is_keyword(string &s)
{
    return s == "if" || s == "else" || s == "void" /* rest of them */;
}
void translateCode(istream &in, ostream &out)
{
    while (!in.eof())
    {
        char c = in.get();
        if (is_letter(c))
        {
            string name = "";
            do
            {
                name += c;
                c = in.get();
            } while (is_letter(c) && !in.eof());
            if (is_keyword(name))
                out << name;
            else
                out << translate(name);
        }
        out << c;  // even if is_letter(c) was true, there is a new c from the
                   // while inside that was read (which was not letter), but
                   // not written, so would be written here.
    }
}

Escribí el código en el editor, por lo que puede haber errores menores. Dime si hay alguno y lo arreglaré.

Edit: Explicación:

Lo que hace el código es simplemente leer la entrada carácter por carácter, dando salida a los caracteres que no son letras que lee (incluidos espacios, tabulaciones y nuevas líneas). Sin embargo, si ve una letra, comenzará a poner todas las letras siguientes en una cadena (hasta que llegue a otra que no sea una letra). Entonces, si la cadena fuera una palabra clave, generaría la palabra clave en sí. Si no fuera así, lo traduciría y lo sacaría.

La salida tendría exactamente el mismo formato que la entrada.

respondido 08 nov., 11:04

void translateCode (istream & in, ostream & out) ;, elimina el final;. - usuario406009

La lista de todas las palabras clave está ahí para cpp: en.cppreference.com/w/cpp/keywords y ahí para c: tigcc.ticalc.org/doc/keywords.html - pero encima de ellos tienes que cuidar todos los símbolos estándar como cin, cout, printf, etc. (toneladas de ellos) y de los nombres de los archivos de encabezado. Sin embargo, este puede ser un buen comienzo: Shlublu

Gracias por el;. Además, un buen recordatorio sobre las funciones y objetos ya definidos de c / c ++ @shlubu. Es solo una cuestión de recopilar la lista de cosas que han escrito en sus programas que deberían excluirse de la traducción y ponerla allí en el programa. - Shahbaz

Hablando de símbolos estándar, los nombres de archivos de encabezado también deben excluirse. - Shahbaz

Hay una C estándar isalpha función que podría utilizar en lugar de su "is_letter". - comida

No creo que reemplazar identificadores en el código sea una buena idea.

Primero, no obtendrá traducciones decentes. Un punto muy importante aquí es que la traducción (especialmente la traducción automática o bastante tonta) pierde y distorsiona la información. De hecho, puede terminar con algo peor que el original.

En segundo lugar, si el código está destinado a compilarse de nuevo, es posible que el compilador no pueda compilar código que contenga letras que no estén en inglés en los identificadores traducidos.

En tercer lugar, si reemplaza los identificadores con otra cosa, debe asegurarse de no reemplazar 2 o más identificadores diferentes con la misma palabra. Eso hará que el código no sea compilable o arruinará su lógica.

En cuarto lugar, debe asegurarse de no traducir palabras reservadas e identificadores que provienen de la biblioteca estándar del idioma. Traducirlos hará que el código no sea compilable e ilegible. Puede que no sea una tarea muy trivial diferenciar entre los identificadores que el programador ha definido de los proporcionados por el lenguaje y su biblioteca estándar.

Lo que haría en lugar de reemplazar los identificadores con sus traducciones es proporcionar las traducciones como comentarios junto a ellos, por ejemplo:

void eat/*comer*/(int* food/*comida*/)
{
  if (*food/*comida*/ <= 0)
  {
    printf("nothing to eat!"/*no hay que comer!*/);
    exit/*salir*/(-1);
  }
  (*food/*comida*/)--;
}

De esta forma no perderá información debido a una traducción incorrecta y no romperá el código.

respondido 08 nov., 11:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.