Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
roccojiang committed Jun 15, 2024
1 parent 5480cdd commit 7f54194
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 25 deletions.
Binary file modified src/body/complex-rules.pdf
Binary file not shown.
37 changes: 22 additions & 15 deletions src/body/complex-rules.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,30 @@

\begin{document}

\ourchapter{Lint Rules Using the New Parser \textsc{ast}}
\ourchapter{Using the New Parser \textsc{ast}}

\section{Removing Left-Recursion: Revisited}
Armed with the new \textsc{ast} representation of parsers, the left-recursion factorisation transformation can be revisited.
What has changed?
* Parsers should be simplified before making the patch
* Update to use \scala{Expr} rather than quasiquotes, to allow the application of higher-order functions to be partially evaluated
* Therefore no need to patch in definitions for flip and compose, since they are now lambdas
\begin{itemize}
\item Parser terms should be lawfully simplified to a more readable form before being written as a Scalafix rewrite patch.
\item Parsers should take advantage of the new \scala{Expr} representation to allow for partial evaluation of higher-order functions, rather than manipulating terms as opaque quasiquotes.
\item The higher-order functions \scala{flip} and \scala{compose} can now be represented as \scala{Expr} lambda expressions, eliminating the need to patch in their definitions as previously required in \cref{sec:leftrec-utils}.
\end{itemize}

% * Parsers should be simplified before making the patch
% * Update to use \scala{Expr} rather than quasiquotes, to allow the application of higher-order functions to be partially evaluated
% * Therefore no need to patch in definitions for flip and compose, since they are now lambdas
* no .curried
* Resugaring
* Optimisation: normalise leftrec part to see if it comes to empty -- if so, don't inline in the NT case

\begin{minted}{scala}
trait Parser {
def prettify: Parser = this.simplify.normaliseExprs.resugar
def normalise: Parser = this.simplify.normaliseExprs
def isEquivalent(other: Parser) = this.normalise == other.normalise

def prettify: Parser = this.normalise.resugar
def resugar: Parser = this.rewrite {
// p.map(\x -> \y -> y) <*> q == p ~> q
case FMap(p, Abs(_, Abs(Var(y, _), Var(z, _)))) <*> q if (y == z) => p ~> q
Expand All @@ -29,11 +37,10 @@ \section{Removing Left-Recursion: Revisited}
Zipped(AbsN(List(x1, x2), body), List(p1, p2))

}.transform {
// Scala 2 cannot resolve implicit stringLifts on "s".map(f)
// Scala 2 cannot resolve implicit stringLifts in some positions
case FMap(Str(s, _), f) => FMap(Str(s, implicitSyntax = false), f)
case Zipped(f, Str(s, _) :: ps) => Zipped(f, Str(s, implicitSyntax = false) :: ps)
}

def normaliseExprs: Parser // applies Expr.normalise on all parsers with Expr arguments
}
\end{minted}

Expand Down Expand Up @@ -92,12 +99,12 @@ \section{Avoid Parser Redefinition}
Looking for dumb definitions of things e.g. endBy(p, sep) implemented as many(p <* sep); or count implemented as a foldLeft, fold fusion
}

\section{Convert to Parser Bridge}
\TODO{
* This would be cool, idk if I have time though, but this should also piggyback off of Func
* the pos bridges don't actually exist, so we can ignore that case and just say its too much code synthesis
* shouldn't be too bad? idk
* indicate limitations that this will only work if the ADT is defined in the same file, in order to extend it
}
% \section{Convert to Parser Bridge}
% \TODO{
% * This would be cool, idk if I have time though, but this should also piggyback off of Func
% * the pos bridges don't actually exist, so we can ignore that case and just say its too much code synthesis
% * shouldn't be too bad? idk
% * indicate limitations that this will only work if the ADT is defined in the same file, in order to extend it
% }

\end{document}
Binary file modified src/body/leftrec.pdf
Binary file not shown.
10 changes: 5 additions & 5 deletions src/body/leftrec.tex
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ \subsection{Unfolding the Core Combinators}
}
\end{minted}
\subsection{Composite Combinators}
\subsection{Composite Combinators}\label{sec:desguar-combinators}
The remaining combinators are defined in terms of the core combinators, and are unfolded by recursively unfolding their constituent parts.
For example, the \scala{map} combinator is defined as \scala{p.map(f) = pure(f) <*> p}, so its unfolding is simply implemented as:
\begin{minted}{scala}
Expand Down Expand Up @@ -477,7 +477,7 @@ \subsection{Composite Combinators}
}
\end{minted}
\subsection{Defining Utility Functions}
\subsection{Defining Utility Functions}\label{sec:leftrec-utils}
In various places within the unfolding transformations, three higher-order functions were utilised which may not be provided by the Scala standard library:
\begin{itemize}
\item The flip function reverses the order of arguments applied to a function. This isn't defined in the standard library, so it must be defined manually.
Expand All @@ -487,11 +487,11 @@ \subsection{Defining Utility Functions}
%
Therefore, \texttt{parsley-garnish} will insert the following definitions into the source file as a patch:
\begin{minted}{scala}
def flip[A, B, C](f: A => B => C)(x: B)(y: A): C = f(y)(x)
def compose[A, B, C](f: B => C)(g: A => B)(x: A): C = f(g(x))
def flip[A, B, C](f: A => B => C)(x: B)(y: A): C = f(y)(x)
def compose[A, B, C](f: B => C)(g: A => B)(x: A): C = f(g(x))
\end{minted}
%
This brings these higher-order functions into scope, allowing the transformed code to make use of it.
Although this isn't very aesthetically pleasing, it is necessary to bring these higher-order functions into scope for the transformed code to make use of them.
\subsection*{Success...?}
With the unfolding transformations defined for all core combinators, the left-recursion factoring transformation is now complete.
Expand Down
Binary file modified src/introduction/acknowledgements.pdf
Binary file not shown.
21 changes: 16 additions & 5 deletions src/introduction/acknowledgements.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,21 @@

\begin{document}

\ourchapterstar{Acknowledgements}
\TODO{
Jamie is cool
I love my family and friends etc.
}
\hspace{0pt}
\vfill
\section*{\centering Acknowledgements}
\noindent
I would like to thank my supervisor, Jamie Willis, for his support throughout not only this project but also my time at Imperial.
Thank you for always being available no matter what time of day, and for introducing me to Scala and parser combinators in the first place.
\newline

\noindent
I would also like to thank my friends for making life interesting, and especially thank those who had to read my drafts and listen to my nonsensical ramblings about this project.
\newline

\noindent
Finally, I'd like to thank my family for their unwavering and unconditional support throughout my life.
\vfill
\hspace{0pt}

\end{document}

0 comments on commit 7f54194

Please sign in to comment.