certi-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[certi-cvs] certi/scripts GenerateMessages.py TestMessageSp...


From: certi-cvs
Subject: [certi-cvs] certi/scripts GenerateMessages.py TestMessageSp...
Date: Tue, 14 Jul 2009 12:40:51 +0000

CVSROOT:        /sources/certi
Module name:    certi
Changes by:     Eric NOULARD <erk>      09/07/14 12:40:50

Modified files:
        scripts        : GenerateMessages.py TestMessageSpec.msg 
Added files:
        scripts        : CertiNetworkMessage.msg 

Log message:
        Better parser.
        The AST is near complete, but
         - needs to attach comment
         - better defined sub-object for 
             EnumSymbol 
             MessageField

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/certi/scripts/GenerateMessages.py?cvsroot=certi&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/certi/scripts/TestMessageSpec.msg?cvsroot=certi&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/certi/scripts/CertiNetworkMessage.msg?cvsroot=certi&rev=1.1

Patches:
Index: GenerateMessages.py
===================================================================
RCS file: /sources/certi/certi/scripts/GenerateMessages.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- GenerateMessages.py 13 Jul 2009 21:39:28 -0000      1.2
+++ GenerateMessages.py 14 Jul 2009 12:40:49 -0000      1.3
@@ -4,8 +4,18 @@
 import getopt, sys
 import shutil
 # We use PLY in order to parse CERTI message specification files 
+# PLY is there: http://www.dabeaz.com/ply/
 import ply.yacc
 import ply.lex
