diff --git a/build/report.pdf b/build/report.pdf index a24dc7e..9b993da 100644 Binary files a/build/report.pdf and b/build/report.pdf differ diff --git a/chapter/ch4.tex b/chapter/ch4.tex index 92e6c0c..91eefb1 100644 --- a/chapter/ch4.tex +++ b/chapter/ch4.tex @@ -6,7 +6,7 @@ In this chapter, the implementation of the tool utilizing the \DSL and \DSLSH wi The architecture of the work described in this thesis is illustrated in \figFull[fig:architecture] -In this tool, there exists two multiple ways to define a proposal, and each provide the same functionality, they only differ in syntax and writing-method. +In this tool, there exists two multiple ways to define a proposal, and each provide the same functionality, they only differ in syntax and writing-method. One can either write the definition in \DSL which utilizes Langium to parse the language, or one can use a JSON definition, which is more friendly as an API or people more familiar with JSON definitions. \begin{figure} \begin{center} @@ -25,7 +25,7 @@ In this tool, there exists two multiple ways to define a proposal, and each prov \node[squarednode] (treebuilder) [below=of babel] {Custom AST builder}; \node[squarednode] (matcher) [below=of treebuilder] {Matcher}; \node[squarednode] (transformer) [below=of matcher] {Transformer}; -\node[squarednode] (joiner) [below=of transformer] {Joiner}; +\node[squarednode] (joiner) [below=of transformer] {Generator}; \draw[->] (jstqlcode.south) -- (langium.north); @@ -45,6 +45,8 @@ In this tool, there exists two multiple ways to define a proposal, and each prov \caption[Tool architecture]{Overview of tool architecture} \label{fig:architecture} \end{figure} + + \section{Parsing \DSL using Langium} In this section, the implementation of the parser for \DSL will be described. This section will outline the tool Langium, used as a parser-generator to create the AST used by the tool later to perform the transformations. @@ -218,9 +220,84 @@ for (let stmt of stmts) { } } } +\end{lstlisting} -\section{} +\section{Using Babel to parse} +Allowing the tool to perform transformations of code requires the generation of an Abstract Syntax Tree from the users code, \texttt{applicable to} and \texttt{transform to}. This means parsing JavaScript into an AST, in order to do this we use a tool \cite[Babel]{Babel}. + +The most important reason for choosing to use Babel for the purpose of generating the AST's used for transformation is due to the JavaScript community surrounding Babel. As this tool is dealing with proposals before they are part of JavaScript, a parser that supports early proposals for JavaScript is required. Babel supports most Stage 2 proposals through its plugin system, which allows the parsing of code not yet part of the language. + + +\subsection*{Custom Tree Structure} + +To allow for matching and transformations to be applied to each of the sections inside a \texttt{pair} definition, they have to be parsed into and AST in order to allow the tool to match and transform accordingly. To do this the tool uses the library \cite[Babel]{Babel} to generate an AST data structure. However, this structure does not suit traversing multiple trees at the same time, this is a requirement for matching and transforming. Therefore we use this Babel AST and transform it into a simple custom tree structure to allow for simple traversal of the tree. + +As can be seen in \figFull[def:TreeStructure] we use a recursive definition of a \texttt{TreeNode} where a nodes parent either exists or is null (it is top of tree), and a node can have any number of children elements. This definition allows for simple traversal both up and down the tree. Which means traversing two trees at the same time can be done in the matcher and transformer section of the tool. + + +\begin{lstlisting}[language={JavaScript}, label={def:TreeStructure}, caption={Simple definition of a Tree structure in TypeScript}] +export class TreeNode { + public parent: TreeNode | null; + public element: T; + public children: TreeNode[] = []; + + constructor(parent: TreeNode | null, element: T) { + this.parent = parent; + this.element = element; + if (this.parent) this.parent.children.push(this); + } +} +\end{lstlisting} + +Placing the AST generated by Babel into this structure means utilizing the library \cite{BabelTraverse}{Babel Traverse}. Babel Traverse uses the \cite{VisitorPattern}{visitor pattern} to allow for traversal of the AST. While this method does not suit traversing multiple trees at the same time, it allows for very simple traversal of the tree in order to place it into our simple tree structure. + +\cite{BabelTraverse}{Babel Traverse} uses the \cite{VisitorPattern}{visitor pattern} to visit each node of the AST in a \textit{depth first} manner, the idea of this pattern is one implements a \textit{visitor} for each of the nodes in the AST and when a specific node is visited, that visitor is then used. In the case of transferring the AST into our simple tree structure we simply have to use the same visitor for all nodes, and place that node into the tree. + +Visiting a node using the \texttt{enter()} function means we went from the parent to that child node, and it should be added as a child node of the parent. The node is automatically added to its parent list of children nodes from the constructor of \texttt{TreeNode}. Whenever leaving a node the function \texttt{exit()} is called, this means we are moving back up into the tree, and we have to update what node was the \textit{last} in order to generate the correct tree structure. + +\begin{lstlisting}[language={JavaScript}] +traverse(ast, { + enter(path: any) { + let node: TreeNode = new TreeNode( + last, + path.node as t.Node + ); + + if (last == null) { + first = node; + } + last = node; + }, + exit(path: any) { + if (last && last?.element?.type != "Program") { + last = last.parent; + } + }, + }); + if (first != null) { + return first; + } \end{lstlisting} + +\section{Matching} + + +Performing the match against the users code it the most important step, as if no matching code is found the tool will do no transformations. Finding the matches will depend entirely on how well the definition of the proposal is written, and how well the proposal actually can be defined within the confines of \DSL. In this chapter we will discuss how matching individual AST nodes to each other, and how wildcard matching is performed. + +\subsection*{Matching singular Expression} + +The method of writing the \texttt{applicable to} section using a singular expression is by far the most versatile way of defining a proposal, this is simply because there will be a much higher chance of discovering matches with a template that is as generic as possible. Therefore only matching against a single expression ensures the matcher tries to perform a match at every level of the AST. + +\subsection*{Matching Statements} + +Using multiple statements in the template of \texttt{applicable to} will result in a much stricter matcher, that will only try to perform an exact match using a sliding window of the amount of statements at every \textit{BlockStatement}, as that is the only placement Statements can reside in JavaScript. + +\section{Transforming} + +\section{Generating} + +To generate JavaScript from the transformed AST created by this tool, we use a JavaScript library titled \cite{BabelGenerate}{babel/generator}. This library is specifically designed for use with Babel to generate JavaScript from a Babel AST. + diff --git a/generators/refs.bib b/generators/refs.bib index 2719e75..be35fbd 100755 --- a/generators/refs.bib +++ b/generators/refs.bib @@ -33,4 +33,33 @@ month = may, note = {[Online; accessed 10. May 2024]}, url = {https://babeljs.io} +} + +@misc{BabelTraverse, + title = {{@babel/traverse {$\cdot$} Babel}}, + year = {2024}, + month = may, + note = {[Online; accessed 12. May 2024]}, + url = {https://babeljs.io/docs/babel-traverse} +} + +@inproceedings{VisitorPattern, + author = {Palsberg, J. and Jay, C.B.}, + booktitle = {Proceedings. The Twenty-Second Annual International Computer Software and Applications Conference (Compsac '98) (Cat. No.98CB 36241)}, + title = {The essence of the Visitor pattern}, + year = {1998}, + volume = {}, + number = {}, + pages = {9-15}, + keywords = {Electrical capacitance tomography;Java;Reflection;Computer science;Australia;Ice;Read only memory;Functional programming;Writing}, + doi = {10.1109/CMPSAC.1998.716629} +} + +@misc{BabelGenerate, + title = {{@babel/generator {$\cdot$} Babel}}, + year = {2024}, + month = may, + urldate = {2024-05-12}, + note = {[Online; accessed 12. May 2024]}, + url = {https://babeljs.io/docs/babel-generator} } \ No newline at end of file