View this PageEdit this PageAttachments to this PageHistory of this PageHomeRecent ChangesSearch the SwikiHelp Guide
Hotspots: Admin Pages | Turn-in Site |
Current Links: Cases Final Project Summer 2007


The Second to Last Team

(Team: Janet Abdul-Karim, Christopher Rogers, Takehiro Takahashi, Christina Zamboni)
Milestone 3
Milestone 4
Milestone 5
Milestone 6
Milestone 7

The Assignment

For this milestone we were to add a SQL-like query engine to Squeaken, giving users the ability to:

1. Find an account given some conditions
2. Give a report for an account, given its number.

A command could be either a SELECT or REPORT query. Here is a loose definition of the grammar.

<query> := <select> | <report>
<select> := SELECT (ACCOUNT | PORTFOLIO) WHERE <condition>
<condition> := (BALANCE | NAME | NUMBER) (> | < | =) <string> | <condition> AND <condition>
<report> := REPORT (NORMAL | EXCEPTION | FULL) FOR "<string>"

For more details on the assignment, including the given grammar for the parser, see the Spring 2003 M6 assignment page. (See the bottom of this page for the grammar's actual implementation.)

What We Did

This milestone required very little change in design to our existing code. In fact, the only "changes" were just additions to the code. We added a new button, "Query", to our main menu, which gave a GUI representation of the query. To handle the queries, we used SmaCC (which you can download through SqueakMap) to create our own custom parser.

More on What We Did

Using SmaCC is fairly straight-forward. Just type in your standard expressions for your tokens and your grammar for the parser, and tell it what kind of parser you want. Take a look at the grammar we fed into SmaCC at the bottom of this page. You can see the basic syntax used from there. Just be sure to give a starting point to your grammar.

Here is a look at the GUI for the query interface.

Uploaded Image: Squeaken.gif

We decided to implement some sort of GUI device that would inform users of the grammar available to them, hinder them from typing in incorrect grammar, while at the same time allowing them to type their query freely, since one of the advantages of having a query engine is being able to quickly type in what you want. So, we chose to have menus that would show what query options were currently available to them. Below this are the query entry box (on the left), and the query results box (on the right). As you click on one option, the rest of the menus change accordingly, and the query entry box updates itself to reflect these changes. Clicking "Submit Query" will trigger parsing and either display a pop-up error message if the query is invalid, or show the results in the results textbox.

The menu was implemented using a collection of the menus and text that would actually be added to the query. Each time a menu change was required, you could call one of various methods that would manipulate the collections for you. For example, you can call addQueryMenu to add a menu to the list, or addQueryLabel to add just plain text (for example, "WHERE", which is not changeable) to the GUI. At the end of all of the It helped a lot to modulize this part into separate "messages" because many of the GUI-adding functions used the same functionality (such as manipulating the collections). It also allowed for easy extension, if we were to add extra features to the GUI, such as a different type of Morph for command selection.

Comments on the Implementation

  • The design of the GUI isn't particularly well laid out, especially the Submit Query Button, but it worked well for our purposes. Perhaps we should've labeled the boxes on the bottom "Query" and "Query Results"...oh well.
  • We didn't have time to add extra functionality such as implementing AND conditions in the GUI. However, I believe the framework would easily allow for such a thing.
  • It might've been better to implement the GUI in another class. That way you could make it reusable in other applications. Right now it is just a collection of class messages in MainMenu.
  • We made out parser a little too closely tied for the GUI. When it was time to use the parser without the GUI in the web server (for M7), we had to change the parser's implementation a lot.

Some Tips & Tricks

  • Make sure that your grammar has a definite starting point! We actually forgot this, and just put in the select and report statements.
  • Be sure to remember what the grammar is when testing! Sometimes seemingly buggy queries may actually be correct, but you just forgot to use quotes or all caps when necessary.
  • Make sure the grammar will parse correctly. By this I mean, make sure it is not left-recursive.

Our Actual SmaCC Grammar:


	"REPORT " &lt;reportType&gt; 'rT' " FOR " &lt;container&gt; 'cT' " WITH " &lt;accountNumber&gt; 'aN' {
		MainMenu instance interpretReportQuery: rT value asString for: cT value asString with: aN value asString.

	"SELECT " &lt;container&gt; 'con' " WHERE " {
		self clearConditions.
		self entity: con value asString.

	&lt;attribute&gt; 'attr' " " &lt;comparison&gt; 'cpr' " " (&lt;number&gt; | &lt;accountNumber&gt;) 'num'
	| coll |
	coll _ OrderedCollection new.
	coll add: attr value asString.
	coll add: cpr value asString.
	coll add: num value asString.
	self addCondition: coll.

	MainMenu instance interpretSelectQuery: self entity where: self conditions.

&lt;number&gt;        :       [0-9]+ (\. [0-9]) ? ;
&lt;attribute&gt;      :        NUMBER | NAME | BALANCE;
&lt;comparison&gt;   :        &gt; | &lt; | =;
&lt;container&gt;     :        ACCOUNT | PORTFOLIO;
&lt;reportType&gt;     :       NORMAL | FULL | EXCEPTION;
&lt;accountNumber&gt; :     " [A-Za-z0-9\ ]+ ";

Downloads and (these require the SmaCC Runtime classes from SqueakMap)