2020-02-25 05:51:39 +00:00
|
|
|
\begin{frame}[fragile]
|
2020-02-25 08:29:00 +00:00
|
|
|
\frametitle{Deep dive into parsing DSL syntax}
|
2020-02-25 05:51:39 +00:00
|
|
|
|
|
|
|
\begin{columns}
|
|
|
|
\begin{column}{0.3\textwidth}
|
2020-02-25 08:29:00 +00:00
|
|
|
\begin{itemize}[<+>]
|
2020-02-25 05:51:39 +00:00
|
|
|
\item Hand-rolled recursive-descent parser.
|
|
|
|
\item Why not use LR parser generator?
|
|
|
|
\end{itemize}
|
|
|
|
\end{column}
|
2020-02-25 08:29:00 +00:00
|
|
|
\begin{column}{0.5\textwidth}
|
|
|
|
\begin{Verbatim}[fontsize=\small]
|
2020-02-25 05:51:39 +00:00
|
|
|
component HelloWorld {
|
|
|
|
model {
|
2020-02-25 08:29:00 +00:00
|
|
|
name: String = "",
|
2020-02-25 05:51:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
view {
|
|
|
|
<input bind:value="name" />
|
|
|
|
"Hello, " {name} "!"
|
|
|
|
}
|
|
|
|
}
|
2020-02-25 08:29:00 +00:00
|
|
|
\end{Verbatim}
|
2020-02-25 05:51:39 +00:00
|
|
|
\end{column}
|
|
|
|
\end{columns}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Taking advantage of Rust syntax}
|
|
|
|
|
|
|
|
\begin{columns}
|
|
|
|
\begin{column}{0.4\textwidth}
|
2020-02-25 08:29:00 +00:00
|
|
|
\begin{Verbatim}
|
2020-02-25 05:51:39 +00:00
|
|
|
// proc-macro library
|
2020-02-25 08:29:00 +00:00
|
|
|
enum TokenTree {
|
2020-02-25 05:51:39 +00:00
|
|
|
Group(Group),
|
|
|
|
Ident(Ident),
|
|
|
|
Punct(Punct),
|
|
|
|
Literal(Literal),
|
|
|
|
}
|
2020-02-25 08:29:00 +00:00
|
|
|
\end{Verbatim}
|
2020-02-25 05:51:39 +00:00
|
|
|
\end{column}
|
|
|
|
\begin{column}{0.4\textwidth}
|
|
|
|
\begin{itemize}
|
|
|
|
\item Get \texttt{\{\}}-bracketed groups for free.
|
|
|
|
\item Easily tell identifiers from strings.
|
|
|
|
\item Punctuation has flexible representation.
|
|
|
|
\item Get literal parsing for free.
|
|
|
|
\end{itemize}
|
|
|
|
\end{column}
|
|
|
|
\end{columns}
|
|
|
|
\end{frame}
|
|
|
|
|
2020-02-25 08:29:00 +00:00
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Abstract syntax}
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
\begin{BVerbatim}[fontsize=\small]
|
|
|
|
struct Component {
|
|
|
|
name: String,
|
|
|
|
model: ModelMap,
|
|
|
|
view: Vec<Rsx>,
|
|
|
|
}
|
|
|
|
|
|
|
|
enum Rsx {
|
|
|
|
Elem(Elem<Rsx>),
|
|
|
|
Code(Context, Expr),
|
|
|
|
Text(String),
|
|
|
|
ForLoop(Pat, Expr, Type, Vec<Rsx>),
|
|
|
|
}
|
|
|
|
|
|
|
|
...
|
|
|
|
\end{BVerbatim}
|
|
|
|
\end{center}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Checking your work.. with property testing}
|
|
|
|
|
|
|
|
\begin{itemize}[<+>]
|
|
|
|
\item Define certain properties about the procedures.
|
|
|
|
\item Define types of data that can be passed in.
|
|
|
|
\item Create "strategies" for randomly generating complex data.
|
|
|
|
\item Computer generates input cases based on the strategies.
|
|
|
|
\item Bonus: input cases are "shrunk" down to the minimal case.
|
|
|
|
\end{itemize}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Property testing example}
|
|
|
|
|
|
|
|
\begin{Verbatim}[fontsize=\small]
|
|
|
|
proptest! {
|
|
|
|
#[test]
|
|
|
|
fn tokens_parse_compatibility(tree in arbitrary_component()) {
|
|
|
|
// turn the input tree into tokens and back
|
|
|
|
let tokens = tree.to_token_stream();
|
|
|
|
let mut visitor = Visitor::from_tokens(tokens.clone());
|
|
|
|
let tree2 = visitor.next().unwrap().unwrap();
|
|
|
|
|
|
|
|
// compare the trees
|
|
|
|
prop_assert_eq!(tree.name, tree2.name);
|
|
|
|
prop_assert_eq!(tree.model, tree2.model);
|
|
|
|
prop_assert_eq!(tree.view, tree2.view);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
\end{Verbatim}
|
|
|
|
\end{frame}
|