Object class
| Identity
|
Diagram | Each diagram will be placed in its own file. This two
diagrams are distinct if they reside in separate files. |
GraphicElement | All of the graphic elements linked to a particular Diagram
will reside in the same file as that Diagram. In addition, the
GraphicElements will be ordered in the file, and their order will
identify their place in the diagram. Since GraphicElements never are
linked with more than one Diagram object, we need not worry about
identifying a GraphicElement object across files. |
ShapeInstance | Since ShapeInstances are GraphicElements, they are
identified in the same way. |
Text | Since Texts are GraphicElements, they are
identified in the same way. |
Library | Libraries are kept in a separate file from diagrams. All
Library objects reside in the same file, and are identified by their
libraryName attribute. |
StandardShape | StandardShape objects reside in the library file with the
Library objects, and are uniquely identified by their shapeName.
Since a given shapeName can only identify at most one StandardShape
object, we need not worry about distinct StandardShapes with the same
name. |
Symbol
| | Expansion
| Meaning
|
coordinate | : | '[' number ','
number ']' | This means that
whenever a coordinate needs to be written, it will consist of two
numbers separated by a comma. For example, to represent the
coordinates 400 by 600, one would write [400,600] to
the ASCII file (In order to figure out how to represent the numbers
400 and 600 in the file, we would have recursively used the
number production rule below.) |
number | : | {'1'-'9'}
{'0'-'9'}* | This means
that a number is represented in the file as at least one non-zero
numeric digit, followed by any number of numeric digits. (The * after
the second group of digits indicates that it may be repeated zero or
more times, just like in UML.) |
name | : | {'a'-'z'}
{'a'-'z'|'0'-'9'|'_'}* |
This means that a name can be represented by at one alphabetic
character, followed by zero or more characters which are either
alphabetic, numeric, or the underscore ('_') character. Again, the *
symbol indicates "repeated zero or more times". Like numbers, names
are not enclosed in square braces because they are "atomic" to the
file format, and should be recognizable without the braces. |
binaryString | : | '[' {'\\'|
'\['| '\]'| {? except '[',
']', and
'\'}}*']' | This production
is a bit complicated because a binaryString might contain ANY
character at all, including square braces. Unfortunately, our parser
will expect square braces to mean the end of a sentence, so we will
have to do something special to store binaryStrings that contain
square braces. The solution is to define a reserved character (in our
case, the backslash) and then demand that if a backslash or a square
brace appears in the binaryString, it must first be preceded by a
backslash. This way, the parser will know when reading the file back
in that when it encounters a lone square brace, that indicates the
beginning or end of a sentence, but when it encounters "\[", it should
treat the pair of characters as a single square brace. This is a very
old trick developed by UNIX hackers many moons ago, so don't feel bad
if you didn't think of this. |
color | : | '['
{'0'-'9'} {'0'-'9'} ','
{'0'-'9'} {'0'-'9'} ','
{'0'-'9'} {'0'-'9'} ']'
| This rule says that a color is represented by a
square-bracketed set of three two-digit numbers, separated by commas.
These 3 numbers are the red, green, and blue percentage intensities of
the color that is represented. The parser will be able to distinguish
colors from coordinates because coordinates have only two
comma-separated numbers, while colors have three. Note that if we had
3D coordinates, we would need to add something to the color rule to
help the parser distinguish between colors and 3D coordinates. |
pattern | : | { '\SOLID' | '\STRIPED' |
'\HOLLOW' } | This rule says that a
pattern is one of the strings "SOLID", "STRIPED", or "HOLLOW",
preceded by a backslash. The backslash is there so that the parser
can distinguish these pattern names from name domains defined
above. This works because we defined names so that they could not
contain backslashes; so when the parser sees the backslash, it knows
that what's coming next is going to be a pattern type. The actual
pattern types I just made up; in real life you would ask the client
how patterns are specified rather than making an assumption like
this. |
longString
| : |
binaryString
|
This rule says to treat text strings just the same as binary
strings are treated. I've done this because I don't want to place
any restrictions on what text the user can insert into their diagram;
I haven't restricted the definition to alphanumeric characters
because some fonts like WingDings store icons in the upper 128 codes
of their character set, so users should be able to include those in
their drawing. |
boolean
| : |
{ '\T' |
'\F' } |
This rule says that a boolean value is represented by either a T
or an F, preceded by a backslash. Again, the backslash is there so
that the parser can distinguish a boolean "T" value from the name "T".
|
Symbol
| | Expansion
| Meaning
|
DiagramFile
| :
|
VersionTag 'Diag-Type' Diagram |
A Diagram file will begin with a versioning tag, a small
identifier to indicate that the file's purpose is to house a diagram,
and then it will contain a single Diagram object, defined below. |
LibraryFile
| :
|
VersionTag 'Lib-Type' Library* |
A Library file will begin with the same versioning tag, an identifier
indicating that it is a library file, and then a number of Libraries,
defined below. Remember, the * indicates "zero or more", so a
particular file might contain a million libraries, or none. |
VersionTag
| :
|
'OOAD-Homework-7-Editor-v1.0' |
A versioning tag. This is a fast way to let the parser know for
sure whether or not the file it has been asked to read was even
created by the correct program. |
Library
| : |
'['
name StandardShape* ']' |
The name of the library, and then zero or more StandardShapes,
all enclosed in brackets. This embedding of shapes within a library
is how we implement the Library-StandardShape link. |
StandardShape
| :
| '['
name binaryString ']' |
Each shape has a name that is used to identify it from the library,
and a bitmap, which is rendered in the file as a binaryString. I
would argue that you don't need brackets surrounding the
StandardShape construct, even though I have put them here. Can you
see why? |
Diagram
| : |
GraphicElement*
| Since all a diagram really is anyway is a
big list of graphicElements, that is all we have defined Diagram to
be. As with libraries, embedding the GraphicElements within Diagram's
representation allows us to implement the Diagram-GraphicElement link. |
GraphicElement
| :
|
{ShapeInstance | Text} |
Even though GraphicElement has attributes, I have chosen to push
them out to the subclasses, because when this file is actually
parsed, it will be a big help to the parser if it doesn't have to
look forward very far to discover which object it should create to
accept the values being read from the file. Thus, GraphicElement has
no real content at all, except to be a placeholder for either Text or
a ShapeInstance. |
Text
| : | '[Text:'
coordinate number longString name boolean boolean number color
']' | Text just consists of all of Text's
attributes, right in a row, with its' superclass attributes at the
beginning. The "Text" tag appears at the beginning so that the parser
can discover early and easily that this is a Text object rather than a
ShapeInstance. Remember that in order for it to have gotten to this
point, the parser must be trying to read a GraphicElement; but a
GraphicElement can be either of the two classes, so we need to give it
a hint so that it knows which rule to process. |
ShapeInstance
| :
| '[Shape:'
coordinate number name name number number color pattern color
number pattern ']' |
Again, this definition just consists of the class's attributes
all in a row. The first two attributes are the superclass's
attributes. The next two names at the beginning of the ShapeInstance
represent the name of the library and the name of the StandardShape
that this instance is based on. This implements the
StandardShape-ShapeInstance link. |
The Diagram File:
OOAD-Homework-7-Editor-v1.0 Diag-Type
[Shape: [-2,0] 0 shapes circle 1 2 [00,99,00] \SOLID [00,00,00] 1 \SOLID]
[Shape: [2,0] 0 shapes square 2 2 [99,00,00] \SOLID [00,00,00] 1 \SOLID]
[Text: [-2,0] 0 [ellipse] helvetica \T \F 12 [00,00,00]]
[Text: [2,0] 0 [square] helvetica \T \F 12 [00,00,00]]
|
The Diagram File:
OOAD-Homework-7-Editor-v1.0 Diag-Type
[Shape: centerPoint: [-2,0] orientation: 0 LibName: shapes ShapeName:
circle xScale: 1 yScale: 2 fillColor: [00,99,00] fillPattern: \SOLID
outlineColor: [00,00,00] outlineThickness: 1 outlinePattern: \SOLID]
[Shape: centerPoint: [2,0] orientation: 0 LibName: shapes ShapeName:
square xScale: 2 yScale: 2 fillColor: [99,00,00] fillPattern: \SOLID
outlineColor: [00,00,00] outlineThickness: 1 outlinePattern: \SOLID]
[Text: centerPoint: [-2,0] orientation: 0 textBody: [ellipse] font:
helvetica bold: \T italic: \F fontSize: 12 colorAttribute: [00,00,00]]
[Text: centerPoint: [2,0] orientation: 0 textBody: [square] font:
helvetica bold: \T italic: \F fontSize: 12 colorAttribute: [00,00,00]]
|