Sunteți pe pagina 1din 24

TECNOLÓGICO NACIONAL DE MÉXICO

INSTITUTO TECNOLÓGICO DE SAN LUIS POTOSÍ

MATERIA

LENGUAJES Y AUTÓMATAS I

NOMBRE DEL TRABAJO

Resumen y Traducción de JFLEX

ALUMNO

Víctor Daniel Padrón Ramos

PROFESOR

Juan Manuel Capetillo Gómez


_________________________Traducción______________________
4 Especificaciones léxicas
Como se muestra arriba, un archivo de especificación léxica para JFlex consta de tres partes divididas por una
sola línea que comienza con %% :

Codigo de Usuario

%%

Opciones y Declaraciones

%%

Reglas Lexicas

En todas las partes de la especificación se permiten los comentarios de la forma /* comment text */ y los /*
comment text */ fin de línea de estilo Java que comienzan con // .Los comentarios de JFlex se anidan, por lo
que el número de /* y */ debe estar equilibrado.

4.1 Código de usuario


La primera parte contiene código de usuario que se copia literalmente al principio del archivo fuente generado
antes de la declaración de clase del escáner. Como se muestra en la especificación de ejemplo, este es el lugar
para colocar declaraciones de package e instrucciones de import . Es posible, pero no se considera un buen
estilo Java para poner clases de ayuda, como clases de token, en esta sección; Por lo general, se declaran
mejor en sus propios archivos .java .

4.2 Opciones y declaraciones.


La segunda parte de la especificación léxica contiene opciones y directivas para personalizar el lexer generado,
las declaraciones de estados léxicos y las definiciones de macro .
Cada directiva JFlex debe sentarse al principio de una línea y comienza con el carácter % . Las directivas que
tienen uno o más parámetros se describen a continuación.
%class "classname"

significa que comienza una línea con %class seguida de un espacio seguido del nombre de la clase para el
escáner generado ( no se deben ingresar las comillas dobles, vea también la especificación del ejemplo ).

4.2.1 Opciones de clase y código de clase de usuario


Estas opciones se refieren al nombre, al constructor, a la API y a las partes relacionadas de la clase de escáner
generada.
 %class "classname"
Le dice a JFlex que le dé a la clase generada el nombre classname y que escriba el código generado
en un archivo classname.java . Si no se utiliza la opción de línea de comando -d <directory> , el código
se escribirá en el directorio donde reside el archivo de especificación. Si no hay %class directiva
de %class presente en la especificación, la clase generada obtendrá el nombre Yylex y se escribirá en
un archivo Yylex.java . Debe haber solo un %class directivo de %class en una especificación.
 %implements "interface 1"[, "interface 2", ..]
Hace que la clase lexer generada implemente las interfaces especificadas. Si hay más de
un %implements directiva %implements , se %implements todas las interfaces especificadas.
 %extends "classname"
Convierte la clase generada en una subclase de la clase nombre de classname . Debe haber solo
un %extends directivas en una especificación.
 %public
Hace que la clase generada sea pública (la clase solo es accesible en su propio paquete por defecto).
 %final
Hace que la clase generada sea final.
 %abstract
Hace que la clase generada sea abstracta.
 %apiprivate
Hace que todos los métodos y campos generados de la clase sean privados. Las excepciones son el
constructor, el código de usuario en la especificación y, si %cup está presente, el
método next_token . Todas las apariciones de public (un carácter de espacio antes y después de public )
en el archivo de esqueleto se reemplazan por private (incluso si se usa un esqueleto especificado por el
usuario). Se espera que el acceso a la clase generada esté mediado por el código de clase de usuario
(vea el siguiente interruptor).
 %{
...
%}
El código incluido en %{ y %} se copia literalmente en la clase generada. Aquí puede definir sus propias
variables y funciones de miembro en el escáner generado. Como todas las opciones,
tanto %{ como %} deben comenzar una línea en la especificación. Si hay más de una directiva de código
de clase %{...%} , el código se concatena en el orden de aparición en la especificación.
 %init{
...
%init}
El código incluido en %init{ y %init} se copia literalmente en el constructor de la clase generada. Aquí,
las variables miembro declaradas en la directiva %{...%} se pueden inicializar. Si hay más de una opción
de inicialización, el código se concatena por orden de aparición en la especificación.
 %initthrow{
"exception1"[,"exception2",...]
%initthrow}
o (en una sola línea) solo
%initthrow "exception1" [, "exception2", ...]
Hace que las excepciones especificadas se declaren en la cláusula de throws del constructor. Si más
de un %initthrow{ ... %initthrow} directiva está presente en la especificación, se declararán todas las
excepciones especificadas.
 %ctorarg "type" "ident"
Agrega el argumento especificado a los constructores del escáner generado. Si hay más de una de estas
directivas, los argumentos se agregan en orden de ocurrencia en la especificación. Tenga en cuenta que
esta opción entra en conflicto con las directivas %standalone y %debug , porque no hay un valor
predeterminado razonable que pueda crearse automáticamente para dichos parámetros en los
métodos main generados. JFlex advertirá en este caso y generará un constructor predeterminado
adicional sin estos parámetros y sin el código de inicio del usuario (que podría referirse a los parámetros).
 %scanerror "exception"
Hace que el escáner generado lance una instancia de la excepción especificada en caso de un error
interno (el valor predeterminado es java.lang.Error ). Tenga en cuenta que esta excepción es solo para
errores internos del escáner. Con las especificaciones habituales, nunca debería ocurrir (es decir, si hay
una regla de recuperación de error en la especificación y solo se utiliza la API del escáner documentada).
 %buffer "size"
Establezca el tamaño inicial del búfer de exploración en el valor especificado (decimal, en bytes). El valor
predeterminado es 16384.
 %include "filename"
Reemplaza el %include textualmente por el archivo especificado.

4.2.2 Método de escaneo


Esta sección muestra cómo se puede personalizar el método de escaneo. Puede redefinir el nombre y el tipo
de retorno del método y es posible declarar las excepciones que se pueden lanzar en una de las acciones de
la especificación. Si no se especifica ningún tipo de retorno, el método de exploración se declarará como valores
de retorno de la clase Yytoken .
 %function "name"
Hace que el método de escaneo obtenga el nombre especificado. Si no hay %function directiva
de %function presente en la especificación, el método de exploración recibe el nombre yylex . Esta
directiva anula la configuración del interruptor %cup . El nombre predeterminado del método de escaneo
con el interruptor %cup es next_token . La anulación de este nombre podría hacer que el escáner
generado se declare implícitamente como abstract , porque no proporciona el método next_token de la
interfaz java_cup.runtime.Scanner . Por supuesto, es posible proporcionar una implementación ficticia
de ese método en la sección de código de clase si aún desea anular el nombre de la función.
 %integer
%int
Ambos hacen que el método de exploración se declare como devuelto tipo Java int . Las acciones en la
especificación pueden devolver valores int como tokens. El valor predeterminado de fin de archivo bajo
esta configuración es YYEOF , que es un miembro public static final int de la clase generada.
 %intwrap
