Learning Objectives
With this assignment you will demonstrate:
- A small understanding of formal language theory and its importance within computer science
- The ability to write grammars for both simple formal languages and for simple programming languages
- The ability to write abstract syntax specifications
- The ability to construct abstract syntax trees
Readings and Videos
Please:
- Read Chapter 0 of Programming Language Explorations, 2nd edition (you will find this in BrightSpace).
- Review the course notes for Language Theory, Syntax, The Language Astro and watch all of the embedded videos in the course notes listed above. Also, follow a few of the links on the page that interest you.
- Read the Introduction and Chapter 1 of the Schmidt book. (There is information here about abstract syntax.)
- Read Chapter 1 of the Slonneger and Kurtz book.
Instructions
Submit your answers on a PDF or Markdown document uploaded to BrightSpace.
Problems to Submit
- In classical logic, $\exists$ and $\forall$ are duals of each other, because $(\neg \exists x.P) \equiv \forall x. \neg P$ and $(\neg \forall x.P) \equiv \exists x.\neg P$. Are the temporal operators $\textbf{F}$ and $\textbf{G}$ duals of each other? Why or why not?
- Suppose that you had a classical, bivalent logistic system powerful enough to express statements about the provability of its own formulas, for example, “This formula is not provable” or equivalently “I am not provable.” Show that such a system, if consistent, must be incomplete, and if complete, must be inconsistent.
- Give grammars for the following mini-languages:
- Odd-length Palindromes of strings made from Unicode letters only
- All strings over the alphabet ${a, b, c, d, e}$ where the symbols are in decreasing alphabetic order
- $\{ 0^i1^j2^k \mid i=j \vee j=k \}$
- $\{ w \in \{0,1\}^* \mid w \textrm{ does not contain the substring 000} \}$
- $\{ w \in \{a,b\}^* \mid w \textrm{ has twice as many $a$'s as $b$'s} \}$
- (EXTRA CREDIT) $\{ a^nb^na^nb^n \mid n \geq 0 \}$
- Give a programming language grammar, using the notation from class, for the programming language described as follows. Programs are made up of a possibly empty sequence of function declarations, followed by a single expression. Each function declaration is of the form $f = (p_1, \ldots, p_m) \Rightarrow e$ where $f$ is the function name (an identifier), each $p_i$ is a parameter (also identifiers) and the result (the “body”) is an expression. Expressions can be numeric literals, string literals, identifiers, function calls, or can be made up of other expressions with the usual binary arithmetic operators (plus, minus, times, divide, remainder) and a unary prefix negation and a unary postfix factorial (
!
). There’s a conditional expression with the syntax x ? y : z
. Parentheses are used, as in most other languages, to group subexpressions. Numeric literals are non-empty sequences of decimal digits with an optional fractional part and an optional exponent part. String literals delimited with double quotes with the escape sequences \'
, \"
, \n
, \\
, and \u{
$hhhhhh$}
where $hhhhhh$ is a sequence of one-to-six hexadecimal digits. Identifiers are non-empty sequences of letters, decimal digits, underscores, and dollar signs, beginning with a letter or dollar sign. Function calls are formed with an identifier followed by a parenthesized, comma-separated list of expressions.
- For the language in the previous problem, write an abstract syntax specification.
- For the language in the previous problem, give an abstract syntax tree for the program:
gcd = (x, y) => y ? gcd(y, x % y) : x
cube = (x) => x * x * x
"The answer is" + cube(gcd(30, 4!)) + "😦😦"
- For the following complete JavaScript program, draw the AST, using the level of detail we used during class. You can use Esprima to guide you and check your work, but remember, the drawing you need to produce for full credit will be far less verbose than the Esprima output.
import x from "x"
console.log(93.8 * {x} << x.r[z])