Pregunta

Como proyecto favorito, me gustaría intentar implementar un lenguaje básico de mi propio diseño que pueda usarse como lenguaje de secuencias de comandos web.Es trivial ejecutar un programa C++ como Apache CGI, por lo que el verdadero trabajo radica en cómo analizar un archivo de entrada que contiene no código (marcado HTML/CSS) y código del lado del servidor.

En mi curso de compilación de pregrado, usamos Doblar y Bisonte generar un escáner y un analizador para un lenguaje simple.Nos dieron una copia de la gramática y escribimos un analizador que traducía el lenguaje simple a un ensamblaje simple para una máquina virtual.El escáner flexible tokeniza la entrada y pasa los tokens al analizador Bison.

La diferencia entre eso y lo que me gustaría hacer es que, al igual que PHP, este lenguaje podría tener marcado HTML simple y el lenguaje de programación intercalado como el siguiente:

<p>Hello,
<? echo "World ?>
</p>

¿Me equivoco al suponer que sería eficiente analizar el archivo de entrada de la siguiente manera?

  1. Escanee la entrada hasta que encuentre una etiqueta de inicio de secuencia de comandos ('
  2. El segundo escáner tokeniza la sección del script del lado del servidor del archivo de entrada (de la etiqueta abierta:'') y pasa el token al analizador, que no necesita conocer el marcado en el archivo.
  3. El control regresa al primer escáner que continúa este patrón general.

Básicamente, el primer escáner solo diferencia entre marcado (que se devuelve directamente al navegador sin modificar) y código, que se pasa al segundo escáner, que a su vez tokeniza el código y pasa los tokens al analizador.

Si esto es no un patrón de diseño sólido, ¿cómo manejan lenguajes como PHP escanear entradas y analizar código de manera eficiente?

¿Fue útil?

Solución

Quiere ver las condiciones de inicio.Por ejemplo:

"<?"            { BEGIN (PHP); }
<PHP>[a-zA-Z]*  { return PHP_TOKEN; }
<PHP>">?"       { BEGIN (0); }
[a-zA-Z]*       { return HTML_TOKEN; }

Comienzas en el estado 0, usa la macro BEGIN para cambiar los estados.Para hacer coincidir un RE solo mientras se encuentra en un estado particular, anteponga el RE con el nombre del estado entre corchetes angulares.

En el ejemplo anterior, "PHP" es el estado."PHP_TOKEN" y "HTML_TOKEN" son _%token_s definidos por su archivo yacc.

Otros consejos

PHP no diferencia entre escaneo y marcado.Simplemente sale al búfer cuando está en modo de marcado y luego cambia a análisis cuando está en modo de código.No necesita un escáner de dos pasos y puede hacerlo con un solo flex lexer.

Si está interesado en cómo funciona PHP, descargue la fuente (pruebe la fuente PHP4, es mucho más fácil de entender).Lo que quieres ver está en el Directorio Zend, zend_language_scanner.l.

Después de haber escrito algo similar, realmente recomendaría reconsiderar la ruta de Flex y Bison, y optar por algo moderno como asta.Es mucho más fácil, más fácil de entender (las macros empleadas en una gramática lex se vuelven muy confusas y difíciles de leer) y tiene un depurador incorporado (AntlrWorks) para que no tengas que pasar horas mirando archivos de depuración de 3 megas.También es compatible con muchos lenguajes (Java, C#, C, Python, Actionscript) y tiene un libro excelente y un sitio web muy bueno que debería poder ponerlo en funcionamiento en poco tiempo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top