Hace que el método de exploración se declare a partir del tipo de contenedor de Java Integer . Las
acciones en la especificación pueden devolver valores Integer como tokens. El valor predeterminado de
fin de archivo en esta configuración es null .
 %type "typename"
Hace que el método de exploración se declare como valores de retorno del tipo especificado. Las
acciones en la especificación pueden devolver valores de typename como tokens. El valor
predeterminado de fin de archivo en esta configuración es null . Si typename no es una subclase
de java.lang.Object , debe especificar otro valor de final de archivo utilizando la %eofval{ ... %eofval} o
la regla <<EOF>> . La directiva de %type anula la configuración del interruptor %cup .
 %yylexthrow{
"exception1"[,"exception2",...]
%yylexthrow}
o, en una sola línea, solo
%yylexthrow "exception1" [, "exception2", ...]
Las excepciones listadas dentro de %yylexthrow{ ... %yylexthrow} se declararán en la cláusula de lanzamientos
del método de escaneo. Si hay más de una %yylexthrow{... %yylexthrow} en la especificación, se declararán
todas las excepciones especificadas.

4.2.3 El final del archivo


Siempre hay un valor predeterminado que devolverá el método de escaneo cuando se llegue al final del
archivo. Sin embargo, puede definir un valor específico para devolver y un fragmento de código específico que
debe ejecutarse cuando se llega al final del archivo.
El valor predeterminado de fin de archivo depende del tipo de retorno del método de escaneo:
 Para %integer , el método de exploración devolverá el valor YYEOF , que es un miembro public static
final int de la clase generada.
 Para %intwrap ,
 para ningún tipo especificado en absoluto, o
 para un tipo definido por el usuario, declarado usando %type , el valor es null .
 En el modo de compatibilidad CUP, usando %cup , el valor es
new java_cup.runtime.Symbol(sym.EOF)
Los valores de usuario y el código que se ejecutará al final del archivo se pueden definir mediante estas
directivas:
 %eofval{
...
%eofval}
El código incluido en %eofval{ ... %eofval} se copiará literalmente en el método de escaneo y se
ejecutará cada vez que se llegue al final del archivo (más de una vez es posible cuando se vuelve a
llamar al método de escaneo después del final de archivo ha sido alcanzado). El código debe devolver
el valor que indica el final del archivo al analizador. Debe haber solo una %eofval{ ... %eofval} en la
especificación. La %eofval{ ... %eofval} anula la configuración del interruptor %cup y del
interruptor %byaccj . También hay una forma alternativa, más legible, de especificar el valor del final del
archivo usando la regla <<EOF>> .
 %eof{
...
%eof}
El código incluido en %{eof ... %eof} se ejecutará exactamente una vez, cuando se llegue al final del
archivo. El código se incluye dentro de un método void yy_do_eof() y no debe devolver ningún valor
(use %eofval{...%eofval} o <<EOF>> para este propósito). Si hay más de una directiva de final de código
de archivo, el código se concatenará en el orden de aparición en la especificación.
 %eofthrow{
"exception1"[,"exception2",...]
%eofthrow}
o, en una sola línea:
%eofthrow "exception1" [, "exception2", ...]
Las excepciones enumeradas dentro de %eofthrow{...%eofthrow} se declararán en la cláusula de tiros
del método yy_do_eof() . Si hay más de una %eofthrow{...%eofthrow} en la especificación, se declararán
todas las excepciones especificadas.
 %eofclose
Hace que JFlex cierre la secuencia de entrada al final del archivo. El código yyclose() se agrega al
método yy_do_eof() (junto con el código especificado en %eof{...%eof}) y la
excepción java.io.IOException se declara en la cláusula de tiros de este método (junto con los
de %eofthrow{...%eofthrow} )
 %eofclose false
%eofclose el efecto de %eofclose nuevamente (por ejemplo, en caso de que no se quiera cerrar el flujo
de entrada después de %cup ).

4.2.4 Escáneres independientes


 %debug
Crea una función principal en la clase generada que espera el nombre de un archivo de entrada en la
línea de comandos y luego ejecuta el escáner en este archivo de entrada imprimiendo información sobre
cada token devuelto a la consola de Java hasta que se alcanza el final del archivo. La información
incluye: número de línea (si el conteo de líneas está habilitado), columna (si está habilitado el conteo de
columnas), el texto coincidente y la acción ejecutada (con el número de línea en la especificación).
 %standalone
Crea una función principal en la clase generada que espera el nombre de un archivo de entrada en la
línea de comandos y luego ejecuta el escáner en este archivo de entrada.Los valores devueltos por el
escáner se ignoran, pero cualquier texto no coincidente se imprime en la consola de Java. Para evitar
tener que usar una clase de token adicional, se declarará que el método de exploración tiene el tipo
predeterminado int , no YYtoken (si no hay ningún otro tipo especificado explícitamente). Esto es, en la
mayoría de los casos, irrelevante, pero podría ser útil saberlo cuando se hace otro escáner
independiente para algún propósito. Debería considerar usar la directiva %debug , si solo desea poder
ejecutar el escáner sin un analizador adjunto para realizar pruebas, etc.

4.2.5 Compatibilidad CUP


También puede leer la sección CUP si está interesado en cómo conectar su escáner generado con CUP.
 %cup
La directiva %cup habilita el modo de compatibilidad CUP y es equivalente al siguiente conjunto de
directivas:
%implements java_cup.runtime.Scanner %function next_token %type java_cup.runtime.Symbol

%eofval{ return new java_cup.runtime.Symbol(<CUPSYM>.EOF); %eofval} %eofclose

El valor de <CUPSYM> defecto es sym y se puede cambiar con la directiva %cupsym . En el modo de
compatibilidad JLex ( --jlex switch en la línea de comando), %eofcloseno se activará.
 %cup2
La %cup2directiva es similar al modo CUP, solo para el generador CUP2 de TU Munich
en http://www2.in.tum.de/cup2 . Hace lo siguiente:

o agrega declaraciones de importación de paquetes CUP2


o implementa la interfaz del escáner CUP2
o Conmutadores en línea y columna.
o establece la función de escáner en readNextTerminal
o establece el tipo de token a ScannerToken<? extends Object>
o devuelve el token EOF de CUP2 especial al final del archivo
o enciende unicode
 %cupsym "classname"
Personaliza el nombre de la clase / interfaz generada por CUP que contiene los nombres de tokens de
terminal. El valor predeterminado es sym. La directiva no debe ser utilizada después %cup, solo antes.
 %cupdebug
Crea una función principal en la clase generada que espera el nombre de un archivo de entrada en la
línea de comandos y luego ejecuta el escáner en este archivo de entrada. Imprime la línea, la columna,
el texto coincidente y el nombre del símbolo CUP para cada token devuelto a la salida estándar.

4.2.6 Compatibilidad BYacc / J


También es posible que desee leer JFlex y BYacc / J si está interesado en cómo conectar su escáner generado
con Byacc / J.
 %byacc
La %byaccdirectiva habilita el modo de compatibilidad BYacc / J y es equivalente al siguiente conjunto
de directivas:
%integer

