org.sc3d.apt.sss.v3
Class Grammar

java.lang.Object
  extended by org.sc3d.apt.sss.v3.Grammar
Direct Known Subclasses:
Grammar.NonTerminal, Grammar.Terminal

public abstract class Grammar
extends java.lang.Object

Represents an SSS grammar. I will explain the data structure used by example. Here is an SSS grammar for ordinary four-operation arithmetic expressions (it is the one used by the Calculator example):

 sign ::= {Minus {"-"}}
 atom ::= {Number {sign* NUMBER} Bracket {sign* BRACKET(sum)}}
 multiplicand ::= {Multiply {"*" atom} Divide {"/" atom}}
 product ::= {Product {atom multiplicand*}}
 summand ::= {Add {"+" product} Subtract {"-" product}}
 sum ::= {Sum {product summand*}}
 ROOT sum
 
I'm sorry it's quite complicated, but I want to illustrate as many of the cases as possible, and I want to use an example that is familiar. Here is an example string of this language, followed by the same string annotated with square brackets to show how it fits the grammar:
     - 5  *  - (     8     +    1      ) /   3    +    7    -    2
 [[[[-]5][*[[-]([[[[]8][]][+[[[]1][]]]])]/[[]3]]][+[[[]7][]]-[[[]2][]]]]
 
I hope that's enough for you to understand the example grammar. Note that all the operator binding rules are as you'd expect, and that the "-" characters have been parsed in different ways (two of them are negations and the third is a subtraction).

Here is the code needed to construct a Grammar to represent the above grammar and assign it to a static final field:

 static final Grammar SUM {
 static {
 // First make all the Terminals we need.
 Terminal plus = new Keyword("+");
 Terminal minus = new Keyword("-");
 Terminal multiply = new Keyword("*");
 Terminal divide = new Keyword("/");
 Terminal number = new Terminal(Token.TYPE_NUMBER);
 Terminal bracket = new Terminal(Token.TYPE_BRACKET) {
   public Grammar getGrammarOfContents() { return SUM; }
 };
 // Construct 'signStar'.
 Production pMinus = new Production("Minus", new Grammar[] {minus});
 NonTerminal signStar = new NonTerminal(new Production[] {pMinus}, true, true);
 // Construct 'atom'.
 Production pNumber = new Production("Number", new Grammar[] {signStar, number});
 Production pBracket = new Production("Bracket", new Grammar[] {signStar, bracket});
 NonTerminal atom = new NonTerminal(new Production[] {pNumber, pBracket}, false, false);
 // Construct 'multiplicandStar'.
 Production pMultiply = new Production("Multiply", new Grammar[] {multiply, atom});
 Production pDivide = new Production("Divide", new Grammar[] {divide, atom});
 NonTerminal multiplicandStar = new NonTerminal(new Production[] {pMultiply, pDivide}, true, true);
 // Construct 'product'.
 Production pProduct = new Production("Product", new Grammar[] {atom, multiplicandStar});
 NonTerminal product = new NonTerminal(new Production[] {pProduct}, false, false);
 // Construct 'summandStar'.
 Production pAdd = new Production("Add", new Grammar[] {plus, product});
 Production pSubtract = new Production("Subtract", new Grammar[] {minus, product});
 NonTerminal summandStar = new NonTerminal(new Production[] {pAdd, pSubtract}, true, true);
 // Construct 'sum'.
 Production pSum = new Production("Sum", new Grammar[] {product, summandStar});
 NonTerminal sum = new NonTerminal(new Production[] {pSum}, false, false);
 // The root is 'sum'.
 SUM = sum;
 }
 
As you see it is really quite a lot of work to construct a Grammar by hand. It is much easier to write an SSS grammar specification and use the GrammarParser.

The example Grammar is provided as a public static final field of the Calculator class, and can be used as a test case in debugging.


Nested Class Summary
static class Grammar.Keyword
          A subclass of Terminal which insists on an exact text match with a Token of type 'Token.TYPE_WORD'.
static class Grammar.NonTerminal
          The subclass of Grammar with 'isTerminal==false'.
static class Grammar.Production
          Represents a production of the grammar.
static class Grammar.Terminal
          The subclass of Grammar with 'isTerminal==true'.
 
Field Summary
 boolean isTerminal
          'true' if this Grammar is an instance of Terminal, otherwise 'false'.
 
Method Summary
abstract  java.lang.String toString()
          Returns a String representation of this Grammar.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

isTerminal

public final boolean isTerminal
'true' if this Grammar is an instance of Terminal, otherwise 'false'.

Method Detail

toString

public abstract java.lang.String toString()
Returns a String representation of this Grammar.

Overrides:
toString in class java.lang.Object