Tengo un convertidor bbcode -> html que responde al evento de cambio en un área de texto. Actualmente, esto se hace usando una serie de expresiones regulares, y hay una cantidad de casos patológicos. Siempre he querido afilar el lápiz en esta gramática, pero no quería meterme en el afeitado de yak. Pero ... recientemente me di cuenta de pegjs, que parece una implementación bastante completa de la generación de analizadores PEG. Tengo la mayor parte de la gramática especificada, pero ahora me pregunto si este es un uso apropiado de un analizador completo.Usando PEG Parser para el análisis de BBCode: pegjs o ... ¿qué?
Mis preguntas específicas son:
Como mi aplicación se basa en la traducción de lo que pueda para HTML y dejando el resto como texto sin formato, no implementar BBCode usando un analizador que puede fallar en un sentido esto error de sintaxis ? Por ejemplo:
[url=/foo/bar]click me![/url]
ciertamente se espera que tenga éxito una vez que se ingrese el corchete de cierre en la etiqueta de cierre. Pero, ¿qué vería el usuario mientras tanto? Con la expresión regular, puedo ignorar cosas que no coinciden y tratarlas como texto normal para fines de vista previa. Con una gramática formal, no sé si esto es posible porque confío en crear el HTML de un árbol de análisis sintáctico y lo que falla es un análisis ... ¿qué?No tengo claro dónde deben realizarse las transformaciones. En un analizador formal basado en lex/yacc, tendría los archivos de cabecera y los símbolos que denotan el tipo de nodo. En pegjs, obtengo matrices anidadas con el texto del nodo. Puedo emitir el código traducido como una acción del analizador generado por pegjs, pero parece un olor a código para combinar un analizador y un emisor. Sin embargo, si llamo
PEG.parse.parse()
, yo vuelva algo como esto:
[
[
"[",
"img",
"",
[
"/",
"f",
"o",
"o",
"/",
"b",
"a",
"r"
],
"",
"]"
],
[
"[/",
"img",
"]"
]
]
dada una gramática como:
document
= (open_tag/close_tag/new_line/text)*
open_tag
= ("[" tag_name "="? tag_data? tag_attributes? "]")
close_tag
= ("[/" tag_name "]")
text
= non_tag+
non_tag
= [\n\[\]]
new_line
= ("\r\n"/"\n")
estoy abreviando la gramática, por supuesto, pero captar la idea. Entonces, si lo nota, no hay información contextual en la matriz de matrices que me diga qué tipo de nodo tengo y me queda hacer comparaciones de cadenas nuevamente aunque el analizador ya lo haya hecho. Espero que sea posible definir devoluciones de llamada y usar acciones para ejecutarlas durante un análisis, pero hay poca información disponible en la Web sobre cómo se podría hacer eso.
¿Estoy ladrando el árbol equivocado? ¿Debería recurrir a la exploración de expresiones regulares y olvidarme del análisis sintáctico?
Gracias
Steve, tu pregunta es muy interesante (+1), solo quiero hacer lo mismo en una extensión: analizar BBCode en un área de texto (lamentablemente este es el formato que todavía está usando un foro), y crear un "live "vista previa del texto escrito usando PEG.js o cualquier otra cosa excepto expresiones regulares. ¿Has logrado crear la gramática para el analizador de BBCode? ¿No podrías compartir tu solución a través de GitHub o cualquier otra cosa? Eso me ayudaría mucho. Muchas gracias de antemano! – Sk8erPeter
Utilicé [pacerjk's bbcode parser] (https://github.com/patorjk/Extendible-BBCode-Parser). Funciona muy bien y puede ajustarse a sus propias necesidades si tiene etiquetas especiales. –
Gracias, ya he visto esta biblioteca, pero usa expresiones regulares, lo que quería evitar, porque teóricamente, el análisis de BBCode con expresiones regulares no se puede hacer sin fallas ([»» enlace] (http: // kore- nordmann.de/blog/do_NOT_parse_using_regexp.html)) en algunos casos, por ejemplo al anidarlos entre ellos, etc. Por eso quería hacerlo usando el formalismo gramatical de expresión de análisis. Entonces, ¿no trataste de mejorar la gramática que comenzaste? :) ¿No podrías compartir la base de esto? :) – Sk8erPeter