LMU ☀️ CMSI 3802
LANGUAGES AND AUTOMATA II
HOMEWORK #5 Due: 2024-04-26

Learning Objectives

In this assignment you will demonstrate:

Readings and Videos

Remember as a student you have responsibility to go beyond lectures and assigned problems. Make sure to interact with the following:

The following readings are optional in the sense that no direct assessment will be based on them. However, as this course marks your deepest dive yet into computing theory and history, you’d be wise to familiarize yourself with the following:

Instructions

As usual, turn in a single submission for your entire group via BrightSpace. Remember to not simply partition the work among team members, as this reduces your learning.

Your team's BrightSpace submission should be an attached PDF or text file with:

  1. The names of every student
  2. For each student, an affidavit that each of the readings and watchings above were individually completed
  3. Answers to each ot the “Problems to Turn In,” numbered and neatly typeset
  4. A link to the public GitHub repository hosting your team’s project

Problems to Turn In

Solutions to these problems will appear in the beautifully formatted PDF that you will submit to BrightSpace. For problems involving code to write, host your code on GitHub or Replit or OneCompiler (or similar) and provide the link to the hosting site in your BrightSpace submission.

  1. Write JavaScript regular expressions for the following. Please take advantage of character classes, lookarounds, and backreferences where they apply.
    1. Canadian Postal Codes (make sure to prohibit D, F, I, O, Q, U)
    2. Legal Visa® Card Numbers, ignoring the Luhn checksums, i.e., accept 4 + 15 digits or 4 + 12 digits.
    3. Legal MasterCard® Numbers, ignoring the Luhn checksums, i.e., accept 51-55 + 14 digits or 2221-2720 + 12 digits.
    4. Strings of Basic Latin letters except those strings that are exactly three letters ending with two Latin letter o’s, of any case.
    5. Binary numerals divisible by 16.
    6. Decimal numerals in the range 8 through 32, inclusive.
    7. All strings of Unicode letters, except python, pycharm, or pyc.
    8. Floating point constants that are allowed to have an empty fractional part, but whose exponent part is required and can have no more than three digits in the exponent part
    9. Palindromes over the letters a, b, and c, of length 2, 3, 5, or 8
    10. Python string literals. Don't get too fancy here—just translate what you see in the Python Reference linked above into Ohm notation.

    You can use this test script, which you can store in test/regex_exercises.test.js:

    import assert from "assert"
    import { matches } from "../regex_exercises.js"
    
    const testFixture = {
      canadianPostalCode: {
        good: ["A7X 2P8", "P8E 4R2", "K1V 9P2", "Y3J 5C0"],
        bad: ["A7X   9B2", "C7E 9U2", "", "Dog", "K1V\t9P2", " A7X 2P8", "A7X 2P8 "],
      },
      visa: {
        good: ["4128976567772613", "4089655522138888", "4098562516243"],
        bad: [
          "43333",
          "42346238746283746823",
          "7687777777263211",
          "foo",
          "π",
          "4128976567772613 ",
        ],
      },
      masterCard: {
        good: [
          "5100000000000000",
          "5294837679998888",
          "5309888182838282",
          "5599999999999999",
          "2221000000000000",
          "2720999999999999",
          "2578930481258783",
          "2230000000000000",
        ],
        bad: [
          "5763777373890002",
          "513988843211541",
          "51398884321108541",
          "",
          "OH",
          "5432333xxxxxxxxx",
        ],
      },
      notThreeEndingInOO: {
        good: ["", "fog", "Tho", "one", "a", "ab", "food"],
        bad: ["fOo", "gOO", "HoO", "zoo", "MOO", "123", "A15"],
      },
      divisibleBy16: {
        good: ["0", "00", "000", "00000", "00000", "000000", "00000000", "1101000000"],
        bad: ["1", "00000000100", "1000000001", "dog0000000"],
      },
      eightThroughThirtyTwo: {
        good: Array(25)
          .fill(0)
          .map((x, i) => i + 8),
        bad: ["1", "0", "00003", "dog", "", "361", "90", "7", "-11"],
      },
      notPythonPycharmPyc: {
        good: ["", "pythons", "pycs", "PYC", "apycharm", "zpyc", "dog", "pythonpyc"],
        bad: ["python", "pycharm", "pyc"],
      },
      restrictedFloats: {
        good: ["1e0", "235e9", "1.0e1", "1.0e+122", "55e20"],
        bad: ["3.5E9999", "2.355e-9991", "1e2210"],
      },
      palindromes2358: {
        good: [
          "aa",
          "bb",
          "cc",
          "aaa",
          "aba",
          "aca",
          "bab",
          "bbb",
          "ababa",
          "abcba",
          "aaaaaaaa",
          "abaaaaba",
          "cbcbbcbc",
          "caaaaaac",
        ],
        bad: ["", "a", "ab", "abc", "abbbb", "cbcbcbcb"],
      },
      pythonStringLiterals: {
        good: String.raw`''
          ""
          'hello'
          "world"
          'a\'b'
          "a\"b"
          '\n'
          "a\tb"
          f'\u'
          """abc"""
          '''a''"''"'''
          """abc\xdef"""
          '''abc\$def'''
          '''abc\''''`
          .split("\n")
          .map((s) => s.trim()),
        bad: String.raw`
          'hello"
          "world'
          'a'b'
          "a"b"
          'a''
          "x""
          """"""""
          frr"abc"
          'a\'
          '''abc''''
          """`
          .split("\n")
          .map((s) => s.trim()),
      },
    }
    
    for (let name of Object.keys(testFixture)) {
      describe(`when matching ${name}`, () => {
        for (let s of testFixture[name].good) {
          it(`accepts ${s}`, () => {
            assert.ok(matches(name, s))
          })
        }
        for (let s of testFixture[name].bad) {
          it(`rejects ${s}`, () => {
            assert.ok(!matches(name, s))
          })
        }
      })
    }
    

    The file regex_exercises.js can be structured like so:

    const regexes = {
      canadianPostalCode: /^ ........ $/,
      visa: /^ ........ $/,
      masterCard: /^ ........ $/,
      notThreeEndingInOO:  /^ ........ $/iu,
      divisibleBy16:  /^ ........ $/,
      eightThroughThirtyTwo:  /^ ........ $/,
      notPythonPycharmPyc:  /^ ........ $/u,
      restrictedFloats:  /^ ........ $/i,
      palindromes2358: /^ ........ $/,
      pythonStringLiterals: /^ ........ $/,
    }
    
    export function matches(name, string) {
      return regexes[name].test(string)
    }  
    
  2. (Here’s a problem which logically belongs in the previous homework assignment, but sometimes it’s best to space things out a bit.) Show the language $\{ \langle M_1\rangle \langle M_2\rangle \mid L(M_1) = L(M_2) \}$ is undecidable, using a rigorous reduction argument.

