2011-01-07 34 views
16

Entiendo que la sintaxis de Perl es ambigua y que su desambiguación no es trivial (sometimes involving execution of code during the compile phase). De todos modos, ¿tiene Perl una gramática formal (aunque ambigua y/o sensible al contexto)?¿Dónde puedo encontrar una gramática formal para el lenguaje de programación Perl?

+0

Incluso si es muy grande. ¿Por qué lo necesitas? Si quieres practicar con gramáticas, existen alternativas que no causan infartos; si quieres construir un analizador/intérprete de Perl, diviértete, pero primero pregúntate por qué nadie más lo intentó;) – delnan

+14

Sí, aquí está la expresión regular para él: '. *' :-) – paxdiablo

+2

@delnan: Estoy de acuerdo, es loca. :) Tengo curiosidad porque estoy estudiando teoría de análisis. Quería ver un ejemplo de una gramática ambigua de la vida real (en lugar de las gramáticas de juguete en los libros de texto). También quería ver una gramática sensible al contexto de la vida real (si Perl terminaba siendo sensible al contexto). Como con la mayoría de las cosas sobre mí, la curiosidad suele ser el factor motivador. :) –

Respuesta

29

De perlfaq7

¿Puedo obtener un BNF/yacc/RE para el lenguaje Perl?

No hay BNF, pero se puede pata su camino a través de la gramática yacc en perly.y en la distribución fuente si eres particularmente valiente. La gramática se basa en un código de tokenización muy inteligente, , así que prepárese para incursionar en toke.c también.

En palabras de Chaim Frenkel: " la gramática de Perl no se puede reducir a BNF El trabajo de análisis sintáctico Perl se distribuye entre yacc, el analizador léxico, humo y espejos.".

Para ver el maravilloso conjunto de ejemplos de por qué es casi casi imposible de analizar Perl debido a las influencias del contexto, por favor mire en Randal Schwartz's post: On Parsing Perl

Además, por favor véase el análisis de "Perl 5 Internals (Chapter 5. The Lexer and the Parser)" por Simon Cozens .


Tenga en cuenta que el answer is different for Perl6:

+0

¡Humo y espejos, brillante! –

+0

Estoy confundido por esa última cita. No lo desafia pero sinceramente curioso. Tenía la impresión de que la entrada a yacc (y los compiladores de compiladores relacionados) era en realidad BNF o EBNF o alguna variante. La salida de ese se alimenta en el lexer y así sucesivamente hasta que se arroja la salida. ¿Dónde estoy equivocado en mi comprensión? gracias – jaydel

+0

ah, encontré esto: http://www.perlmonks.org/?node_id=471598 y tiene una buena discusión que responde mi pregunta. – jaydel

6

No hay gramática formal en el sentido de "este es el especificación de Perl 5 "(El Perl 6 esfuerzo está tratando de arreglar eso, sin embargo). Pero hay una gramática formal en el código fuente de Perl 5. Por supuesto, entender el código probablemente no sea una tarea trivial.

Jeffrey Kegler también ha escrito algunos buenos artículos sobre la gramática Perl en su blog. En particular, vea, this post y this one. El resto del blog tiene algunas reflexiones bastante interesantes sobre el análisis en general también.

+0

+1 para enlaces de blog – DVK

+0

Para referencia de lectores: Jeffrey Kegler es el autor de Marpa, que parece ser el analizador más moderno y de gran prestigio para Perl (Marpa :: R2); así como el autor del artículo "Perl no se puede analizar" que cita la respuesta de Joel Berger. – DVK

7

Otras personas han publicado este enlace anteriormente en preguntas similares, pero creo que es divertido y tiene un gran ejemplo de ejemplo: Perl Cannot Be Parsed (A Formal Proof).

A partir de este enlace:

[Considerar] la siguiente diabólica fragmento de código, inventado por Randal Schwartz, y determinar la correcta de análisis para ello:

lo/25; # /; morir "esto muere!";

de fragmentos de Schwartz puede analizar dos maneras diferentes: si lo es nularia (es decir, no tiene argumentos), la primera declaración es una división en vacío contexto, y el resto de la línea es un comentario . Si lo toma un argumento , fragmentos de Schwartz analiza como una llamada al cualquier función con el resultado de un operador de juego, a continuación, una llamada a la función die().

Esto significa que, con el fin de Statically parse Perl, debe ser posible determinar a partir de una cadena de Código Perl 5 si establece un prototipo nulo para la subrutina .

Acabo de publicar esta parte para mostrar que realmente se pone realmente difícil muy rápido.

Alternativamente, muchos editores de código y texto pueden hacer un trabajo decente (aunque nunca excelente) de resaltado de sintaxis para que pueda comenzar con esas especificaciones para ver lo que hacen. De hecho, me has inspirado, creo que publicaré una pregunta relacionada preguntando qué editor destaca mejor a Perl.

+0

¡Ese es un excelente ejemplo! Jaja, sabes que tienes un lenguaje extraño cuando el simple acto de * analizar * ¡inspira a la gente! :) –

+0

No significa que no pueda analizarlo; significa que hay análisis ambiguos. Este caso es divertido porque parece que debes tener una tabla de símbolos para leer; esto plantea la pregunta de ¿cómo se puede tener una tabla de símbolos sin tener ya lexed? ¿Perl solo analiza las líneas cuando tiene que ejecutarlas (lo que le permitiría ejecutar primero la definición de "lo que sea" y luego ejecutar esta línea)? ¿El significado de esta línea cambia si redefino "lo que sea" durante la ejecución, si puedo hacer eso? Más diversión. –

+0

@IraBaxter, sé que ha pasado mucho tiempo, pero pensé que iba a responder. Este ejemplo no es el "no dispersable". Si lees el enlace, hay un ejemplo que es mucho más complejo y aparentemente imposible de analizar. –

Cuestiones relacionadas