Enunciado

Anuncio
Trabajo Práctico
Teorı́a de Lenguajes
Segundo cuatrimestre de 2010
1
Introducción
El objetivo de este trabajo práctico es desarrollar un compositor de fórmulas
matemáticas. El mismo tomará como entrada la descripción de una fórmula
en una versión muy simplificada del lenguaje utilizado por LATEX y producirá como salida un archivo PostScript.
Para simplificar el trabajo utilizaremos una tipografı́a monoespaciada.
Esto permitirá resolver el problema sin necesidad de contar con información
sobre la métrica de los distintos caracteres de la tipografı́a.
2
Lenguaje de entrada
La siguiente gramática ambigua describe la sintaxis que deben seguir las
expresiones que acepte el programa:
E
→
|
|
|
|
|
|
|
|
EE
E^E
E E
E^E E
E E^E
E/E
(E)
{E}
l
(concatenación)
(superı́ndice)
(subı́ndice)
(super y subı́ndice)
(sub y superı́ndice)
(división)
(encerrar entre paréntesis)
(agrupar)
(cualquier caracter salvo ^, , /, {, }, ( y ))
Para eliminar la ambigüedad en la interpretación, se debe tener en cuenta que la división es la de menor precedencia, seguida de la concatenación.
Ambas son asociativas a izquierda. El superı́ndice y subı́ndice son no asociativos (no es lı́cito escribir a^b^c ni a b c) y tienen más precedencia que la
concatenación. Por ejemplo, la cadena (A^BC^D/E^F_G+H)-I es equivalente
a {({{A^B}{C^D}}/{{{E^F_G}+}H})-}I, y el resultado se podrı́a ver ası́:
ABCD -I
EFG+H
( )
1
3
Descripción de la salida
PostScript es un lenguaje de programación orientado a la descripción de
páginas inventado por Adobe Systems. Una de sus caracterı́sticas distintivas es que prácticamente todas las operaciones se realizan sobre una pila. Los operandos deben ser apilados para operar con ellos, por lo tanto
aparecen en el código antes que el operador, como en la notación postfija. El manual de referencia del lenguaje PostScript se puede obtener en
http://www.adobe.com/devnet/postscript/index.html.
Existen distintas convenciones para especificar tamaños de letra. Una de
las más usadas es la de indicar el interlineado para el cual está diseñada
la tipografı́a. Cuando se habla de una tipografı́a de 10 puntos usando esta
convención, se quiere decir la tipografı́a está diseñada para que la distancia
vertical entre las lı́neas de base de los caracteres sea de 10 puntos cuando se
usa interlineado normal. Un punto es 1/72 de pulgada.
En PostScript, las tipografı́as están diseñadas para que las lı́neas de
base de los caracteres estén separadas verticalmente por una unidad. En
la tipografı́a monoespaciada Courier, la separación horizontal entre cada
caracter es de 0.6 unidades.
Durante la ejecución de un programa en PostScript se mantienen como
parte del estado gráfico el punto actual y la tipografı́a actual. El operador
show dibuja la cadena de caracteres que esté en el tope de la pila usando la
tipografı́a actual y tomando el punto actual como inicio de la lı́nea de base
para el texto. Por ejemplo, los comandos:
/Courier findfont setfont
1 5 moveto
(The quick brown fox) show
1 4 moveto
(jumps over the lazy dog) show
producen el siguiente resultado:
The quick brown fox
jumps over the lazy dog
al que le agregamos una grilla y algunas anotaciones para que se vea cuáles
son las dimensiones y coordenadas resultantes:
{
0.6
The quick brown fox{
jumps over the lazy dog
1.0
(1,5)
(1,4)
2
Cuadro 1: Ejemplo de salida para la cadena de entrada (A^BC^D/E^F G+H)-I
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 0 0 55 33
0 14 translate
12 12 scale
.03 setlinewidth
/Courier findfont setfont
gsave 0.69 0.47 moveto 1.00 1.00 scale (A) show grestore
gsave 1.29 0.92 moveto 0.70 0.70 scale (B) show grestore
gsave 1.71 0.47 moveto 1.00 1.00 scale (C) show grestore
gsave 2.31 0.92 moveto 0.70 0.70 scale (D) show grestore
gsave 0.60 -0.68 moveto 1.00 1.00 scale (E) show grestore
gsave 1.20 -0.93 moveto 0.70 0.70 scale (G) show grestore
gsave 1.20 -0.23 moveto 0.70 0.70 scale (F) show grestore
gsave 1.62 -0.68 moveto 1.00 1.00 scale (+) show grestore
gsave 2.22 -0.68 moveto 1.00 1.00 scale (H) show grestore
gsave 0.60 0.28 moveto 2.22 0.00 rlineto stroke grestore
gsave 0.00 -0.36875 moveto 1.00 2.475 scale (\() show grestore
gsave 2.82 -0.36875 moveto 1.00 2.475 scale (\)) show grestore
gsave 3.42 0.00 moveto 1.00 1.00 scale (-) show grestore
gsave 4.02 0.00 moveto 1.00 1.00 scale (I) show grestore
showpage
Al comienzo de la ejecución de un programa PostScript, una unidad
mide 1 punto. El operador scale permite cambiar arbitrariamente el tamaño
de una unidad. Esto permitirá seleccionar el tamaño al que se quiere que
aparezcan los distintos caracteres. Este operador tiene efecto global: afecta
a todos los comandos que se ejecuten después de él. Para acotar su alcance
se pueden usar los operadores gsave y grestore, que guardan y recuperan
el estado gráfico de una pila dedicada.
Para el super y subı́ndice se suele reducir el tamaño de letra a un 70 %
del original y desplazar la lı́nea de base hacia arriba o hacia abajo respectivamente. Para las divisiones, la lı́nea de división se suele alinear con la
lı́nea horizontal de los signos más y menos (aproximadamente 0.28 unidades sobre la lı́nea de base). El numerador y el divisor se ubican centrados
horizontalmente con respecto a la lı́nea de división.
En el cuadro 1 se ve una posible salida para la cadena de entrada
(A^BC^D/E^F_G+H)-I, cuya imagen mostramos en la sección anterior.
3
4
Modo de uso
El programa debe poder ser invocado por lı́nea de comandos, recibiendo
como parámetro la especificación de la fórmula y escribiendo el resultado
en su salida standard o en un archivo. En caso de que lo recibido como
parámetro no sea una fórmula válida se lo debe informar en la salida de
error standard.
5
Implementación
Hay dos grupos de herramientas que se pueden usar para generar los analizadores léxico y sintáctico, y agregar las acciones requeridas para generar el
documento de salida:
• Uno utiliza expresiones regulares y autómatas finitos para el análisis
lexicográfico, y la técnica LALR para el análisis sintáctico. Ejemplos
de esto son lex y yacc, que generan código C o C++, o JLex y CUP,
que generan código Java.
flex y bison son implementaciones libres y gratuitas de lex y yacc.
Son parte de todas las distribuciones Linux. Para Windows pueden
ser instalados como parte de Cygwin (http://www.cygwin.com/), o
de DJGPP (http://www.delorie.com/djgpp/). También se pueden
conseguir en forma independiente en http://www.gnu.org/.
JLex y CUP se pueden conseguir en http://www.jflex.de/ y
http://www2.cs.tum.edu/projects/cup/
• El otro grupo utiliza la técnica ELL(k) tanto para el análisis léxico
como para el sintáctico, generando parsers descendentes iterativos recursivos. Ejemplos son JavaCC, que genera código Java, y ANTLR, que
está escrito en Java pero puede generar código Java, C++ o C#. ANTLR
se puede conseguir en http://www.antlr.org/ y JavaCC en
http://javacc.dev.java.net/.
Se puede utilizar la herramienta GSview para ver que el código PostScript
generado sea sintácticamente correcto y visualizar el resultado. Se puede
obtener en http://www.cs.wisc.edu/~ghost/gsview/
La entrega debe incluir:
• Un programa que cumpla con lo solicitado.
• El código fuente impreso del programa. Si se usaron herramientas generadoras de código, imprimir la fuente ingresada a la herramienta, no
el código generado.
• Informe conteniendo:
4
– Las modificaciones a la gramática o indicaciones adicionales que
hayan sido necesarias para utilizarla con la herramienta elegida.
– Descripción de cómo se implementó la solución
– Ejemplos de fórmulas sintácticamente correctas e incorrectas, los
resultados obtenidos y conclusiones.
5
Descargar