\documentclass[12pt]{amsart}

\usepackage[portuges]{babel}
\usepackage{color}
\usepackage{listings}
\lstloadlanguages{Haskell}
\usepackage{enumerate}

\input{defport}
\input{deflogic}

\def\expr{express\ao}
\def\Token{\textbf{Token}}
\def\Expression{\textbf{Expression}}
\def\getToken{\textbf{getToken}}
\def\tokenize{\textbf{tokenize}}
\def\parseSum{\textbf{parseSum}}
\def\parseSumOp{\textbf{parseSumOp}}
\def\parseSumOperator{\textbf{parseSumOperator}}
\def\eval{\textbf{eval}}
\def\treeEval{\textbf{treeEval}}
\def\parse{\textbf{parse}}
\def\parseExpr{\textbf{parseExpr}}
\def\TokOpen{\textbf{TokOpen}}
\def\TokClose{\textbf{TokClose}}
\def\alex{\textbf{Alex}}
\def\haskell{\textbf{Haskell}}
\def\cpc{C\'alculo de Proposi\coes}
\def\inp{\emph{input}}
\title{Analisador L\'exico para PC}
\author{Raul H.C.Lopes}

\begin{document}
\maketitle


\lstset{
basicstyle=\small,
frame=tb,
keywordstyle=\color{blue}\bfseries,
language=Haskell,
indent=20pt
}

\section{Introdu\cao}
Este documento apresenta um analisador l\'exico na linguagem de \alex, que \'e 
um gerador de analisadores. O programa \alex\ l\^e uma \emph{descri\cao}
do l\'exico de uma linguagem $\mathcal{L}$ e gera um programa que 
faz a an\'alise 
l\'exica de qualquer documento dado para descobrir se ele  est\'a escrito
na linguagem $\mathcal{L}$. 

Por exemplo, se seu objetivo consiste em lidar com f\'ormulas do 
c\'alculo de proposi\coes, a sua linguagem dever\'a ter senten\cas (as
f\'ormulas do c\'alculo de proposi\coes)  construidas com os seguintes
\emph{tokens}, entre outros: vari\'aveis proposicionais (como $p, q, r$)
e constantes l\'ogicas, como $\limp, \land$. Entenda os tokens da 
linguagem como as palavras v\'alidas da mesma. Os s\ii mbolos usados para 
escrever os tokens s\ao\ o alfabeto da linguagem.  

A descri\cao\ do l\'exico de uma linguagem apresenta:
\begin{itemize}
  \item O alfabeto (conjunto de s\ii mbolos) admiss\ii veis na constru\cao\
de tokens da linguagem. Note que isso inclui n\ao apenas s\ii mbolos para 
construir palavras, mas tamb\'em sinais de pontua\cao.
  \item As palavras (tokens) aceit\'aveis da linguagem.
\end{itemize}

\subsection{A gera\cao do analisador}

Use o programa \textbf{lst2code.pl} para extrair o programa em \alex\ que
descreve um linguagem de f\'ormulas do c\'alculo proposicional:

\begin{verbatim}
  ./lst2code.pl PCTokens.tex
\end{verbatim}

Esse comando gerar\'a um arquivo de nome \textbf{PCTokens.x}. Esse arquivo
cont\'em um \emph{programa} em \alex. Use \alex\ para transform\'a-lo
em um programa em \haskell, que conter\a' um analisador l\'exico
para o c\'alculo de proposi\coes.

\begin{verbatim}
  alex -o PCTokens.hs PCTokens.x
\end{verbatim}

A linha acima executa o programa \alex, que ler\'a o arquivo 
\textbf{PCTokens.x} e produzir\'a o arquivo \textbf{PCTokens.hs}, contendo
um analisador l\'exico (escrito em Haskell) para o c\'alculo de proposi\coes.

\subsection{Onde encontrar o \alex}

O link 
\begin{verbatim} http://www.haskell.org/alex/
\end{verbatim}

cont\'em pacote \textbf{RPM}, fontes e documenta\cao\ do \alex.

\subsection{O programa \emph{lst2code.pl}}
O programa \textbf{lst2code.pl} segue neste diret\'orio. Ele \'e ligeiramente
diferente do programa de mesmo nome divulgado anteriormente: as diretivas
com nome de arquivos de output devem agora aparecer em linhas isoladas.

\section{O que o analisador exporta}

O seu programa em \alex\ (que descreve o l\'exico do \cpc) come\ca\ com
um trecho de c\'odigo que ser\'a incorporado diretamente ao analisador
em Haskell. Sempre necessitar fazer isso, cerque o c\'odigo a incorporar
no analisador com '\textbf{\{}' e '\textbf{\}}'.

%!file: PCTokens.x
\begin{lstlisting}{} 

{
module PCTokens (Token(..), alexScanTokens) where
}

\end{lstlisting}

O trecho acima incorpora a linha 

\begin{verbatim}
  module PCTokens (Token(..), alexScanTokens) where

\end{verbatim}

no topo do c\'odigo em Haskell do analisador. Ele descreve o que o m\'odulo
\textbf{PCTokens} exporta. Repare que \textbf{alexScanTokens} \'e fun\cao\
gerado por \alex, que realizar\'a a an\'alise l\'exica de qualquer
texto.

A linha a seguir importa um m\'odulo, \textbf{basic}, do \alex.

\begin{lstlisting}{} 

%wrapper "basic"
\end{lstlisting}


\section{Os tokens da linguagem}

O alfabeto do \cpc\ admitir\'a:
\begin{itemize}
\item d\ii gitos e caracteres alfab\'eticos, que
ser\ao\ usados para formar nomes de vari\
\item conectivos para representar as constantes l\'ogicas: $\land$
para conjun\cao, $\lor$ para disjun\cao, etc.
\end{itemize}

O trecho abaixo d\'a nomes para alguns desses s\ii mbolos: por exemplo,
estabele que \textbf{\$digit} \'e qualquer d\ii gito de $0$ a $9$.
\begin{lstlisting}{} 

$digit = 0-9			-- digits
$alpha = [a-zA-Z]		-- alphabetic characters
$disj = [\|]
$neg  = [\-]
$conj = [\&]

\end{lstlisting}
%$

\subsection{The real stuff}
A descri\cao\ das a\coes\ do analisador come\ca\ com a palavra reservada 
\textbf{tokens}:

\begin{lstlisting}{} 
tokens :-

\end{lstlisting}

O programa em \alex\ cont\'em uma \sqn\ de linhas contendo cada uma
um par designando: texto esperado no \inp\ e a\cao\ a realizar se o
texto ocorrer. Por exemplo, no trecho a seguir
\begin{itemize}
  \ibf{\$white} denota uma ocorr\^encia de um espa\co\ no \inp;
  \ibf{\$white+} denota a ocorr\^encia de ao menos um espa\co\ no \inp;
  \item essa regra manda que espa\co s no \inp\ sejam ignorados: 
\end{itemize}
\begin{lstlisting}{}
  
  $white+				;
  "--+".*				;
\end{lstlisting}
%$

A linha seguinte manda que ao encontrar a \sqn\
'\textbf{--+}' o restante da linha seja ignorado.

No trecho a seguir, a primeira linha manda que ao ser encontrado o
s\ii mbolo da disjun\cao\ o analisador retorne o token correspondente:
\textbf{TokDisj}.

\begin{lstlisting}{}
  $disj                                 { \s -> TokDisj}
  $neg                                 	{ \s -> TokNeg}
  $conj					{ \s -> TokConj}
  \(					{ \s -> TokOpen}
  \)					{ \s -> TokClose}
  \=\> 					{ \s -> TokImp}
  \<\=\>				{ \s -> TokEquiv}
\end{lstlisting}
%$

A \'ultima a\cao\ do analisador recomenda que diante de um \inp\ constitu\ii do
de um caracter alfab\'etico e zero ou mais caracteres alfab\'eticos ou
d\ii gitos, um token contendo o string lido seja retornado: \textbf{(TokVar s)}
const\'oi um token a partir de um string '\textbf{s}'. 
\begin{lstlisting}{}
  $alpha [$alpha $digit]*		{ \s -> TokVar s }
\end{lstlisting}
%$

\section{Os tokens como tipo indutivo em Haskell}
Um novo trecho de c\'odigo em Haskell, precedido de '\textbf{\{}' e seguido de
'\textbf{\}}, declara o tipo \textbf{Token}, que \'e uma enumera\cao\
de todos os tokens da linguagem.
\begin{lstlisting}{} 
{
-- Each right-hand side has type :: String -> Token

-- The token type:
data Token =
        TokNeg		|
        TokDisj		|
	TokConj		|
        TokImp		|
  	TokEquiv	|
	TokOpen		|
	TokClose	|
	TokVar String	|
	TokEOF
	deriving (Eq,Show)

}
\end{lstlisting}

Esse programa em \alex\ gerar\'a um analisador l\'exico, escrito em Haskell.
A fun\cao\ inicial do analisador gerado ser\'a \textbf{alexScanTokens}, que
mapear\'a uma lista de caracteres para uma lista de tokens.
\section{\alex, lex, flex}

O programa \alex\ e sua linguagem s\ao\ modelados no programa \textbf{lex} 
do sistema operacional Unix, escrito na d\'ecada de 70 e que gera analisadores 
l\'exicos. Nos sistemas operacionais como \textbf{Linux} e \textbf{FreeBSD},
\textbf{flex}, uma vers\ao\ mais moderna de \textbf{lex}, \'e encontrado.
\end{document}
