CPS506 - Comparative Programming Languages - Winter 2022

Lab 3 - A Brief Introduction to Parsing in Smalltalk

Objectives

  • Become familar with a simple parsing framework in Smaltalk
  • Examine a parse tree produced in Smalltalk
  • Evaluate a parse tree for a simple arithmetic grammar

Introduction

Parsers are programs which recognize languages according to a specific grammar. They usually produce a syntax tree from the recognized input and may preform some action upon it. Parsers are a central compontent of compilers and parsing in general is a common task, so many languages have libraries and features to make it easier for us, including Smalltalk.

PetitParser is a parser generator in Smalltalk. It takes a definition of a grammar and we get back a parser that will parse the language we have defined. The topic of parsing is quite involved and numerous courses cover components of it in quite some depth, but in this lab we will take a look at parsing a small set of simple language in Smalltalk.

Installing

To install the PetitParser library into your Smalltalk image, open the world and select Catalog from tools. Search for PetitParser, right click on it in the list and select 'Install stable version'.

Simple Parsers

Petit parser allows us to construct simple parsers easily. For example a parser for a word is:

#word asParser

And one for a digit is:

#digit asParser

In order to parse a string we can send a parse message like so:

#digit asParser parse: '5'

which if we inspect it, we can see results in a syntax tree containing only the digit.

Compound Parsers

We can construct parsers for more interesting languages by joining them together. A compound parser might be:

#letter asParser,#word asParser

which means a letter followed immediately by a word.

Practicing Parsers

Work through Section 1.1 of the PetitParser tutorial (ignoring the installation of PetitParser in script 1.1 - because you already installed it above). Once you have completed the section, see if you can alter the arithmetic expression parser to work with subtraction and division instead of addition and multiplication. Now, can you make it do both?

Practicing Streams

Experiment with streams in a playground. Try the following:

x:=ReadStream on: #(1 2 3 4 5).

x next.
x atEnd.  
Position the cursor on the first line and "Do" it (cmd/ctrl-D or right click) once. Then try positioning on the other lines and "Print" it (cmd/ctrl-P or right click) until you understand what is going on. You can "Do" the first line again to get a new stream.

You can also create a ReadStream with the method readStream which is understood by collections (including strings) and readStreams themselves:

x:=#(1 2 3 4 5) readStream.
x:='abcdef' readStream.
x:=x readStream.
Inspect x after each of the assignments to recognize how you can create streams.

Similarly, try write streams in a playground:

x := WriteStream on: #().
x nextPut: 3.
x nextPutAll: #(4 5 6).
x contents.

You can also create a WriteStream and easily get the contents as a String:

String streamContents: [: s | 42 printOn: s. s cr. s nextPutAll: 'this and that']
Try printing that.

Once your code is complete commit the CPS506-Lab3 package to a FileTree in your private CPS506 Fossil repository (see Lab 1 if you need a reminder of how to do this).