For Your Project

Add optimizations to your compiler project. You do not have to do too many, but the few you do should be non-trivial. Because everyone in class is compiling a somewhat different language, you must check with me early regarding which optimizations are appropriate for your project. Don’t worry, we will negotiate the set of optimizations that you are responsible for, so there should be no surprises when you get your grade.

Your project should end up with a project structured as follows:

  .
  ├── .gitignore
  ├── README.md
  ├── LICENSE
  ├── package.json
  ├── .prettierrc.json        -- (optional, you don’t have to have one)
  ├── docs
  │   └── ...                 -- logo, companion website, etc.
  ├── examples
  │   └── ...                 -- lots of example programs
  ├── src
  │   ├── (yourlanguagename).js
  │   ├── (yourlanguagename).ohm
  │   ├── compiler.js
  │   ├── core.js
  │   ├── analyzer.js
  │   ├── optimizer.js        -- implement this for this assignment
  │   └── generator.js
  └── test
      ├── compiler.test.js
      ├── grammar.test.js
      ├── analyzer.test.js
      ├── optimizer.test.js   -- implement this for this assignment
      └── generator.test.js

The most important things to keep in mind as you wrap up your project are:

Presentation!

During the last class session, present, as your entire group, a lightning talk introducing (and showing off!) your language) to the rest of the class. Be personal, be funny, and be brief! You may use slides, video, and even music. If you are using slides, don’t use too many, and make sure they are colorful...with images, and please put these in your project repository. If your language has a theme (pirates, horror, uwu, vikings, fashion, sci-fi, anime, social policy, medical, whatever), you can dress up (but avoid stereotypes and be respectful).

For tips on how to do a good lightning talk, see here, here, and here. What’s a lightning talk? Wikipedia can tell you.

Grading Rubric

To help you get a good score on the remaining 80 points, here are all the things you will be graded on.

Also, as an audience member, you will be expected to be attentive, respectful, and encouraging, and celebrate and applaud your classmates when they present.

Fairness in Team Grading

Finally, I will be interviewing each team to gauge the contributions of each team member. The old ”I participated in meetings but we always committed from so-and-so’s computer” isn’t really acceptable.