add java 1.5 annotation grammar for all types of annotation(marker, single value...
authoryeom <yeom>
Tue, 1 Mar 2011 01:48:09 +0000 (01:48 +0000)
committeryeom <yeom>
Tue, 1 Mar 2011 01:48:09 +0000 (01:48 +0000)
Robust/src/IR/Tree/AnnotationNode.java [new file with mode: 0644]
Robust/src/IR/Tree/BuildIR.java
Robust/src/IR/Tree/Modifiers.java
Robust/src/Lex/Lexer.java
Robust/src/Lex/Separator.java
Robust/src/Parse/java14.cup

diff --git a/Robust/src/IR/Tree/AnnotationNode.java b/Robust/src/IR/Tree/AnnotationNode.java
new file mode 100644 (file)
index 0000000..b0622ca
--- /dev/null
@@ -0,0 +1,12 @@
+package IR.Tree;
+
+public class AnnotationNode extends TreeNode {
+  //currently it only supports marker annotation that have no variables.
+  String name;
+  
+  public AnnotationNode(String name){
+    //constructor for marker annotation
+    this.name=name;
+  }
+  
+}
index 100b5e2f0a4e8ebf3bb05865c51450f6226c0ee1..9a20ec9a550527b0942857cbcbe27f314b503192 100644 (file)
@@ -1067,6 +1067,12 @@ public class BuildIR {
 
       blockstatements.add(new TagDeclarationNode(name, type));
     } else if (isNode(pn,"local_variable_declaration")) {
+      
+      ParseNode mn=pn.getChild("modifiers");
+      if(mn!=null){
+        Modifiers m=parseModifiersList(mn);
+        // TODO: add annotations to corresponding descriptor
+      }      
       TypeDescriptor t=parseTypeDescriptor(pn);
       ParseNode vn=pn.getChild("variable_declarators_list");
       ParseNodeVector pnv=vn.getChildren();
@@ -1287,7 +1293,7 @@ public class BuildIR {
     if (modlist!=null) {
       ParseNodeVector pnv=modlist.getChildren();
       for(int i=0; i<pnv.size(); i++) {
-       ParseNode modn=pnv.elementAt(i);
+       ParseNode modn=pnv.elementAt(i);        
        if (isNode(modn,"public"))
          m.addModifier(Modifiers.PUBLIC);
        else if (isNode(modn,"protected"))
@@ -1310,11 +1316,31 @@ public class BuildIR {
       m.addModifier(Modifiers.VOLATILE);
     else if (isNode(modn,"transient"))
       m.addModifier(Modifiers.TRANSIENT);
-       else throw new Error("Unrecognized Modifier");
+    else if(isNode(modn,"annotation_list"))
+      parseAnnotationList(modn,m);    
+       else{     
+         throw new Error("Unrecognized Modifier:"+modn.getLabel());}
       }
     }
     return m;
   }
+  
+  private void parseAnnotationList(ParseNode pn, Modifiers m){
+      ParseNodeVector pnv=pn.getChildren();
+      for(int i=0; i<pnv.size(); i++) {
+        ParseNode body_list=pnv.elementAt(i);
+        if(isNode(body_list,"annotation_body")){
+          ParseNode body_node=body_list.getFirstChild();
+          if (isNode(body_node,"marker_annotation")){          
+            m.addAnnotation(new AnnotationNode(body_node.getChild("name").getTerminal()));
+          }else if(isNode(body_node,"single_annotation")){
+            throw new Error("Annotation with single piece of data is not supported yet.");
+          } else if(isNode(body_node,"normal_annotation")){
+            throw new Error("Annotation with multiple data members is not supported yet.");
+          }   
+        }
+      }    
+  }
 
   private boolean isNode(ParseNode pn, String label) {
     if (pn.getLabel().equals(label))
index c49c35d2409998bb02a3a00a93ae142f7c6ec7f9..fa35937472a8f6b0b26f8f878f3b3a4eedf84a63 100644 (file)
@@ -1,5 +1,7 @@
 package IR.Tree;
 
+import java.util.Vector;
+
 public class Modifiers {
   public static final int PUBLIC=1;
   public static final int PROTECTED=2;
@@ -14,16 +16,23 @@ public class Modifiers {
 //     STRICTFP=1024
   public static final int ATOMIC=2048;
 
-
+  // java annotation can be intermixed freely with modifiers
+  // so Modifiers  maintains the list of annotations for later usage
+  Vector<AnnotationNode> annotations;  
   private int value;
 
   public Modifiers() {
     value=0;
+    annotations=new Vector<AnnotationNode>();
   }
 
   public Modifiers(int v) {
     value=v;
   }
+  
+  public void addAnnotation(AnnotationNode an){
+    annotations.add(an);
+  }
 
   public void addModifier(int mod) {
     value|=mod;
index 6cb427f91b4015cbbdd7ada08dba20c5073b916c..ba081e8699dc6d9f5a9b3acde9c2af6934926f72 100644 (file)
@@ -207,6 +207,7 @@ public class Lexer {
     case ']':
     case ';':
     case ',':
+    case '@':
       return new Separator(consume());
 
       // Operators:
index f2b1ac1212a99c0de30c7f17a9f9287e0f238c73..f6b1e3a35276f748458bfaacb0f784d1dba5e954 100644 (file)
@@ -29,6 +29,8 @@ class Separator extends Token {
 
     case '.': return new Symbol(Sym.DOT);
 
+    case '@': return new Symbol(Sym.AT);
+
     case '\u2026':  return new Symbol(Sym.ELLIPSIS);
 
     default:
index 0158c96f8fa26bcb5b56c70923f1c63f406a6d59..448e3b6290388802a30ffc0a2ee2913d197f2ae9 100644 (file)
@@ -85,6 +85,7 @@ terminal QUESTION; // conditional_expression
 terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator
 terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator
 terminal ANDEQ, XOREQ, OREQ; // assignment_operator
+terminal AT;           // support annotations
 
 terminal java.lang.Number INTEGER_LITERAL;
 terminal java.lang.Number FLOATING_POINT_LITERAL;
@@ -131,7 +132,8 @@ non terminal ParseNode single_type_import_declaration;
 non terminal ParseNode type_import_on_demand_declaration;
 non terminal ParseNode type_declaration;
 // 19.7) Productions used only in the LALR(1) grammar
-non terminal ParseNode modifiers_opt, modifiers, modifier;
+non terminal ParseNode modifiers_opt, modifiers, modifiers_at, modifier;
+non terminal ParseNode mixed_modifiers, mixed_modifiers_at;
 // 19.8.1) Class Declaration
 non terminal ParseNode class_declaration, super, super_opt;
 non terminal ParseNode interfaces, interfaces_opt, interface_type_list;
@@ -158,6 +160,7 @@ non terminal ParseNode constructor_body;
 non terminal ParseNode explicit_constructor_invocation;
 // 19.9.1) Interface Declarations
 non terminal ParseNode interface_declaration;
+non terminal normal_interface_declaration, annotation_type_declaration;
 non terminal ParseNode extends_interfaces_opt, extends_interfaces;
 non terminal ParseNode interface_body;
 non terminal ParseNode interface_member_declarations_opt, interface_member_declarations;
@@ -280,6 +283,15 @@ non terminal ParseNode enum_declaration;
 non terminal ParseNode enum_body, enum_constants_opt, enum_constants, enum_constant;
 //non terminal ParseNode enum_arguments_opt, enum_body_declarations_opt;
 
+// annotation expressions
+non terminal ParseNode annotations_opt, annotations, annotations_at, annotation, annotation_body;
+non terminal ParseNode normal_annotation_body, marker_annotation_body;
+non terminal ParseNode single_element_annotation_body;
+non terminal ParseNode annotation_type_body, annotation_type_element_declarations;
+non terminal ParseNode annotation_type_element_declarations_opt;
+non terminal ParseNode annotation_type_element_declaration, default_value_opt, default_value;
+non terminal ParseNode element_value_pairs_opt, element_value_pairs, element_value_pair;
+non terminal ParseNode element_values_opt, element_values, element_value, element_value_array_initializer;
 
 start with goal;
 
@@ -661,7 +673,7 @@ type_declarations ::=
        ;
 
 package_declaration ::=
-               PACKAGE name:name SEMICOLON {: 
+                PACKAGE name:name SEMICOLON {: 
        ParseNode pn=new ParseNode("package");
        pn.addChild(name);
        RESULT=pn;
@@ -713,15 +725,44 @@ modifiers_opt::=
                RESULT=mo;
        :}
        ;
-modifiers ::=  modifier:mo {: 
+modifiers_at ::=
+               mixed_modifiers_at
+       |       annotations_at
+       ;
+modifiers ::=   mixed_modifiers : mmo {:
+               RESULT=mmo; 
+       :}
+       |       annotations : an {:
                ParseNode pn=new ParseNode("modifier_list");
-               pn.addChild(mo);
+               pn.addChild(an);
                RESULT=pn;
        :}
-       |       modifiers:mos modifier:mo {: 
-               mos.addChild(mo);
-               RESULT=mos;
+       ;
+mixed_modifiers_at ::=
+               mixed_modifiers : mmos AT {:
+               RESULT=mmos;
+        :}
+       ;
+mixed_modifiers ::=
+               modifier : mo {:
+                ParseNode pn=new ParseNode("modifier_list");
+               pn.addChild(mo);
+               RESULT=pn;
+        :}
+       |       annotations:as modifier:mo {:
+               ParseNode pn=new ParseNode("modifier_list");
+               pn.addChild(mo);
+               pn.addChild(as);
+               RESULT=pn;
+        :}
+       |       mixed_modifiers : mmos modifier : mo {:
+                mmos.addChild(mo);
+               RESULT=mmos;
        :}
+       |       mixed_modifiers_at:mma annotation_body:ab {:
+                mma.addChild("annotation_list").addChild(ab); 
+               RESULT=mma;             
+        :}
        ;
 modifier ::=   
        PUBLIC {: RESULT=new ParseNode("public"); :}|
@@ -739,7 +780,100 @@ modifier ::=
 //     STRICTFP // note that semantic analysis must check that the
                         // context of the modifier allows strictfp.
        ;
-
+//annotations_opt ::=
+//     {: RESULT=new ParseNode("empty"); :}
+//     |       annotations:an {: 
+//             RESULT=an;
+//     :}
+//     ;
+annotations ::= 
+               AT annotation_body:ab {:
+                ParseNode pn=new ParseNode("annotation_list");
+               pn.addChild(ab);
+               RESULT=pn;
+        :}
+       |       annotations_at:aat annotation_body:ab {:
+               aat.addChild(ab);
+               RESULT=aat;
+       :}
+       ;
+annotations_at ::=
+              annotations:as AT {:
+              RESULT=as;
+        :}
+       ;
+annotation ::=
+              AT annotation_body:ab {:
+               RESULT=ab;
+       :}
+       ;
+annotation_body ::=
+               normal_annotation_body:nab {:
+               ParseNode pn=new ParseNode("annotation_body");
+               pn.addChild(nab);
+                RESULT = pn;
+        :}
+        |       marker_annotation_body:mab {:
+               ParseNode pn=new ParseNode("annotation_body");
+               pn.addChild(mab);
+               RESULT = pn;
+        :}
+        |      single_element_annotation_body:seab {:
+               ParseNode pn=new ParseNode("annotation_body");
+               pn.addChild(seab);
+                RESULT = pn;
+        :}
+        ;
+normal_annotation_body ::=
+               IDENTIFIER LPAREN element_value_pairs_opt RPAREN
+        ;
+marker_annotation_body ::=
+                IDENTIFIER:id
+       {:
+       ParseNode pn=new ParseNode("marker_annotation");
+       pn.addChild("name").addChild(id);
+       RESULT=pn;
+       :}
+        ;
+single_element_annotation_body ::=
+                IDENTIFIER:id LPAREN element_value:ev RPAREN {:
+                ParseNode pn=new ParseNode("single_annotation");
+               pn.addChild("name").addChild(id);
+               pn.addChild("element_value").addChild(ev);
+               RESULT=pn;
+        :}
+        ;
+element_value_pairs_opt ::=
+       |       element_value_pairs
+       ;               
+element_value_pairs ::=
+               element_value_pair
+       |       element_value_pairs COMMA element_value_pair
+       ;
+element_value_pair ::=
+               IDENTIFIER EQ element_value
+       ;
+element_value ::=
+               annotation:an {:
+               RESULT=an;
+       :}  
+       |       element_value_array_initializer:evai {: 
+               RESULT=evai;
+        :}
+       |       conditional_expression:ce {:
+               RESULT=ce;
+       :}
+       ;
+element_value_array_initializer ::=
+               LBRACE element_values_opt RBRACE
+       ;
+element_values_opt ::=
+       |       element_values
+       ;
+element_values ::=
+               element_value
+       |       element_values COMMA element_value
+       ;
 // 19.8) Classes
 
 // 19.8.1) Class Declaration:
@@ -1161,6 +1295,7 @@ interface_declaration ::=
        pn.addChild("interfacebody").addChild(body);
        RESULT=pn;
        :}
+       | annotation_type_declaration
        ;
 extends_interfaces_opt ::=
        {: RESULT=new ParseNode("empty"); :}
@@ -1229,6 +1364,28 @@ abstract_method_declaration ::=
        :}
        ;
 
+annotation_type_declaration ::=
+               AT INTERFACE IDENTIFIER annotation_type_body
+       |       modifiers_at INTERFACE IDENTIFIER annotation_type_body
+       ;
+annotation_type_body ::=
+               LBRACE annotation_type_element_declarations_opt RBRACE
+       ;
+annotation_type_element_declarations_opt ::=
+       |       annotation_type_element_declarations
+       ;
+annotation_type_element_declarations ::=
+               annotation_type_element_declaration
+        |      annotation_type_element_declarations annotation_type_element_declaration
+       ;
+annotation_type_element_declaration ::=
+               constant_declaration
+       |       modifiers_opt type IDENTIFIER LPAREN RPAREN default_value_opt SEMICOLON
+        |      class_declaration 
+        |      enum_declaration 
+        |      interface_declaration 
+       |       SEMICOLON
+        ;
 
 // 19.10) Arrays
 array_initializer ::=
@@ -1315,10 +1472,13 @@ local_variable_declaration ::=
                pn.addChild(var);
                RESULT=pn;
        :}
-       |       FINAL type:type variable_declarators:var {: 
+//     |       FINAL type:type variable_declarators:var {: 
+         /* CAUTION:  only FINAL and annotations are legal modifiers here */
+       |       modifiers:mo type:type variable_declarators:var {:
                ParseNode pn=new ParseNode("local_variable_declaration");
                pn.addChild(type);
                pn.addChild(var);
+               pn.addChild("modifiers").addChild(mo);
                RESULT=pn;
        :}
        ;