2011-01-26 28 views
7

estoy trabajando en la tarea expresiones regulares donde uno pregunta es:¿Qué caracteres están permitidos en los identificadores de Perl?

El uso de manuales de referencia del lenguaje en línea determinar las expresiones regulares para las constantes e identificadores numéricos enteros para Java, Python, Perl y C.

No necesito ayuda con la expresión regular, simplemente no tengo idea de cómo son los identificadores en Perl. Encontré páginas que describen identificadores válidos para C, Python y Java, pero no puedo encontrar nada sobre Perl.

EDITAR: para aclarar, encontrar la documentación era fácil (como hacer una búsqueda en Google para python identifiers). No tomaré una clase para "hacer búsquedas en Google".

+0

Con respecto a su aclaración: ¿Ha buscado "identificadores de perl"? Tal vez intentarlo citado? Los resultados de las respuestas no estaban en la parte superior, pero no estaban muy lejos o eran difíciles de reconocer. Sin embargo, la respuesta de Tchrist ciertamente hizo que valiera la pena preguntar. :) – Ashley

+0

'hombre perlvar' debería ser suficiente entonces, ¿eh? – tchrist

+0

@Ashley: http://www.google.com/search?q=%22perl+identifiers%22 No veo nada que se vea útil en eso. Muchos ejemplos de Perl y una descripción incompleta de los nombres de variables (básicamente comienzan con '$'). Realmente no esperaba que fuera tan difícil de responder. Sin embargo, esperamos que ayude a las personas en el futuro ya que SO tiende a aparecer cerca de la cima en las búsquedas de Google. –

Respuesta

29

Perl constantes enteras

Las constantes enteras en Perl puede ser

  • en base 16 si comienzan con ^0x
  • en base 2 si comienzan con ^0b
  • en base 8 si comenzar con 0
  • de lo contrario están en la base 10.

A continuación, ese líder es cualquier número de dígitos válidos en esa base y también caracteres de subrayado opcionales.

Tenga en cuenta que el dígito no significa \p{POSIX_Digit}; significa \p{Decimal_Number}, que es realmente bastante diferente, ya sabes.

Tenga en cuenta que cualquier signo menos es no parte de la constante entera, que es fácilmente demostrada por:

