2010-12-17 17 views
5

Un código fuente de programa C se puede analizar de acuerdo con la gramática C (descrito en CFG) y eventualmente convertido en muchos AST. Estoy considerando si dicha herramienta existe: puede hacer lo contrario generando aleatoriamente muchos AST, que incluyen tokens que no tienen los valores de las cadenas de hormigón, solo los tipos de los tokens, según el CFG, y luego generan el hormigón tokens según las definiciones de los tokens en la expresión regular.¿Alguna herramienta puede generar aleatoriamente el código fuente según una gramática de lenguaje?

Me imagino que el primer paso parece un reemplazo iterativo no terminal, que es aleatorio y puede estar limitado por cierto número de veces de iteración. El segundo paso es simplemente generar cadenas aleatoriamente de acuerdo con expresiones regulares.

¿Hay alguna herramienta que pueda hacer esto?

+0

Pero ... ¿por qué ?: p Supongo que podría: si sigue la especificación CFG, tiene la seguridad de que obtendrá un código C al menos sintácticamente válido. Pero no lo hago. Creo que alguien ha tratado de hacer tal cosa. Probablemente necesites escribir algún tipo de analizador inverso ... – Robert

+0

He trabajado con algunos ... (esto es una broma; Amo a todos mis colegas). –

+2

¿Hay alguna razón por la cual uno quisiera un código fuente aleatorio y sin sentido que (muy probablemente) no haría nada? –

Respuesta

3

El "lenguaje de generación de datos" DGL hace esto, con la capacidad añadida de ponderar las probabilidades de producciones en la gramática que se imprime.

En general, un analizador de descenso recursivo se puede reescribir bastante directamente en un conjunto de procedimientos recursivos para generar, en lugar de analizar/reconocer, el idioma.

0

Si usted tiene un modelo de la gramática en una forma normalizada (todas las reglas de este tipo):

LHS = RHS1 RHS2 ... RHSn ; 

y el lenguaje prettyprinter (por ejemplo, AST a la herramienta de conversión de texto), se puede construir uno de estos bonitos fácilmente.

Simplemente comience con el símbolo de objetivo como árbol de unidades.

Repeat until no nonterminals are left: 
    Pick a nonterminal N in the tree; 
     Expand by adding children for the right hand side of any rule 
     whose left-hand side matches the nonterminal N 

Para terminales que llevan valores (por ejemplo, nombres de variables, números, cadenas, ...) se tendrán que generar contenido aleatorio.

Una complicación con el algoritmo anterior es que no termina claramente. Lo que realmente quiere hacer es elegir un límite en el tamaño de su árbol, y ejecutar el algoritmo hasta que todos los no terminales se hayan ido o exceda el límite. En el último caso, retroceda, deshaga el último reemplazo y pruebe otra cosa. Esto le proporciona una búsqueda de profundidad limitada para un AST de su tamaño determinado.

Luego imprima el resultado. Es el prettyprinter part que es difícil de entender.

[Usted puede construir todo esto usted mismo, incluyendo la impresora bonita, pero es una buena cantidad de trabajo. Construyo herramientas que incluyen toda esta maquinaria directamente en una forma parametrizada por el lenguaje; ver mi biografía].

Un problema desagradable incluso con AST bien formados es que pueden ser absurdos; puede generar una declaración de un entero X y asignarle un valor literal de cadena para un idioma que no lo permita.Probablemente pueda eliminar algunos problemas simples, pero la semántica del lenguaje puede ser increíblemente compleja, considere C++ como ejemplo. Asegurar que termines con un programa semánticamente significativo es extremadamente difícil; en esencia, tiene que analizar el texto resultante y realizar el nombre y el tipo de resolución/verificación en él. Para C++, necesita una interfaz completa de C++.

0

el problema con la generación aleatoria es que para muchos CFG, la longitud esperada de la cadena de salida es infinita (hay un cálculo fácil de la longitud esperada usando funciones generadoras correspondientes a los símbolos no terminales y ecuaciones correspondientes a las reglas de la gramática); tienes que controlar las probabilidades relativas de las producciones de ciertas maneras para garantizar la convergencia; por ejemplo, a veces, ponderar cada regla de producción para un símbolo no terminal de manera inversa a la longitud de su RHS es suficiente

Hay mucho más sobre este tema en: Noam Chomsky, Marcel-Paul Sch \ "{u} tzenberger , `` The Algebraic Theory of Context-Free Languages ​​'', pp. 118-161 en P. Braffort y D. Hirschberg (eds.), Programación de computadoras y sistemas formales, North-Holland (1963) (ver entrada en Wikipedia) en el teorema de enumeración de Chomsky-Schützenberger)

Cuestiones relacionadas