Estoy escribiendo un programa donde necesito analizar un archivo fuente JavaScript, extraer algunos datos e insertar/reemplazar partes del código. Una descripción simplificada de los tipos de cosas que había que hacer es, dado este código:Usando ANTLR para analizar y modificar el código fuente; ¿Lo estoy haciendo mal?
foo(['a', 'b', 'c']);
Extracto 'a'
, 'b'
y 'c'
y volver a escribir el código como:
foo('bar', [0, 1, 2]);
estoy usando ANTLR para mis necesidades de análisis, produciendo el código C# 3. Alguien más ya había contribuido con una gramática de JavaScript. El análisis del código fuente está funcionando.
El problema que estoy encontrando es averiguar cómo analizar y modificar correctamente el archivo de origen. Cada enfoque que intento tomar en realidad para resolver el problema me lleva a un callejón sin salida. No puedo evitar pensar que no estoy usando la herramienta como estaba previsto o que soy demasiado novato cuando se trata de tratar con AST.
Mi primer enfoque fue analizar utilizando TokenRewriteStream
e implementar los métodos parciales EnterRule_*
para las reglas que me interesan. Si bien esto parece hacer bastante fácil la modificación de la secuencia de token, no hay suficiente información contextual para mi análisis. Parece que todo lo que tengo acceso es una secuencia plana de tokens, lo que no me dice lo suficiente sobre toda la estructura del código. Por ejemplo, para detectar si la función foo
está siendo llamado, simplemente mirando el primer token no funcionaría, ya que coincidiría también falsamente:
a.b.foo();
Para permitir que haga el análisis de código más sofisticado, mi segundo enfoque fue modificar la gramática con reglas de reescritura para producir más de un árbol. Ahora, el primer bloque de código de muestra produce esto:
Program CallExpression Identifier('foo') ArgumentList ArrayLiteral StringLiteral('a') StringLiteral('b') StringLiteral('c')
Esto funciona muy bien para analizar el código. Sin embargo, ahora no puedo volver a escribir fácilmente el código. Claro, podría modificar la estructura de árbol para representar el código que quiero, pero no puedo usar esto para dar salida al código fuente. Tenía la esperanza de que el token asociado con cada nodo al menos me diera información suficiente para saber en qué parte del texto original necesitaría hacer las modificaciones, pero todo lo que obtengo son índices simbólicos o números de línea/columna. Para usar los números de línea y columna, tendría que hacer un segundo pase incómodo a través del código fuente.
Sospecho que me falta algo para entender cómo usar ANTLR correctamente para hacer lo que necesito. ¿Hay una forma más adecuada para mí para resolver este problema?
* "¿Hay una manera más adecuada para mí para resolver este problema?" *: No, no AFAIK. Analizas tu entrada, la manipulas y luego la sacas tú mismo. StringTemplate, puede, como Dave menciona, ayudarte con esto. –