parsing - romualfons - ¿Existe una forma establecida de escribir analizadores que puedan reconstruir su entrada exacta?
romuald seo (2)
Digamos que quiero analizar un archivo en el lenguaje X. Realmente, solo estoy interesado en una pequeña parte de la información dentro. Es bastante fácil escribir un analizador sintáctico en uno de los muchos eDSL de Haskell para ese fin (por ejemplo, Megaparsec).
data Foo = Foo Int -- the information I''m after.
parseFoo :: Parsec Text Foo
parseFoo = ...
Eso fácilmente da lugar a una función getFoo :: Text -> Maybe Foo
.
Pero ahora también me gustaría modificar la fuente de la información de Foo
, es decir, básicamente, quiero implementar
changeFoo :: (Foo -> Foo) -> Text -> Text
con las propiedades
changeFoo id ≡ id
getFoo . changeFoo f ≡ fmap f . getFoo
Es posible hacer eso cambiando el resultado del analizador a algo así como una lente
parseFoo :: Parsec Text (Foo, Foo -> Text)
parseFoo = ...
pero eso hace que la definición sea mucho más engorrosa: ya no puedo pasar por alto la información irrelevante, sino que necesito almacenar la coincidencia de cada subcadena de string
y volver a montarla manualmente.
Esto podría ser algo automatizado al mantener el ensamblaje de cadenas en una capa StateT
alrededor de la mónada del analizador, pero no podría simplemente usar los analizadores primitivos existentes.
¿Hay una solución existente para este problema?
¿Es este un caso de "transformación bidireccional"? Por ejemplo, http://ceur-ws.org/Vol-1571/
En particular, "Descripciones de sintaxis invertible: análisis unificador y impresión bonita" por Rendel y Osterman http://dblp.org/rec/conf/haskell/RendelO10 , Haskell Symposium 2010 (véase http: // lambda-the-ultimate. org / node / 4191 )
¿Una solución implementada en Haskell? No sé de uno; ellos pueden existir.
En general, sin embargo, uno puede almacenar suficiente información para regenerar una versión legal del programa que se asemeja al original en un grado arbitrario, al almacenar información de "formateo" con tokens recogidos. En el límite, la información de formato es la cadena original para el token; cualquier aproximación de eso dará respuestas sucesivamente menos precisas.
Si mantiene el espacio en blanco como tokens explícitos en el árbol de análisis sintáctico, en el límite puede incluso regenerarlo. Si eso es útil probablemente dependa de la aplicación. En general, creo que esto es excesivo.
Los detalles sobre qué / cómo capturar y cómo regenerar se pueden encontrar en mi respuesta de SO: compilación de un AST de nuevo al código fuente