%eofval { return 0;

%eofval

} %eofclose

4.2.7 Conjuntos de caracteres de entrada


 %7bit
Hace que el escáner generado use un juego de caracteres de entrada de 7 bits (códigos de caracteres
0-127). Si se encuentra un carácter de entrada con un código mayor que 127 en una entrada en tiempo
de ejecución, el escáner lanzará un ArrayIndexOutofBoundsException. No solo por esto, debe considerar
el uso de la %unicodedirectiva. Consulte también Codificaciones para obtener información sobre las
codificaciones de caracteres. Este es el valor predeterminado en el modo de compatibilidad JLex.
 %full
%8bit
Ambas opciones hacen que el escáner generado use un juego de caracteres de entrada de 8 bits
(códigos de caracteres 0-255). Si se encuentra un carácter de entrada con un código mayor a 255 en
una entrada en tiempo de ejecución, el escáner lanzará un ArrayIndexOutofBoundsException. Tenga en
cuenta que incluso si su plataforma usa solo un byte por carácter, el valor Unicode de un carácter puede
ser mayor que 255. Si está escaneando archivos de texto, debe considerar el uso de
la %unicodedirectiva. Consulte también la sección Econdings para obtener más información acerca de
las codificaciones de caracteres.
 %unicode
%16bit
Ambas opciones hacen que el escáner generado use el conjunto completo de caracteres de entrada
Unicode, incluidos los puntos de código suplementarios: 0-0x10FFFF. %unicodeno significa que el
escáner leerá dos bytes a la vez. Lo que se lee y lo que constituye un personaje depende de la plataforma
de tiempo de ejecución. Consulte también la sección Codificaciones para obtener más información sobre
las codificaciones de caracteres. Este es el valor predeterminado a menos que se use el modo de
compatibilidad JLex (opción de línea de comando --jlex).
 %caseless
%ignorecase
Esta opción hace que JFlex maneje todos los caracteres y cadenas en la especificación como si
estuvieran especificados en mayúsculas y minúsculas. Esto permite una forma fácil de especificar un
escáner para un lenguaje con palabras clave que no distinguen entre mayúsculas y minúsculas. La
cadena breaken una especificación se maneja, por ejemplo, como la
expresión [bB][rR][eE][aA][kK]. La %caselessopción no cambia el texto coincidente y no afecta a las
clases de caracteres. Así que [a]todavía solo coincide con el personaje ay no A. Las letras en mayúsculas
y las letras en minúsculas se definen en el estándar Unicode. En el modo de compatibilidad JLex ( --
jlexcambiar en la línea de comando), %caselessy %ignorecasetambién afecta a las clases de caracteres.

4.2.8 Conteo de líneas, caracteres y columnas.


 %char
Activa el conteo de personajes. La intvariable miembro yycharcontiene el número de caracteres
(comenzando con 0) desde el comienzo de la entrada hasta el comienzo del token actual.
 %line
Activa el conteo de líneas. La intvariable miembro yylinecontiene el número de líneas (comenzando con
0) desde el comienzo de la entrada hasta el comienzo del token actual.
 %column
Activa el conteo de columnas. La intvariable miembro yycolumncontiene el número de caracteres
(comenzando con 0) desde el comienzo de la línea actual hasta el comienzo del token actual.

4.2.9 Opciones obsoletas de JLex


 %notunix
Esta opción de JLex está obsoleta en JFlex pero aún se reconoce como directiva válida. Se utiliza para
cambiar entre el tipo de terminadores de línea de Windows y Unix ( \r\ny \n) para el $operador en
expresiones regulares. JFlex siempre reconoce ambos estilos de terminadores de línea dependientes
de la plataforma.
 %yyeof
Esta opción de JLex está obsoleta en JFlex pero aún se reconoce como directiva válida. En JLex se
declara un miembro público constante YYEOF. JFlex lo declara en cualquier caso.

4.2.10 Declaraciones de estado


Las declaraciones de los estados tienen la siguiente forma:
%s[tate]"stateidentifier"[,"stateidentifier",...]para
%x[state] "state identifier" [, "state identifier",... ] estados inclusivos o exclusivos
Puede haber más de una línea de declaraciones de estado, cada una comenzando con %stateo %xstate. Los
identificadores de estado son letras seguidas de una secuencia de letras, dígitos o guiones bajos. Los
identificadores de estado pueden estar separados por espacios en blanco o comas.
La secuencia
%state STATE1

%xstate STATE3, XYZ, STATE_10

%state ABC STATE5

declara el conjunto de identificadores STATE1, STATE3, XYZ, STATE_10, ABC, STATE5como estados
léxicos, STATE1, ABC, STATE5lo más inclusivo, y STATE3, XYZ, STATE_10como exclusiva. Vea
también Cómo se empareja la entrada en la forma en que los estados léxicos influyen en cómo se empareja la
entrada.
4.2.11 Definiciones de macros
Una macro definición tiene la forma.
macroidentifier = regular expression

Eso significa que una definición de macro es un identificador de macro (letra seguida de una secuencia de
letras, dígitos o guiones bajos), que luego se puede usar para hacer referencia a la macro, seguida de un
espacio en blanco opcional, seguida de una =, seguida de un blanco opcional. espacio, seguido de una
expresión regular (consulte Reglas léxicas para obtener más información sobre la sintaxis de las expresiones
regulares).
La expresión regular en el lado derecho debe estar bien formada y no debe contener los operadores ^, /o $. A
diferencia de JLex, las macros no son solo fragmentos de texto que se expanden al copiar , sino que se analizan
y deben estar bien formados.
Esta es una característica Elimina algunos errores muy difíciles de encontrar en especificaciones léxicas (como
no tener paréntesis alrededor de macros más complicadas, lo que no es necesario con JFlex). Consulte Portar
desde JLex para obtener más detalles sobre los problemas de las macros de estilo JLex.
Como se permite tener usos de macros en las definiciones de macros, es posible usar una notación similar a la
gramática para especificar la estructura léxica deseada. Sin embargo, las macros permanecen solo como
abreviaturas de las expresiones regulares que representan. No son no terminales de una gramática y no pueden
usarse recursivamente. JFlex detecta ciclos en definiciones de macros y los informa en el momento de la
generación. JFlex también le advierte acerca de las macros que se han definido pero nunca se usaron en
la sección de reglas léxicas de la especificación.

4.3 Reglas léxicas


La sección de reglas léxicas de una especificación JFlex contiene un conjunto de expresiones y acciones
regulares (código Java) que se ejecutan cuando el escáner coincide con la expresión regular asociada.
La %includedirectiva se puede usar en esta sección para incluir reglas léxicas de un archivo separado. La
directiva será reemplazada textualmente por el contenido del archivo especificado.

4.3.1 Sintaxis
La sintaxis de la sección de reglas léxicas se describe mediante la siguiente gramática EBNF (los símbolos de
la terminal están incluidos entre "citas"):
LexicalRules ::= (Include|Rule)+

Include ::= '% include' (' '|'\t'|'\b')+ File

