Your first programming assignment is to implement a Scalable Vector Graphics viewer for a small subset of the SVG specification. SVG is a standard for describing two-dimensional graphics and animations in XML. Most web browsers are capable of rendering .svg files like the following, which shows the contents of the file min-grammar.svg:
<svg xmlns="http://www.w3.org/2000/svg"> <!-- rectangles --> <rect x="20" y="20" width="300" height="250" fill="red" /> <rect x="30" y="20" width="300" height="250" fill="blue" /> <rect x = "40" y = "20" width = "300" height = "250" fill="green" /> <!-- white circle on top of rectangles --> <circle cx="120" cy="150" r="60" fill="white" /> <!-- black diagonal line --> <line x1="0" y1="0" x2="300" y2="300" stroke="black" /> </svg>A rendering of the above SVG description can be seen by saving the following file to your drive and then opening it in your browser: min-grammar.svg
For this programming assignment, a driver MiniSVGShell class is provided to get you started. When executed with the following command (or from within Eclipse):
% javac MiniSVGShell infile.svg
the MiniSVGShell driver opens
a window and renders a hardcoded series of graphics commands for
the same set of objects described in the min-grammar.svg file.
Currently the driver creates a PushbackReader for the given input file,
but does not actually read anything from the file. Your assignment
is to write lexer and a parser that parser the input .svg file and
render the graphics elements specified in the .svg file.
svg -> SVG_START elem_list SVG_END
elem_list -> elem_list elem | epsilon
elem ->
RECT_START KW_X EQ NUM KW_Y EQ NUM KW_WIDTH EQ NUM KW_HEIGHT EQ NUM KW_FILL EQ COLOR ELEM_END
| CIRCLE_START KW_CX EQ NUM KW_CY EQ NUM KW_R EQ NUM KW_FILL EQ COLOR ELEM_END
| LINE_START KW_X1 EQ NUM KW_Y1 EQ NUM KW_X2 EQ NUM KW_Y2 EQ NUM KW_STROKE EQ COLOR ELEM_END
To recognize the above grammar, you should write a top-down, predictive
parser. That will require making one modification to the grammar to
remove left-recursion (go to class and read the book to see more details).
As each elem grammar rule is matched in the predictive parser, the
specified element should be rendered to a window and the appropriate
SVGReporter method should be called to output logging messages.
Notes about the grammar:
The parser queries the lexer for a stream of tokens. The lexer is actually the more difficult part of this programming assignment. Here are some of the regular expressions for the terminals described above in JFlex syntax. Note that {SYMBOL} indicates textual substitution for SYMBOL just as in many unix scripting languages.
EOL = \r | \n | \r\n
WHITE_SPACE = [ \r\n\t]
DIGIT = [0-9]
NOT_DIGIT = ??
NOT_GT = [^>]
NOT_DASH = [^-]
COMMENT = "<!" {WHITE_SPACE}* "--" ({NOT_DASH} | {EOL} | "-" {NOT_DASH} )* "--" {WHITE_SPACE}* ">"
SVG_START = "<svg" {NOT_GT}* ">"
SVG_END = "</svg>"
RECT_START = "<rect"
KW_X = "x"
EQ = "="
COLOR = "red" | "blue" | "green" | "black" | "white"
The MiniSVGShell project provides token classes (i.e., Token, Word, Color, Num)
and provides some utility methods for implementing the lexer.
In class, we will be providing the deterministic finite automata for
recognizing most of the tokens, and covering a range of techniques for
implementing a lexer.
Lexer generators such as JLex and parser generators such as JavaCUP are not allowed for this programming assignment.
Your program should include error handling through the use of the ParseException class for the following situations:
[LINE,POS] Expecting character 'X' and got 'D'.
[LINE,POS] Expect only numbers or colors in quotes.
[LINE,POS] Unexpected word 'theword'.
[LINE,POS] Unexpected character 'C'.
[LINE,POS] Expecting token TOKENTAG and got < OTHERTOKENTAG >.
[LINE,POS] Unexpected token < TOKENTAG, otherinfo >.
% svn log -r HEAD:1
% svn info
% svnlook tree REPOSITORY_PATH // svnlook must be issued on a department machine
For the initial subversion.txt file, you need to have at least put the
starting code provided for any assignment into a subversion repository.
For the final subversion.txt file, there should be on average one commit
per day of the assignment. Revision control is important.
See http://www.cs.colostate.edu/~mstrout/setup-notes.html for an example of how to
set up a subversion repository. Subversion will also be covered
in the discussion section.
Start this assignment by copying MiniSVGShell.tar to your directory. MiniSVGShell untars to a src/ directory that contains the src/ and TestCases/ subdirectories. The TestCases/ directory contains example input and output. You can check the visual component by comparing with what a web browser displays. For grading, we will be performing diffs on your text output with the text output from the reference compiler. The src/ directory has the following organization:
driver/
MiniSVG.java
exceptions/
...
lexer/
...
Lexer.java
Token.java
...
parser/
Parser.java
util/
...
The main for this code is in MiniSVG.java. Currently some graphics
are hardcoded to appear in a window. You will be putting implementation
into the Lexer.java and Parser.java files. The Lexer.scan() routine
returns Token instances to the Parser.
Set up a subversion repository for the programming assignment.
After setting up the subversion repository, check that the given MiniSVGShell runs and read the code to understand what it is doing.
Implement a lexer that can recognize the various tokens in the MiniSVG grammar.
Implement a predictive parser that reports what SVG elements were parsed and renders the elements to the screen.
If you send an example .svg file to the class mailing list, then we will send you back the reference compiler text output.
Here are some sites with SVG examples:
% svn log -r HEAD:1
% svn info
% svnlook tree REPOSITORY_PATH // svnlook must be issued on the machine where the repository is stored
tar cvf PA1_groupname.tar PA1
~cs453/bin/checkin PA1 PA1_groupname.tar
% tar xf PA1_groupname.tar
% cd PA1
% javac MiniSVGShell.java
% java MiniSVGShell input.svg --batch-mode