|
@@ -146,22 +146,29 @@ Need to give thanks to
|
|
|
\chapter{Abstract Syntax Trees, Matching, and Recursion}
|
|
|
\label{ch:trees-recur}
|
|
|
|
|
|
-In this chapter, we introduce key concepts about abstract syntax trees, pattern
|
|
|
-matching, and (structural) recursion. Understanding these three concepts are
|
|
|
-helpful in compiler implementation.
|
|
|
-
|
|
|
+In this chapter, we review the basic tools that are needed for
|
|
|
+implementing a compiler. We use abstract syntax trees (ASTs) to
|
|
|
+represent programs (Section~\ref{sec:ast}) and pattern matching to
|
|
|
+inspect an AST node (Section~\ref{sec:pattern-matching}). We use
|
|
|
+recursion to construct and deconstruct entire ASTs
|
|
|
+(Section~\ref{sec:recursion}).
|
|
|
+
|
|
|
\section{Abstract Syntax Trees and Grammars}
|
|
|
-In programming language theory (PLT), abstract syntax trees (AST) are used to
|
|
|
-structurally model the syntax of a program. As an example, we first provide the
|
|
|
-Backus-Naur Form (BNF), or grammar, of a simple arithmetic language, {\tt Arith}.
|
|
|
+\label{sec:ast}
|
|
|
+
|
|
|
+In programming language theory (PLT), abstract syntax trees (AST) are
|
|
|
+used to structurally model the syntax of a program. As an example, we
|
|
|
+first provide the Backus-Naur Form (BNF), or grammar, of a simple
|
|
|
+arithmetic language, {\tt Arith}.
|
|
|
+
|
|
|
\begin{figure}[htbp]
|
|
|
\centering
|
|
|
\fbox{
|
|
|
\begin{minipage}{0.85\textwidth}
|
|
|
\[
|
|
|
\begin{array}{lcl}
|
|
|
- \Op &::=& \key{+} \mid \key{-} \\
|
|
|
- Arith &::=& Integer \mid (Arith \; \Op \; Arith) \mid (\Op \; Arith)
|
|
|
+ \Op &::=& \key{+} \mid \key{-} \mid \key{*} \\
|
|
|
+ \itm{Arith} &::=& \itm{Integer} \mid (\Op \; \itm{Arith} \; \itm{Arith}) \mid (\Op \; \itm{Arith})
|
|
|
\end{array}
|
|
|
\]
|
|
|
\end{minipage}
|
|
@@ -169,12 +176,13 @@ Backus-Naur Form (BNF), or grammar, of a simple arithmetic language, {\tt Arith}
|
|
|
\caption{The syntax of the {\tt Arith} language.}
|
|
|
\label{fig:arith-syntax}
|
|
|
\end{figure}
|
|
|
+
|
|
|
From this grammar, we have defined {\tt Arith} by constraining its syntax.
|
|
|
Effectively, we have defined {\tt Arith} by first defining what a legal
|
|
|
expression (or program) within the language is. To clarify further, we can
|
|
|
think of {\tt Arith} as a \textit{set} of expressions, where, under syntax
|
|
|
-constraints, \mbox{{\tt 1 + 1}} and {\tt -1} are inhabitants and {\tt 3.2 + 3}
|
|
|
-and {\tt 2 ++ 2} are not (see ~Figure\ref{fig:ast}).
|
|
|
+constraints, \mbox{{\tt (+ 1 1)}} and {\tt -1} are inhabitants and {\tt (+ 3.2 3)}
|
|
|
+and {\tt (++ 2 2)} are not (see ~Figure\ref{fig:ast}).
|
|
|
|
|
|
The relationship between a grammar and an AST is then similar to that of a set
|
|
|
and an inhabitant. From this, every syntaxically valid expression, under the
|
|
@@ -238,6 +246,8 @@ expression is returned wrapped in a {\tt quote} expression.
|
|
|
% that the reader is already familiar with. -JGS}
|
|
|
|
|
|
\section{Pattern Matching}
|
|
|
+\label{sec:pattern-matching}
|
|
|
+
|
|
|
% \begin{enumerate}
|
|
|
% \item Syntax transformation
|
|
|
% \item Some Racket examples (factorial?)
|
|
@@ -297,6 +307,8 @@ expression (i.e., {\tt arith-exp}). Thus, {\tt `(,e1 ,op ,e2)} and
|
|
|
{\tt `(e1 op e2)} are not equivalent.
|
|
|
|
|
|
\section{Recursion}
|
|
|
+\label{sec:recursion}
|
|
|
+
|
|
|
% \begin{enumerate}
|
|
|
% \item \textit{What is a base case?}
|
|
|
% \item Using on a language (lambda calculus ->
|