Rule ::= [StateList] ['^'] RegExp [LookAhead] Action

| [StateList] '<<EOF>>' Action

| StateGroup

StateGroup ::= StateList '{' Rule+ '}'

StateList ::= '<' Identifier (',' Identifier)* '>'

LookAhead ::= '$' | '/' RegExp

Action ::= '{' JavaCode '}' | '|'

RegExp ::= RegExp '|' RegExp


| RegExp RegExp

| '(' RegExp ')'

| ('!'|'~') RegExp

| RegExp ('*'|'+'|'?')

| RegExp "{" Number ["," Number] "}"

| CharClass

| PredefinedClass

| MacroUsage

| '"' StringCharacter+ '"'

| Character

CharClass ::= '[' ['^'] CharClassContent* ']'

| '[' ['^'] CharClassContent+ CharClassOperator CharClassContent+ ']'

CharClassContent ::= CharClass | Character

| Character'-'Character

| MacroUsage | PredefinedClass

CharClassOperator ::= '||' | '&&' | '--' | '~~'

MacroUsage ::= '{' Identifier '}'

PredefinedClass ::= '[:jletter:]'

| '[:jletterdigit:]'

| '[:letter:]'

| '[:digit:]'

| '[:uppercase:]'

| '[:lowercase:]'

| '\d' | '\D'

| '\s' | '\S'

| '\w' | '\W'

| '\p{' UnicodePropertySpec '}'

| '\P{' UnicodePropertySpec '}'

| '\R' | '.'

UnicodePropertySpec ::= BinaryProperty |


EnumeratedProperty (':' | '=') PropertyValue

BinaryProperty ::= Identifier

EnumeratedProperty ::= Identifier

PropertyValue ::= Identifier

La gramática utiliza los siguientes símbolos terminales:


 File
un nombre de archivo, ya sea absoluto o relativo al directorio que contiene la especificación léxica.
 JavaCode
una secuencia de la BlockStatementsdescrita en la Especificación del lenguaje Java (Gosling, Joy y
Steele 1996) , sección 14.2.
 Number
un entero decimal no negativo.
 Identifier
una letra [a-zA-Z]seguida de una secuencia de cero o más letras, dígitos o guiones bajos[a-zA-Z0-9_]
 Character
una secuencia de escape o cualquier carácter Unicode que no sea uno de estos metacaracteres: | ( ) { }
[]<>\.*+?^$/."~!
 StringCharacter
una secuencia de escape o cualquier carácter Unicode que no sea uno de estos metacaracteres: \ "
 Una secuencia de escape
o \n \r \t \f \b
o a \xseguido de dos dígitos hexadecimales [a-fA-F0-9](que denota una secuencia de escape
ASCII);
o a \useguido de cuatro dígitos hexadecimales [a-fA-F0-9], que denota una secuencia de escape
Unicode. Tenga en cuenta que estos son precisamente cuatro dígitos, \u12345es decir, es el
carácter \u1234seguido por el carácter 5.
o a \U(tenga en cuenta que la 'U' está en mayúsculas) seguido de seis dígitos hexadecimales [a-
fA-F0-9], que denota una secuencia de escape de punto de código Unicode;
o \u{H+( H+)*}, donde H+hay uno o más dígitos hexadecimales [a-fA-F0-9], cada uno H+denota un
punto de código; tenga en cuenta que en las clases de caracteres, solo se permite un punto de
código;
o una barra invertida seguida de un número octal de tres dígitos de 000 a 377, que denota una
secuencia de escape ASCII;
Tenga en cuenta que la \nsecuencia de escape representa el carácter ASCII LF, no el final de la línea. Si desea
hacer coincidir el terminador de línea, debe usar la expresión\r|\n|\r\nsi desea las convenciones de Java,
o \r\n|[\r\n\u2028\u2029\u000B\u000C\u0085](proporcionado como clase predefinida \R) si desea ser totalmente
compatible con Unicode (consulte también (Davis y Heninger 2013) ).
Los caracteres de espacio en blanco " "(espacio) y \t(tabulación) se pueden usar para mejorar la legibilidad de
las expresiones regulares. Ellos serán ignorados por JFlex. Sin embargo, en las clases de caracteres y cadenas,
los caracteres de espacios en blanco se mantienen en pie por sí mismos (de modo que la cadena " "aún coincide
exactamente con un carácter de espacio y [ \n]aún coincide con un LF ASCII o un carácter de espacio).
JFlex aplica las siguientes precedencias de operadores estándar en expresiones regulares (de mayor a menor):
 operadores de sufijo unarios ( *, +, ?, {n}, {n,m})
 operadores de prefijo unarios ( !, ~)
 concatenación ( RegExp::= RegExp Regexp)
 unión ( RegExp::= RegExp '|' RegExp)
Así que la expresión a | abc | !cd*por ejemplo se analiza como (a|(abc)) | ((!c)(d*)).

4.3.2 Semántica
Esta sección proporciona una descripción informal de qué texto coincide con una expresión regular, es decir,
una expresión descrita por la RegExpproducción de la gramática anterior .
Una expresión regular que consiste únicamente en
 a Charactercoincide con este personaje.
 una clase de personaje [...]coincide con cualquier personaje en esa clase. A Characterse considera un
elemento de una clase si aparece en la lista o si su código se encuentra dentro de un rango de
caracteres Character'-'Charactero macro o una clase de caracteres predefinidos. Así, [a0-3\n]por
ejemplo, coincide con los personajes
a 0 1 2 3 \n
Si la lista de caracteres está vacía (es decir, solo []), la expresión no coincide con nada (el conjunto
vacío), ni siquiera con la cadena vacía. Esto puede ser útil en combinación con el operador de
negación.! .
Los conjuntos de caracteres pueden estar anidados, por ejemplo, [[[abc]d[e]]fg]es equivalente
a [abcdefg].
Operaciones de juego de caracteres soportadas:
o Unión ( ||), por ejemplo [[ac]||[df]], equivalente a [a-cd-f]: esta es la operación predeterminada del
conjunto de caracteres cuando no se especifica ningún operador.
o Intersección ( &&), por ejemplo [[af]&&[fm]], equivalente a [f].
o Establecer diferencia ( --), por ejemplo [[az]--m], equivalente a [a-ln-z].
o Diferencia simétrica ( ~~): la unión de dos clases menos su intersección. Por ejemplo
[\p{Letter}~~\p{ASCII}]

es equivalente a
[[\p{Letter}||\p{ASCII}]--[\p{Letter}&&\p{ASCII}]]

el conjunto de caracteres que están presentes en cualquiera \p{Letter}o en \p{ASCII}, pero no en


ambos.
 una clase de caracteres negados '[^...]'coincide con todos los caracteres que no figuran en la clase. Si
la lista de caracteres está vacía (es decir [^]), la expresión coincide con cualquier carácter del conjunto
de caracteres de entrada.
 una cadena '' StringCharacter+ ''coincide con el texto exacto entre comillas dobles. Todos los meta
