diff -r c7e944977e39 -r 68b1a84efce6 cws/cw03.tex --- a/cws/cw03.tex Wed Sep 17 14:29:52 2025 +0100 +++ b/cws/cw03.tex Wed Sep 17 15:11:48 2025 +0100 @@ -17,7 +17,8 @@ you need to submit the source code with which you answered the questions, otherwise a mark of 0\% will be awarded. If you use Scala in your code, a good place to start is the file \texttt{comb1.sc} and -\texttt{comb2.sc} uploaded to KEATS. Feel free to use the ``hack'' +\texttt{comb2.sc} uploaded to KEATS. Make sure your parser combinators +process list of tokens as input, not strings. Feel free to use the ``hack'' explained during the lectures. This might make your grammar simpler. However, make sure you understand the code involved in the ``hack'' because if you just do ``mix-and-match'' you will receive @@ -27,7 +28,7 @@ ``runs'' the program. The marks will be distributed such that 6 marks are given for the correct grammar (and parsers); 4 marks for the correct \texttt{eval} function. You should use the lexer from CW2 for the -parser - you potentially need to make additions for CW2. +parser - you potentially need to make additions for CW3. \subsection*{Disclaimer\alert} @@ -35,35 +36,36 @@ effort. You have not copied from anyone else. An exception is the Scala code I showed during the lectures or uploaded to KEATS, which you can both use. You can also use your own code from the CW~1 and -CW~2. But do not -be tempted to ask Github Copilot for help or do any other -shenanigans like this! - -\subsection*{Syntax Error in Template File cw03.sc\alert} - -Apologies, there is a small syntax error in the template file where a variable -needs to be called \texttt{tks} instead of \texttt{tk}. The code -in question is at the end of \texttt{cw03.sc} and should be like -this (see lines 5, 6 and 8): +CW~2. +%But do not +%be tempted to ask Github Copilot for help or do any other +%shenanigans like this! -\begin{lstlisting}[language=Scala,numbers=left] -@main -def test(file: String) = { - val contents = os.read(os.pwd / "examples" / file) - println(s"Lex $file: ") - val tks = tokenise(contents) - println(tks.mkString(",")) - println(s"Parse $file: ") - val ast = Stmts.parse_all(tks).head - println(ast) - println(s"Eval $file: ") - println(eval(ast)) -} -\end{lstlisting} +%\subsection*{Syntax Error in Template File cw03.sc\alert} +% +%Apologies, there is a small syntax error in the template file where a variable +%needs to be called \texttt{tks} instead of \texttt{tk}. The code +%in question is at the end of \texttt{cw03.sc} and should be like +%this (see lines 5, 6 and 8): +% +%\begin{lstlisting}[language=Scala,numbers=left] +%@main +%def test(file: String) = { +% val contents = os.read(os.pwd / "examples" / file) +% println(s"Lex $file: ") +% val tks = tokenise(contents) +% println(tks.mkString(",")) +% println(s"Parse $file: ") +% val ast = Stmts.parse_all(tks).head +% println(ast) +% println(s"Eval $file: ") +% println(eval(ast)) +%} +%\end{lstlisting} -\subsection*{Question 1} +\subsection*{Task 1} Design a grammar for the WHILE language and give the grammar rules. The main categories of non-terminals should be: @@ -84,7 +86,7 @@ \noindent Make sure the grammar is not left-recursive. -\subsection*{Question 2} +\subsection*{Task 2} You should implement a parser for the WHILE language using parser combinators. Be careful that the parser takes as input a list of @@ -125,10 +127,28 @@ \caption{The datatype for abstract syntax trees in Scala.\label{trees}} \end{figure} -\subsection*{Question 3} +\subsection*{Task 3} + +In addition to the simple assignments of the form \code{... := ...} +from Task 1, parse the assignments of the form + +\begin{quote} +\texttt{... += ...} \;\;and\;\; \texttt{... *= ...} +\end{quote} + +and translate them into simple assignments. For example + +\begin{quote} +\texttt{cnt += 1} +\end{quote} + +should give the assignment \texttt{cnt := cnt + 1}. Similarly +for \texttt{*=}. + +\subsection*{Task 4} Implement an interpreter for the WHILE language you designed -and parsed in Question 1 and 2. This interpreter should take +and parsed in Tasks 1 and 2. This interpreter should take as input an AST. However be careful because, programs contain variables and variable assignments. This means you need to maintain a kind of memory, or environment, @@ -156,7 +176,7 @@ evaluates to \pcode{true}, otherwise the else-branch. Loops should be run as long as the boolean is \pcode{true}. Note also that some programs contain a read-statement, -which means you need to read and integer from the commandline +which means you need to read an integer from the commandline and store the value in the corresponding variable. Programs you should be able to run are given in the \texttt{examples} directory. The output