SlideShare a Scribd company logo
1 of 17
Sintaxis para la construcción de archivos de gramática para JavaCC 
Los Tokens en los archivos de gramática siguen las mismas convenciones que para el 
lenguaje de programación Java. Por tanto identificadores, cadenas, caracteres, etc. 
Utilizada en las gramáticas son iguales que los identificadores de Java, cadenas de Java, 
caracteres de Java, etc. 
Los espacios en blanco en los archivos de gramática también siguen las mismas 
convenciones para el lenguaje de programación Java. Este incluye la sintaxis para 
comentarios. La mayor parte de los comentarios presentes en los archivos de gramáticas 
son generados dentro del analizador léxico/sintáctico generado. 
Los archivos de gramática son preprocesados por códigos de escape Unicode tal como 
aparecen en los archivos Java (las ocurrencias de cadenas tales como uxxxx – donde 
xxxx es un valor hex – son convertidos al carácter Unicode correspondiente antes de 
efectuar el análisis léxico). 
Las excepciones a las reglas antes descritas: Los operadores de Java: "<<", ">>", ">>>", 
"<<=", ">>=", y ">>>=" son retiradas por la izquierda de la lista de tokens de entrada de 
JavaCC para permitir un uso conveniente de la especificación de tokens. Finalmente, las 
siguientes son las palabras reservadas adicionales en los archivos de gramática de 
JavaCC. 
EOF IGNORE_CASE JAVACODE LOOKAHEAD 
MORE options PARSER_BEGIN PARSER_END 
SKIP SPECIAL_TOKEN TOKEN TOKEN_MGR_DECLS 
Cualquier entidad de Java utilizada en las reglas de la gramática que a continuación 
aparezca con el prefijo java_ (Ej., java_compilation_unit). 
-------------------------------------------------------------------------------- 
javacc_input ::= javacc_options 
"PARSER_BEGIN" "(" <IDENTIFIER> ")" 
java_compilation_unit 
"PARSER_END" "(" <IDENTIFIER> ")" 
( production )* 
<EOF> 
Los archivos de gramática comienzan con una lista de opciones (las cuales son 
opcionales). Esto es entonces seguido por la unidad de compilación de Java encerrado 
entre "PARSER_BEGIN(name)" y "PARSER_END(name)". Despues de esto hay una 
lista de producciones de la gramática. Las opciones y producciones son descritas 
posteriormente. 
El nombre que sigue a "PARSER_BEGIN" y "PARSER_END" debe ser el mismo e 
identifica el nombre del parser generado. Por ejemplo, si el nombre es "MiParser", 
entonces se generan los siguientes archivos: 
MiParser.java: El analizador generado. 
MiParserTokenManager.java: El manejador de tokens generado (o analizador léxico).
MiParserConstants.java: Un conjunto de constantes útiles. 
Otros archivos como "Token.java", "ParseError.java", etc. También son generados. 
Estos archivos contienen código modelo y son el mismo para cualquier gramática y 
pueden ser reutilizadas en otras gramáticas. 
Entre las construcciones PARSER_BEGIN y PARSER_END se encuentra una unidad 
regular de compilación de Java (una unidad de compilación en java puede ser el 
contenido completo de un archivo en Java). Esto puede ser cualquier unidad de 
compilación arbitraria tan grande como contenga una declaración de clase y cuyo 
nombre sea el mismo que el nombre del parser generado ("MiParser" en el ejemplo 
anterior). Por tanto, en general, esta parte del archivo de la gramática se vera como: 
PARSER_BEGIN(parser_name) 
. . . 
clase parser_name . . . { 
. . . 
} 
. . . 
PARSER_END(parser_name) 
JavaCC no realiza ninguna revisión detallada en la unidad de compilación, así esto es 
posible para un archivo de gramática pasar a través de JavaCC y generar los archivos 
que producen errores cuando estos son compilados. 
Si la unidad de compilación incluye un paquete de declaración, esto es incluido en todos 
los archivos generados. Si la unidad de compilación importa declaraciones, estas se 
incluyen en el parser generado y en los archivos del manejador de tokens. 
Si el archivo de parser generado contiene todo en la unida de compilación y en adición, 
contiene el código generado del parser que se incluye al fin de la clase del parser. Para 
el ejemplo anterior, el parser generado se podría ver como sigue: 
. . . 
clase parser_name . . . { 
. . . 
// El parser generado se incluye aqui. 
} 
. . . 
Los parsers generados incluyen la declaración de un método público para cada no-terminal 
(ver javacode_production y bnf_production) en el archivo de gramática. El 
Análisis Sintáctico con respecto a un no-terminal se logra invocando el método 
correspondiente a ese no-terminal. A diferencia de yacc, no hay ningún símbolo inicial 
en JavaCC – uno puede iniciar el análisis sintáctico con respecto a cualquier no-terminal 
en la gramática. 
El manejador de tokens provee un método público: 
Token getNextToken() throws ParseError;
Para más detalles en como puede ser utilizado este método, lea la documentación de 
JavaCC. 
javacc_options ::= [ "options" "{" ( option_binding )* "}" ] 
Si la palabra “options” está presente, inicia con la palabra reservada “options” seguida 
de una lista de más opciones encerradas con corchetes. Cada opción encerrada 
especifica el establecimiento de una opción. La misma opción no debe ser indicada 
varias veces. 
Las opciones pueden ser especificadas tanto aquí en el archivo de gramática o desde la 
línea de comandos. Si la opción se coloca desde la línea de comandos, esta toma 
precedencia. 
Los nombres de opciones pueden ser mayúsculas o minúsculas. 
-------------------------------------------------------------------------------- 
option_binding ::= "LOOKAHEAD" "=" java_integer_literal ";" 
| "CHOICE_AMBIGUITY_CHECK" "=" java_integer_literal ";" 
| "OTHER_AMBIGUITY_CHECK" "=" java_integer_literal ";" 
| "STATIC" "=" java_boolean_literal ";" 
| "DEBUG_PARSER" "=" java_boolean_literal ";" 
| "DEBUG_LOOKAHEAD" "=" java_boolean_literal ";" 
| "DEBUG_TOKEN_MANAGER" "=" java_boolean_literal ";" 
| "OPTIMIZE_TOKEN_MANAGER" "=" java_boolean_literal ";" 
| "ERROR_REPORTING" "=" java_boolean_literal ";" 
| "JAVA_UNICODE_ESCAPE" "=" java_boolean_literal ";" 
| "UNICODE_INPUT" "=" java_boolean_literal ";" 
| "IGNORE_CASE" "=" java_boolean_literal ";" 
| "USER_TOKEN_MANAGER" "=" java_boolean_literal ";" 
| "USER_CHAR_STREAM" "=" java_boolean_literal ";" 
| "BUILD_PARSER" "=" java_boolean_literal ";" 
| "BUILD_TOKEN_MANAGER" "=" java_boolean_literal ";" 
| "TOKEN_MANAGER_USES_PARSER" "=" java_boolean_literal ";" 
| "SANITY_CHECK" "=" java_boolean_literal ";" 
| "FORCE_LA_CHECK" "=" java_boolean_literal ";" 
| "COMMON_TOKEN_ACTION" "=" java_boolean_literal ";" 
| "CACHE_TOKENS" "=" java_boolean_literal ";" 
| "OUTPUT_DIRECTORY" "=" java_string_literal ";" 
LOOKAHEAD: El numero de tokens a observar por delante antes de tomar una 
decisión en un punto de opciones durante el Análisis Sintáctico. El valor por default es 
1. Mientras más pequeño sea dicho numero, el Análisis será más rápido. Este número 
puede ser sobre-encimado por producciones específicas dentro de la gramática como se 
describirá posteriormente. Ver la descripción del algoritmo lookahead para los detalles 
completos en como trabaja lookahead. 
CHOICE_AMBIGUITY_CHECK: Esta es una opción entera la cual tiene un valor por 
default de 2. Este es el numero de tokens considerados en la revisión de ambigüedad de 
opciones desde “A|B…”. Por ejemplo, si hay dos prefijos de tokens comunes tanto para 
A y B, pero no hay tres tokens prefijos comunes, (asumiendo que esta opción se pone a 
3) entonces JavaCC puede informarte que debes usar un lookahead de 3 para propósitos
de eliminar la ambigüedad. Y si A y B tienen tres tokens prefijos comunes, entonces 
JavaCC solo te dice que puedes necesitar tener un lookahead de 3 o más. Al incrementar 
este valor te puede dar más información respecto a la ambigüedad al costo de más 
tiempo de procesamiento. Para gramáticas más grandes como la gramática de Java, 
incrementar este número mas allá causa que la revisión tome mucho más tiempo. 
OTHER_AMBIGUITY_CHECK: Esta es una opción de un número entero el cual su 
valor por defecto es 1. Este es el numero de tokens considerados en la revisión de todos 
los otros tipos de opciones de ambigüedad (ej. de las formas "(A)*", "(A)+", y "(A)?"). 
Esto toma más tiempo en hacerse que revisar la opción, y por tanto el valor por default 
es colocado en 1 más bien que 2. 
STATIC: Esta es una opción tipo lógica la cual su valor por default es verdadero. Si es 
verdadero, todos los métodos y variables de clases son especificados como estáticas en 
el analizador generado y el manejador de tokens. Esto solo permite que un objeto parser 
esté presente, pero mejora el rendimiento del analizador. Para realizar varios 
analizadores durante una ejecución del programa Java, tienes que invocar el método 
ReInit() para reinicializar el parser si éste es estático. Si el parser es no-static puedes 
utilizar el operador “new” para construir tantos parsers como necesites. Estos pueden 
ser utilizados simultáneamente desde diferentes threads. 
DEBUG_PARSER: Esta es una opción tipo lógica la cual establece un valor por default 
de falso. Esta opción es utilizada para obtener información de depuración desde los 
analizadores generados. Al establecer estas opciones en verdadero ocasiona que los 
parsers generen el seguimiento de sus acciones. El seguimiento puede ser deshabilitado 
invocando el método disable_tracing() en la clase del parser generado. El seguimiento 
puede ser posteriormente habilitado al invocar el método enable_tracing() en la clase del 
parser generado. 
DEBUG_LOOKAHEAD: Esta es una opción tipo lógica la cual tiene un valor por 
default de falso. Al establecer esta opción en verdadero (true) causa que el parser genere 
toda la información de seguimiento que se hace cuando se establece la opción 
DEBUG_PARSER en verdadero, en adición, esto también ocasiona que se genere la 
ruta de las acciones realizadas durante las operaciones de lookahead 
DEBUG_TOKEN_MANAGER: Esta es una opción de tipo lógica la cual por default se 
establece en false. Esta opción es utilizada para obtener información de depuración 
desde el manejador de tokens. Al establecer esta opción en true ocasiona que el 
manejador de tokens genere un seguimiento de sus acciones. Este seguimiento es 
bastante extenso y solo debe usarse cuando tengas un error léxico que haya sido 
reportado y no comprendas porque. Típicamente, en esta situación, puedes determinar el 
problema observando las últimas cuantas líneas del seguimiento. 
ERROR_REPORTING: Esta es una opción la cual tiene un valor por default de 
verdadero “true”. Si se establece en falso causará que los errores sean reportados con 
menos detalles. La única razón para poner ésta opción en falso es mejorar su eficiencia. 
JAVA_UNICODE_ESCAPE: Esta es una opción tipo lógica la cual tiene un valor por 
default de falso. Cuando se establece en “true”, el parser generado utiliza un objeto de 
flujo de entrada que procesa los códigos de escape Unicode de Java (u...) antes de
enviar los caracteres al manejador de tokens. Por default, los códigos de escape Unicode 
de Java no son procesados. Esta opción se ignora si cualquiera de las opciones 
USER_TOKEN_MANAGER, USER_CHAR_STREAM se establece en true. 
UNICODE_INPUT: Esta es una opción tipo lógica la cual su valor por default es falso. 
Cuando se establece en true, el parser generado utiliza un objeto de flujo de entrada que 
lee los archivos Unicode. Por default se asume que los archivos son ASCII. Esta opción 
se ignora si se establece en true cualquiera de las opciones 
USER_TOKEN_MANAGER, USER_CHAR_STREAM. 
IGNORE_CASE: Esta es una opción de tipo lógica la cual el valor default es falso. Al 
poner esta opción causa que el manejador de tokens generado ignore la diferencia entre 
mayúsculas y minúsculas en la especificación de tokens y los archivos de entrada. Esto 
es útil para escribir gramáticas para lenguajes tales como HTML. 
USER_TOKEN_MANAGER: Esta es una opción tipo lógica la cual tiene por default el 
valor falso. La acción por default es generar un token manager que trabaja en aceptar 
tokens desde cualquier token manager de tipo “TokenManager” – esta interfase es 
generada dentro del directorio del parser generado. 
USER_CHAR_STREAM: Esta es una opción tipo lógica la cual por default se establece 
en falso. La acción por default es generar un lector de flujo de caracteres tal como se 
especifica en las opciones JAVA_UNICODE_ESCAPE y UNICODE_INPUT. El 
analizador léxico generado recibe los caracteres de este lector de flujo. Si esta opción se 
establece en verdadero (true), entonces el analizador léxico generado para leer los 
caracteres desde cualquier lector de flujo de tipo "CharStream.java". El archivo es 
generado dentro del directorio del analizador sintáctico generado 
Esta opción se ignora si USER_TOKEN_MANAGER se establece en verdadero. 
BUILD_PARSER: Esta es una opción de tipo lógica la cual tiene un valor por default 
de verdadero. La acción por default es generar el archivo de parser (("MiParser.java" en 
el ejemplo anterior). Cuando se establece en falso, el archivo del parser no es generado. 
Típicamente esta opción se pone en falso cuando solamente se desea generar el 
analizador léxico y utilizarlo sin el analizador léxico asociado (parser). 
BUILD_TOKEN_MANAGER: Esta es una opción de tipo lógico la cual se establece 
por default al valor “true”. La acción por default es generar el archivo del Manejador de 
Tokens (Analizador léxico - "MiParserTokenManager.java" en el ejemplo anterior). 
Cuando se establece en falso el archivo del analizador léxico no se genera. La única 
razón para colocar esta opción en falso es ahorrar tiempo durante la generación del 
analizador léxico cuando se arregla un problema en la parte de la gramática del 
analizador y se deja las especificaciones sin modificación alguna. 
TOKEN_MANAGER_USES_PARSER: Esta es una opción de tipo lógico la cual tiene 
un valor por default de “false”. Cuando se establece en true, el manejador de token 
(analizador léxico) generado incluirá un campo llamado parser que referenciará el 
objeto instanciado del Parser (de tipo MiParser en el ejemplo anterior). La principal 
razón de contar con una referencia al parser en un analizador léxico es el utilizar 
algunas de su lógica en las acciones léxicas. Esta opción no tiene efecto si la opción 
STATIC se establece en true.
SANITY_CHECK: Esta es una opción lógica la cual su valor por default es true. 
JavaCC realiza muchas revisiones sintácticas y semánticas en el archivo de la gramática 
durante la generación del analizador sintáctico. Algunas revisiones tales como la 
detección de recursividad por la izquierda, detección de ambigüedad y mal uso de 
expansiones vacías pueden ser suprimidas para la generación de un parser más rápido al 
colocar ésta opción en falso. Note que la presencia de estos errores (aun cuando estas no 
son detectadas y reportadas al establecer ésta opción a Falso) pueden ocasionar un 
comportamiento inesperado desde el parser generado. 
FORCE_LA_CHECK: Esta es una opción de tipo lógica la cual por default se encuentra 
en falso. Esta opción controla la revisión de búsqueda adelantada de ambigüedad que se 
realiza para todos los puntos de opción donde se utiliza el valor por default de 1 para la 
búsqueda adelantada (o LookAhead) 
La búsqueda adelantada de ambigüedad no se realiza en puntos de opción donde hay 
una especificación explícita de búsqueda adelantada, o si la opción LOOKAHEAD se 
establece en otro valor distinto de 1. Al colocar esta opción en “true” se realiza una 
búsqueda adelantada de ambigüedad revisando todas las opciones a pesar de la 
especificación de búsqueda adelantada en el archivo de la gramática 
COMMON_TOKEN_ACTION: Esta es una opción lógica la cual tiene el valor por 
default de falso. Cuando se establece en true, cada llamada al método getNextToken del 
analizador léxico originara una llamada al método "CommonTokenAction" después de 
que el token ha sido reconocido por el analizador léxico. El usuario debe definir éste 
método dentro de la sección TOKEN_MGR_DECLS. El prototipo de éste método es: 
void CommonTokenAction(Token t) 
CACHE_TOKENS: Esta es una opción de valor lógico la cual por default es falso. Al 
establecer esta opción en true ocasiona que el parser generado revise por tokens extra de 
forma anticipada. Esto facilita alguna mejora de eficiencia. Sin embargo, en este caso 
(cuando la opción se establece en true), las aplicaciones interactivas podrían no trabajar 
ya que el parser necesita trabajar en sincronía con la disponibilidad de tokens desde el 
flujo de entrada. En tales casos, es mejor dejar esta opción con su valor por default. 
OUTPUT_DIRECTORY: Esta es una opción para un valor de cadena de caracteres la 
cual el valor por default es el directorio actual. Esta opción controla donde se generan 
los archivos de salida. 
----------------------------------------------------- --------------------------- 
production ::= javacode_production 
| regular_expr_production 
| bnf_production 
| token_manager_decls 
Hay cuatro tipos de producciones en JavaCC. javacode_production y bnf_production 
son utilizadas para definir la gramática desde la cual se genera el Parser. 
regular_expr_production se utiliza para definir la gramática de tokens – el token 
manager es generado a partir de ésta información (también desde la especificación de
tokens en línea en la gramática del parser). token_manager_decls se utiliza para 
introducir declaraciones que se insertan dentro del analizador léxico generado. 
-------------------------------------------------------------------------------- 
javacode_production ::= "JAVACODE" 
java_access_modifier java_return_type java_identifier "(" 
java_parameter_list ")" 
java_block 
La producción JAVACODE es una manera de escribir código Java para algunas 
producciones en lugar de utilizar la expansión usual EBNF. Esto es útil cuando hay 
necesidad de reconocer algo en un contexto no libre o por cualquier otra razón que sea 
difícil para la cual sea difícil escribir una gramática. Un ejemplo del uso de 
JAVACODE se muestra a continuación. En éste ejemplo, el no terminal 
"skip_to_matching_brace" consume todos los tokens en el flujo de entrada hasta hacer 
coincidir con el corchete que cierra (se asume que el corchete izquierdo ya fue 
reconocido): 
JAVACODE 
void skip_to_matching_brace() { 
Token tok; 
int nesting = 1; 
while (true) { 
tok = getToken(1); 
if (tok.kind == LBRACE) nesting++; 
if (tok.kind == RBRACE) { 
nesting--; 
if (nesting == 0) break; 
} 
tok = getNextToken(); 
} 
} 
Se debe tener mucho cuidad en utilizar las producciones JAVACODE. 
Mientras que puedes decir bastante de lo que se desea con estas producciones, JavaCC 
simplemente las considera como una caja negra (algo que se realiza dentro de la tarea 
del análisis). Esto puede ser un problema cuando las producciones JAVACODE 
aparecen en puntos de selección. Por ejemplo, si la producción JAVACODE de arriba 
estuviera referenciada desde la siguiente producción: 
void NT() : 
{} 
{ 
skip_to_matching_brace() 
| 
some_other_production() 
} 
Entonces JavaCC no podría saber como escoger entre las dos opciones. De otra manera, 
si la producción JAVACODE es utilizada en un punto que no hay opciones, como se 
muestra en el siguiente ejemplo, no habrá problemas:
void NT() : 
{} 
{ 
"{" skip_to_matching_brace() 
| 
"(" parameter_list() ")" 
} 
Cuando las producciones JAVACODE son utilizadas en puntos de elección, JavaCC 
imprimirá un mensaje de advertencia. Tendrás entonces que insertar algunas 
especificaciones explícitas LOOKAHEAD para ayudar al JavaCC. 
El modificador por default para producción JAVACODE es un paquete privado. 
-------------------------------------------------------------------------------- 
bnf_production ::= java_access_modifier java_return_type 
java_identifier "(" java_parameter_list ")" ":" 
java_block 
"{" expansion_choices "}" 
La producción BNF es la producción estándar utilizada en la especificación de 
gramáticas JavaCC. Cada producción BNF tiene un lado izquierdo el cual es una 
especificación no-terminal. La producción BNF entonces define este no-terminal en 
términos de expansiones BNF en el lado derecho. El no-terminal es escrito exactamente 
como la declaración de un método en Java. Dado que cada no-termina es traducido 
dentro de un método en el analizador generado, este estilo de escribir el no-terminal 
hace obvia esta asociación. El nombre del no-terminal es el nombre del método, y los 
parámetros y valores de retorno declarados son los medios para pasar los valores hacia 
arriba y abajo en el árbol sintáctico. Tal como se verá posteriormente, el paso de valores 
hacia arriba y abajo del árbol se realiza utilizando exactamente el mismo paradigma que 
la invocación y retorno a métodos. El modificador de acceso para las producciones BNF 
es public. 
Hay dos partes en el lado derecho de la producción BNF. La primer parte es el conjunto 
arbitrario de declaraciones de Java y código (el bloque Java). Este código es generado al 
inicio del método generado por el no-terminal Java. Por tanto, cada vez que se utilice 
este no-terminal en el proceso de análisis sintáctico, estas declaraciones y código son 
ejecutados. Las declaraciones en esta parte son visibles para todo el código Java en las 
acciones en las expansiones BNF. JavaCC no realiza cualquier procesamiento de estas 
declaraciones y código, excepto el salto hasta el corchete final, colectando todo el texto 
encontrado en el camino. Por tanto el compilador de Java puede detectar los errores en 
este código que ha sido procesado por JavaCC. 
La segunda parte del lado derecho está en formato de expansión BNF. Esta se describe 
posteriormente. 
-------------------------------------------------------------------------------- 
regular_expr_production ::= [ lexical_state_list ] 
regexpr_kind [ "[" "IGNORE_CASE" "]" ] ":"
"{" regexpr_spec ( "|" regexpr_spec )* "}" 
Una producción de expresión regular se utiliza para definir entidades léxicas a ser 
procesadas por el manejador de tokens. Esta sección describe los aspectos sintácticos de 
la especificación de entidades léxicas. 
Una producción de expresión regular comienza con una especificación del l estado 
léxico para las cuales aplica (la lista de estados léxicos). Hay un estado léxico estándar 
llamado “DEFAULT”. Si se omite la lista de estados léxicos, las producciones de 
expresión regular aplican el estado léxico "DEFAULT". 
Siguiendo esto es una descripción de que tipo de producción de expresión regular que 
es. 
Despues de esto hay un "[IGNORE_CASE]" opcional. Si esta presente, la producción 
de expresión regular no distingue de mayúsculas y minúsculas – que es el mismo efecto 
que la opción IGNORE_CASE, excepto que en este caso aplica localmente a esta 
producción de expresión regular. 
Esto es entonces seguido por la especificación de una lista de expresiones que describen 
con más detalle las entidades léxicas de esta producción de expresión regular. 
-------------------------------------------------------------------------------- 
token_manager_decls ::= "TOKEN_MGR_DECLS" ":" java_block 
Las declaraciones del manejador de tokens comienza con la palabra reservada 
"TOKEN_MGR_DECLS" seguida por ":" y entonces un conjunto de declaraciones y 
sentencias Java (el bloque Java). Estas declaraciones y sentencias están escritas dentro 
del manejador de tokens y están accesibles desde las acciones léxicas. 
Solo puede haber una declaración de manejador de tokens en una declaración en un 
archivo de gramáticas de JavaCC. 
-------------------------------------------------------------------------------- 
lexical_state_list ::= "<" "*" ">" 
| "<" java_identifier ( "," java_identifier )* ">" 
La lista de estados léxicos describe el conjunto de estados léxicos para los cuales 
corresponda la aplicación de una producción de expresión regular. Si esta escrita "<*>", 
la producción de la expresión regular aplica a todos los estados léxicos. De otra forma, 
este aplica a todos los estados léxicos en la lista de identificadores dentro de los 
paréntesis angulares. 
-------------------------------------------------------------------------------- 
regexpr_kind ::= "TOKEN"
| "SPECIAL_TOKEN" 
| "SKIP" 
| "MORE" 
Este especifica el tipo de producción de expresión regula. Existen cuatro tipos: 
TOKEN: La expresión regular en esta producción de expresión regular describe 
los componentes léxicos (tokens) en la gramática. El manejador de tokens 
(analizador léxico) crea un objeto Token para cada coincidencia de cada 
expresión regular y la retorna al analizador sintáctico. 
SPECIAL_TOKEN: La expresión regular en esta producción de expresión 
regular describe tokens especiales. Los tokens especiales son como los tokens 
normales, excepto que no tienen significado durante el análisis sintáctico – tal 
que las producciones BNF las ignoran. Los tokens especiales son pasados al 
parser enlazándolos a los tokens vecinos reales utilizando el campo 
“specialToken” en la clase Token. Los tokens especiales son útiles en el 
procesamiento de entidades léxicas tales como comentarios en los cuales no se 
realizar un análisis significativo, pero son una parte importante del archivo de 
entrada. 
SKIP: Las coincidencias a una expresión regular en ésta producción de 
expresión regular son simplemente ignoradas por el manejador de tokens 
(Analizador léxico). 
MORE: Algunas veces es útil construir gradualmente un token a ser pasado al 
parser. Las coincidencias de este tipo de expresiones regulares son almacenadas 
en un buffer hasta que coincida con TOKEN o SPECIAL_TOKEN. Entonces 
todas las coincidencias encontradas en el buffer y las coincidencias 
TOKEN/SPECIAL_TOKEN son concatenadas en la forma 
TOKEN/SPECIAL_TOKEN que es pasada al analizador sintáctico. Si a una 
coincidencia a la expresión regular SKIP sigue una secuencia de coincidencias 
de tipo MORE, el contenido del buffer se descarta. 
-------------------------------------------------------------- ------------------ 
regexpr_spec ::= regular_expression [ java_block ] [ ":" java_identifier ] 
La especificación de expresiones regulares inicia la descripción actual de las entidades 
léxicas que son parte de la producción de la expresión regular. Cada producción de 
expresión regular puede contener cualquier número de especificaciones de expresiones 
regulares. 
Cada especificación de expresión regular contiene una expresión regular seguida de un 
bloque de Java (acción léxica) la cual es opcional. Esta es entonces seguida de un 
identificador de un estado lógico (la cual es opcional). Donde quiera que coincida ésta
expresión regular, la acción léxica (si la hay) se ejecuta, seguida por cualquier cantidad 
de acciones comunes de los tokens. Entonces la acción depende del tipo de producción 
de la expresión regular seleccionada. Finalmente, si se especifica un estado léxico, el 
manejador de tokens (analizador léxico), se mueve a ese estado léxico para futuro 
procesamiento (el analizador léxico inicia con el estado “DEFAULT”). 
-------------------------------------------------------------------------------- 
expansion_choices ::= expansion ( "|" expansion )* 
Las selecciones de expansión se escriben como un alista de una o más expansiones 
separadas por "|"’s. El conjunto de analizadores legales seguidos por una selección de 
expansión es un análisis legal de cualquier de las expansiones contenidas. 
-------------------------------------------------------------------------------- 
expansion ::= ( expansion_unit )* 
Una expansión esta escrita como una secuencia de unidades de expansion. La 
concatenación de unidades de expansión correctamente analizadas es una expansión de 
analizador sintáctico correcto. 
Por ejemplo, la expansión "{" decls() "}" consiste de tres unidades de expansión - "{", 
decls(), y "}". Una coincidencia para la expansión es una concatenación de las 
coincidencias individuales de las unidades de expansión – en este caso, que podría ser 
una cadena que inicie con “{“, termine con “}” y contenga una coincidencia intermedia 
para decls() 
-------------------------------------------------------------------------------- 
expansion_unit ::= local_lookahead 
| java_block 
| "(" expansion_choices ")" [ "+" | "*" | "?" ] 
| "[" expansion_choices "]" 
| [ java_assignment_lhs "=" ] regular_expression 
| [java_assignment_lhs "="] java_identifier "(" 
java_expression_list")" 
Una unidad de expansión puede ser una especificación local LOOKAHEAD. Esto 
instruye al parser generado en como tomar las decisiones en los puntos de opciones. 
Una unidad de expansion puede ser un conjunto de declaraciones de Java y código 
encerrado entre corchetes (bloque Java). Estas también se denominan acciones del 
analizador sintáctico. Este es generado dentro del método de análisis del no-terminal en 
el lugar apropiado. Este bloque se ejecuta cada vez que el proceso de análisis cruza este 
punto de forma exitosa. Cuando JavaCC procesa el bloque en Java, este no realiza 
ninguna revisión de la sintaxis o semántica. Por lo tanto es posible que el compilador de
Java pueda encontrar errores en las acciones que han sido procesadas por JavaCC. Las 
acciones no se ejecutan durante la evaluación de adelantada de tokens. 
Una unidad de expansión puede ser un conjunto de una o más opciones entre paréntesis. 
En cuyo caso, un análisis válido de una unidad de expansión es cualquier análisis legal 
de las expresiones anidadas. El conjunto de opciones de expansión entre paréntesis 
puede ser opcionalmente acompañada a su derecha por: 
"+": Aquí cualquier coincidencia valida de la unidad es una o más repeticiones de la 
coincidencia valida del conjunto de opciones entre paréntesis. 
"*": Aquí cualquier coincidencia valida de la unidad es cero o más repeticiones de una 
coincidencia valida del conjunto de opciones entre paréntesis. 
"?": Aquí cualquier coincidencia valida de la unidad es tanto la cadena vacía como 
cualquier coincidencia valida de las opciones anidadas. 
Una sintaxis alterna para esta construcción es para encerrar las opciones de expansión 
dentro de los paréntesis rectangulares "[...]". 
Una unidad de expresión puede ser una expresión regular. Entonces un análisis válido 
de la unidad de expansión es cualquier token que coincide esta expresión regular. 
Cuando coincide una expresión regular, este crea un objeto de tipo Token. Este objeto 
puede ser accesado asignándolo a una variable con el prefijo de la expresión regular con 
"variable =". En general, puedes tener cualquier asignación valida de Java en el lado 
izquierdo del signo de igual "=". Esta asignación no se realiza durante la evaluación de 
la búsqueda anticipada (lookahead). 
Una unidad de expansión puede ser un no-terminal (la última opción en la sintaxis 
descrita anteriormente). En cuyo caso, toma la forma de una invocac ión a un método 
con el nombre del no-terminal utilizado como el nombre del método. Un análisis 
exitoso del no-terminal origina que los parámetros colocados en la llamada del método 
sean empleados para las operaciones y retornados sus valores (en el caso de que un no-terminal 
no sea declarado del tipo “void”). El valor retornado puede ser asignado 
(opcionalmente) a una variable colocando como prefijo de la expresión regular con 
“variable=”. En general, puedes colocar cualquier asignación valida de Java del lado 
izquierdo del signo “=”. Esta asignación no se efectúa durante la evaluación adelantada 
de tokens. Los no-terminales no deben ser utilizados en una expansión de manera tal 
que introduzca una recursión por la izquierda. JavaCC realiza esta revisión. 
-------------------------------------------------------------------------------- 
local_lookahead ::= "LOOKAHEAD" "(" [ java_integer_literal ] [ "," ] 
[ expansion_choices ] [ "," ] [ "{" java_expression "}" ] ")" 
Una especificación local de búsqueda anticipada de tokens (lookahead) se utiliza para 
influenciar la manera en que el analizador sintáctico hace sus elecciones en varios 
puntos de opciones en la gramática. Una especificación local lookahead inicia con la 
palabra reservada "LOOKAHEAD" seguido por un conjunto de restricciones de 
lookahead entre paréntesis. Hay tres tipos de restricciones – un límite de lookahead, un 
lookahead sintáctico (elección de expansiones) y un lookahead semántico (la expresión
entre paréntesis). Al menos debe estar presente una restricción de lookahead. Si está 
presente más de una restricción lookahead, estas deben ser separadas por comas. 
A continuación se proporciona una breve descripción de cada tipo de restricción del 
algoritmo LookAhead: 
Lookahead Limit (Limite LookAhead): Este es el máximo número de tokens 
(componentes léxicos) de búsqueda adelantada que pueden ser utilizados para 
propósitos de determinación de selección de opciones. Esto sobre-escribe el valor por 
default el cual se especifica por la opción LOOKAHEAD. Este limite lookahead aplica 
solo al punto de selección de opción de la especificación local de lookahead. Si la 
especificación local de lookahead no esta en éste punto de selección, el limite de 
lookahead (si lo hay) es ignorado. 
Syntactic Lookahead: Esta es una expansión (o expansión de opciones) que se utiliza 
con el propósito de determinar si tiene que ser tomada o no una selección particular que 
aplica a esta especificación local de lookahead. Si no se provee esto, el parser utilizará 
la expansión a ser seleccionada durante la determinación lookahead. Si la especificación 
local de lookahead no está en un punto de selección, la búsqueda sintáctica anticipada 
(si la hay) es ignorada. 
Semantic Lookahead: Esta es una expresión de tipo lógica que se evalúa cuando el 
parser cruza este punto durante el análisis sintáctico. Si la expresión se evalúa a 
verdadero, el análisis sintáctico continúa normalmente. Si la expresión se evalúa como 
falso y la especificación local de lookahead se encuentra en un punto de elección, la 
opción actual no se toma y se considera la siguiente opción. Si la expresión se evalúa 
con falso y la especificación local de búsqueda anticipado no se encuentra en un punto 
de elección, entonces se aborta el análisis sintáctico con un error de tipo Sintáctico. A 
diferencia de las otras dos restricciones de lookahead que son ignoradas en puntos que 
no tienen opciones, el lookahead semántico siempre es evaluado. En efecto, el 
lookahead semántico es evaluado aun si esta se encuentra durante la evaluación de 
alguna otra evaluación sintáctica. 
El valor default para las restricciones lookahead: Si fue provista una especificación local 
de lookahead, pero no se incluyeron todas las restricciones lookahead, entonces las que 
fueron omitidas se asignan con los valores que se indica a continuación: 
Si el límite de lookahead no fue provisto y se provee un lookahead sintáctico, 
entonces el límite de lookahead se pone por default al valor entero más grande 
(2147483647). Esto esencialmente implementa lo que se conoce como 
“lookahead infinito” – esto es buscar de forma adelantada todos los tokens que 
sean necesarios para hacer coincidir el lookahead sintáctico que se haya 
establecido. 
Si no se ha provisto de un limite de lookahead o un lookahead sintáctico, el valor 
limite de lookahead por default es 0. Esto significa que no se realizará un 
lookahead sintáctico, y solo se realizará un lookahead semántico. 
Si no se provee de un lookahead sintáctico, se hace default la selección en la 
cual se aplica la especificación lookahead local. Si la especificación lookahead
no está en un punto de elección, entonces se ignora el lookahead sintáctico – por 
tanto el valor por default no es relevante. 
Si no se provee de una búsqueda anticipada de la semántica, este se aplica con la 
expresión lógica "true". 
-------------------------------------------------------------------------------- 
regular_expression ::= java_string_literal 
| "<" [ [ "#" ] java_identifier ":" ] 
complex_regular_expression_choices ">" 
| "<" java_identifier ">" 
| "<" "EOF" ">" 
Hay dos lugares en el archivo de la gramática en la cual se pueden escribir expresiones 
regulares: 
Dentro de la especificación de una expresión regular (parte de una producción de una 
expresión regular), 
Como una unidad de expansión con una expansión. Cuando una expresión regular se 
utiliza de ésta manera, esto es como si la expresión regular estuviera definida en la 
siguiente manera en ésta localidad y entonces referenciada por su etiqueta desde la 
unidad de expansión: 
<DEFAULT> TOKEN : 
{ 
Expresión regular 
} 
Esto es, el uso de expresiones regulares puede ser re-escritas utilizando otro tipo de 
forma. 
La descripción de la construcción sintáctica sigue a continuación. 
El primer tipo de expresión regular es una cadena de caracteres literal. La entrada a ser 
analizada coincide con la expresión regular si el manejador de tokens esta en un estado 
léxico por el cual esta expresión regular aplica y el siguiente conjunto de caracteres en 
el flujo de entradas es el mismo (posiblemente se ignore la diferencia entre mayúsculas 
y minúsculas) como esta literal de cadena de caracteres. 
Una expresión regular puede también ser una expresión regular compleja utilizando mas 
expresiones regulares relacionadas (mas que la definición de la cadena de caracteres). 
Tal expresión regular es colocada dentro de paréntesis angulares "<...>", y 
opcionalmente puede ser etiquetada con un identificador. Esta etiqueta puede ser 
utilizada para referir a esta expresión regular desde unidades de expansión o desde otras 
expresiones regulares. Si la etiqueta es precedida por el símbolo “#”, entonces esta 
expresión regular no puede ser referenciada desde unidades de expansión y solo desde 
otras expresiones regulares. Cuando esta presente el símbolo “#”, las expresiones 
regulares son referenciadas como “expresiones regulares privadas”
Una expresión regular puede referenciar a otras expresiones regulares etiquetadas, en 
cuyo caso está escrita como la etiqueta encerrada entre paréntesis angulares "<...>". 
Finalmente, una expresión regular puede ser una referencia a una expresión regular 
predefinida "<EOF>" la cual es la coincidencia con el fin del archivo. 
Las expresiones regulares privadas no son hechas coincidir como tokens por el 
manejador de tokens (analizador léxico). Su propósito solamente es para facilitar la 
definición de otras expresiones regulares más complejas. 
Considere el siguiente ejemplo de definición de las literales de números flotantes en 
Java: 
TOKEN : 
{ 
< FLOATING_POINT_LITERAL: 
(["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? 
(["f","F","d","D"])? 
| "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? 
| (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? 
| (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"] 
> 
| 
< #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > 
} 
En este ejemplo, el token FLOATING_POINT_LITERAL es definido utilizando la 
definición de otro token llamado EXPONENT. El símbolo "#" previo a la etiqueta que 
este existe solamente para propósito de definir otros tokens 
(FLOATING_POINT_LITERAL en este caso). La definición de 
FLOATING_POINT_LITERAL no es afectado por la presencia o ausencia de "#". Sin 
embargo, el comportamiento del manejador de tokens es: si se omite el símbolo "#" el 
manejador de tokens erróneamente reconocerá una cadena como E123 como un token 
valido del tipo EXPONENT (en lugar del IDENTIFIER en la gramática de Java). 
-------------------------------------------------------------------------------- 
complex_regular_expression_choices ::= complex_regular_expression ( "|" 
complex_regular_expression )* 
Las expresiones regulares complejas están hechas de una liste de una o mas expresiones 
regulares complejas separadas por "|"s. Una coincidencia de una opción de expresión 
regular compleja es la coincidencia de cualquiera de sus expresiones regulares 
complejas que la constituyen. 
-------------------------------------------------------------------------------- 
complex_regular_expression ::= ( complex_regular_expression_unit )*
Una expresión regular compleja es una secuencia de unidades de expresiones regulares 
complejas. Una coincidencia de una expresión regular compleja es una concatenación 
de las coincidencias de las unidades de expresiones regulares. 
-------------------------------------------------------------------------------- 
complex_regular_expression_unit ::= java_string_literal 
| "<" java_identifier ">" 
| character_list 
| "(" complex_regular_expression_choices ")" [ "+" | "*" | "?" ] 
Una unidad de expresión regular compleja puede ser una literal de cadena de caracteres, 
en la cual existe solamente una coincidencia para esta unidad, denominada por la cadena 
de caracteres en si misma. 
Una unidad de expresión regular puede ser una referencia a otra expresión regular. La 
otra expresión regular tiene que ser etiquetada de tal manera que pueda ser referenciada. 
La coincidencia de ésta unidad son todas las coincidencias de esta otra expresión 
regular. Tal referencia en expresiones regulares no puede inducir ciclos en la 
dependencia entre tokens. 
Una unidad de expresión regular compleja puede ser una lista de caracteres. Una lista de 
caracteres es la manera de definir un conjunto de caracteres. Una coincidencia de este 
tipo de expresiones regulares complejas es cualquier carácter permitido por la lista de 
caracteres. 
Una expresión regular compleja puede ser un conjunto de opciones como expresiones 
regulares entre paréntesis. En este caso, una coincidencia valida de la unidad es 
cualquiera de las coincidencias anidadas. El conjunto de opciones entre paréntesis puede 
opcionalmente seguir por: 
"+": Aquí cualquier coincidencia valida de la unidad es una o más repeticiones de la 
coincidencia valida del conjunto de opciones entre paréntesis. 
"*": Aquí cualquier coincidencia valida de la unidad es cero o más repeticiones de una 
coincidencia valida del conjunto de opciones entre paréntesis. 
"?": Aquí cualquier coincidencia valida de la unidad es tanto la cadena vacía como 
cualquier coincidencia valida de las opciones anidadas. 
Nótese que a pesar de las expansiones BNF, la expresión regular "[...]" no es 
equivalente a la expresión regular "(...)?". Esto es porque la construcción [...] es 
utilizada para describir la lista de caracteres en expresiones regulares. 
-------------------------------------------------------------------------------- 
character_list ::= [ "~" ] "[" [ character_descriptor ( "," character_descriptor )* ] "]" 
Una lista de caracteres describe el conjunto de caracteres. Una coincidencia legal para 
una lista de caracteres es cualquier carácter en este conjunto. Una lista de caracteres es 
una lista de descriptores de caracteres separados por comas y dentro de paréntesis
rectangulares. Cada descriptor de carácter describe un solo carácter o un rango de 
caracteres (ver la descripción a continuación) y esta es agregada al conjunto de 
caracteres de la lista de caracteres. Si la lista de caracteres comienza con el símbolo "~" 
el conjunto de caracteres es representado por cualquier carácter UNICODE no 
especificado en el conjunto especificado. 
-------------------------------------------------------------------------------- 
character_descriptor::= java_string_literal ["-" java_string_literal] 
Un descriptor de un carácter puede ser una cadena de solo caracter literal, en cuyo caso 
describe al mismo carácter; o si son dos caracteres separados por un guión “-“, en cuyo 
caso, describe el conjunto de todos los caracteres en el rango entre e incluyendo estos 
dos caracteres.

More Related Content

What's hot

Tema 4 excepciones por gio
Tema 4   excepciones por gioTema 4   excepciones por gio
Tema 4 excepciones por gioRobert Wolf
 
Contructores en java(grupo 8)
Contructores en java(grupo 8)Contructores en java(grupo 8)
Contructores en java(grupo 8)Manuel Ch.
 
Kit de supervivencia para Java 8 : como prepararse para Java 9
Kit de supervivencia para Java 8 :  como prepararse para Java 9Kit de supervivencia para Java 8 :  como prepararse para Java 9
Kit de supervivencia para Java 8 : como prepararse para Java 9Eudris Cabrera
 
Introducción a la Programaciónen Java
Introducción a la Programaciónen JavaIntroducción a la Programaciónen Java
Introducción a la Programaciónen Javasantosisidrorivera
 
ENTRADA Y SALIDA DE DATOS EN JAVA
ENTRADA Y SALIDA DE DATOS EN JAVAENTRADA Y SALIDA DE DATOS EN JAVA
ENTRADA Y SALIDA DE DATOS EN JAVAGabriel Suarez
 

What's hot (10)

Tema 4 excepciones por gio
Tema 4   excepciones por gioTema 4   excepciones por gio
Tema 4 excepciones por gio
 
Contructores en java(grupo 8)
Contructores en java(grupo 8)Contructores en java(grupo 8)
Contructores en java(grupo 8)
 
Introducción a java
Introducción a javaIntroducción a java
Introducción a java
 
Kit de supervivencia para Java 8 : como prepararse para Java 9
Kit de supervivencia para Java 8 :  como prepararse para Java 9Kit de supervivencia para Java 8 :  como prepararse para Java 9
Kit de supervivencia para Java 8 : como prepararse para Java 9
 
Programación en java
Programación en javaProgramación en java
Programación en java
 
Introducción a la Programaciónen Java
Introducción a la Programaciónen JavaIntroducción a la Programaciónen Java
Introducción a la Programaciónen Java
 
ENTRADA Y SALIDA DE DATOS EN JAVA
ENTRADA Y SALIDA DE DATOS EN JAVAENTRADA Y SALIDA DE DATOS EN JAVA
ENTRADA Y SALIDA DE DATOS EN JAVA
 
Portafolio
PortafolioPortafolio
Portafolio
 
Clase 2 JAVA 2012
Clase 2 JAVA 2012Clase 2 JAVA 2012
Clase 2 JAVA 2012
 
Greenfoot 3
Greenfoot 3Greenfoot 3
Greenfoot 3
 

Viewers also liked

Viewers also liked (10)

Manual netbeans
Manual netbeans Manual netbeans
Manual netbeans
 
Lista de java
Lista de javaLista de java
Lista de java
 
Pilas colas listas
Pilas colas listasPilas colas listas
Pilas colas listas
 
MéTodos Java
MéTodos JavaMéTodos Java
MéTodos Java
 
Lista simple
Lista simpleLista simple
Lista simple
 
Manual Netbeans Bases Datos2
Manual Netbeans Bases Datos2Manual Netbeans Bases Datos2
Manual Netbeans Bases Datos2
 
Manejo de archivos en java
Manejo de archivos en javaManejo de archivos en java
Manejo de archivos en java
 
Estructura de datos listas, pilas y colas
Estructura de datos listas, pilas y colasEstructura de datos listas, pilas y colas
Estructura de datos listas, pilas y colas
 
Listas enlazadas
Listas enlazadasListas enlazadas
Listas enlazadas
 
Estructura datos pilas y colas
Estructura datos pilas y colasEstructura datos pilas y colas
Estructura datos pilas y colas
 

Similar to Archivos java

Similar to Archivos java (20)

2introduccionallenguajejava 141109171757-conversion-gate02
2introduccionallenguajejava 141109171757-conversion-gate022introduccionallenguajejava 141109171757-conversion-gate02
2introduccionallenguajejava 141109171757-conversion-gate02
 
INTRODUCCION LENGUAJE JAVA
INTRODUCCION LENGUAJE JAVAINTRODUCCION LENGUAJE JAVA
INTRODUCCION LENGUAJE JAVA
 
2) introduccion al lenguaje java
2) introduccion al lenguaje java2) introduccion al lenguaje java
2) introduccion al lenguaje java
 
Articulo
ArticuloArticulo
Articulo
 
comandos
comandoscomandos
comandos
 
Tabla de símbolos
Tabla de símbolosTabla de símbolos
Tabla de símbolos
 
Sintaxisenjava
Sintaxisenjava Sintaxisenjava
Sintaxisenjava
 
Unidad 2 Sintaxis en java
Unidad 2 Sintaxis en javaUnidad 2 Sintaxis en java
Unidad 2 Sintaxis en java
 
Documeto compilardorcontadorletras
Documeto compilardorcontadorletrasDocumeto compilardorcontadorletras
Documeto compilardorcontadorletras
 
Documento Margarita
Documento MargaritaDocumento Margarita
Documento Margarita
 
OCP, JSE 6 Programmer (1z0-851) - Guia practica 3 de 7(ap-is)
OCP, JSE 6 Programmer (1z0-851) - Guia practica 3 de 7(ap-is)OCP, JSE 6 Programmer (1z0-851) - Guia practica 3 de 7(ap-is)
OCP, JSE 6 Programmer (1z0-851) - Guia practica 3 de 7(ap-is)
 
J Flex Cup
J Flex CupJ Flex Cup
J Flex Cup
 
5 sentenciasselectivasocondicionales
5 sentenciasselectivasocondicionales5 sentenciasselectivasocondicionales
5 sentenciasselectivasocondicionales
 
Edhiel y aranza_22
Edhiel y aranza_22Edhiel y aranza_22
Edhiel y aranza_22
 
Edhiel y aranza_22
Edhiel y aranza_22Edhiel y aranza_22
Edhiel y aranza_22
 
Tabladesmbolos 101103230525-phpapp02
Tabladesmbolos 101103230525-phpapp02Tabladesmbolos 101103230525-phpapp02
Tabladesmbolos 101103230525-phpapp02
 
Taller analisis semantico
Taller analisis semanticoTaller analisis semantico
Taller analisis semantico
 
Lenguajes de programación orientados a objetos
Lenguajes de programación orientados a objetosLenguajes de programación orientados a objetos
Lenguajes de programación orientados a objetos
 
TABLA DE SIMBOLOS
TABLA DE SIMBOLOSTABLA DE SIMBOLOS
TABLA DE SIMBOLOS
 
Ejercicio compiladores
Ejercicio compiladoresEjercicio compiladores
Ejercicio compiladores
 

Recently uploaded

OCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VS
OCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VSOCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VS
OCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VSYadi Campos
 
Caja de herramientas de inteligencia artificial para la academia y la investi...
Caja de herramientas de inteligencia artificial para la academia y la investi...Caja de herramientas de inteligencia artificial para la academia y la investi...
Caja de herramientas de inteligencia artificial para la academia y la investi...Lourdes Feria
 
BIOMETANO SÍ, PERO NO ASÍ. LA NUEVA BURBUJA ENERGÉTICA
BIOMETANO SÍ, PERO NO ASÍ. LA NUEVA BURBUJA ENERGÉTICABIOMETANO SÍ, PERO NO ASÍ. LA NUEVA BURBUJA ENERGÉTICA
BIOMETANO SÍ, PERO NO ASÍ. LA NUEVA BURBUJA ENERGÉTICAÁngel Encinas
 
plan de capacitacion docente AIP 2024 clllll.pdf
plan de capacitacion docente  AIP 2024          clllll.pdfplan de capacitacion docente  AIP 2024          clllll.pdf
plan de capacitacion docente AIP 2024 clllll.pdfenelcielosiempre
 
SEXTO SEGUNDO PERIODO EMPRENDIMIENTO.pptx
SEXTO SEGUNDO PERIODO EMPRENDIMIENTO.pptxSEXTO SEGUNDO PERIODO EMPRENDIMIENTO.pptx
SEXTO SEGUNDO PERIODO EMPRENDIMIENTO.pptxYadi Campos
 
La empresa sostenible: Principales Características, Barreras para su Avance y...
La empresa sostenible: Principales Características, Barreras para su Avance y...La empresa sostenible: Principales Características, Barreras para su Avance y...
La empresa sostenible: Principales Características, Barreras para su Avance y...JonathanCovena1
 
INSTRUCCION PREPARATORIA DE TIRO .pptx
INSTRUCCION PREPARATORIA DE TIRO   .pptxINSTRUCCION PREPARATORIA DE TIRO   .pptx
INSTRUCCION PREPARATORIA DE TIRO .pptxdeimerhdz21
 
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdfSELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdfAngélica Soledad Vega Ramírez
 
Valoración Crítica de EEEM Feco2023 FFUCV
Valoración Crítica de EEEM Feco2023 FFUCVValoración Crítica de EEEM Feco2023 FFUCV
Valoración Crítica de EEEM Feco2023 FFUCVGiustinoAdesso1
 
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...Carlos Muñoz
 
ORGANIZACIÓN SOCIAL INCA EN EL TAHUANTINSUYO.pptx
ORGANIZACIÓN SOCIAL INCA EN EL TAHUANTINSUYO.pptxORGANIZACIÓN SOCIAL INCA EN EL TAHUANTINSUYO.pptx
ORGANIZACIÓN SOCIAL INCA EN EL TAHUANTINSUYO.pptxnandoapperscabanilla
 
La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.amayarogel
 
Ejercicios de PROBLEMAS PAEV 6 GRADO 2024.pdf
Ejercicios de PROBLEMAS PAEV 6 GRADO 2024.pdfEjercicios de PROBLEMAS PAEV 6 GRADO 2024.pdf
Ejercicios de PROBLEMAS PAEV 6 GRADO 2024.pdfMaritzaRetamozoVera
 
AFICHE EL MANIERISMO HISTORIA DE LA ARQUITECTURA II
AFICHE EL MANIERISMO HISTORIA DE LA ARQUITECTURA IIAFICHE EL MANIERISMO HISTORIA DE LA ARQUITECTURA II
AFICHE EL MANIERISMO HISTORIA DE LA ARQUITECTURA IIIsauraImbrondone
 
Estrategia de prompts, primeras ideas para su construcción
Estrategia de prompts, primeras ideas para su construcciónEstrategia de prompts, primeras ideas para su construcción
Estrategia de prompts, primeras ideas para su construcciónLourdes Feria
 
PLAN DE REFUERZO ESCOLAR primaria (1).docx
PLAN DE REFUERZO ESCOLAR primaria (1).docxPLAN DE REFUERZO ESCOLAR primaria (1).docx
PLAN DE REFUERZO ESCOLAR primaria (1).docxlupitavic
 
Sesión de aprendizaje Planifica Textos argumentativo.docx
Sesión de aprendizaje Planifica Textos argumentativo.docxSesión de aprendizaje Planifica Textos argumentativo.docx
Sesión de aprendizaje Planifica Textos argumentativo.docxMaritzaRetamozoVera
 
PIAR v 015. 2024 Plan Individual de ajustes razonables
PIAR v 015. 2024 Plan Individual de ajustes razonablesPIAR v 015. 2024 Plan Individual de ajustes razonables
PIAR v 015. 2024 Plan Individual de ajustes razonablesYanirisBarcelDelaHoz
 

Recently uploaded (20)

OCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VS
OCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VSOCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VS
OCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VS
 
Caja de herramientas de inteligencia artificial para la academia y la investi...
Caja de herramientas de inteligencia artificial para la academia y la investi...Caja de herramientas de inteligencia artificial para la academia y la investi...
Caja de herramientas de inteligencia artificial para la academia y la investi...
 
BIOMETANO SÍ, PERO NO ASÍ. LA NUEVA BURBUJA ENERGÉTICA
BIOMETANO SÍ, PERO NO ASÍ. LA NUEVA BURBUJA ENERGÉTICABIOMETANO SÍ, PERO NO ASÍ. LA NUEVA BURBUJA ENERGÉTICA
BIOMETANO SÍ, PERO NO ASÍ. LA NUEVA BURBUJA ENERGÉTICA
 
plan de capacitacion docente AIP 2024 clllll.pdf
plan de capacitacion docente  AIP 2024          clllll.pdfplan de capacitacion docente  AIP 2024          clllll.pdf
plan de capacitacion docente AIP 2024 clllll.pdf
 
SEXTO SEGUNDO PERIODO EMPRENDIMIENTO.pptx
SEXTO SEGUNDO PERIODO EMPRENDIMIENTO.pptxSEXTO SEGUNDO PERIODO EMPRENDIMIENTO.pptx
SEXTO SEGUNDO PERIODO EMPRENDIMIENTO.pptx
 
La empresa sostenible: Principales Características, Barreras para su Avance y...
La empresa sostenible: Principales Características, Barreras para su Avance y...La empresa sostenible: Principales Características, Barreras para su Avance y...
La empresa sostenible: Principales Características, Barreras para su Avance y...
 
INSTRUCCION PREPARATORIA DE TIRO .pptx
INSTRUCCION PREPARATORIA DE TIRO   .pptxINSTRUCCION PREPARATORIA DE TIRO   .pptx
INSTRUCCION PREPARATORIA DE TIRO .pptx
 
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdfSELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
 
Valoración Crítica de EEEM Feco2023 FFUCV
Valoración Crítica de EEEM Feco2023 FFUCVValoración Crítica de EEEM Feco2023 FFUCV
Valoración Crítica de EEEM Feco2023 FFUCV
 
Unidad 3 | Metodología de la Investigación
Unidad 3 | Metodología de la InvestigaciónUnidad 3 | Metodología de la Investigación
Unidad 3 | Metodología de la Investigación
 
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
 
ORGANIZACIÓN SOCIAL INCA EN EL TAHUANTINSUYO.pptx
ORGANIZACIÓN SOCIAL INCA EN EL TAHUANTINSUYO.pptxORGANIZACIÓN SOCIAL INCA EN EL TAHUANTINSUYO.pptx
ORGANIZACIÓN SOCIAL INCA EN EL TAHUANTINSUYO.pptx
 
La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.
 
Ejercicios de PROBLEMAS PAEV 6 GRADO 2024.pdf
Ejercicios de PROBLEMAS PAEV 6 GRADO 2024.pdfEjercicios de PROBLEMAS PAEV 6 GRADO 2024.pdf
Ejercicios de PROBLEMAS PAEV 6 GRADO 2024.pdf
 
AFICHE EL MANIERISMO HISTORIA DE LA ARQUITECTURA II
AFICHE EL MANIERISMO HISTORIA DE LA ARQUITECTURA IIAFICHE EL MANIERISMO HISTORIA DE LA ARQUITECTURA II
AFICHE EL MANIERISMO HISTORIA DE LA ARQUITECTURA II
 
Estrategia de prompts, primeras ideas para su construcción
Estrategia de prompts, primeras ideas para su construcciónEstrategia de prompts, primeras ideas para su construcción
Estrategia de prompts, primeras ideas para su construcción
 
Sesión de clase: Fe contra todo pronóstico
Sesión de clase: Fe contra todo pronósticoSesión de clase: Fe contra todo pronóstico
Sesión de clase: Fe contra todo pronóstico
 
PLAN DE REFUERZO ESCOLAR primaria (1).docx
PLAN DE REFUERZO ESCOLAR primaria (1).docxPLAN DE REFUERZO ESCOLAR primaria (1).docx
PLAN DE REFUERZO ESCOLAR primaria (1).docx
 
Sesión de aprendizaje Planifica Textos argumentativo.docx
Sesión de aprendizaje Planifica Textos argumentativo.docxSesión de aprendizaje Planifica Textos argumentativo.docx
Sesión de aprendizaje Planifica Textos argumentativo.docx
 
PIAR v 015. 2024 Plan Individual de ajustes razonables
PIAR v 015. 2024 Plan Individual de ajustes razonablesPIAR v 015. 2024 Plan Individual de ajustes razonables
PIAR v 015. 2024 Plan Individual de ajustes razonables
 

Archivos java

  • 1. Sintaxis para la construcción de archivos de gramática para JavaCC Los Tokens en los archivos de gramática siguen las mismas convenciones que para el lenguaje de programación Java. Por tanto identificadores, cadenas, caracteres, etc. Utilizada en las gramáticas son iguales que los identificadores de Java, cadenas de Java, caracteres de Java, etc. Los espacios en blanco en los archivos de gramática también siguen las mismas convenciones para el lenguaje de programación Java. Este incluye la sintaxis para comentarios. La mayor parte de los comentarios presentes en los archivos de gramáticas son generados dentro del analizador léxico/sintáctico generado. Los archivos de gramática son preprocesados por códigos de escape Unicode tal como aparecen en los archivos Java (las ocurrencias de cadenas tales como uxxxx – donde xxxx es un valor hex – son convertidos al carácter Unicode correspondiente antes de efectuar el análisis léxico). Las excepciones a las reglas antes descritas: Los operadores de Java: "<<", ">>", ">>>", "<<=", ">>=", y ">>>=" son retiradas por la izquierda de la lista de tokens de entrada de JavaCC para permitir un uso conveniente de la especificación de tokens. Finalmente, las siguientes son las palabras reservadas adicionales en los archivos de gramática de JavaCC. EOF IGNORE_CASE JAVACODE LOOKAHEAD MORE options PARSER_BEGIN PARSER_END SKIP SPECIAL_TOKEN TOKEN TOKEN_MGR_DECLS Cualquier entidad de Java utilizada en las reglas de la gramática que a continuación aparezca con el prefijo java_ (Ej., java_compilation_unit). -------------------------------------------------------------------------------- javacc_input ::= javacc_options "PARSER_BEGIN" "(" <IDENTIFIER> ")" java_compilation_unit "PARSER_END" "(" <IDENTIFIER> ")" ( production )* <EOF> Los archivos de gramática comienzan con una lista de opciones (las cuales son opcionales). Esto es entonces seguido por la unidad de compilación de Java encerrado entre "PARSER_BEGIN(name)" y "PARSER_END(name)". Despues de esto hay una lista de producciones de la gramática. Las opciones y producciones son descritas posteriormente. El nombre que sigue a "PARSER_BEGIN" y "PARSER_END" debe ser el mismo e identifica el nombre del parser generado. Por ejemplo, si el nombre es "MiParser", entonces se generan los siguientes archivos: MiParser.java: El analizador generado. MiParserTokenManager.java: El manejador de tokens generado (o analizador léxico).
  • 2. MiParserConstants.java: Un conjunto de constantes útiles. Otros archivos como "Token.java", "ParseError.java", etc. También son generados. Estos archivos contienen código modelo y son el mismo para cualquier gramática y pueden ser reutilizadas en otras gramáticas. Entre las construcciones PARSER_BEGIN y PARSER_END se encuentra una unidad regular de compilación de Java (una unidad de compilación en java puede ser el contenido completo de un archivo en Java). Esto puede ser cualquier unidad de compilación arbitraria tan grande como contenga una declaración de clase y cuyo nombre sea el mismo que el nombre del parser generado ("MiParser" en el ejemplo anterior). Por tanto, en general, esta parte del archivo de la gramática se vera como: PARSER_BEGIN(parser_name) . . . clase parser_name . . . { . . . } . . . PARSER_END(parser_name) JavaCC no realiza ninguna revisión detallada en la unidad de compilación, así esto es posible para un archivo de gramática pasar a través de JavaCC y generar los archivos que producen errores cuando estos son compilados. Si la unidad de compilación incluye un paquete de declaración, esto es incluido en todos los archivos generados. Si la unidad de compilación importa declaraciones, estas se incluyen en el parser generado y en los archivos del manejador de tokens. Si el archivo de parser generado contiene todo en la unida de compilación y en adición, contiene el código generado del parser que se incluye al fin de la clase del parser. Para el ejemplo anterior, el parser generado se podría ver como sigue: . . . clase parser_name . . . { . . . // El parser generado se incluye aqui. } . . . Los parsers generados incluyen la declaración de un método público para cada no-terminal (ver javacode_production y bnf_production) en el archivo de gramática. El Análisis Sintáctico con respecto a un no-terminal se logra invocando el método correspondiente a ese no-terminal. A diferencia de yacc, no hay ningún símbolo inicial en JavaCC – uno puede iniciar el análisis sintáctico con respecto a cualquier no-terminal en la gramática. El manejador de tokens provee un método público: Token getNextToken() throws ParseError;
  • 3. Para más detalles en como puede ser utilizado este método, lea la documentación de JavaCC. javacc_options ::= [ "options" "{" ( option_binding )* "}" ] Si la palabra “options” está presente, inicia con la palabra reservada “options” seguida de una lista de más opciones encerradas con corchetes. Cada opción encerrada especifica el establecimiento de una opción. La misma opción no debe ser indicada varias veces. Las opciones pueden ser especificadas tanto aquí en el archivo de gramática o desde la línea de comandos. Si la opción se coloca desde la línea de comandos, esta toma precedencia. Los nombres de opciones pueden ser mayúsculas o minúsculas. -------------------------------------------------------------------------------- option_binding ::= "LOOKAHEAD" "=" java_integer_literal ";" | "CHOICE_AMBIGUITY_CHECK" "=" java_integer_literal ";" | "OTHER_AMBIGUITY_CHECK" "=" java_integer_literal ";" | "STATIC" "=" java_boolean_literal ";" | "DEBUG_PARSER" "=" java_boolean_literal ";" | "DEBUG_LOOKAHEAD" "=" java_boolean_literal ";" | "DEBUG_TOKEN_MANAGER" "=" java_boolean_literal ";" | "OPTIMIZE_TOKEN_MANAGER" "=" java_boolean_literal ";" | "ERROR_REPORTING" "=" java_boolean_literal ";" | "JAVA_UNICODE_ESCAPE" "=" java_boolean_literal ";" | "UNICODE_INPUT" "=" java_boolean_literal ";" | "IGNORE_CASE" "=" java_boolean_literal ";" | "USER_TOKEN_MANAGER" "=" java_boolean_literal ";" | "USER_CHAR_STREAM" "=" java_boolean_literal ";" | "BUILD_PARSER" "=" java_boolean_literal ";" | "BUILD_TOKEN_MANAGER" "=" java_boolean_literal ";" | "TOKEN_MANAGER_USES_PARSER" "=" java_boolean_literal ";" | "SANITY_CHECK" "=" java_boolean_literal ";" | "FORCE_LA_CHECK" "=" java_boolean_literal ";" | "COMMON_TOKEN_ACTION" "=" java_boolean_literal ";" | "CACHE_TOKENS" "=" java_boolean_literal ";" | "OUTPUT_DIRECTORY" "=" java_string_literal ";" LOOKAHEAD: El numero de tokens a observar por delante antes de tomar una decisión en un punto de opciones durante el Análisis Sintáctico. El valor por default es 1. Mientras más pequeño sea dicho numero, el Análisis será más rápido. Este número puede ser sobre-encimado por producciones específicas dentro de la gramática como se describirá posteriormente. Ver la descripción del algoritmo lookahead para los detalles completos en como trabaja lookahead. CHOICE_AMBIGUITY_CHECK: Esta es una opción entera la cual tiene un valor por default de 2. Este es el numero de tokens considerados en la revisión de ambigüedad de opciones desde “A|B…”. Por ejemplo, si hay dos prefijos de tokens comunes tanto para A y B, pero no hay tres tokens prefijos comunes, (asumiendo que esta opción se pone a 3) entonces JavaCC puede informarte que debes usar un lookahead de 3 para propósitos
  • 4. de eliminar la ambigüedad. Y si A y B tienen tres tokens prefijos comunes, entonces JavaCC solo te dice que puedes necesitar tener un lookahead de 3 o más. Al incrementar este valor te puede dar más información respecto a la ambigüedad al costo de más tiempo de procesamiento. Para gramáticas más grandes como la gramática de Java, incrementar este número mas allá causa que la revisión tome mucho más tiempo. OTHER_AMBIGUITY_CHECK: Esta es una opción de un número entero el cual su valor por defecto es 1. Este es el numero de tokens considerados en la revisión de todos los otros tipos de opciones de ambigüedad (ej. de las formas "(A)*", "(A)+", y "(A)?"). Esto toma más tiempo en hacerse que revisar la opción, y por tanto el valor por default es colocado en 1 más bien que 2. STATIC: Esta es una opción tipo lógica la cual su valor por default es verdadero. Si es verdadero, todos los métodos y variables de clases son especificados como estáticas en el analizador generado y el manejador de tokens. Esto solo permite que un objeto parser esté presente, pero mejora el rendimiento del analizador. Para realizar varios analizadores durante una ejecución del programa Java, tienes que invocar el método ReInit() para reinicializar el parser si éste es estático. Si el parser es no-static puedes utilizar el operador “new” para construir tantos parsers como necesites. Estos pueden ser utilizados simultáneamente desde diferentes threads. DEBUG_PARSER: Esta es una opción tipo lógica la cual establece un valor por default de falso. Esta opción es utilizada para obtener información de depuración desde los analizadores generados. Al establecer estas opciones en verdadero ocasiona que los parsers generen el seguimiento de sus acciones. El seguimiento puede ser deshabilitado invocando el método disable_tracing() en la clase del parser generado. El seguimiento puede ser posteriormente habilitado al invocar el método enable_tracing() en la clase del parser generado. DEBUG_LOOKAHEAD: Esta es una opción tipo lógica la cual tiene un valor por default de falso. Al establecer esta opción en verdadero (true) causa que el parser genere toda la información de seguimiento que se hace cuando se establece la opción DEBUG_PARSER en verdadero, en adición, esto también ocasiona que se genere la ruta de las acciones realizadas durante las operaciones de lookahead DEBUG_TOKEN_MANAGER: Esta es una opción de tipo lógica la cual por default se establece en false. Esta opción es utilizada para obtener información de depuración desde el manejador de tokens. Al establecer esta opción en true ocasiona que el manejador de tokens genere un seguimiento de sus acciones. Este seguimiento es bastante extenso y solo debe usarse cuando tengas un error léxico que haya sido reportado y no comprendas porque. Típicamente, en esta situación, puedes determinar el problema observando las últimas cuantas líneas del seguimiento. ERROR_REPORTING: Esta es una opción la cual tiene un valor por default de verdadero “true”. Si se establece en falso causará que los errores sean reportados con menos detalles. La única razón para poner ésta opción en falso es mejorar su eficiencia. JAVA_UNICODE_ESCAPE: Esta es una opción tipo lógica la cual tiene un valor por default de falso. Cuando se establece en “true”, el parser generado utiliza un objeto de flujo de entrada que procesa los códigos de escape Unicode de Java (u...) antes de
  • 5. enviar los caracteres al manejador de tokens. Por default, los códigos de escape Unicode de Java no son procesados. Esta opción se ignora si cualquiera de las opciones USER_TOKEN_MANAGER, USER_CHAR_STREAM se establece en true. UNICODE_INPUT: Esta es una opción tipo lógica la cual su valor por default es falso. Cuando se establece en true, el parser generado utiliza un objeto de flujo de entrada que lee los archivos Unicode. Por default se asume que los archivos son ASCII. Esta opción se ignora si se establece en true cualquiera de las opciones USER_TOKEN_MANAGER, USER_CHAR_STREAM. IGNORE_CASE: Esta es una opción de tipo lógica la cual el valor default es falso. Al poner esta opción causa que el manejador de tokens generado ignore la diferencia entre mayúsculas y minúsculas en la especificación de tokens y los archivos de entrada. Esto es útil para escribir gramáticas para lenguajes tales como HTML. USER_TOKEN_MANAGER: Esta es una opción tipo lógica la cual tiene por default el valor falso. La acción por default es generar un token manager que trabaja en aceptar tokens desde cualquier token manager de tipo “TokenManager” – esta interfase es generada dentro del directorio del parser generado. USER_CHAR_STREAM: Esta es una opción tipo lógica la cual por default se establece en falso. La acción por default es generar un lector de flujo de caracteres tal como se especifica en las opciones JAVA_UNICODE_ESCAPE y UNICODE_INPUT. El analizador léxico generado recibe los caracteres de este lector de flujo. Si esta opción se establece en verdadero (true), entonces el analizador léxico generado para leer los caracteres desde cualquier lector de flujo de tipo "CharStream.java". El archivo es generado dentro del directorio del analizador sintáctico generado Esta opción se ignora si USER_TOKEN_MANAGER se establece en verdadero. BUILD_PARSER: Esta es una opción de tipo lógica la cual tiene un valor por default de verdadero. La acción por default es generar el archivo de parser (("MiParser.java" en el ejemplo anterior). Cuando se establece en falso, el archivo del parser no es generado. Típicamente esta opción se pone en falso cuando solamente se desea generar el analizador léxico y utilizarlo sin el analizador léxico asociado (parser). BUILD_TOKEN_MANAGER: Esta es una opción de tipo lógico la cual se establece por default al valor “true”. La acción por default es generar el archivo del Manejador de Tokens (Analizador léxico - "MiParserTokenManager.java" en el ejemplo anterior). Cuando se establece en falso el archivo del analizador léxico no se genera. La única razón para colocar esta opción en falso es ahorrar tiempo durante la generación del analizador léxico cuando se arregla un problema en la parte de la gramática del analizador y se deja las especificaciones sin modificación alguna. TOKEN_MANAGER_USES_PARSER: Esta es una opción de tipo lógico la cual tiene un valor por default de “false”. Cuando se establece en true, el manejador de token (analizador léxico) generado incluirá un campo llamado parser que referenciará el objeto instanciado del Parser (de tipo MiParser en el ejemplo anterior). La principal razón de contar con una referencia al parser en un analizador léxico es el utilizar algunas de su lógica en las acciones léxicas. Esta opción no tiene efecto si la opción STATIC se establece en true.
  • 6. SANITY_CHECK: Esta es una opción lógica la cual su valor por default es true. JavaCC realiza muchas revisiones sintácticas y semánticas en el archivo de la gramática durante la generación del analizador sintáctico. Algunas revisiones tales como la detección de recursividad por la izquierda, detección de ambigüedad y mal uso de expansiones vacías pueden ser suprimidas para la generación de un parser más rápido al colocar ésta opción en falso. Note que la presencia de estos errores (aun cuando estas no son detectadas y reportadas al establecer ésta opción a Falso) pueden ocasionar un comportamiento inesperado desde el parser generado. FORCE_LA_CHECK: Esta es una opción de tipo lógica la cual por default se encuentra en falso. Esta opción controla la revisión de búsqueda adelantada de ambigüedad que se realiza para todos los puntos de opción donde se utiliza el valor por default de 1 para la búsqueda adelantada (o LookAhead) La búsqueda adelantada de ambigüedad no se realiza en puntos de opción donde hay una especificación explícita de búsqueda adelantada, o si la opción LOOKAHEAD se establece en otro valor distinto de 1. Al colocar esta opción en “true” se realiza una búsqueda adelantada de ambigüedad revisando todas las opciones a pesar de la especificación de búsqueda adelantada en el archivo de la gramática COMMON_TOKEN_ACTION: Esta es una opción lógica la cual tiene el valor por default de falso. Cuando se establece en true, cada llamada al método getNextToken del analizador léxico originara una llamada al método "CommonTokenAction" después de que el token ha sido reconocido por el analizador léxico. El usuario debe definir éste método dentro de la sección TOKEN_MGR_DECLS. El prototipo de éste método es: void CommonTokenAction(Token t) CACHE_TOKENS: Esta es una opción de valor lógico la cual por default es falso. Al establecer esta opción en true ocasiona que el parser generado revise por tokens extra de forma anticipada. Esto facilita alguna mejora de eficiencia. Sin embargo, en este caso (cuando la opción se establece en true), las aplicaciones interactivas podrían no trabajar ya que el parser necesita trabajar en sincronía con la disponibilidad de tokens desde el flujo de entrada. En tales casos, es mejor dejar esta opción con su valor por default. OUTPUT_DIRECTORY: Esta es una opción para un valor de cadena de caracteres la cual el valor por default es el directorio actual. Esta opción controla donde se generan los archivos de salida. ----------------------------------------------------- --------------------------- production ::= javacode_production | regular_expr_production | bnf_production | token_manager_decls Hay cuatro tipos de producciones en JavaCC. javacode_production y bnf_production son utilizadas para definir la gramática desde la cual se genera el Parser. regular_expr_production se utiliza para definir la gramática de tokens – el token manager es generado a partir de ésta información (también desde la especificación de
  • 7. tokens en línea en la gramática del parser). token_manager_decls se utiliza para introducir declaraciones que se insertan dentro del analizador léxico generado. -------------------------------------------------------------------------------- javacode_production ::= "JAVACODE" java_access_modifier java_return_type java_identifier "(" java_parameter_list ")" java_block La producción JAVACODE es una manera de escribir código Java para algunas producciones en lugar de utilizar la expansión usual EBNF. Esto es útil cuando hay necesidad de reconocer algo en un contexto no libre o por cualquier otra razón que sea difícil para la cual sea difícil escribir una gramática. Un ejemplo del uso de JAVACODE se muestra a continuación. En éste ejemplo, el no terminal "skip_to_matching_brace" consume todos los tokens en el flujo de entrada hasta hacer coincidir con el corchete que cierra (se asume que el corchete izquierdo ya fue reconocido): JAVACODE void skip_to_matching_brace() { Token tok; int nesting = 1; while (true) { tok = getToken(1); if (tok.kind == LBRACE) nesting++; if (tok.kind == RBRACE) { nesting--; if (nesting == 0) break; } tok = getNextToken(); } } Se debe tener mucho cuidad en utilizar las producciones JAVACODE. Mientras que puedes decir bastante de lo que se desea con estas producciones, JavaCC simplemente las considera como una caja negra (algo que se realiza dentro de la tarea del análisis). Esto puede ser un problema cuando las producciones JAVACODE aparecen en puntos de selección. Por ejemplo, si la producción JAVACODE de arriba estuviera referenciada desde la siguiente producción: void NT() : {} { skip_to_matching_brace() | some_other_production() } Entonces JavaCC no podría saber como escoger entre las dos opciones. De otra manera, si la producción JAVACODE es utilizada en un punto que no hay opciones, como se muestra en el siguiente ejemplo, no habrá problemas:
  • 8. void NT() : {} { "{" skip_to_matching_brace() | "(" parameter_list() ")" } Cuando las producciones JAVACODE son utilizadas en puntos de elección, JavaCC imprimirá un mensaje de advertencia. Tendrás entonces que insertar algunas especificaciones explícitas LOOKAHEAD para ayudar al JavaCC. El modificador por default para producción JAVACODE es un paquete privado. -------------------------------------------------------------------------------- bnf_production ::= java_access_modifier java_return_type java_identifier "(" java_parameter_list ")" ":" java_block "{" expansion_choices "}" La producción BNF es la producción estándar utilizada en la especificación de gramáticas JavaCC. Cada producción BNF tiene un lado izquierdo el cual es una especificación no-terminal. La producción BNF entonces define este no-terminal en términos de expansiones BNF en el lado derecho. El no-terminal es escrito exactamente como la declaración de un método en Java. Dado que cada no-termina es traducido dentro de un método en el analizador generado, este estilo de escribir el no-terminal hace obvia esta asociación. El nombre del no-terminal es el nombre del método, y los parámetros y valores de retorno declarados son los medios para pasar los valores hacia arriba y abajo en el árbol sintáctico. Tal como se verá posteriormente, el paso de valores hacia arriba y abajo del árbol se realiza utilizando exactamente el mismo paradigma que la invocación y retorno a métodos. El modificador de acceso para las producciones BNF es public. Hay dos partes en el lado derecho de la producción BNF. La primer parte es el conjunto arbitrario de declaraciones de Java y código (el bloque Java). Este código es generado al inicio del método generado por el no-terminal Java. Por tanto, cada vez que se utilice este no-terminal en el proceso de análisis sintáctico, estas declaraciones y código son ejecutados. Las declaraciones en esta parte son visibles para todo el código Java en las acciones en las expansiones BNF. JavaCC no realiza cualquier procesamiento de estas declaraciones y código, excepto el salto hasta el corchete final, colectando todo el texto encontrado en el camino. Por tanto el compilador de Java puede detectar los errores en este código que ha sido procesado por JavaCC. La segunda parte del lado derecho está en formato de expansión BNF. Esta se describe posteriormente. -------------------------------------------------------------------------------- regular_expr_production ::= [ lexical_state_list ] regexpr_kind [ "[" "IGNORE_CASE" "]" ] ":"
  • 9. "{" regexpr_spec ( "|" regexpr_spec )* "}" Una producción de expresión regular se utiliza para definir entidades léxicas a ser procesadas por el manejador de tokens. Esta sección describe los aspectos sintácticos de la especificación de entidades léxicas. Una producción de expresión regular comienza con una especificación del l estado léxico para las cuales aplica (la lista de estados léxicos). Hay un estado léxico estándar llamado “DEFAULT”. Si se omite la lista de estados léxicos, las producciones de expresión regular aplican el estado léxico "DEFAULT". Siguiendo esto es una descripción de que tipo de producción de expresión regular que es. Despues de esto hay un "[IGNORE_CASE]" opcional. Si esta presente, la producción de expresión regular no distingue de mayúsculas y minúsculas – que es el mismo efecto que la opción IGNORE_CASE, excepto que en este caso aplica localmente a esta producción de expresión regular. Esto es entonces seguido por la especificación de una lista de expresiones que describen con más detalle las entidades léxicas de esta producción de expresión regular. -------------------------------------------------------------------------------- token_manager_decls ::= "TOKEN_MGR_DECLS" ":" java_block Las declaraciones del manejador de tokens comienza con la palabra reservada "TOKEN_MGR_DECLS" seguida por ":" y entonces un conjunto de declaraciones y sentencias Java (el bloque Java). Estas declaraciones y sentencias están escritas dentro del manejador de tokens y están accesibles desde las acciones léxicas. Solo puede haber una declaración de manejador de tokens en una declaración en un archivo de gramáticas de JavaCC. -------------------------------------------------------------------------------- lexical_state_list ::= "<" "*" ">" | "<" java_identifier ( "," java_identifier )* ">" La lista de estados léxicos describe el conjunto de estados léxicos para los cuales corresponda la aplicación de una producción de expresión regular. Si esta escrita "<*>", la producción de la expresión regular aplica a todos los estados léxicos. De otra forma, este aplica a todos los estados léxicos en la lista de identificadores dentro de los paréntesis angulares. -------------------------------------------------------------------------------- regexpr_kind ::= "TOKEN"
  • 10. | "SPECIAL_TOKEN" | "SKIP" | "MORE" Este especifica el tipo de producción de expresión regula. Existen cuatro tipos: TOKEN: La expresión regular en esta producción de expresión regular describe los componentes léxicos (tokens) en la gramática. El manejador de tokens (analizador léxico) crea un objeto Token para cada coincidencia de cada expresión regular y la retorna al analizador sintáctico. SPECIAL_TOKEN: La expresión regular en esta producción de expresión regular describe tokens especiales. Los tokens especiales son como los tokens normales, excepto que no tienen significado durante el análisis sintáctico – tal que las producciones BNF las ignoran. Los tokens especiales son pasados al parser enlazándolos a los tokens vecinos reales utilizando el campo “specialToken” en la clase Token. Los tokens especiales son útiles en el procesamiento de entidades léxicas tales como comentarios en los cuales no se realizar un análisis significativo, pero son una parte importante del archivo de entrada. SKIP: Las coincidencias a una expresión regular en ésta producción de expresión regular son simplemente ignoradas por el manejador de tokens (Analizador léxico). MORE: Algunas veces es útil construir gradualmente un token a ser pasado al parser. Las coincidencias de este tipo de expresiones regulares son almacenadas en un buffer hasta que coincida con TOKEN o SPECIAL_TOKEN. Entonces todas las coincidencias encontradas en el buffer y las coincidencias TOKEN/SPECIAL_TOKEN son concatenadas en la forma TOKEN/SPECIAL_TOKEN que es pasada al analizador sintáctico. Si a una coincidencia a la expresión regular SKIP sigue una secuencia de coincidencias de tipo MORE, el contenido del buffer se descarta. -------------------------------------------------------------- ------------------ regexpr_spec ::= regular_expression [ java_block ] [ ":" java_identifier ] La especificación de expresiones regulares inicia la descripción actual de las entidades léxicas que son parte de la producción de la expresión regular. Cada producción de expresión regular puede contener cualquier número de especificaciones de expresiones regulares. Cada especificación de expresión regular contiene una expresión regular seguida de un bloque de Java (acción léxica) la cual es opcional. Esta es entonces seguida de un identificador de un estado lógico (la cual es opcional). Donde quiera que coincida ésta
  • 11. expresión regular, la acción léxica (si la hay) se ejecuta, seguida por cualquier cantidad de acciones comunes de los tokens. Entonces la acción depende del tipo de producción de la expresión regular seleccionada. Finalmente, si se especifica un estado léxico, el manejador de tokens (analizador léxico), se mueve a ese estado léxico para futuro procesamiento (el analizador léxico inicia con el estado “DEFAULT”). -------------------------------------------------------------------------------- expansion_choices ::= expansion ( "|" expansion )* Las selecciones de expansión se escriben como un alista de una o más expansiones separadas por "|"’s. El conjunto de analizadores legales seguidos por una selección de expansión es un análisis legal de cualquier de las expansiones contenidas. -------------------------------------------------------------------------------- expansion ::= ( expansion_unit )* Una expansión esta escrita como una secuencia de unidades de expansion. La concatenación de unidades de expansión correctamente analizadas es una expansión de analizador sintáctico correcto. Por ejemplo, la expansión "{" decls() "}" consiste de tres unidades de expansión - "{", decls(), y "}". Una coincidencia para la expansión es una concatenación de las coincidencias individuales de las unidades de expansión – en este caso, que podría ser una cadena que inicie con “{“, termine con “}” y contenga una coincidencia intermedia para decls() -------------------------------------------------------------------------------- expansion_unit ::= local_lookahead | java_block | "(" expansion_choices ")" [ "+" | "*" | "?" ] | "[" expansion_choices "]" | [ java_assignment_lhs "=" ] regular_expression | [java_assignment_lhs "="] java_identifier "(" java_expression_list")" Una unidad de expansión puede ser una especificación local LOOKAHEAD. Esto instruye al parser generado en como tomar las decisiones en los puntos de opciones. Una unidad de expansion puede ser un conjunto de declaraciones de Java y código encerrado entre corchetes (bloque Java). Estas también se denominan acciones del analizador sintáctico. Este es generado dentro del método de análisis del no-terminal en el lugar apropiado. Este bloque se ejecuta cada vez que el proceso de análisis cruza este punto de forma exitosa. Cuando JavaCC procesa el bloque en Java, este no realiza ninguna revisión de la sintaxis o semántica. Por lo tanto es posible que el compilador de
  • 12. Java pueda encontrar errores en las acciones que han sido procesadas por JavaCC. Las acciones no se ejecutan durante la evaluación de adelantada de tokens. Una unidad de expansión puede ser un conjunto de una o más opciones entre paréntesis. En cuyo caso, un análisis válido de una unidad de expansión es cualquier análisis legal de las expresiones anidadas. El conjunto de opciones de expansión entre paréntesis puede ser opcionalmente acompañada a su derecha por: "+": Aquí cualquier coincidencia valida de la unidad es una o más repeticiones de la coincidencia valida del conjunto de opciones entre paréntesis. "*": Aquí cualquier coincidencia valida de la unidad es cero o más repeticiones de una coincidencia valida del conjunto de opciones entre paréntesis. "?": Aquí cualquier coincidencia valida de la unidad es tanto la cadena vacía como cualquier coincidencia valida de las opciones anidadas. Una sintaxis alterna para esta construcción es para encerrar las opciones de expansión dentro de los paréntesis rectangulares "[...]". Una unidad de expresión puede ser una expresión regular. Entonces un análisis válido de la unidad de expansión es cualquier token que coincide esta expresión regular. Cuando coincide una expresión regular, este crea un objeto de tipo Token. Este objeto puede ser accesado asignándolo a una variable con el prefijo de la expresión regular con "variable =". En general, puedes tener cualquier asignación valida de Java en el lado izquierdo del signo de igual "=". Esta asignación no se realiza durante la evaluación de la búsqueda anticipada (lookahead). Una unidad de expansión puede ser un no-terminal (la última opción en la sintaxis descrita anteriormente). En cuyo caso, toma la forma de una invocac ión a un método con el nombre del no-terminal utilizado como el nombre del método. Un análisis exitoso del no-terminal origina que los parámetros colocados en la llamada del método sean empleados para las operaciones y retornados sus valores (en el caso de que un no-terminal no sea declarado del tipo “void”). El valor retornado puede ser asignado (opcionalmente) a una variable colocando como prefijo de la expresión regular con “variable=”. En general, puedes colocar cualquier asignación valida de Java del lado izquierdo del signo “=”. Esta asignación no se efectúa durante la evaluación adelantada de tokens. Los no-terminales no deben ser utilizados en una expansión de manera tal que introduzca una recursión por la izquierda. JavaCC realiza esta revisión. -------------------------------------------------------------------------------- local_lookahead ::= "LOOKAHEAD" "(" [ java_integer_literal ] [ "," ] [ expansion_choices ] [ "," ] [ "{" java_expression "}" ] ")" Una especificación local de búsqueda anticipada de tokens (lookahead) se utiliza para influenciar la manera en que el analizador sintáctico hace sus elecciones en varios puntos de opciones en la gramática. Una especificación local lookahead inicia con la palabra reservada "LOOKAHEAD" seguido por un conjunto de restricciones de lookahead entre paréntesis. Hay tres tipos de restricciones – un límite de lookahead, un lookahead sintáctico (elección de expansiones) y un lookahead semántico (la expresión
  • 13. entre paréntesis). Al menos debe estar presente una restricción de lookahead. Si está presente más de una restricción lookahead, estas deben ser separadas por comas. A continuación se proporciona una breve descripción de cada tipo de restricción del algoritmo LookAhead: Lookahead Limit (Limite LookAhead): Este es el máximo número de tokens (componentes léxicos) de búsqueda adelantada que pueden ser utilizados para propósitos de determinación de selección de opciones. Esto sobre-escribe el valor por default el cual se especifica por la opción LOOKAHEAD. Este limite lookahead aplica solo al punto de selección de opción de la especificación local de lookahead. Si la especificación local de lookahead no esta en éste punto de selección, el limite de lookahead (si lo hay) es ignorado. Syntactic Lookahead: Esta es una expansión (o expansión de opciones) que se utiliza con el propósito de determinar si tiene que ser tomada o no una selección particular que aplica a esta especificación local de lookahead. Si no se provee esto, el parser utilizará la expansión a ser seleccionada durante la determinación lookahead. Si la especificación local de lookahead no está en un punto de selección, la búsqueda sintáctica anticipada (si la hay) es ignorada. Semantic Lookahead: Esta es una expresión de tipo lógica que se evalúa cuando el parser cruza este punto durante el análisis sintáctico. Si la expresión se evalúa a verdadero, el análisis sintáctico continúa normalmente. Si la expresión se evalúa como falso y la especificación local de lookahead se encuentra en un punto de elección, la opción actual no se toma y se considera la siguiente opción. Si la expresión se evalúa con falso y la especificación local de búsqueda anticipado no se encuentra en un punto de elección, entonces se aborta el análisis sintáctico con un error de tipo Sintáctico. A diferencia de las otras dos restricciones de lookahead que son ignoradas en puntos que no tienen opciones, el lookahead semántico siempre es evaluado. En efecto, el lookahead semántico es evaluado aun si esta se encuentra durante la evaluación de alguna otra evaluación sintáctica. El valor default para las restricciones lookahead: Si fue provista una especificación local de lookahead, pero no se incluyeron todas las restricciones lookahead, entonces las que fueron omitidas se asignan con los valores que se indica a continuación: Si el límite de lookahead no fue provisto y se provee un lookahead sintáctico, entonces el límite de lookahead se pone por default al valor entero más grande (2147483647). Esto esencialmente implementa lo que se conoce como “lookahead infinito” – esto es buscar de forma adelantada todos los tokens que sean necesarios para hacer coincidir el lookahead sintáctico que se haya establecido. Si no se ha provisto de un limite de lookahead o un lookahead sintáctico, el valor limite de lookahead por default es 0. Esto significa que no se realizará un lookahead sintáctico, y solo se realizará un lookahead semántico. Si no se provee de un lookahead sintáctico, se hace default la selección en la cual se aplica la especificación lookahead local. Si la especificación lookahead
  • 14. no está en un punto de elección, entonces se ignora el lookahead sintáctico – por tanto el valor por default no es relevante. Si no se provee de una búsqueda anticipada de la semántica, este se aplica con la expresión lógica "true". -------------------------------------------------------------------------------- regular_expression ::= java_string_literal | "<" [ [ "#" ] java_identifier ":" ] complex_regular_expression_choices ">" | "<" java_identifier ">" | "<" "EOF" ">" Hay dos lugares en el archivo de la gramática en la cual se pueden escribir expresiones regulares: Dentro de la especificación de una expresión regular (parte de una producción de una expresión regular), Como una unidad de expansión con una expansión. Cuando una expresión regular se utiliza de ésta manera, esto es como si la expresión regular estuviera definida en la siguiente manera en ésta localidad y entonces referenciada por su etiqueta desde la unidad de expansión: <DEFAULT> TOKEN : { Expresión regular } Esto es, el uso de expresiones regulares puede ser re-escritas utilizando otro tipo de forma. La descripción de la construcción sintáctica sigue a continuación. El primer tipo de expresión regular es una cadena de caracteres literal. La entrada a ser analizada coincide con la expresión regular si el manejador de tokens esta en un estado léxico por el cual esta expresión regular aplica y el siguiente conjunto de caracteres en el flujo de entradas es el mismo (posiblemente se ignore la diferencia entre mayúsculas y minúsculas) como esta literal de cadena de caracteres. Una expresión regular puede también ser una expresión regular compleja utilizando mas expresiones regulares relacionadas (mas que la definición de la cadena de caracteres). Tal expresión regular es colocada dentro de paréntesis angulares "<...>", y opcionalmente puede ser etiquetada con un identificador. Esta etiqueta puede ser utilizada para referir a esta expresión regular desde unidades de expansión o desde otras expresiones regulares. Si la etiqueta es precedida por el símbolo “#”, entonces esta expresión regular no puede ser referenciada desde unidades de expansión y solo desde otras expresiones regulares. Cuando esta presente el símbolo “#”, las expresiones regulares son referenciadas como “expresiones regulares privadas”
  • 15. Una expresión regular puede referenciar a otras expresiones regulares etiquetadas, en cuyo caso está escrita como la etiqueta encerrada entre paréntesis angulares "<...>". Finalmente, una expresión regular puede ser una referencia a una expresión regular predefinida "<EOF>" la cual es la coincidencia con el fin del archivo. Las expresiones regulares privadas no son hechas coincidir como tokens por el manejador de tokens (analizador léxico). Su propósito solamente es para facilitar la definición de otras expresiones regulares más complejas. Considere el siguiente ejemplo de definición de las literales de números flotantes en Java: TOKEN : { < FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])? | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"] > | < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > } En este ejemplo, el token FLOATING_POINT_LITERAL es definido utilizando la definición de otro token llamado EXPONENT. El símbolo "#" previo a la etiqueta que este existe solamente para propósito de definir otros tokens (FLOATING_POINT_LITERAL en este caso). La definición de FLOATING_POINT_LITERAL no es afectado por la presencia o ausencia de "#". Sin embargo, el comportamiento del manejador de tokens es: si se omite el símbolo "#" el manejador de tokens erróneamente reconocerá una cadena como E123 como un token valido del tipo EXPONENT (en lugar del IDENTIFIER en la gramática de Java). -------------------------------------------------------------------------------- complex_regular_expression_choices ::= complex_regular_expression ( "|" complex_regular_expression )* Las expresiones regulares complejas están hechas de una liste de una o mas expresiones regulares complejas separadas por "|"s. Una coincidencia de una opción de expresión regular compleja es la coincidencia de cualquiera de sus expresiones regulares complejas que la constituyen. -------------------------------------------------------------------------------- complex_regular_expression ::= ( complex_regular_expression_unit )*
  • 16. Una expresión regular compleja es una secuencia de unidades de expresiones regulares complejas. Una coincidencia de una expresión regular compleja es una concatenación de las coincidencias de las unidades de expresiones regulares. -------------------------------------------------------------------------------- complex_regular_expression_unit ::= java_string_literal | "<" java_identifier ">" | character_list | "(" complex_regular_expression_choices ")" [ "+" | "*" | "?" ] Una unidad de expresión regular compleja puede ser una literal de cadena de caracteres, en la cual existe solamente una coincidencia para esta unidad, denominada por la cadena de caracteres en si misma. Una unidad de expresión regular puede ser una referencia a otra expresión regular. La otra expresión regular tiene que ser etiquetada de tal manera que pueda ser referenciada. La coincidencia de ésta unidad son todas las coincidencias de esta otra expresión regular. Tal referencia en expresiones regulares no puede inducir ciclos en la dependencia entre tokens. Una unidad de expresión regular compleja puede ser una lista de caracteres. Una lista de caracteres es la manera de definir un conjunto de caracteres. Una coincidencia de este tipo de expresiones regulares complejas es cualquier carácter permitido por la lista de caracteres. Una expresión regular compleja puede ser un conjunto de opciones como expresiones regulares entre paréntesis. En este caso, una coincidencia valida de la unidad es cualquiera de las coincidencias anidadas. El conjunto de opciones entre paréntesis puede opcionalmente seguir por: "+": Aquí cualquier coincidencia valida de la unidad es una o más repeticiones de la coincidencia valida del conjunto de opciones entre paréntesis. "*": Aquí cualquier coincidencia valida de la unidad es cero o más repeticiones de una coincidencia valida del conjunto de opciones entre paréntesis. "?": Aquí cualquier coincidencia valida de la unidad es tanto la cadena vacía como cualquier coincidencia valida de las opciones anidadas. Nótese que a pesar de las expansiones BNF, la expresión regular "[...]" no es equivalente a la expresión regular "(...)?". Esto es porque la construcción [...] es utilizada para describir la lista de caracteres en expresiones regulares. -------------------------------------------------------------------------------- character_list ::= [ "~" ] "[" [ character_descriptor ( "," character_descriptor )* ] "]" Una lista de caracteres describe el conjunto de caracteres. Una coincidencia legal para una lista de caracteres es cualquier carácter en este conjunto. Una lista de caracteres es una lista de descriptores de caracteres separados por comas y dentro de paréntesis
  • 17. rectangulares. Cada descriptor de carácter describe un solo carácter o un rango de caracteres (ver la descripción a continuación) y esta es agregada al conjunto de caracteres de la lista de caracteres. Si la lista de caracteres comienza con el símbolo "~" el conjunto de caracteres es representado por cualquier carácter UNICODE no especificado en el conjunto especificado. -------------------------------------------------------------------------------- character_descriptor::= java_string_literal ["-" java_string_literal] Un descriptor de un carácter puede ser una cadena de solo caracter literal, en cuyo caso describe al mismo carácter; o si son dos caracteres separados por un guión “-“, en cuyo caso, describe el conjunto de todos los caracteres en el rango entre e incluyendo estos dos caracteres.