caracteres aparte de \y "pierden su significado especial dentro de una cadena. Véase también
el %ignorecaseinterruptor.
 el uso de una macro '{' Identifier '}'coincide con la entrada que coincide con el lado derecho de la macro
con el nombre Identifier.
 una clase de caracteres predefinida coincide con cualquiera de los caracteres en esa clase. Hay las
siguientes clases de caracteres predefinidos:
o dos clases de caracteres predefinidas que están determinadas por las funciones de la biblioteca
Java en la clase java.lang.Character:
[:jletter:] isJavaIdentifierStart() [:jletterdigit:] isJavaIdentifierPart()

o cuatro clases de caracteres predefinidas equivalentes a las siguientes propiedades Unicode


(descritas a continuación ):
[:letter:] \p{Letter} [:digit:] \p{Digit} [:uppercase:] \p{Uppercase} [:lowercase:]

\p{Lowercase}

o los siguientes metacaracteres, equivalentes a estos (conjuntos de) propiedades de Unicode


(descritos a continuación ):
\d \p{Digit} \D \P{Digit} \s \p{Whitespace} \S \P{Whitespace} \w

[\p{Alpha}\p{Digit}\p{Mark} \p{Connector Punctuation}\p{Join Control}] \W

[^\p{Alpha}\p{Digit}\p{Mark} \p{Connector Punctuation}\p{Join Control}]

o Las propiedades de Unicode son clases de caracteres especificadas por cada versión de Unicode
Standard. JFlex admite un subconjunto de todas las propiedades definidas para cada versión
Unicode compatible. Para ver la lista completa de propiedades admitidas, dé la –uniprops
<ver>opción en la línea de comandos de JFlex, donde <ver>está la versión Unicode. Algunas
propiedades tienen alias; JFlex reconoce todos los alias para todas las propiedades soportadas.
JFlex admite la concordancia suelta de Propiedades: se ignoran las distinciones entre
mayúsculas y minúsculas, espacios en blanco, guiones y guiones bajos.
Para referirse a una propiedad de Unicode, use la \p{...}sintaxis, por ejemplo, el bloque griego
puede denominarse \p{Block:Greek}. Para hacer coincidir todos los caracteres no incluidos en
una propiedad, use la \P{...}sintaxis (tenga en cuenta que ' P' está en mayúsculas), por ejemplo,
para hacer coincidir todos los caracteres que no son letras, use \P{Letter}.
Consulte UTS # 18 (Davis y Heninger 2013) para obtener una descripción y enlaces a las
definiciones de algunas propiedades admitidas. UnicodeSet (“Unicode Utilities: UnicodeSet”
2015) es una utilidad en línea para mostrar los conjuntos de caracteres correspondientes a las
propiedades de Unicode y establecer operaciones en ellos, pero solo para la versión más reciente
de Unicode.
o Dot(.) coincide [^\r\n\u2028\u2029\u000B\u000C\u0085].
Utilice la –legacydotopción para emparejar en su lugar [^\n].
o \Rcoincide con cualquier carácter de nueva línea: \r\n|[\r\n\u2028\u2029\u000B\u000C\u0085].

Si ay bson expresiones regulares, entonces


 a | b (Unión)
es la expresión regular que coincide con todas las entradas coincidentes por ao por b.
 ab (concatenación)
es la expresión regular que coincide con la entrada coincidente con aseguida por la entrada coincidente
con b.
 a* (Cierre de Kleene)
coincide con cero o más repeticiones de la entrada que coincide con a
 a+ (iteración)
es equivalente a aa*
 a? (opción)
coincide con la entrada vacía o la entrada coincidente con a
 !a (negación)
coincide con todo, pero las cadenas emparejadas por a. Use con cuidado: la construcción de !aimplica
una transformación adicional, posiblemente exponencial de NFA a DFA en la NFA para a. Tenga en
cuenta que con la negación y la unión también tiene (aplicando DeMorgan) intersección y diferencia de
conjunto: la intersección de ay bes !(!a|!b), la expresión que coincide con todo lo que ano coincide
con bes!(!a|b)
 ~a (hasta)
hace coincidir todo hasta (e incluido) la primera aparición de un texto que coincida con a. La
expresión ~aes equivalente a !([^]* a [^]*) a. Un comentario tradicional de estilo C es emparejado por"/*"
~"*/"
 a {n} (repetir)
Es equivalente a nveces la concatenación de a. Entonces, a{4}por ejemplo, es equivalente a la
expresión aaaa. El entero decimal ndebe ser positivo.
 a {n,m}
es equivalente a al menos nveces y la mayoría de las mveces la concatenación de a. Entonces, a{2,4}por
ejemplo, es equivalente a la expresiónaaa? a? .Ambos ny mson enteros decimales no negativos y mno
deben ser más pequeños que n.
 (a)
coincide con la misma entrada que a.
En una regla léxica, una expresión regular rpuede estar precedida por ^(el principio de un operador de
línea). rentonces solo se hace coincidir al principio de una línea en la entrada. Una línea comienza después de
cada aparición de \r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085(vea también (Davis y Heninger 2013) ) y al
comienzo de la entrada. El terminador de línea anterior en la entrada no se consume y puede coincidir con otra
regla.
En una regla léxica, una expresión regular rpuede ir seguida de una expresión de anticipación. Una expresión
de anticipación es $(el operador de fin de línea) o /seguida de una expresión regular arbitraria. En ambos casos,
la visión hacia adelante no se consume y no se incluye en la región de texto coincidente, pero se considera al
determinar qué regla tiene el partido más largo (ver también cómo se empareja la entrada ).
En el $caso, rsolo se hace coincidir al final de una línea en la entrada. El final de una línea se denota mediante
la expresión regular \r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085. Entonces a$es equivalente a a /
\r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085. Esto es diferente a la situación descrita en (Davis y Heninger
2013) : dado que en JFlex $es un verdadero contexto final, el final del archivo no cuenta como final de línea.
Para una vista anticipada arbitraria (también llamada contexto final ), la expresión coincide solo cuando está
seguida por una entrada que coincide con el contexto final.
JFlex permite <<EOF>>reglas de estilo lex / flex en especificaciones léxicas. Una regla
[StateList] <<EOF>> { action code }

Es muy similar a la %eofvaldirectiva. La diferencia radica en el opcional StateListque puede preceder a


la <<EOF>>regla. El código de acción solo se ejecutará cuando se lea el final del archivo y el escáner se
encuentre actualmente en uno de los estados léxicos enumerados en StateList. Lo mismo StateGroup(ver la
sección Cómo se hace coincidir la entrada ) y las reglas de precedencia que se aplican en el caso de la regla
"normal" (es decir, si hay más de una <<EOF>>regla para un determinado estado léxico, la acción de la que
apareció anteriormente en la especificación será ejecutado). <<EOF>>reglas de prioridad sobre los valores de
la %cupy %byaccj opciones y no se deben mezclar con la %eofvalDirectiva.
Una Action consiste en un fragmento de código Java incluido entre llaves o es el especial| acción. La |acción es
una abreviatura de la acción de la siguiente expresión.
Ejemplo:
expression1 | expression2 | expression3 { some action }

