SINTAXIS
Definición de Gramáticas: Una gramática libre de contexto G = (T,N,S,R) consiste en:
ejemplo:
Ejemplo Propuesto
Arboles de análisis sintáctico: Representación gráfica de una derivación, la manera en que el símbolo inicial de una gramática deriva a una cadena en el lenguaje. Tiene las siguientes propiedades:
1. La raíz se etiqueta con el símbolo inicial.
2. Cada hoja se etiqueta con un terminal, o con Є.
3. Cada nodo interior se etiqueta con un no terminal.
4. Si A es el no terminal que etiqueta a cierto nodo interior, y X1, X2,…,Xn son las etiquetas de los hijos de ese nodo de izquierda a derecha.
ejemplo:
De la derivación anterior se forma el siguiente árbol sintáctico:

Ejemplo Propuesto:
Ambigüedad: Diremos que una gramática G es ambigua si el lenguaje definido por ella tiene alguna sentencia para la cual existe más de un árbol sintáctico. Hay que tener claro que la que es ambigua es la gramática, no el lenguaje y que con una gramática ambigua no será posible implementar un analizador. Asimismo, siempre es posible modificar las reglas de la gramática para solucionar la ambigüedad y manteniendo el mismo lenguaje.
Por ejemplo, la suma binaria + tiene asociatividad izquierda, lo que significa que en una expresión como:
a + b + c + d;
- ejemplo Propuesto:
1+5+3-8;
((1+5)+(3-8))
Precedencia de operadores: indica cual es el orden de ejecución de los operadores cuando existen varios.
Por ejemplo, en la expresión:
Por ejemplo:
- ejemplo Propuesto:
1*3+8*5-4
((1*3)+(8*5)-4)
- un conjunto
de terminales T
- un conjunto
de no terminales N
- un símbolo
de inicio S
- un conjunto
de producciones R o reglas de derivación, cada una de la forma:
X ->Y1Y2 : : : Yn
Donde X € N e Yi € T U N U {€}
ejemplo:
La gramática G=(N,T,I,P) donde,
N={I,A,B}
T={x,(,),+,-,*,/}
P={
I->I+I
I->I-I
I->A
A->A*A
A->A/A
A-> (I)
A->x
Ejemplo Propuesto
La gramática G=(A,B,C,D) donde,
A={C,F,G}
B={y,(,),+,-,*,/}
D={
C->C+C
C->C-C
C->G
C->G
G->G*G
G->G/G
G-> (A)
G->y
Derivaciones: Tratando las reglas de producción como una
regla de reescritura, en la que el no terminal del lado izquierdo es reemplazado por la cadena del lado derecho de
la producción, se obtiene una derivación.
Derivación por la izquierda: Derivación donde
solo el no terminal de más a la izquierda de cualquier forma de frase se
sustituye en cada paso.
Derivación por la derecha o Derivación
canónica: Derivación donde el no terminal más a la derecha se sustituye en cada
paso.
Por ejemplo, una gramática para operaciones matemáticas
simples puede ser (1) (que también se puede escribir con el operador |1 como en (2)):
S -> E
E -> E
+ E
E -> E
* E (1)
E -> (E)
E -> id
S -> E
E -> E
+ E
| E * E (2)
| (E)
| id
Las expresiones gramaticales derivan en arboles sintácticos, por ejemplo para la expresión:
id * id + id
La derivación se hace remplazando los no
terminales por la regla de producción hasta “calzar" la expresión, según el ejemplo:
S -> E -> E + E -> E * E + E -> id
* E + E -> id * id + E -> id * id + id
Ejemplo Propuesto:
a/b-c
P -> F -> F - F -> F / F - F -> a / F - F -> a / b - F -> a / b - c
Ejemplo Propuesto:
a/b-c
P -> F -> F - F -> F / F - F -> a / F - F -> a / b - F -> a / b - c
Esta es una derivación por la izquierda porque
a cada paso remplazamos el no terminal de mas a la izquierda.
Arboles de análisis sintáctico: Representación gráfica de una derivación, la manera en que el símbolo inicial de una gramática deriva a una cadena en el lenguaje. Tiene las siguientes propiedades:
1. La raíz se etiqueta con el símbolo inicial.
2. Cada hoja se etiqueta con un terminal, o con Є.
3. Cada nodo interior se etiqueta con un no terminal.
4. Si A es el no terminal que etiqueta a cierto nodo interior, y X1, X2,…,Xn son las etiquetas de los hijos de ese nodo de izquierda a derecha.
ejemplo:
De la derivación anterior se forma el siguiente árbol sintáctico:

Ejemplo Propuesto:
Ambigüedad: Diremos que una gramática G es ambigua si el lenguaje definido por ella tiene alguna sentencia para la cual existe más de un árbol sintáctico. Hay que tener claro que la que es ambigua es la gramática, no el lenguaje y que con una gramática ambigua no será posible implementar un analizador. Asimismo, siempre es posible modificar las reglas de la gramática para solucionar la ambigüedad y manteniendo el mismo lenguaje.
Ejemplo.
G = { {s}, {a,+,*}, P, S }
P: S -> a
S -> S+S
S -> S*S
Si dibujamos el árbol de derivación para
"a*a+a", nos puede salir de dos formas distintas:
Aquí se ve claramente que la gramática es
ambigua, pues podemos aplicar indistintamente la segunda o la tercera regla.
Existen algunas soluciones para este tipo de
ambigüedad sin reescribir la gramática y como un “mecanismo externo”:
a) Dar mayor prioridad al producto que a la
suma.
b) En caso de igualdad en la prioridad obligar
al uso de paréntesis.
Asociatividad de operadores: indica el orden de ejecución cuando en una
expresión existen diversos operadores de igual precedencia. Puede ser de dos
tipos: izquierda (→) o derecha (←) .Por ejemplo, la suma binaria + tiene asociatividad izquierda, lo que significa que en una expresión como:
la ejecución seguirá el orden:
(((a + b) + c) + d);
Los operadores unarios y el de asignación (=),
tienen asociatividad derecha (←). Todos los demás la tienen izquierda (→). En
consecuencia, si @ representa un operador binario, ante una expresión
como:
a @ b @ c @ d;
el orden de evaluación es desde la izquierda
hacia la derecha. Pero si la expresión es del tipo:
(...) @ (...) @ (...) @ (...);
el orden de evaluación de los paréntesis es
indefinido. Aunque una vez obtenidos todos los resultados parciales, la
computación sigue el orden indicado en el punto anterior.
Si existen paréntesis anidados se procede
desde dentro hacia fuera:
(((.1.)@(.1.)2) @ (.2.));
1+5+3-8;
((1+5)+(3-8))
Precedencia de operadores: indica cual es el orden de ejecución de los operadores cuando existen varios.
Por ejemplo, en la expresión:
a * b + c++; // L.1
la precedencia determina que se ejecutará primero el operador postincremento ++ sobre c. A continuación se aplicará el operador de multiplicación * entre a y b. Finalmente se aplicará el operador suma + entre los resultados anteriores. Así pues, la expresión es equivale a:
(a * b) + (c++); // L.2
Este orden "natural" del compilador no necesita paréntesis de forma que las sentencias L1 y L2 producen el mismo resultado. Cualquier otro debe ser forzado específicamente mediante la utilización de los paréntesis correspondientes.
Por ejemplo:
a * (b + c)++; // L.3
- ejemplo Propuesto:
1*3+8*5-4
((1*3)+(8*5)-4)
0 comentarios:
Publicar un comentario