texto - libreria fstream c++
Código para identificar el lenguaje de programación en un archivo de texto (10)
Como la lista de idiomas se conoce por adelantado, usted conoce la sintaxis / gramática de cada uno de ellos. Por lo tanto, puede, como ejemplo, escribir una función para extraer palabras reservadas del código fuente proporcionado.
Cree un árbol binario que tenga todas las palabras reservadas para todos los idiomas que admita. Y luego simplemente camine ese árbol con las palabras reservadas extraídas del paso anterior.
Si al final solo te queda 1 posibilidad, este es tu idioma. Si llega al final del programa demasiado pronto, entonces (desde donde se detuvo), puede analizar su posición en un árbol para determinar qué idiomas son todavía las posibilidades.
se supone que debo escribir un código que, cuando se le presente un archivo de texto (código fuente) como entrada, generará el lenguaje de programación que sea. Esta es la definición más básica del problema. Siguen más restricciones:
- Debo escribir esto en C ++.
- Se debe reconocer una amplia variedad de idiomas: html, php, perl, ruby, C, C ++, Java, C # ...
- La cantidad de falsos positivos (reconocimiento incorrecto) debe ser baja; es mejor que se muestre "desconocido" que un resultado incorrecto. (estará en la lista de probabilidades, por ejemplo, como desconocida: 100%, ver más abajo)
- La salida debe ser una lista de probabilidades para cada idioma que el código conoce, por lo tanto, si conoce C, Java y Perl, la salida debería ser, por ejemplo: C: 70%, Java: 50%, Perl: 30% (note que hay no hay necesidad de tener la suma de las probabilidades hasta el 100%)
- Debe tener una buena relación de precisión / velocidad (la velocidad es un poco más favorecida)
Sería muy bueno si el código pudiera escribirse de manera tal que agregar nuevos idiomas para el reconocimiento sea bastante fácil e implique simplemente agregar "configuraciones / datos" para ese idioma en particular. Puedo usar cualquier cosa disponible: una heurística, una red neuronal, magia negra. Cualquier cosa. Incluso se me permite usar las soluciones existentes, pero: la solución debe ser gratuita, de código abierto y permitir el uso comercial. Debe venir en forma de código fuente fácilmente integrable o como una biblioteca estática, sin DLL. Sin embargo, prefiero escribir mi propio código o simplemente usar fragmentos de otra solución, estoy harto de integrar el código de otros. Última nota: tal vez algunos de ustedes sugieran FANN (biblioteca de red neuronal artificial rápida): esto es lo único que no puedo usar, ya que es lo que usamos YA y queremos reemplazarlo.
Ahora la pregunta es: ¿cómo manejarías esa tarea, qué harías? ¿Alguna sugerencia de cómo implementar esto o qué usar?
EDITAR: en base a los comentarios y las respuestas, debo enfatizar algunas cosas que olvidé: la velocidad es muy importante, ya que esto obtendrá miles de archivos y se supone que responderá rápidamente, por lo que mirar mil archivos debería producir respuestas para todos ellos en una Unos segundos como máximo (el tamaño de los archivos será pequeño, por supuesto, unos cuantos kB cada uno). Así que tratar de compilar cada uno está fuera de discusión. La cuestión es que realmente quiero probabilidades para cada idioma, por lo que quiero saber que el archivo es probablemente C o C ++, pero que la posibilidad de que sea un script de bash es muy bajo. Debido a ofuscación de código, comentarios, etc. creo que buscar un código 100% preciso es una mala idea y, de hecho, no es el objetivo de esto.
Como sugirió dmckee, es posible que desee echar un vistazo al programa de file
Unix, cuya fuente está disponible . Las heurísticas utilizadas por esta utilidad pueden ser una gran fuente de inspiración. Ya que está escrito en C, supongo que califica para C ++. :) Sin embargo, no obtienes los porcentajes de confianza directamente; tal vez son utilizados internamente?
Echa un vistazo a nedit . Tiene un sistema de reconocimiento de resaltado de sintaxis, bajo Resaltado de sintaxis -> Patrones de reconocimiento . Puede examinar los patrones de reconocimiento de muestra here , o descargar el programa y revisar los estándares.
Aquí hay una descripción del sistema de resaltado .
El algoritmo de Sequitur infiere gramáticas libres de contexto a partir de secuencias de símbolos terminales. Quizás podría usar eso para comparar con un conjunto de reglas de producción conocidas para cada idioma.
Este no es rápido y puede que no satisfaga sus requisitos, sino solo una idea. Debe ser fácil de implementar y debe dar un resultado del 100%.
Puede intentar compilar / ejecutar el texto de entrada con diferentes compiladores / intérpretes (opensource o gratis) y verificar si hay errores detrás de la escena.
Lo siento, pero si tiene que analizar miles de archivos, entonces su mejor opción es mirar la extensión del archivo . No diseñe en exceso un problema simple, ni imponga requisitos onerosos en una tarea sencilla.
Parece que tienes miles de archivos de código fuente y no tienes idea de en qué lenguaje de programación fueron escritos. ¿En qué tipo de entorno de programación trabajas? (Eliminando la posibilidad de un requisito de tarea artificial) Me refiero a uno de los conceptos básicos de ingeniería de software en los que siempre puedo confiar es que los archivos de código c ++ tienen la extensión .cpp, que los archivos de código java tienen la extensión .java, que los archivos de código c tiene la extensión .c, etc ... ¿Su empresa está jugando de manera rápida y flexible con estos estándares? Si es así estaría muy preocupado.
Si sabe que los archivos de origen se ajustarán a los estándares, las extensiones de archivo son únicas para casi todos los idiomas. Supongo que ya lo ha considerado y lo ha descartado basándose en otra información.
Si no puede usar las extensiones de archivo, la mejor manera sería encontrar las cosas entre los idiomas más diferentes y usarlas para determinar el tipo de archivo. Por ejemplo, para la sintaxis de sentencias de bucle no variará mucho entre idiomas, pero las declaraciones de inclusión de paquetes deberían. Si tiene un archivo que incluye java.util. *, Entonces sabe que es un archivo java.
Tal vez pueda tratar de pensar en las diferencias de idiomas y modelarlas con un árbol binario, como "¿se encuentra la característica X?" En caso afirmativo, proceda en una dirección, si no, proceda en otra dirección.
Al construir este árbol de búsqueda de manera eficiente, podría terminar con un código bastante rápido.
Tienes un problema de clasificación de documentos . Le sugiero que lea sobre los clasificadores ingenuos de bayes y las máquinas de vectores de soporte . En los artículos hay enlaces a bibliotecas que implementan estos algoritmos y muchos de ellos tienen interfaces C ++.
Una solución simple en la que podría pensar es que solo podría identificar las palabras clave utilizadas en diferentes idiomas. Cada palabra identificada tendría una puntuación de +1. Luego, calcule la proporción = identificadas_delas / total_words. El idioma que obtenga la mayor puntuación es el ganador. Por supuesto, hay problemas como el uso de comentarios, etc. Pero creo que es una solución muy simple que debería funcionar en la mayoría de los casos.