+# We use logging for ... logging :-)
+import logging 
+
+
+stdoutHandler = logging.StreamHandler(sys.stdout)
+stdoutHandler.setFormatter(logging.Formatter("%(msecs)d-[%(name)s::%(levelname)s]
 %(message)s"))
+mylogger = logging.Logger("GenerateMessage")
+mylogger.setLevel(logging.ERROR)
+mylogger.addHandler(stdoutHandler)
 
 def usage():
     print "Usage:\n %s --file=<message> [--language=C++|Java|Python] 
[--type=header|body|factory] [--verbose] [--help]" % 
os.path.basename(sys.argv[0])
@@ -13,7 +23,7 @@
 try:
     opts, args = getopt.getopt(sys.argv[1:], "f:l:t:vh", 
["file=","language=","type=","verbose","help"])
 except getopt.GetoptError, err:
-    print >> stderr, "opt = %s, msg = %s" % (err.opt,err.msg)
+    mylogger.error("opt = %s, msg = %s" % (err.opt,err.msg))    
     usage()
     sys.exit(2)
 
@@ -43,6 +53,7 @@
 # Lexer+Parser specification begins here
 # reserved keywords
 reserved = {
+   'package'        : 'PACKAGE',
    'native_message' : 'NATIVE_MESSAGE',            
    'message' : 'MESSAGE',
    'merge' : 'MERGE',
@@ -77,9 +88,10 @@
           'COMMA',
           'EQUAL',
           'COLON',
+          'PERIOD',
           ] + list(reserved.values())
 
-# This is a message of field identifier          
+# This is a message of field or name identifier          
 def t_ID(t):
     r'[a-zA-Z_][a-zA-Z_0-9]*'
     t.type = reserved.get(t.value,'ID')    # Check for reserved words
@@ -128,6 +140,7 @@
 t_COMMA = r','
 t_EQUAL = r'='
 t_COLON = r':'
+t_PERIOD = r'\.'
 
 # Define a rule so we can track line numbers
 def t_newline(t):
@@ -145,17 +158,60 @@
 # Build the PLY lexer
 lexer = ply.lex.lex()
 
+# Named Class
+class Named(object):
+    def __init__(self,name):
+        self.__name    = name
+        self.__comment = None
+    
+    def __getName(self):
+        return self.__name    
+    def __setName(self,name):
+        self.__name = name
+    # pythonic getter/setter using properties    
+    name = property(fget=__getName,fset=__setName)
+    
+    def __getComment(self):
+        return self.__comment    
+    def __setComment(self,comment):
+        self.__comment = comment
+    # pythonic getter/setter using properties    
+    name = property(fget=__getComment,fset=__setComment)
+
 # Message set
-class MessageAST(object):
+class MessageNotAnAST(Named):
     def __init__(self,name):
-        self.name = name
-        self.nativeMessageType = set()
-        self.messageTypeSet    = set()
-        self.enumTypeSet       = set()
+        super(MessageNotAnAST,self).__init__(name=name)        
+        self.__nativeMessageTypeSet = set()
+        self.__messageTypeSet       = set()
+        self.__enumTypeSet          = set()
+        self.__package              = None
+        self.__types                = dict()
+        self.logger = logging.Logger("MessageNotAnAST")
+        self.logger.setLevel(logging.ERROR)
+        self.logger.addHandler(stdoutHandler)
+        
+    def __getNativeMessageTypeSet(self):
+        return self.__nativeMessageTypeSet        
+    nativeMessages = property(fget=__getNativeMessageTypeSet)
+    
+    def __getMessageTypeSet(self):
+        return self.__messageTypeSet        
+    messages = property(fget=__getMessageTypeSet)
+    
+    def __getEnumTypeSet(self):
+        return self.__enumTypeSet    
+    enums = property(fget=__getEnumTypeSet)         
+    
+    def __getPackage(self):
+        return self.__package
+    def __setPackage(self,package):
+        self.__package = package
+    package = property(fget=__getPackage,fset=__setPackage)
         
     def add(self,any):
         if any == None:
-            print "<None> given to AST some rule aren't finished"
+            self.logger.error("<None> given to AST some rule aren't finished")
         elif isinstance(any,type("")):
             pass
         else:         
@@ -165,33 +221,61 @@
                 self.addNativeMessageType(any)
             elif isinstance(any,MessageType):
                 self.addMessageType(any)
+            elif isinstance(any,Package):
+                self.package = any
             else:            
-                print "<%s> not handle [yet]" % any
-            print "%s added to AST" % any
+                self.logger.error("<%s> not handle [yet]" % any)            
             
     def addMessageType(self,message):
-        self.messageTypeSet.add(message)
+        self.__messageTypeSet.add(message)
+        self.__types[message.name] = message
         
     def addEnumType(self,enumType):
-        self.enumTypeSet.add(enumType)
+        self.__enumTypeSet.add(enumType)
+        self.__types[enumType.name] = enumType       
+        self.logger.debug("Adding enum type %s" % enumType.name) 
     
     def addNativeMessageType(self,message):
-        self.messageTypeSet.add(message)
+        self.__nativeMessageTypeSet.add(message)
+        self.__types[message.name] = message
+        
+    def isDefined(self,typename):
+        self.logger.debug("%s" % self.__types.keys())
+        if typename in self.__types.keys():
+            return True
+        else:
+            return False 
+    
+    def __repr__(self):
+        res = "AST with:\n <%d> native messages type,\n <%d> message type,\n 
<%d> enum type\n" % 
(len(self.nativeMessages),len(self.messages),len(self.enums))
+        res = res + " will be in package <%s>\n" % self.package
+        return res
+    
+    def visit(self):        
+        return None
+    
+class Package(Named):
+    """Represents a package"""
+    def __init__(self,name):
+        super(Package,self).__init__(name=name)
         
-class NativeMessageType(object):
+    def __repr__(self):
+        return "package %s" % self.name
+     
+class NativeMessageType(Named):
     """ Represents a native message type
     """
     def __init__(self,name):
-        self.name = name      
+        super(NativeMessageType,self).__init__(name=name)        
         
     def __repr__(self):
         return "native_message %s" % self.name 
                     
-class MessageType(object):
+class MessageType(Named):
     """ Represents a message type
     """
     def __init__(self,name,field_list,merge):
-        self.name       = name
+        super(MessageType,self).__init__(name=name)
         self.field_list = field_list
         self.merge      = merge
         
@@ -202,11 +286,11 @@
         res = "message %s " % self.name
         return res
                 
-class EnumType(object):
+class EnumType(Named):
     """ Represents an enum type 
     """
     def __init__(self,name,values):
-        self.name   = name
+        super(EnumType,self).__init__(name=name)
         # rebuild dictionary with value from the list                     
         self.values = []
         lastval = -1        
@@ -221,54 +305,67 @@
     def __repr__(self):
         res = "Enum %s {\n" % self.name
         for val in self.values:            
-            res = res + "  " + str(val[0]) + "=" + str(val[1]) + ", \n"
+            res = res + "  " + str(val[0]) + " = " + str(val[1]) + ", \n"
         res = res + "}"
         return res 
                 
-        
     def addValue(self,value):
         self.values.append(value)
 
+def p_statement_list(p):
+    '''statement_list : statement 
+                      | statement statement_list'''
+    p.parser.AST.add(p[1])
+
 def p_statement(p):
     '''statement : comment_line
-                 | comment_line statement
+                 | package                 
                  | message
-                 | message statement
                  | native_message
-                 | native_message statement  
-                 | enum
-                 | enum statement'''
-        
-    p.parser.AST.add(p[1])                            
+                 | enum'''        
+    p[0]=p[1]                            
         
 def p_comment_line(p):
     '''comment_line : COMMENT'''
     p[0]=p[1].strip('/')    
             
+def p_package(p):
+    '''package : PACKAGE package_id 
+               | PACKAGE package_id optional_comment'''    
+    p[0]=Package(p[2])
+    
+def p_package_id(p):
+    '''package_id : ID 
+                  | ID PERIOD package_id'''
+    if len(p)==2:
+        p[0]=p[1]
+    else:
+        p[0]=p[1]+"."+p[3]
+            
 def p_message(p):
-    '''message : MESSAGE ID LBRACE optional_comment field_list RBRACE 
optional_comment
-               | MESSAGE ID LBRACE optional_comment RBRACE optional_comment
-               | MESSAGE ID COLON MERGE ID LBRACE  optional_comment RBRACE 
optional_comment
-               | MESSAGE ID COLON MERGE ID LBRACE optional_comment field_list 
RBRACE optional_comment'''
-    if len(p)==7:        
+    '''message : MESSAGE ID LBRACE RBRACE optional_comment
+               | MESSAGE ID LBRACE field_list RBRACE optional_comment
+               | MESSAGE ID COLON MERGE ID LBRACE RBRACE optional_comment
+               | MESSAGE ID COLON MERGE ID LBRACE field_list RBRACE 
optional_comment'''
+    if len(p)==6:        
         p[0] = MessageType(p[2],[],None)
+    elif len(p)==7:
+        p[0] = MessageType(p[2],p[4],None)
     elif len(p)==8:
-        p[0] = MessageType(p[2],p[5],None)
+        p[0] = MessageType(p[2],[],p[4])
     elif len(p)==9:
-        p[0] = MessageType(p[2],[],p[5])
-    elif len(p)==10:
-        p[0] = MessageType(p[2],p[7],p[5])                                    
+        p[0] = MessageType(p[2],p[7],p[4])                                    
 
 def p_native_message(p): 
-    'native_message : NATIVE_MESSAGE ID optional_comment'
+    'native_message : NATIVE_MESSAGE ID'
     p[0]=NativeMessageType(p[2])    
         
 def p_enum(p):
-    'enum : ENUM ID LBRACE optional_comment enum_value_list RBRACE 
optional_comment'
+    'enum : ENUM ID LBRACE enum_value_list RBRACE optional_comment'
     # we should reverse the enum value list
     # because the parse build it the other way around (recursive way)
-    p[5].reverse()
-    p[0] = EnumType(p[2],p[5])
+    p[4].reverse()
+    p[0] = EnumType(p[2],p[4])
     
 def p_empty(p):
     'empty :'
@@ -310,7 +407,8 @@
     if len(p)==3:
         p[0] = [p[1]]
     else:
-        p[0] = p[3].append(p[1])     
+        p[0] = p[3]
+        p[0].append(p[1])    
 
 def p_field_spec(p):
     '''field_spec : qualifier typeid ID optional_comment
@@ -340,17 +438,36 @@
               | UINT64_T
               | FLOAT_T
               | DOUBLE_T
-              | ID'''
+              | defined_type'''
     p[0] = p[1]    
     
+def p_defined_type(p):
+    '''defined_type : ID'''
+    # This kind of type should be checked
+    # When the AST has been built.
+    # We cannot check it now because of the recursive
+    # nature of the parser.
+    p[0]=p[1]    
+    
 def p_value(p):
     '''value : INTEGER_VALUE 
              | FLOAT_VALUE 
              | BOOL_VALUE'''
     p[0]=p[1].value
     
+# Compute column. 
+#     input is the input text string
+#     token is a token instance
+def find_column(input,token):
+    last_cr = input.rfind('\n',0,token.lexpos)
+    if last_cr < 0:
+        last_cr = 0
+    column = (token.lexpos - last_cr) + 1
+    return column
+    
 def p_error(p):     
-    print "Syntax error at '%s' on line %d (token type is '%s')" % 
(p.value,p.lineno,p.type)    
+    print "Syntax error at '%s' on line %d column %d (token type is '%s')" % 
(p.value,p.lineno,find_column(p.lexer.lexdata, p),p.type)
+    
          
 # Build the PLY parser
 parser = ply.yacc.yacc() 
@@ -372,10 +489,10 @@
 print "Trying to parse..."    
 msgFile =  open(messagefile,'r')
 lexer.lineno = 1
-parser.AST = MessageAST(messagefile)
-ast = parser.parse(msgFile.read(),lexer=lexer)
+parser.AST = MessageNotAnAST(messagefile)
+parser.parse(msgFile.read(),lexer=lexer)
 msgFile.close()
-print "Parse succeeded AST = %s" % ast
+print "Parse succeeded AST = %s (type=%s)" % (parser.AST,type(parser.AST)) 
 
 sys.exit()
 for l in msgFile:

Index: TestMessageSpec.msg
===================================================================
RCS file: /sources/certi/certi/scripts/TestMessageSpec.msg,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- TestMessageSpec.msg 13 Jul 2009 21:39:28 -0000      1.2
+++ TestMessageSpec.msg 14 Jul 2009 12:40:49 -0000      1.3
@@ -1,10 +1,14 @@
-
 // CERTI message description spec test file
+package my.hierarchy.pack // don't you know it
 
+//
+//  This is a multiline
+//  comment
+//
 enum MessageType {
-   FIRST_VAL = 0,
-   REAL_VAL1,
-   REAL_VAL2,
+   FIRST_VAL = 0, // one may specify the value of the first enum symbol
+   REAL_VAL1    ,
+   REAL_VAL2    ,
    UNUSED
 }
 
@@ -15,10 +19,12 @@
 
 native_message ANotherativeMessageType 
 
-message MyMessage { // another comment
+message MyMessage { 
     repeated int32 whatever
 }
 
 message MyOtherMessage : merge MyMessage {
        required bool constrained
+       required MessageType       type
+       required uint32            a
 }
\ No newline at end of file

Index: CertiNetworkMessage.msg
===================================================================
RCS file: CertiNetworkMessage.msg
diff -N CertiNetworkMessage.msg
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ CertiNetworkMessage.msg     14 Jul 2009 12:40:49 -0000      1.1
@@ -0,0 +1,108 @@
+// CERTI messages description
+
+// The messages related classes will be placed in the certi package
+package certi
+
+// Network message is the base class
+// for message exchanged between RTIA and RTIG
+// AKA CERTI Network Message
+native_message NetworkMessage
+
+native_message BasicMessage
+
+native_message Message
+
+enum Message_T {
+               NOT_USED = 0, // Not used.
+               CLOSE_CONNEXION,
+               MESSAGE_NULL,
+               CREATE_FEDERATION_EXECUTION,
+               DESTROY_FEDERATION_EXECUTION,
+               JOIN_FEDERATION_EXECUTION,
+               RESIGN_FEDERATION_EXECUTION,
+               SET_TIME_REGULATING,
+               SET_TIME_CONSTRAINED,
+               TIME_REGULATION_ENABLED, // RTIG to RTIA
+               TIME_CONSTRAINED_ENABLED, // RTIG to RTIA
+               REGISTER_FEDERATION_SYNCHRONIZATION_POINT,
+               SYNCHRONIZATION_POINT_REGISTRATION_SUCCEEDED, // RTIG to RTIA
+               ANNOUNCE_SYNCHRONIZATION_POINT, // RTIG to RTIA
+               SYNCHRONIZATION_POINT_ACHIEVED,
+               FEDERATION_SYNCHRONIZED, // RTIG to RTIA
+               REQUEST_FEDERATION_SAVE,
+               FEDERATE_SAVE_BEGUN,
+               FEDERATE_SAVE_COMPLETE,
+               FEDERATE_SAVE_NOT_COMPLETE,
+               INITIATE_FEDERATE_SAVE, // RTIG to RTIA
+               FEDERATION_SAVED, // RTIG to RTIA
+               FEDERATION_NOT_SAVED, // RTIG to RTIA
+               REQUEST_FEDERATION_RESTORE,
+               FEDERATE_RESTORE_COMPLETE,
+               FEDERATE_RESTORE_NOT_COMPLETE,
+               REQUEST_FEDERATION_RESTORE_SUCCEEDED, // RTIG to RTIA
+               REQUEST_FEDERATION_RESTORE_FAILED, // RTIG to RTIA
+               FEDERATION_RESTORE_BEGUN, // RTIG to RTIA
+               INITIATE_FEDERATE_RESTORE, // RTIG to RTIA
+               FEDERATION_RESTORED, // RTIG to RTIA
+               FEDERATION_NOT_RESTORED, // RTIG to RTIA
+               PUBLISH_OBJECT_CLASS,
+               UNPUBLISH_OBJECT_CLASS,
+               PUBLISH_INTERACTION_CLASS,
+               UNPUBLISH_INTERACTION_CLASS,
+               SUBSCRIBE_OBJECT_CLASS,
+               UNSUBSCRIBE_OBJECT_CLASS,
+               SUBSCRIBE_INTERACTION_CLASS,
+               UNSUBSCRIBE_INTERACTION_CLASS,
+               TURN_INTERACTIONS_ON, // only RTIG->RTIA
+               TURN_INTERACTIONS_OFF, // only RTIG->RTIA
+               REGISTER_OBJECT,
+               DISCOVER_OBJECT, // only RTIG->RTIA
+               UPDATE_ATTRIBUTE_VALUES,
+               REFLECT_ATTRIBUTE_VALUES, // only RTIG->RTIA
+               SEND_INTERACTION,
+               RECEIVE_INTERACTION, // only RTIG->RTIA
+               DELETE_OBJECT,
+               REMOVE_OBJECT, // only RTIG->RTIA
+               CHANGE_ATTRIBUTE_TRANSPORT_TYPE,
+               CHANGE_ATTRIBUTE_ORDER_TYPE,
+               CHANGE_INTERACTION_TRANSPORT_TYPE,
+               CHANGE_INTERACTION_ORDER_TYPE,
+               REQUEST_CLASS_ATTRIBUTE_VALUE_UPDATE,
+               REQUEST_OBJECT_ATTRIBUTE_VALUE_UPDATE,
+               IS_ATTRIBUTE_OWNED_BY_FEDERATE,
+               QUERY_ATTRIBUTE_OWNERSHIP,
+               ATTRIBUTE_IS_NOT_OWNED,
+               INFORM_ATTRIBUTE_OWNERSHIP,
+               NEGOTIATED_ATTRIBUTE_OWNERSHIP_DIVESTITURE,
+               ATTRIBUTE_OWNERSHIP_ACQUISITION_NOTIFICATION,
+               ATTRIBUTE_OWNERSHIP_DIVESTITURE_NOTIFICATION,
+               REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION,
+               ATTRIBUTE_OWNERSHIP_UNAVAILABLE,
+               ATTRIBUTE_OWNERSHIP_ACQUISITION_IF_AVAILABLE,
+               UNCONDITIONAL_ATTRIBUTE_OWNERSHIP_DIVESTITURE,
+               ATTRIBUTE_OWNERSHIP_ACQUISITION,
+               REQUEST_ATTRIBUTE_OWNERSHIP_RELEASE,
+               CANCEL_NEGOTIATED_ATTRIBUTE_OWNERSHIP_DIVESTITURE,
+               ATTRIBUTE_OWNERSHIP_RELEASE_RESPONSE,
+               CANCEL_ATTRIBUTE_OWNERSHIP_ACQUISITION,
+               CONFIRM_ATTRIBUTE_OWNERSHIP_ACQUISITION_CANCELLATION,
+               DDM_CREATE_REGION,
+               DDM_MODIFY_REGION,
+               DDM_DELETE_REGION,
+               DDM_ASSOCIATE_REGION,
+               DDM_REGISTER_OBJECT,
+               DDM_UNASSOCIATE_REGION,
+               DDM_SUBSCRIBE_ATTRIBUTES,
+               DDM_UNSUBSCRIBE_ATTRIBUTES,
+               DDM_SUBSCRIBE_INTERACTION,
+               DDM_UNSUBSCRIBE_INTERACTION,
+               PROVIDE_ATTRIBUTE_VALUE_UPDATE,
+               GET_FED_FILE,
+               SET_CLASS_RELEVANCE_ADVISORY_SWITCH,
+               SET_INTERACTION_RELEVANCE_ADVISORY_SWITCH,
+               SET_ATTRIBUTE_RELEVANCE_ADVISORY_SWITCH,
+               SET_ATTRIBUTE_SCOPE_ADVISORY_SWITCH,
+               START_REGISTRATION_FOR_OBJECT_CLASS,
+               STOP_REGISTRATION_FOR_OBJECT_CLASS,
+               LAST            
+}
\ No newline at end of file




reply via email to

[Prev in Thread] Current Thread [Next in Thread]