$ perl -MO=Concise,-exec -le '$x = -3**$y' 
1 <0> enter 
2 <;> nextstate(main 1 -e:1) v:{ 
3 <$> const(IV 3) s 
4 <$> gvsv(*y) s 
5 <2> pow[t1] sK/2 
6 <1> negate[t2] sK/1 
7 <$> gvsv(*x) s 
8 <2> sassign vKS/2 
9 <@> leave[1 ref] vKP/REFC 
-e syntax OK 

Ver el 3 const, y mucho más tarde en el código de operación negate? Eso te dice un montón, incluida una curiosidad de precedencia.

Perl Identificadores

identificadores especificados a través de desreferencia simbólica tienen absolutamente ninguna restricción alguna en sus nombres.

  • Por ejemplo, 100->(200) llama a la función llamada 100 con los arugments (100, 200).
  • Por otro lado, ${"What’s up, doc?"} se refiere a la variable del paquete escalar con ese nombre en el paquete actual.
  • Por otro lado, ${"What's up, doc?"} se refiere a la variable de paquete escalar cuyo nombre es ${"s up, doc?"} y que es no en el paquete actual, sino más bien en el paquete What. Bueno, a menos que el paquete actual sea el paquete What, por supuesto. Similary $Who's es la variable $s en el paquete Who.

Uno también puede tener los identificadores de la forma ${^identificador}; estos no se consideran desreferencias simbólicas en la tabla de símbolos.

Los identificadores con un solo carácter solo pueden ser un carácter de puntuación, incluyen $$ o %!.

Los identificadores también pueden ser de la forma $^C, que es un carácter de control o un circunflejo seguido por un carácter sin control.

Si ninguna de esas cosas es verdad, una lista (no completo) identificador sigue las reglas relacionadas con Unicode caracteres con las propiedades ID_Start seguidos de los que tienen la propiedad ID_Continue. Sin embargo, se invalida esto al permitir identificadores de todos los dígitos e identificadores que comienzan con (y quizás no tienen nada más) un guión bajo. En general puede pretender (pero en realidad solo es fingir) que eso es como decir \w+, donde \w es como se describe en Annex C of UTS#18. Es decir, cualquier cosa que tenga cualquiera de estos:

  • la propiedad alfabética, que incluye mucho más que solo letras; También contiene varios caracteres de combinación y los puntos de código Letter_Number, además de las letras dentro de círculos
  • la propiedad número_decimal, que es algo más que simplemente [0-9]
  • Cualquiera y todos los personajes con la propiedad de Mark, no sólo aquellas marcas que se consideran Other_Alphabetic
  • Cualquier carácter con la propiedad Connector_Puncutation, de la cual el subrayado es solo uno.

Así que, o ^\d+$ o de lo contrario

^[\p{Alphabetic}\p{Decimal_Number}\p{Mark}\p{Connector_Punctuation}]+$ 

debe hacerlo por los realmente simples, si no le importa para explorar las complejidades de las propiedades Unicode ID_Start y ID_Continue. Así es como está realmente hecho, pero apuesto a que tu instructor no lo sabe. Quizás uno no le diga, ¿eh?

Pero debe cubrir las sencillas que describo anteriormente.

Y aún no hemos hablado de los paquetes.

Paquetes Perl en Identificadores

Más allá de esas reglas simples, también se deben tener en cuenta que los identificadores pueden calificarse con un nombre de paquete, y nombres de los paquetes propios seguir las reglas de los identificadores.

El separador de paquetes es :: o ' a su antojo.

No tiene que especificar un paquete si es el primer componente en un identificador totalmente calificado, en cuyo caso significa el paquete main. Eso significa que cosas como $::foo y $'foo son equivalentes a $main::foo, y isn't_it() es equivalente a isn::t_it(). (Typo removed)

Finalmente, como un caso especial, se permite un doble de colon de salida (pero no una comilla simple) en el extremo de un hash, y esto, entonces se refiere a la tabla de símbolos de ese nombre.

Así %main:: es la tabla de símbolos main, y porque puede omitir main, también lo es %::.

Mientras tanto %foo:: es la tabla foo símbolo, como es %main::foo:: y también %::foo:: sólo por el bien de la perversidad.

Resumen

Es agradable ver los instructores que dan las personas tareas no triviales. La pregunta es si el instructor se dio cuenta de que no era trivial. Probablemente no.

Y tampoco es solo Perl. En cuanto a los identificadores de Java, ¿ya descubriste que los libros de texto mienten? Aquí está la demostración:

$ perl -le 'print qq(public class escape { public static void main(String argv[]) { String var_\033 = "i am escape: ^\033"; System.out.println(var_\033); }})' > escape.java 
$ javac escape.java 
$ java escape | cat -v 
i am escape: ^[ 

Sí, es cierto. También es cierto para muchos otros puntos de código, especialmente si usa -encoding UTF-8 en la línea de compilación. Su trabajo es encontrar el patrón que describe estos identificadores Java sorprendentemente no prohibidos. Sugerencia: asegúrese de incluir el punto de código U + 0000.

Ahí, ¿no te alegra que hayas preguntado? Espero que esto ayude. O algo. ☺

+5

Nota para Brendan: si realmente desea presentar esta respuesta de tamaño War and Piece a su profesor como parte de la documentación que muestra por qué su identificador Perl toma 2 páginas completas, y comienza a cuestionar la cordura de la persona que se cita, simplemente dígale que la persona que proporcionó la respuesta podría escribir fácilmente un libro sobre la programación de Perl. – DVK

+0

Guau, esto va a ser difícil. Muchas gracias sin embargo. La cosa de Java que leí decía que podían estar formadas por letras, números o básicamente cualquier letra Unicode. Para ese, simplemente asumí que los "javaletters" estaban definidos para mí. Pero, ¿por qué U + 000 es un personaje válido? ¿Solo para que sea difícil escribir un compilador de Java en C? : D –

+5

@Brendan: Estoy seguro de que su instructor tampoco pensó que sería tan difícil. Me temo que aquí, como en tantas actividades académicas, la mejor manera de obtener una buena nota es dar la respuesta que se espera de ti, no la respuesta que intenta modelar con precisión una realidad que es mucho más complicada que la persona que da la tarea imaginado – tchrist

1

Al no tener una especificación oficial (Perl es lo que sea que el intérprete de perl puede analizar), estos pueden ser un poco difíciles de discernir.

This page tiene ejemplos de todos los formatos constantes enteros. El formato de los identificadores deberá deducirse de varias páginas en perldoc.

+0

Tenga en cuenta también que cualquier cosa que pretenda que existe algo así como una constante negativa no comprende la gramática; simplemente ejecute 'perl -MO = Concise, -exec -le '$ x = -3 ** $ y'' para descubrir los porqués y las dónde. – tchrist

+0

Perl6 es realmente una especificación, pero sí ... Perl5 y versiones anteriores utilizan el método "El lenguaje es lo que el compilador dice que es". –

+1

@Autocracy: Eso exagera las cosas. – tchrist

5

La tarea requiere que use los manuales de referencia, por lo que responderé en esos términos.

La documentación de Perl está disponible en http://perldoc.perl.org/. La sección que trata sobre las variables es perldata. Eso le dará fácilmente una respuesta utilizable.

En realidad, dudo que la respuesta completa esté disponible en la documentación. Hay variables especiales (ver perlvar), y "use utf8;" puede afectar en gran medida la definición de "letra" y "número".

$ perl -E'use utf8; $é=123; say $é' 
123 

[Solo cubrí la parte del identificador. Me acabo de dar cuenta de que la pregunta es más grande que eso]

+0

El objetivo de la tarea es escribir la expresión regular. Los docentes de esta escuela probablemente solo asuman que todos conocemos Perl, a pesar de que no se enseña en ninguna clase aquí (¿y por qué aprender Perl si conozco a Python?). –

+7

Siempre es bueno aprender nuevos idiomas. Le da nuevas perspectivas sobre cómo abordar muchos problemas. – ikegami

+4

@Brendan: El punto es que puedes hacer un trabajo real en tiempo real. – tchrist

5

La página perlvar de la documentación de Perl tiene un section al final que resume la sintaxis permisible. En resumen:

  1. cualquier combinación de letras, dígitos, guiones, y la secuencia especial :: (o '), con la condición de que comience con una letra o un guión.
  2. Una secuencia de dígitos.
  3. Un solo carácter de puntuación.
  4. Un solo carácter de control, que también se puede escribir como caret- {letra}, p. Ej. ^W.
  5. Una cadena alfanumérica que comienza con un carácter de control.

Tenga en cuenta que la mayoría de los identificadores que no sean los del conjunto 1 tienen un significado especial por Perl, o están reservados y pueden tener un significado especial en versiones posteriores. Pero si solo estás tratando de averiguar qué es un identificador válido, entonces eso realmente no importa en tu caso.

+0

¡No hagas la tarea de Brendan para él! – mscha

+1

@mscha: La tarea es crear una expresión regular. Encontrar los documentos es, en el mejor de los casos, una distracción. –

+7

Me temo que representa una versión ** MUY ** simplificada de la realidad. Tendrás que examinar la función 'scan_ident' del lexer, más las macros' UTF8_IS_START', 'isALNUM_utf8', y' UTF8_IS_CONTINUED'. Para una primera aproximación, un identificador es algo con solo caracteres alfabéticos, de marca, de número decimal o de tipo de función de conector. También ha olvidado las variables de estilo MJD como '$ {^ TAINT}' y '$ {^ UNICODE}'. ¡Pero eso no significa que no puedas tener '$ {"! ##%^& - !! " } 'tipo variables; esos son perfectamente válidos Simplemente no pueden ser léxicos. ** HTH && HAND! ** – tchrist

Cuestiones relacionadas