Lab 1: Stacks Solution



In this lab you’ll experiment with some linked lists to refresh your memory.

You’ll write a C and Python implementation of a stack.

And you’ll write a parenthesis checker in both languages, using the stack

data structure.

Minimal test code will be provided. Write your own test code, but

ensure that you strip any test code, except where indicated.

The lab will be due IN YOUR LAB SESSION, at the end of session.

You will submit this using the submitcsc190s command.

I.e., to submit file.c

submitcsc190s 0 file.c

This lab is practice for your tests and final exam. Start this lab early, so

that you complete it prior to your lab session.

Due: in lab, during the lab sessions during the week of Jan 14.


A. Introduction: getData.c

Read and confirm you understand getData.c

Compile it, run it and test it for various cases, as per the instructions

in the comments.

We have implemented a simple linked list that deals with integers; the

linked list was necessary because, as you can see from the code, the input

data that is read in is of a length (i.e., number of data items) that is

unknown, a priori. Hence, a while loop is necessary to get the data from

the user, and a dynamic sequential data structure — a list — is needed

to store that data.

We have provided three helper functions:

* llnode_add_to_tail

* llnode_print_from_head

* llnode_print_from_tail

These functions enable you to simulate the behavior of

* first-in first-out (FIFO, aka “queue”)

* last-in first-out (LIFO, aka “stack”)

data strutures.

Once again, Stacks and Queues are merely special cases of general lists.

Whereas a general list can be read from and written to in arbitrary

ways, a stack and queue are special cases of lists where the write

and read policies are restricted.


* Stacks: write to the tail, read from the tail

* Queues: write to the tail, read from the head

(Convince yourself by drawing a diagram

that the alternative spec also works:

* Stacks: write to the head, read from the head

* Queues: write to the head, read from the tail



A.1. cp getData.c getData_char.c

and then modify getData_char.c so that it will

handle characters instead of integers

A.2. cp getData_char.c getData_charHead.c

and then modify getData_charHead.c so that it has a new function


A.3. cp getData_charHead.c getData_charStack.c

and then modify it so that it has two new functions:

int push(llnode **x, char value);


int pop(llnode **x, char *return_value);

Use the appropriate llnode_add_… function for the push function, which

will add the value to the linked list so that the list behaves like a stack.

The return value is 0 for success, and -1 for failure.

Now, write the pop function that will assign to *return_value the

appropriate value from the linked list so that the list behaves like a stack.

(Recall: return_value is a mechanism via which we can “return” a value via

the argument list, rather than via the return statement. Why do we require

a pointer?)

The function should ensure that the linked list node corresponding to the

pop’d value is also deleted from the linked list.

The return value is 0 for success, and -1 for failure.

Modify the main function so that instead of calling add and print, it calls

push and pop. Test your code.

Submit all of the .c files you created for this section:

getData_char.c, getData_charHead.c, and getData_charStack.c


B. Parenthesis Checking

The algorithm for Parenthesis Checking is as follows:

* Read in an expression from the user (e.g., 1+2*(3+4*[5-6*{100+200}]))

* In your while loop:

* Every time you get a left bracket input (i.e., ‘(‘, ‘[‘, or ‘{‘)

push that bracket onto the stack

* Every time you get a right bracket input:

– pop stack to a variable (popped_value, say)

– make sure that the popped value is the correct closing bracket

that corresponds to the input, and continue

-> otherwise: break out of the loop

* If the Stack is empty by the time you get to the end of the input

stream (i.e., once you exit the while loop), then the brackets

are balanced.

Before the program ends: print out a message with the EXACT FORMAT:




where 5 is a number indicating that the bracket matcher failed at the

fifth char input

Make sure your program does NOT print out anything other than specified.

Submit this program as “bc.c”

Test your program with a variety of inputs.

For example: 1+2*(3+4*[5-6*{100+200}])

should yield “PASS”

Note: this expression can be read in by the

getData_char.c and getData_charHead.c programs

Test your getData_char code by:

gcc getData_char.c

echo “1+2*(3+4*[5-6*{100+200}]))” | ./a.out


./a.out (press enter)

and then enter the string 1+2*(3+4*[5-6*{100+200}]))

press enter

and then Ctrl-D

Note: in UNIX, the echo “1+2*(3+4*[5-6*{100+200}]))”

simply gets UNIX to print out that string.

Above, we pipe that printed string into the ./a.out



C. Python

Write a class for a stack, as, which will implement a stack

data structure (LIFO).

It will have an internal list variable, to handle the data that is

input to it.

It should have two methods (in addition to __init__(self)):

* push

* pop

You may choose where to write to/read from the underlying list data structure

as long as you are implementing a stack data structure.

C.1. Submit, which should online contain the complete class

definition and no test code.

C.2. In create a function “bc” that will

take in a string, and return a length-2 list, L.

The 0 element (i.e., L[0]) of the return value will be True if the

result of bracket checking indicates that all brackets are matched, and

False if otherwise.

The 1 element of the return value will indicate the index of the input

string where bracket checking failed.

Submit, which will only contain the function definition, and

whatever helpers, import statements, etc, you require; no test code

should be included (if you python — nothing should happen).

Note: the function bc must use the stack data structure you created;

hence, there will be an import in


1. When you input to the while loop in the above code, you will need to

signify the End of Input. To do that: Ctrl-D.

So if you call ./a.out on getData.c and you want to enter the numbers yourself

instead of via echo (as above), you will have to press Ctrl-D after you enter your

last data item.

2. For gdb to work you will have to delete your .mycshrc file from last semster.

Or comment out the bash line in .mycshrc