// generate.cd -- class dictionary for Demeter/Java code generator // $Id: generate.cd,v 1.11 2000/09/19 21:08:21 dougo Exp $ // modified for syntax commands 2004/04/19 import edu.neu.ccs.demeter.dj.*; import java.util.*; import java.util.zip.*; import java.io.*; *public* SyntaxMain = . // Program is the starting nonterminal of the class dictionary grammar, // as well as the root class of the class dictionary class graph. *public* Program = GlobalImports ClassGraphh *EOF* . GlobalImports = [ SList(Import) *l ] . Import = "import" PackageName [ ImportAllClasses ] ";". ImportAllClasses = ".*". ClassGraphh = Hashtable DList(ClassGraphEntry). ClassGraphEntry : lookahead (@ 2 @) Directive | Definition. Directive : ParseDirective | VisitorDirective | PackageDirective. ParseDirective = ParseKeyword. VisitorDirective = VisitorKeyword. PackageDirective = Package *l LocalImports. Package = "package" PackageName ";". LocalImports = [ SList(Import) *l ] . Definition : ClassDef. public ClassDef = [ lookahead (@ 1 @) ClassKeyword_NList ] ParamClassName [ *s ParseDirective ] *s ClassParts [ *s EOFtoken ] "." . ClassKeyword_NList ~ ClassKeyword { lookahead (@ 1 @) ClassKeyword }. ParamClassName = ClassName ["(" Commalist(ClassName) ")"]. ClassParts : ConstOrAltClass | RepetitionClass. ConstOrAltClass : ConstructionClass | AlternationClass *common* + + + List(PartOrSyntax) ClassParents - - -. PartOrSyntax : Part | OptionalPart | Syntax. Part = [ "<" PartName ">" *s ] [ lookahead (@ 1 @) PartKeyword_NList ] ClassSpec [ lookahead (@ 2 @) PartInit ]. PartKeyword_NList ~ PartKeyword { lookahead (@ 1 @) PartKeyword }. PartInit = PartInitKeyword *s JavaCode. OptionalPart = "[" [ lookahead (@ 2 @) LocalLookahead] Sandwich(Part) "]". ClassParents = [ Superclasses ] [ Interfaces ]. Superclasses = ExtendsKeyword Commalist(Superclass). Superclass = ClassSpec. Interfaces = ImplementsKeyword Commalist(Interface). Interface = ClassSpec. ConstructionClass = "=". AlternationClass = ":" + + + [ *lookahead* (@ _Subclass() @) Barlist(Subclass) ] - - - [ lookahead (@ _CommonKeyword() @) CommonKeyword ]. Subclass = [ lookahead (@ 2 @) LocalLookahead ] ClassSpec. LocalLookahead = LookaheadKeyword JavaCode. RepetitionClass = "~" Sandwich(RepeatedPart). RepeatedPart = [ ClassSpec ] "{" [ lookahead (@ 2 @) LocalLookahead ] Sandwich(ClassSpec) *s "}". Sandwich(S) = List(Syntax) *s S List(Syntax) . ClassSpec = ClassName ["(" Commalist(ClassSpec) ")" ] . Syntax : SyntaxToken | PrintCommand. SyntaxToken = String. PrintCommand : PrintIndent | PrintUnindent | PrintSkip | PrintSpace. PrintIndent = "+" . PrintUnindent = "-" . PrintSkip = "*l" . PrintSpace = "*s" . // Terminal buffer classes. PackageName ~ IdentOrKeyword { *lookahead* (@ 2 @) "." IdentOrKeyword }. ClassName = Ident. PartName = IdentOrKeyword. JavaType = Name List(ArraySpec). ArraySpec = "[" "]". JavaCode = Text. // The problem here is that "." is used to end a class def, which is // usually followed by the beginning of another class def, which // starts with an ident or keyword... So we have to use semantic // lookahead to make sure we're not in that situation if we want to // consume the next ident for the qualified name. If the ident is // followed by . ident . then we know we're still in the qualified // name. Otherwise, we have several possibilities for when not to // consume: // 1. ident1 . ident2 = ... (or : or ~) // ident2 is a class being defined. // 2. ident1 . ident2 ( ... // ident2 is a parameterized class being defined. // 3. ident1 . visitor ... (or notparsed) // assume a class keyword begins a class definition. // 4. ident1 . parse ... (or noparse or visitors or endvisitors) // assume a directive keyword is a directive. Name ~ IdentOrKeyword { lookahead (@ "." _IdentOrKeyword(), { getToken(3).image.equals(".") || getToken(3).kind == EOF || ("=:~(".indexOf(getToken(3).image) == -1 && !getToken(2).image.equals("visitor") && !getToken(2).image.equals("notparsed") && !getToken(2).image.equals("parse") && !getToken(2).image.equals("noparse") && !getToken(2).image.equals("visitors") && !getToken(2).image.equals("endvisitors")) } @) "." IdentOrKeyword }. // All the keywords that look like identifiers in the grammar that // aren't keywords in Java. IdentOrKeyword : ParseIdent | NoParseIdent | VisitorsIdent | EndVisitorsIdent | VisitorIdent | NotParsedIdent | DerivedIdent | InitIdent | CommonIdent | LookaheadIdent | StrategyIdent | WithIdent | ThroughIdent | ViaIdent | BypassingIdent | ToIdent | DoIdent | JoinIdent | MergeIdent | IntersectIdent | TraversalIdent | BeforeIdent | AroundIdent | AfterIdent | GetIdent | SetIdent | StartIdent | FinishIdent | OtherIdent. ParseIdent = "parse". NoParseIdent = "noparse". VisitorsIdent = "visitors". EndVisitorsIdent = "endvisitors". VisitorIdent = "visitor". NotParsedIdent = "notparsed". DerivedIdent = "derived". InitIdent = "init". CommonIdent = "common". LookaheadIdent = "lookahead". StrategyIdent = "strategy". WithIdent = "with". ThroughIdent = "through". ViaIdent = "via". BypassingIdent = "bypassing". ToIdent = "to". DoIdent = "do". JoinIdent = "join". MergeIdent = "merge". IntersectIdent = "intersect". TraversalIdent = "traversal". BeforeIdent = "before". AroundIdent = "around". AfterIdent = "after". GetIdent = "get". SetIdent = "set". StartIdent = "start". FinishIdent = "finish". OtherIdent = Ident. // Keywords with optional star forms. ParseKeyword : DoParse | DontParse. DoParse : DoParseWithoutStars | DoParseWithStars. DoParseWithoutStars = "parse". DoParseWithStars = *s "*parse*" *s. DontParse : DontParseWithoutStars | DontParseWithStars. DontParseWithoutStars = "noparse". DontParseWithStars = *s "*noparse*" *s. VisitorKeyword : BeginVisitors | EndVisitors. BeginVisitors : BeginVisitorsWithoutStars | BeginVisitorsWithStars. BeginVisitorsWithoutStars = "visitors". BeginVisitorsWithStars = *s "*visitors*" *s. EndVisitors : EndVisitorsWithoutStars | EndVisitorsWithStars. EndVisitorsWithoutStars = "endvisitors". EndVisitorsWithStars = *s "*endvisitors*" *s. ClassKeyword : PublicClass | FinalClass | InterfaceClass | VisitorClass | NotParsedClass. PublicClass : PublicClassWithoutStars | PublicClassWithStars. PublicClassWithoutStars = "public". PublicClassWithStars = *s "*public*" *s. FinalClass : FinalClassWithoutStars | FinalClassWithStars. FinalClassWithoutStars = "final". FinalClassWithStars = *s "*final*" *s. InterfaceClass : InterfaceClassWithoutStars | InterfaceClassWithStars. InterfaceClassWithoutStars = "interface". InterfaceClassWithStars = *s "*interface*" *s. VisitorClass : VisitorClassWithoutStars | VisitorClassWithStars. VisitorClassWithoutStars = "visitor". VisitorClassWithStars = *s "*visitor*" *s. NotParsedClass : NotParsedClassWithoutStars | NotParsedClassWithStars. NotParsedClassWithoutStars = "notparsed". NotParsedClassWithStars = *s "*notparsed*" *s. PartKeyword : FinalPart | StaticPart | ReadOnlyPart | PrivatePart | DerivedPart. FinalPart : FinalPartWithoutStars | FinalPartWithStars. FinalPartWithoutStars = "final". FinalPartWithStars = *s "*final*" *s. StaticPart : StaticPartWithoutStars | StaticPartWithStars. StaticPartWithoutStars = "static". StaticPartWithStars = *s "*static*" *s. ReadOnlyPart : ReadOnlyPartWithoutStars | ReadOnlyPartWithStars. ReadOnlyPartWithoutStars = "read-only". ReadOnlyPartWithStars = *s "*read-only*" *s. PrivatePart : PrivatePartWithoutStars | PrivatePartWithStars. PrivatePartWithoutStars = "private". PrivatePartWithStars = *s "*private*" *s. DerivedPart : DerivedPartWithoutStars | DerivedPartWithStars. DerivedPartWithoutStars = "derived". DerivedPartWithStars = *s "*derived*" *s. PartInitKeyword : PartInitKeywordWithoutStars | PartInitKeywordWithStars. PartInitKeywordWithoutStars = "init". PartInitKeywordWithStars = *s "*init*" *s. ExtendsKeyword : ExtendsKeywordWithoutStars | ExtendsKeywordWithStars. ExtendsKeywordWithoutStars = "extends". ExtendsKeywordWithStars = *s "*extends*" *s. ImplementsKeyword : ImplementsKeywordWithoutStars | ImplementsKeywordWithStars. ImplementsKeywordWithoutStars = "implements". ImplementsKeywordWithStars = *s "*implements*" *s. CommonKeyword : CommonWithoutStars | CommonWithStars. CommonWithoutStars = *l + "common" -. CommonWithStars = *l + *s "*common*" *s -. LookaheadKeyword : LookaheadKeywordWithoutStars | LookaheadKeywordWithStars. LookaheadKeywordWithoutStars = "lookahead". LookaheadKeywordWithStars = *s "*lookahead*" *s. EOFtoken : EOFtokenWithoutStars | EOFtokenWithStars. EOFtokenWithoutStars = "EOF". EOFtokenWithStars = *s "*EOF*" *s. // Parameterized class definitions. List(S) ~ {*s S}. NList(S) ~ S {*s S}. SList(S) ~ S { *l S } . DList(S) ~ S { *l *l S } *l . Commalist(S) ~ S {"," *s S}. Barlist(S) ~ S { *l "|" *s S}. ////////////////////// //syntax enhancement// ////////////////////// SyntaxEnhancement = List(Enhancement) EOF. Enhancement = Where EnhancementBody. EnhancementBody : ClassBody | PartCoordinate | CollectionCoordinate common ":" SyntaxToken . PartCoordinate = "part" SyntaxClassName "." SyntaxPartName. ClassBody = "class" SyntaxClassName. CollectionCoordinate = "collection" SyntaxClassName CurlyBracket. CurlyBracket : Left | Right. Left = "{". Right = "}". SyntaxClassName = Ident. SyntaxPartName = Ident. Where : Before | After. Before = "before". After = "after". //populates hashtable with classgraph information ClassGraphVisitor = extends Visitor. //provides behavior for different types of syntax commands CommandVisitor = extends Visitor. //three types ClassCommandVisitor = extends Visitor. CollectionCommandVisitor = extends Visitor. PartCommandVisitor = extends Visitor.