make, gdb - Back to Syntax




CS152

Chris Pollett

Sep 13, 2021

Outline

Introduction

make

Makefile Structure

A Makefile consists of rules of the form:

target1: depends_on1 depends_on2 ...
<tab>command1
<tab>command2
...
<blankline>
target2: depends_on1 depends_on2 ... #etc
# is used for a single-line comment

Notice the use of tabs is important!

Some example targets

myprog: myprog.o
	cc -o $@ $<
 
myprog.o: myprog.c
	cc -c -o $@ $<
# $@ refers to the target $< refers to the first dependency
clean:
	rm -f myprog myprog.o

More on Makefiles

You can declare variables in a Makefile using the format varname = value like:

   CC = gcc
   SUBDIRS = io linkedlist

These variables could then be used:

all : $(SUBDIRS)
   $(CC) historylesson.c -o historylesson

An example of a multi-line make rule might be something like:

io :
   @echo "Making io..."
   cd io
   make all

gdb

Quiz

Which of the following statements is true?

  1. A symbol table could be used to check if a variable is used before it is declared.
  2. Abstract syntax tree is the name of the assembly language generated by a compiler.
  3. C by default uses a garbage collector to automatically free memory.

Some useful gdb commands

Back to Syntax

Nondeterministic Finite Automaton

Example of an NFA for Calculator Literals

Any regular expression can be converted to an NFA

Proof cont'd

Assume now the result holds for regular expressions for which the total number of uses of union, `\star`, or concatenation is at most `n`. Consider `R` a regular language of complexity `n+1`. There are three cases to consider:

  1. `R` is of the form `(R_1 | R_2)` where `R_1` and `R_2` are regular expressions of complexity `leq n`. By induction let `N_1` and `N_2` be the machines for `R_1` and `R_2`. Define `N` for `R` as:
    NFA for the union of two NFAs
    Roughly, we make a new machine that has a copy of each of the two machines `N_1` and `N_2` together with a new start state for the overall machine. From this new start state we have two `epsilon` transitions: one to what had been the start state of `N_1` and one to what had been the start state of `N_2`.
  2. `(R_1R_2)` where `R_1` and `R_2` are regular expressions of complexity `leq n`. By induction let `N_1` and `N_2` be the machines for `R_1` and `R_2`. Define `N` for `R` as:
    NFA for the concatenation of two NFAs
    The idea is we make a new machine with copies of `N_1`, `N_2`. In this new machine the start state will be the start state of the copy of `N_1`. The `N_1` copy will no longer have accept states; however, we will have an `epsilon` transition from each former accept state of `N_1` to a what had been the start state of `N_2`.
  3. `(R_1)^star` where `R_1` is a regular expression of complexity `leq n`. By induction let `N_1` be the machine for `R_1`. Define `N` for `R` as:
    NFA for the Kleene star of an NFA
    That is, we make a new machine `N` which consists of a new start state that is accepting. From this, we add an `epsilon` transition to what had been the start state of a copy of `N_1`. For each accept state in this `N_1` copy, we add an `epsilon` transition back to what had been the start state of `N_1`.

From Regular Expressions to NFAs - a Second Construction

An Algorithm to Check if a string is accepted by an NFA