\documentclass[12pt]{amsart}


\usepackage{color}
\usepackage{listings}
\lstloadlanguages{Haskell}
\usepackage{enumerate}

\input{deflogic}

\def\sqn{sequence}
\def\happy{\textbf{Hlex}}
\def\haskell{\textbf{Haskell}}
\def\pc{Propositional Calculus}
\def\inp{\emph{input}}
\def\linux{\textbf{Linux}}
\def\freebsd{\textbf{FreeBSD}}
\title{A parser for the propositional calculus}
\author{Raul H.C.Lopes}

\begin{document}
\maketitle


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

\section{Introdution}
This document introduces a parser for the \pc\ written in the language of
the program \happy, a compiler-compiler that generates parsers in Haskell
from the description of the grammar of the target language.
\happy\ reads the grammar (indeed a description of ) of some language
$\mathcal{L}$ and generates a parser (a program that decides whether 
input sentences are $\mathcal{L}$ sentences.)
It must be clear that input for the parser must be a sequence of tokens.

For example, if you're dealing with \pc\ formulae, the sentences should 
consist of disjuntions of formulae, conjunction, implications and so on.

The grammar is described by presenting 
\begin{itemize}
  \item the set of amissible tokens;
  \item the actions to take when legal sentences (sequences of tokens) are
identified in the input.
\end{itemize}

\subsection{Generating the parser}

Use the program \textbf{lst2code.pl} to extract a program in \happy
that describes the syntax for the \pc.


\begin{verbatim}
  ./lst2code.pl PCFormula.tex > PCFormula.y
\end{verbatim}

A file named \textbf{PCFormula.y} will be created that will contain a 
\happy\ program for parsing \pc\ formulae. Use \happy\ to produce a
haskell parser for the \pc. The line bellow will create a file named
\textbf{PCFormula.hs} containing the Haskell encoded parser.

\begin{verbatim}
  happy PCFormula.y
\end{verbatim}

\subsection{Where to find \happy}

Follow the link
\begin{verbatim} http://www.haskell.org/happy/
\end{verbatim}

to get sources and documentation for \happy.

\subsection{The program \emph{lst2code.pl}}
The program  \textbf{lst2code.pl} extracts code from a \LaTeX\ document.


\section{What the parser exports}
The first thing to do is to introduce a module that will implement the
parser. A \sqn\ of lines preceded by '\textbf{\{}' and followed by
'\textbf{\{}' introduces is literally inserted in the generated \haskell\
code. The code that follows declares the module \textbf{PCFormula}, and exports
\textbf{Formula}, \textbf{parseFormula}, and \textbf{parse}. Notice that
it imports the lexical analyser \textbf{PCTokens}.

%!file: PCFormula.y
\begin{lstlisting}{}
-- -*-Text -*-
{
module PCFormula(Formula(..),parseFormula,parse)
where
import Char
import PCTokens
}
\end{lstlisting}


\section{Interfacing with pasrser}
A name is declared for the function that will map a \sqn\ of tokens to
a parsing tree: it is named \textbf{parseFormula}. The \haskell\ data type
of tokens is also declared: \textbf{Token}.


\begin{lstlisting}{}
%name parseFormula

%tokentype { Token }
\end{lstlisting}

At last, the tokens are presented.
\begin{lstlisting}{}

%token 
        not		{ TokNeg }
	or		{ TokDisj }
	var		{ TokVar $$ }
	and		{ TokConj }
	imp 		{ TokImp  }
        equiv		{ TokEquiv}
        '('   		{ TokOpen }
        ')'  		{ TokClose}
\end{lstlisting}

Notice the line
\begin{verbatim}
	var		{ TokVar $$ }
\end{verbatim}

that declares a name \textbf{var} for the token \textbf{(TokVar \$\$\$)},
where \textbf{\$\$\$} will stand for the identifier carried along with
this kind of token.

\section{The grammar}
The target language grammar is presented next. First priorities are introduced
for some tokens. In the following lines, \textbf{imp} and \textbf{equiv}
have the same priority which is lower than the priority attibuted to
\textbf{and} and \textbf{or}.

\begin{lstlisting}{}

--%left not
--%left and or
%left imp equiv
%left and or
%left not
%%
\end{lstlisting}


The syntax of formulae is presented next.
\begin{lstlisting}{}

Formula : var				{ Var $1 }
	| not Formula			{ Neg $2 }
	| '(' not Formula ')'		{ Neg $3 }
	| '(' Formula and Formula ')'	{ Conj $2 $4 }
	| Formula and Formula	  	{ Conj $1 $3 }
	| '(' Formula or Formula ')'	{ Disj $2 $4 }
	| Formula or Formula	 	{ Disj $1 $3 }
	| '(' Formula imp Formula ')'	{ Imp $2 $4 }
	| Formula imp Formula		{ Imp $1 $3 }
	| '(' Formula equiv Formula ')'	{ Equiv $2 $4 }
	| Formula equiv Formula 	{ Equiv $1 $3 }
\end{lstlisting}
%$

For example the line

\begin{verbatim}
	| '(' Formula and Formula ')'	{ Conj $2 $4 }
  
\end{verbatim}

states if a disjunction of formulae enclose by parentheses is seen on input,
then the constructor \textbf{Conj} should be called with second and
fourth tokens of the input sentence as arguments. Notice that in such a 
sentence the first token is '\textbf{(}', the second token is a formula,
the third one the conjunction token, and the fourth one is  '\textbf{)}'.

A last stretch of \haskell\ code is introduced to declared an error 
function, the type of formulas, and the function \textbf{parse}, a composition
of \textbf{parseFormula} and \textbf{alexScanToken}, capable of mapping
\textbf{String} to  a \textbf{Formula}.
\begin{lstlisting}{}

{

happyError :: [Token] -> a
happyError _ = error ("Parse error\n")


data Formula = 
  Var String |
  Neg Formula |
  Disj Formula Formula |
  Conj Formula Formula |
  Imp Formula Formula |
  Equiv Formula Formula 
 deriving(Eq,Read,Show)

parse = parseFormula . alexScanTokens


                                        

}
\end{lstlisting}

\section{\happy, yacc, bison}
\happy\ is Haskell implementation of a compiler-compiler based on the ideas
introduced in seventies by \textbf{yacc}. Another descendant of \textbf{yacc}
is \textbf{bison}, found in systems like \linux\ and \freebsd. If you're
interested in parsers you should also take a look at \textbf{Antlr}.
\end{document}