es equivalente a la forma expandida


expression1 { some action } expression2 { some action } expression3 { some action }

Son útiles cuando se trabaja con expresiones de contexto finales. La expresión a | (c / d) | bno es una expresión
regular sintácticamente legal, pero se puede expresar mediante la |acción:
a | c / d | b { some action }

4.3.3 Cómo se empareja la entrada


Cuando consume su entrada, el escáner determina la expresión regular que coincide con la parte más larga de
la entrada (regla de coincidencia más larga). Si hay más de una expresión regular que coincide con la parte
más larga de la entrada (es decir, todas coinciden con la misma entrada), el escáner generado elige la expresión
que aparece primero en la especificación. Después de determinar la expresión regular activa, se ejecuta la
acción asociada. Si no hay una expresión regular coincidente, el escáner finaliza el programa con un mensaje
de error (si %standalone se ha utilizado la directiva, el escáner imprime la entrada no
coincidente java.lang.System.outy, en su lugar, reanuda el escaneo).
Los estados léxicos se pueden usar para restringir aún más el conjunto de expresiones regulares que coinciden
con la entrada actual.
 Una expresión regular solo puede coincidir cuando su conjunto asociado de estados léxicos incluye el
estado léxico activo actual del escáner o si el conjunto de estados léxicos asociados está vacío y el
estado léxico activo actual es inclusivo. Los estados exclusivos e inclusivos solo difieren en este punto:
las reglas con un conjunto vacío de estados asociados.
 El estado léxico actualmente activo del escáner se puede cambiar desde una acción de una expresión
regular usando el método yybegin().
 El escáner se inicia en el estado léxico inclusivo YYINITIAL, que siempre se declara de forma
predeterminada.
 El conjunto de estados léxicos asociados con una expresión regular es el StateListque precede a la
expresión. Si una regla está contenida en uno o más StateGroups, entonces los estados de estos
también están asociados con la regla, es decir, se acumulan StateGroups.
Ejemplo:
%states A, B %xstates C %% expr1 { yybegin(A); action } <YYINITIAL, A> expr2 { action } <A>

{ expr3 { action } <B,C> expr4 { action } }

La primera línea declara dos estados léxicos (inclusive) Ay B, la segunda línea, un estado léxico
exclusivo C. El estado predeterminado (incluido) YYINITIALsiempre está implícitamente allí y no es
necesario declararlo. La regla de expr1no tiene estados mencionados, y por lo tanto se corresponde en
todos los estados los mas exclusivos, es decir A, B, y YYINITIAL. En su acción, el escáner se cambia a
estado A. La segunda regla expr2solo puede coincidir cuando el escáner está en estado YYINITIALo A.
La regla expr3sólo puede ser igualado en el estado Ay expr4en los estados A, By C.
 Los estados léxicos se declaran y se usan como intconstantes de Java en la clase generada con el
mismo nombre que se usan en la especificación. No hay garantía de que los valores de estas constantes
enteras sean distintos. Son indicadores en la tabla DFA generada, y si JFlex reconoce dos estados como
equivalentes léxicos (si se usan con el mismo conjunto de expresiones regulares), las dos constantes
obtendrán el mismo valor.

4.3.4 La clase generada


JFlex genera exactamente un archivo que contiene una clase de la especificación (a menos que haya declarado
otra clase en la primera sección de especificación).
La clase generada contiene (entre otras cosas) las tablas DFA, un búfer de entrada, los estados léxicos de la
especificación, un constructor y el método de exploración con las acciones proporcionadas por el usuario.
El nombre de la clase es por defecto Yylex. El nombre es personalizable con la %classdirectiva. El búfer de
entrada del lexer está conectado con una entrada externa a través del java.io.Readerobjeto que se pasa al lexer
en el constructor generado. Si proporciona su propio constructor para el lexer, siempre debe realizar una llamada
en cadena al generado para inicializar el búfer de entrada. No se debe acceder al búfer de entrada directamente,
sino solo a través de la API anunciada (consulte también Métodos de escáner ). Su implementación interna
puede cambiar entre versiones o archivos esqueléticos sin previo aviso.
La interfaz principal para el mundo exterior es el método de escaneo generado (nombre yylexpredeterminado,
tipo de retorno predeterminado Yytoken). La mayoría de sus aspectos son personalizables (nombre, tipo de
devolución, excepciones declaradas, etc.). Si se llama, consumirá entrada hasta que una de las expresiones de
la especificación coincida o se produzca un error. Si una expresión coincide, se ejecuta la acción
correspondiente. Puede devolver un valor del tipo de retorno especificado (en cuyo caso el método de escaneo
regresa con este valor) o, si no devuelve un valor, el escáner continúa consumiendo información hasta que la
siguiente expresión coincida. Si se llega al final del archivo, el escáner ejecuta la EOFacción y (también con
cada llamada adicional al método de escaneo) devuelve el EOFvalor especificado .

4.3.5 Métodos y campos de escáner accesibles en acciones (API)


Los métodos generados y los campos de miembros en los escáneres JFlex tienen el prefijo yypara indicar que
se generaron y para evitar conflictos de nombre con el código de usuario copiado en la clase. Dado que el
código de usuario es parte de la misma clase, JFlex no tiene medios de lenguaje como el privatemodificador
para indicar qué miembros y métodos son internos y cuáles pertenecen a la API. En su lugar, JFlex sigue una
convención de denominación: todo lo que comienza con zz, por ejemplo zzStartRead, es interno y está sujeto
a cambios sin previo aviso entre las versiones de JFlex. Los métodos y los miembros de la clase generada que
no tienen un zzprefijo, como por ejemplo yycharat, pertenecen a la API que la clase de escáner proporciona a
los usuarios en el código de acción de la especificación. Permanecerán estables y soportados entre las
versiones de JFlex el mayor tiempo posible.
Actualmente, la API consta de los siguientes métodos y campos de miembros:
 String yytext()
devuelve la región de texto de entrada coincidente
 int yylength()
devuelve la longitud de la región de texto de entrada coincidente como número de Java chars(a
diferencia de los puntos de código Unicode). No requiere que un Stringobjeto sea creado.
 char yycharat(int pos)
devuelve el Java charen la posición posdel texto coincidente. Es equivalente a yytext().charAt(pos), pero
más rápido. posdebe ser un valor de 0a yylength()-1.
 void yyclose()
cierra el flujo de entrada. Todas las llamadas posteriores al método de escaneo devolverán el valor del
final del archivo
 void yyreset(java.io.Reader reader)
