// generate.cd -- class dictionary for Demeter/Java code generator // $Id: generate.cd,v 1.11 2000/09/19 21:08:21 dougo Exp $ package edu.neu.ccs.demeter.tools.generate; import java.util.*; import java.util.zip.*; import java.io.*; import edu.neu.ccs.demeter.common.tg.*; *public* Main = . // 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 ClassGraph *EOF* . GlobalImports = [ SList(Import) *l ] . Import = "import" PackageName [ ImportAllClasses ] ";". ImportAllClasses = ".*". ClassGraph = 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 [ ClassMethods ] [ *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 : PlainSyntax | PrintCommand. PlainSyntax = String. PrintCommand : PrintIndent | PrintUnindent | PrintSkip | PrintSpace. PrintIndent = "+" . PrintUnindent = "-" . PrintSkip = "*l" . PrintSpace = "*s" . ////////////////////// // Behavior (methods). ////////////////////// // ProgramBehavior is the starting nonterminal of the behavior file grammar. ProgramBehavior = [ DList(Behavior) ] *EOF* . Behavior : lookahead (@ 2 @) StrategyDefinition | ClassBehavior. StrategyDefinition = "strategy" StrategyName "=" StrategyExpression ".". StrategyExpression : StrategyGraph | PathDirective | StrategyVariable | CompoundStrategy common [ "with" *s NameMap ]. StrategyGraph = "{" *l + [ "vec:" *s Vector ] SList(SGEdge) - *l "}" *s [ "source:" ClassGlobSpec ] [ "source-edge:" NList(Integer) ] [ "target:" ClassGlobSpec ] implements StrategyGraphI . SGEdge = ClassGlobSpec *s "->" *s ClassGlobSpec [ lookahead (@2@) NegativeConstraint ]. PathDirective = [ NegativeConstraint ] List(PathSegment) TargetDirective. PathSegment = PositiveConstraint [ NegativeConstraint ]. Constraint : PositiveConstraint | NegativeConstraint *common* *s GlobSpec. PositiveConstraint : Through | Via. // synonyms Through = "through". Via = "via". NegativeConstraint : Bypassing | OnlyThrough. // antonyms Bypassing = "bypassing". OnlyThrough = "only-through". TargetDirective : To | ToStop *common* ClassGlobSpec. To = "to". ToStop = "to-stop". StrategyVariable = "do" StrategyName. CompoundStrategy : Join | Merge | Intersect *common* "(" Commalist(StrategyExpression) ")". Join = "join". Merge = "merge". Intersect = "intersect". NameMap = "{" *s Commalist(NameBinding) *s "}". NameBinding = Name "=" Name. GlobSpec : OneGlob | GlobSet. OneGlob = Glob. GlobSet = "{" *s [ Commalist(Glob) *s ] "}". Glob : ClassGlob | EdgeGlob. EdgeGlob : PartGlob | SubclassGlob | SuperclassGlob. ClassGlob = ClassNameGlob. PartGlob = "->" *s SourceGlob "," *s PartNameGlob "," *s DestGlob. SubclassGlob = "=>" *s SourceGlob "," *s DestGlob. SuperclassGlob = ":>" *s SourceGlob "," *s DestGlob. SourceGlob = ClassNameGlob. DestGlob = ClassNameGlob. ClassNameGlob : ClassNameExact | AnyClass. ClassNameExact = ClassName. AnyClass = "*". PartNameGlob : PartNameExact | AnyPart. PartNameExact = PartName. AnyPart = "*". ClassGlobSpec : OneClassGlob | ClassGlobSet. OneClassGlob = ClassGlob. ClassGlobSet = "{" *s Commalist(ClassGlob) *s "}". ClassBehavior = ClassGlobSpec ClassMethods. ClassMethods = "{" *l + [ SList(Method) ] - *l "}" [ "wrappers:" Hashtable // maps Wrapper-kind -> HostSet ] . HostSet = [ "exact:" Hashtable ] // globs with no stars [ "partnames:" Hashtable ] // -> *,name,* globs [ "globs:" GlobSet] . // other globs // We have to explicitly specify lookahead 1 here so that if we see // the appropriate keyword we choose that instead of thinking it might // be a return type for MethodDef. Also, MethodDef has to go after // all the others that start with keywords. Method : lookahead (@ 1 @) TraversalDef | lookahead (@ 1 @) Wrapper | lookahead (@ 1 @) Accessor | lookahead (@ 1 @) Constructor | lookahead (@ 1 @) Start | lookahead (@ 1 @) Finish | lookahead (@ 1 @) ReturnValue | MethodDef | Verbatim. // Class graph traversal definitions. TraversalDef = "traversal" TraversalName TraversalParms *s "{" *l + StrategyExpression ";" - *l "}". TraversalParms = "(" [ Commalist(Visitor) ] ")" . Visitor = ClassName [ VisitorName ]. // Adaptive methods. MethodDef = MethodSignature MethodBody. MethodSignature = List(MethodKeyword) JavaType MethodName "(" [ Commalist(MethodParm) ] ")" Throws. MethodKeyword : PublicMethod | ProtectedMethod | PrivateMethod | StaticMethod | FinalMethod | AbstractMethod. PublicMethod = "public". ProtectedMethod = "protected". PrivateMethod = "private". StaticMethod = "static". FinalMethod = "final". AbstractMethod = "abstract". MethodParm = JavaType ParmName List(ArraySpec). Throws = [ *s "throws" Commalist(ClassName) ]. MethodBody : VerbatimMethodBody | AdaptiveMethodBody | NoMethodBody. VerbatimMethodBody = JavaCode. AdaptiveMethodBody = TraversalExpression VisitorExpression. NoMethodBody = ";". TraversalExpression : lookahead (@ _TraversalSpec() @) TraversalSpec | TraversalRef. TraversalRef = [Equals] TraversalName. Equals = "=". // optional syntax TraversalSpec = StrategyExpression. VisitorExpression : VisitorRef | VisitorSpec. VisitorRef = "(" Commalist(ClassName) ")" ";". VisitorSpec = [VisitorNameSpec] [VisitorExtendsSpec] ClassMethods . VisitorNameSpec = VisitorClass ClassName. VisitorExtendsSpec = ExtendsKeyword ClassName. // Visit methods. Wrapper = WrapperKind HostSpec JavaCode. WrapperKind : Before | Around | After. Before = "before". Around = "around". After = "after". HostSpec : GlobSpec. // Derived part accessors. Accessor : Getter | Setter *common* PartName JavaCode . Getter = "get" . Setter = "set" . // Constructor method. // Only no-arg constructors supported for now. Constructor = "init" JavaCode. // Methods called at the beginning and ending of a traversal. Start = "start" JavaCode. Finish = "finish" JavaCode. // Code for computing the return value of a visitor when used in an // adaptive method. ReturnValue = "return" [ JavaType ] JavaCode. // Verbatim java code. Verbatim = JavaCode. // Terminal buffer classes. PackageName ~ IdentOrKeyword { *lookahead* (@ 2 @) "." IdentOrKeyword }. public ClassName = Name implements NameI. public PartName = IdentOrKeyword implements NameI. TraversalName = Name. VisitorName = Name. MethodName = IdentOrKeyword. ParmName = IdentOrKeyword. StrategyName = 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}. *noparse* // Utility classes. TraversalMethodName = MethodName. UniversalTraversalGraph = extends TraversalGraph. ClassType = boolean boolean boolean boolean boolean boolean boolean boolean. PartType = boolean boolean boolean boolean boolean . Parts ~ { Part }. // Visitors. *visitors* ClassDefVisitor : . ClassGlobVisitor : . ClassNameAccessor : . PartVisitor : . EdgeVisitor : . GlobVisitor : ClassGlobCollector | SGEdgeMatcher . ClassGlobCollector = ClassGlobSet. SGEdgeMatcher = NameI int Vector. VisitorNameVisitor : . EdgeGlobMaker = ClassName ClassName ClassName PartName Glob extends EdgePartsVisitor. // TAO stuff: TAOVisitor : FindVisitorTargetsV |CreateMethodsV . FindVisitorTargetsV = Vector Vector Vector String Vector. CreateMethodsV = ClassDef String String Vector Vector Vector boolean Vector String String String String String String int int boolean Vector String String String String Vector .