cierra el flujo de entrada actual y restablece el escáner para leer desde un nuevo Reader. Todas las
variables internas se restablecen, el antiguo Reader no se puede reutilizar (el contenido del búfer interno
se descarta y se pierde). El estado léxico se establece en YY_INITIAL. El %{initcódigo no se incluye
en yyreset, porque se supone que se ejecuta en el contexto de un constructor, no un método
normal. Si %{inites necesario repetirlo, considere construir un nuevo objeto lexer en su lugar, o llamar a
una función personalizada que realice un restablecimiento de estado de nivel de usuario adicional.
 void yypushStream(java.io.Reader reader)
Almacena el flujo de entrada actual en una pila y lee de un nuevo flujo. El estado léxico, la línea, el
carácter y el recuento de columnas permanecen intactos. El flujo de entrada actual se puede restaurar
con yypopStream(normalmente en una <<EOF>>acción).
Un ejemplo típico de esto son los archivos incluidos en estilo del preprocesador C. La especificación
JFlex correspondiente podría verse así:
"#include" {FILE} { yypushStream(new FileReader(getFile(yytext()))); } ... <<EOF>> { if

(yymoreStreams()) yypopStream(); else return EOF; }

Este método solo está disponible en el archivo esqueleto skeleton.nested. Lo puedes encontrar en
el srcdirectorio de la distribución JFlex.
 void yypopStream()
Cierra la secuencia de entrada actual y continúa leyendo desde la que está en la parte superior de la
pila de secuencias.
Este método solo está disponible en el archivo esqueleto skeleton.nested. Lo puedes encontrar en
el srcdirectorio de la distribución JFlex.
 boolean yymoreStreams()
Devuelve verdadero si todavía hay secuencias para yypopStreamleer en la pila de secuencias.
Este método solo está disponible en el archivo esqueleto skeleton.nested. Lo puedes encontrar en
el srcdirectorio de la distribución JFlex.
 int yystate()
Devuelve el estado léxico actual del escáner.
 void yybegin(int lexicalState)
entra en el estado léxico lexicalState
 void yypushback(int number)
empuja numberJava chars (a diferencia de los puntos de código Unicode) del texto coincidente de nuevo
en el flujo de entrada. Se volverán a leer en la próxima llamada del método de escaneo. El número de
caracteres que se volverán a leer no debe ser mayor que la longitud del texto coincidente. Los caracteres
rechazados no se incluirán en yylength()y yytext(). Tenga en cuenta que en Java las cadenas son
invariables, es decir, un código de acción como
String matched = yytext(); yypushback(1); return matched;

devolverá todo el texto combinado, mientras que


yypushback(1); return yytext();
devolverá el texto coincidente menos el último carácter.
Tenga en cuenta que con los caracteres sustitutos de Unicode es posible que expresiones tales
como [^]coincidan con más de uno char.
 int yyline
contiene la línea de entrada actual (comenzando con 0, solo activa con la lineCountingdirectiva)
 int yychar
contiene el recuento de caracteres actual en la entrada (comenzando con 0, solo activo con
la charCountingdirectiva)
 int yycolumn
contiene la columna actual de la línea actual (comenzando con 0, solo activa con
la columnCountingdirectiva)
Unicode y viceversa, pero lo importante es que esta asignación es al menos posible (puedes asignar caracteres
Kanji a Unicode, pero no puede mapearlos a ASCII o iso-latin-1).
_________________________RESUMEN_________________________
4 Especificaciones léxicas
JFlex consta de tres partes divididas por una sola línea que comienza con %% :

UserCode %% Options and declarations %% Lexical rules

En todas las partes de la especificación se permiten los comentarios de la forma /* comment text */ y los /*
comment text */ fin de línea de estilo Java que comienzan con // .Los comentarios de JFlex se anidan, por lo
que el número de /* y */ debe estar equilibrado.

4.1 Codigo de usuario


La primera parte contiene código de usuario que se copia literalmente al principio del archivo fuente generado
antes de la declaración de clase del escáner.

4.2 Opciones y declaraciones.


La segunda parte de la especificación léxica contiene opciones y directivas para personalizar el lexer generado,
las declaraciones de estados léxicos y las definiciones de macro .

Cada directiva JFlex debe sentarse al principio de una línea y comienza con el carácter % . Las directivas que
tienen uno o más parámetros se describen a continuación.

%class "classname"

4.2.1 Opciones de clase y código de clase de usuario


Estas opciones se refieren al nombre, al constructor, a la API y a las partes relacionadas de la clase de escáner
generada. Algunos ejemplos son:
 %class "classname"
Le dice a JFlex que le dé a la clase generada el nombre classname y que escriba el código generado
en un archivo classname.java.
 %implements "interface 1"[, "interface 2", ..]
Hace que la clase lexer generada implemente las interfaces especificadas.
 %public
Hace que la clase generada sea pública
 %final
Hace que la clase generada sea final.
 %api private
Hace que todos los métodos y campos generados de la clase sean privados. .
 %scanerror "exception"
Hace que el escáner generado lance una instancia de la excepción especificada en caso de un error
interno
4.2.2 Método de escaneo
Esta sección muestra cómo se puede personalizar el método de escaneo. Puede redefinir el nombre y el tipo
de retorno del método y es posible declarar las excepciones que se pueden lanzar en una de las acciones de
la especificación. Algunos Ejemplos son:
 %function "name"
Hace que el método de escaneo obtenga el nombre especificado.
 %integer
%int
Ambos hacen que el método de exploración se declare como devuelto tipo Java int.

4.2.3 El final del archivo


Siempre hay un valor predeterminado que devolverá el método de escaneo cuando se llegue al final del archivo.
El valor predeterminado de fin de archivo depende del tipo de retorno del método de escaneo:
 Para %integer , el método de exploración devolverá el valor YYEOF , que es un miembro public static
final int de la clase generada.
 para un tipo definido por el usuario, declarado usando %type , el valor es null .
 En el modo de compatibilidad CUP, usando %cup , el valor es new java_cup.runtime.Symbol(sym.EOF)

4.2.4 Escáneres independientes


 %debug
Crea una función principal en la clase generada que espera el nombre de un archivo de entrada en la
línea de comandos y luego ejecuta el escáner en este archivo de entrada imprimiendo información sobre
cada token devuelto a la consola.
 %standalone
Crea una función principal en la clase generada que espera el nombre de un archivo de entrada en la
línea de comandos y luego ejecuta el escáner en este archivo de entrada.

4.2.5 Compatibilidad CUP


 %cup
La directiva %cup habilita el modo de compatibilidad CUP y es equivalente al siguiente conjunto de
directivas:
 %cup2
La %cup2directiva es similar al modo CUP, solo para el generador CUP2 de TU Munich. Hace lo
siguiente:

 Agrega declaraciones de importación de paquetes CUP2


 Implementa la interfaz del escáner CUP2
 Conmutadores en línea y columna.
 Establece la función de escáner en readNextTerminal
 Establece el tipo de token a ScannerToken<? extends Object>
 Devuelve el token EOF de CUP2 especial al final del archivo
 Enciende Unicode
4.2.6 Compatibilidad BYacc / J
También es posible que desee leer JFlex y BYacc / J si está interesado en cómo conectar su escáner generado
con Byacc / J.
 %byacc

4.2.7 Conjuntos de caracteres de entrada


Algunos ejemplos:
 %7bit
Hace que el escáner generado use un juego de caracteres de entrada de 7 bits (códigos de caracteres
0-127). Si se encuentra un carácter de entrada con un código mayor que 127, el escáner lanzará
un ArrayIndexOutofBoundsException.
 %full
%8bit
Ambas opciones hacen que el escáner generado use un juego de caracteres de entrada de 8 bits
(códigos de caracteres 0-255). Si se encuentra un carácter mayor a 255 en una entrada en tiempo de
ejecución, el escáner lanzará un ArrayIndexOutofBoundsException.

4.2.8 Conteo de líneas, caracteres y columnas.


 %char
Activa el conteo de personajes. La variable miembro int y char,contiene el número de caracteres desde
el comienzo de la entrada hasta el comienzo del token actual.
 %line
Activa el conteo de líneas. La variable miembro y line contiene el número de líneas.
 %column
Activa el conteo de columnas. La variable miembro y column contiene el número de caracteres desde el
comienzo de la línea actual hasta el comienzo del token actual.

4.2.9 Opciones obsoletas de JLex


 %notunix
Esta opción de JLex está obsoleta en JFlex pero aún se reconoce como directiva válida. Se utiliza para
cambiar entre el tipo de terminadores de línea de Windows y Unix.
 %yyeof
Esta opción de JLex está obsoleta en JFlex pero aún se reconoce como directiva válida.

4.2.10 Declaraciones de estado


Las declaraciones de los estados tienen la siguiente forma:
%s[tate]"stateidentifier"[,"stateidentifier",...].para
%x[state] "state identifier" [, "state identifier", ... ] estados inclusivos o exclusivos
4.2.11 Definiciones de macros
Una macro definición tiene la forma.
macroidentifier = regular expression

Eso significa que una definición de macro es un identificador de macro, seguida de una =, seguida de un blanco
opcional,espacio, seguido de una expresión regular
La expresión regular en el lado derecho debe estar bien formada y no debe contener los operadores ^, /o $.

4.3 Reglas léxicas


La sección de reglas léxicas de una especificación JFlex contiene un conjunto de expresiones y acciones
regulares que se ejecutan cuando el escáner coincide con la expresión regular asociada.

4.3.1 Sintaxis
La sintaxis de la sección de reglas léxicas se describe mediante la siguiente gramática EBNF. La gramática
utiliza los siguientes símbolos terminales: (Algunos Ejemplos)

 File
un nombre de archivo, ya sea absoluto o relativo al directorio que contiene la especificación léxica.
 Number
un entero decimal no negativo.
 Identifier
una letra [a-zA-Z]seguida de una secuencia de cero o más letras
 Character
una secuencia de escape o cualquier carácter Unicode que no sea uno de estos metacaracteres: | ( ) { }
[]<>\.*+?^$/."~!
 StringCharacter
una secuencia de escape o cualquier carácter Unicode que no sea uno de estos metacaracteres: \ "
Los caracteres de espacio en blanco " y \t se pueden usar para mejorar la legibilidad de las expresiones
regulares. Ellos serán ignorados por JFlex.
JFlex aplica las siguientes precedencias de operadores estándar en expresiones regulares operadores de sufijo
unarios
 operadores de prefijo unarios ( !, ~)
 concatenación ( RegExp::= RegExp Regexp)
 unión ( RegExp::= RegExp '|' RegExp)

4.3.2 Semántica
Esta sección proporciona una descripción informal de qué texto coincide con una expresión regular.
Una expresión regular que consiste únicamente en
 Un Character coincide con este personaje.
 Una clase de personaje [...] coincide con cualquier personaje en esa clase.
 Si la lista de caracteres está vacía,la expresión no coincide con nada, ni siquiera con la cadena vacía. .
Los conjuntos de caracteres pueden estar anidados
o Unión ( ||), por ejemplo [[ac]||[df]], equivalente a [a-cd-f].
o Intersección ( &&), por ejemplo [[af]&&[fm]], equivalente a [f].
o Establecer diferencia ( --), por ejemplo [[az]--m], equivalente a [a-ln-z].
Si a y b son expresiones regulares, entonces
 a | b (Unión) es la expresión regular que coincide con todas las entradas coincidentes por a o por b.
 ab (concatenación) es la expresión regular que coincide con la entrada coincidente con a seguida por la
entrada coincidente con b.
 a* coincide con cero o más repeticiones de la entrada que coincide con a
 a+ (iteración) es equivalente a aa*
 a? (opción) coincide con la entrada vacía o la entrada coincidente con a
 !a (negación) coincide con todo, pero las cadenas emparejadas por a.
 ~a (hasta) hace coincidir todo hasta la primera aparición de un texto que coincida con a.
 a {n} (repetir)
 a {n,m} es equivalente a al menos n veces y la mayoría de las m veces la concatenación de a
 (a) coincide con la misma entrada que a.

4.3.3 Cómo se empareja la entrada


Cuando consume su entrada, el escáner determina la expresión regular que coincide con la parte más larga de
la entrada. Si hay más de una expresión regular que coincide con la parte más larga de la entrada, el escáner
generado elige la expresión que aparece primero en la especificación.
Los estados léxicos se pueden usar para restringir aún más el conjunto de expresiones regulares que coinciden
con la entrada actual.
 Una expresión regular solo puede coincidir cuando su conjunto asociado de estados léxicos incluye el
estado léxico activo actual del escáner.
 El estado léxico actualmente activo del escáner se puede cambiar desde una acción de una expresión
regular usando el método yybegin().
 El escáner se inicia en el estado léxico inclusivo YYINITIAL, que siempre se declara de forma
predeterminada.
 El conjunto de estados léxicos asociados con una expresión regular es el StateListque precede a la
expresión.

4.3.4 La clase generada


JFlex genera exactamente un archivo que contiene una clase de la especificación.
La clase generada contiene las tablas DFA, un búfer de entrada, los estados léxicos de la especificación, un
constructor y el método de exploración con las acciones proporcionadas por el usuario.
El nombre de la clase es por defecto Yylex..
La interfaz principal para el mundo exterior es el método de escaneo generado. La mayoría de sus aspectos
son personalizables.
4.3.5 Métodos y campos de escáner accesibles en acciones (API)
Los métodos generados y los campos de miembros en los escáneres JFlex tienen el prefijo yy para indicar que
se generaron y para evitar conflictos de nombre con el código de usuario copiado en la clase.
Actualmente, la API consta de los siguientes métodos y campos de miembros:(Algunos ejemplos)
 String yytext()
Devuelve la región de texto de entrada coincidente
 int yylength()
Devuelve la longitud de la región de texto de entrada coincidente como número de Java chars(a
diferencia de los puntos de código Unicode
 char yy charat
Devuelve el Java charen la posición posdel texto coincidente.
 void yyclose()
Cierra el flujo de entrada.
 int yystate()
Devuelve el estado léxico actual del escáner.
 void yybegin(int lexicalState)
Entra en el estado léxico lexicalState
 void yypushback(int number)
Empuja numberJava chars del texto coincidente de nuevo en el flujo de entrada.
 int yyline
Contiene la línea de entrada actual
 int yychar
Contiene el recuento de caracteres actual en la entrada.
 int yycolumn
Contiene la columna actual de la línea actual.

S-ar putea să vă placă și