Пример #1
0
 def _add_class(self, the_type):
     logger.info(' Parser    : Adding class %s', the_type.name)
     new_class = find_or_add_class(the_type.name)
     new_class.in_file = self._current_file
     if new_class not in self._current_file.members:
         self._current_file.members.append(new_class)
     new_class.setup_from(the_type)
Пример #2
0
 def _add_class(self, the_type):
     logger.info(' Parser    : Adding class %s', the_type.name)
     new_class = find_or_add_class(the_type.name)
     new_class.in_file = self._current_file
     if new_class not in self._current_file.members:
         self._current_file.members.append(new_class)
     new_class.setup_from(the_type)
Пример #3
0
 def process_variable_decl(self, block, token):
     '''
     '''
     
     while True:
         names = [self._match_token('id')[1]] #the name of the var
         
         while self._match_lookahead('symbol', ',', True): #separated by ,'s
             names.append(self._match_token('id')[1]) #add next name.
         
         self._match_token('symbol',':') # ... : type
         the_type = self._read_type_usage()
         self._match_token('symbol', ';')
         
         #apply type to all names, and add to block as field
         for name in names:
             field = SGField(name)
             self._apply_attributes_to(field)
             field.is_static = True #these are globals
             field.data_type = the_type
             
             if not field.is_ignored:
                 block.add_member(field)
             else:
                 logger.info('Parser    : Ignoring field %s', name)
         
         #read the next batch of comments
         self.process_meta_comments()
         
         #variable list is ended by ...
         tok = self._lookahead(1)[0]
         if tok[1].lower() in ['function', 'procedure', 'type', 'var', 'const', 'implementation']:
             break
Пример #4
0
    def process_block_types(self, block, token):
        '''Reads the types within a type declaration'''
        logger.info(' Parser    : Processing types')
        logger.info('-' * 70)

        self.process_meta_comments()

        #following type... in pascal
        while True:
            type_name = self._match_token('id')[1]  #read the types name
            self._match_token('operator', '=')  #read the =

            the_type = find_or_add_type(type_name)
            the_type.file_line_details = self._tokeniser.line_details()
            the_type.meta_comment_line_details = self._tokeniser.meta_comment_line_details(
            )

            self._parse_type_declaration(the_type)

            if 'type' or 'class' or 'struct' in the_type.keys():
                self._add_class(the_type)

            self.process_meta_comments()

            tok1, tok2 = self._lookahead(2)
            #looking for... type_name =
            if tok2[0] != 'operator' or tok2[1] != '=' or tok1[0] != 'id':
                logger.info('-' * 70)
                logger.debug('Parser    : At end of block types')
                break
Пример #5
0
 def _parse_type_declaration(self, the_type):
     '''
     Parse a type from the next token, add details to the_type.
     this is called for each type declaration... type_name = BLAH
     Need to process BLAH and add details to the_type
     '''
     #check what kind of type it is...
     if self._match_lookahead('symbol', '(', True):
         values = []
         while not self._match_lookahead('symbol',')'):
             temp = self._match_token('id')[1]
             if self._match_lookahead('operator', '=', True) or self._match_lookahead('operator', ':=', True): #assigned value
                 values.append('%s = %s' % (temp, self._match_token('number')[1]))
             else:
                 values.append(temp)
             self._match_lookahead('symbol', ',', True) #consume commas
         self._match_token('symbol',')') #read close bracket
         the_type.values = tuple(values)
     elif (self._match_lookahead('id', 'packed', True) and self._match_lookahead('id', 'record', True)) or self._match_lookahead('id', 'record', True):
         #packed record field: Type end;
         while not self._match_lookahead('id', 'end', True):
             #read field
             variables = self._read_variable_list()
             self._match_token('symbol', ';')
             for name, data_type in variables:
                 field = SGField(name)
                 field.data_type = data_type
                 the_type.fields.append(field)
     elif self._match_lookahead('id', 'array') or self._match_lookahead('symbol', '^'):
         #is pointer or array
         the_type.clone(self._read_type_usage())
     elif self._match_lookahead('id', 'procedure', True):
         #procedure type: read ( params );
         self._match_token('symbol', '(')
         m = SGMethod(the_type.name)
         m.in_file = self._current_file
         self._read_params(m)
         the_type.is_procedure = True
         the_type.method = m
         if self._lookahead(2)[1][1] == 'cdecl':
             self._match_token('symbol', ';')
             self._match_token('id', 'cdecl')
     elif self._match_lookahead('id'):
         other_id = self._match_token('id')[1]
         other_type = find_or_add_type(other_id)
         the_type.related_type = other_type
     else:
         tok = self._next_token()
         logger.error('Parser Error %s: unknown type %s(%s)', 
             self._tokeniser.line_details(), tok[0], tok[1])
         assert False
             
     if the_type.related_type != None:
         logger.info(' Parser    : Setup type %s = %s', the_type, the_type.related_type)
     elif the_type.is_enum:
         logger.info(' Parser    : Setup type %s = %s', the_type, the_type.values)
     else:
         logger.info(' Parser    : Setup type %s = %s', the_type, the_type.fields)
     self._apply_attributes_to(the_type)
     self._match_token('symbol', ';')
Пример #6
0
 def process_block_types(self, block, token):
     '''Reads the types within a type declaration'''
     logger.info(' Parser    : Processing types')
     logger.info('-' * 70)
     
     self.process_meta_comments()
     
     #following type... in pascal
     while True:
         type_name = self._match_token('id')[1] #read the types name
         self._match_token('operator','=') #read the =
         
         the_type = find_or_add_type(type_name)
         the_type.file_line_details = self._tokeniser.line_details()
         the_type.meta_comment_line_details = self._tokeniser.meta_comment_line_details()
         
         self._parse_type_declaration(the_type)
         
         if 'type' or 'class' or 'struct'in the_type.keys():
             self._add_class(the_type)
         
         self.process_meta_comments()
         
         tok1, tok2 = self._lookahead(2)
         #looking for... type_name = 
         if tok2[0] != 'operator' or tok2[1] != '=' or tok1[0] != 'id':
             logger.info('-' * 70)
             logger.debug('Parser    : At end of block types')
             break
Пример #7
0
 def complete_method_processing(self):
     '''
     This is called on methods that are read by the parser from the 
     Pascal file.
     
     Set up the call from the library to this method if marked.
     Check the call's validity
     
     Steps:
         1: Get other methods related to this one
         2: Set parameters on library method (if called)
     '''
     logger.info(' Method    : Completing processing of %s', self)
     
     #This is 'the' method it has its params
     self.params = self.params
     
     #Find the length method if it exists
     if self.length_call != None:
         self.length_call = self.in_class.find_method(self.length_call)
     
     #Convert args to appropriate values...
     self._process_args()
     self._check_args_match_params()
     
     #Get other methods
     lib_method = self.method_called
     class_method = self.class_method
     
     #check rules
     if lib_method == None and not self.is_operator:
         logger.error('Method    : Found method %s without lib', self)
         assert False
         
     if lib_method != None:
         #set up library method
         self.setup_lib_method(lib_method)
     
         logger.info(' Method    : %s calls %s', self.name, lib_method.name)
         lib_method.called_by.append(self)
     
     #set up class method
     if class_method != None:
         logger.debug(' Method    : %s is also %s', self.name, class_method)
         self._setup_class_method(class_method)
         logger.info(' Method    : %s calls %s', class_method.name, lib_method.name)
         lib_method.called_by.append(class_method) #library is also called by class
     elif self.is_operator:
         assert self.other_class != None
         self.name = 'operator ' + self.name
         self.other_method = self.in_class.find_method(self['calls'].other)
         self.doc = self.other_method.doc
         self.method_called = self.other_method.method_called
         self.method_called.called_by.append(self) #library is also called by operator
         self.is_static = True
         
         self.in_class.operators[self.signature] = None
         self.in_class = self.other_class
         self.in_class.add_member(self)
         self.args = list(self.params) # operators must match directly
Пример #8
0
    def process_variable_decl(self, block, token):
        '''
        '''

        while True:
            names = [self._match_token('id')[1]]  #the name of the var

            while self._match_lookahead('symbol', ',',
                                        True):  #separated by ,'s
                names.append(self._match_token('id')[1])  #add next name.

            self._match_token('symbol', ':')  # ... : type
            the_type = self._read_type_usage()
            self._match_token('symbol', ';')

            #apply type to all names, and add to block as field
            for name in names:
                field = SGField(name)
                self._apply_attributes_to(field)
                field.is_static = True  #these are globals
                field.data_type = the_type

                if not field.is_ignored:
                    block.add_member(field)
                else:
                    logger.info('Parser    : Ignoring field %s', name)

            #read the next batch of comments
            self.process_meta_comments()

            #variable list is ended by ...
            tok = self._lookahead(1)[0]
            if tok[1].lower() in [
                    'function', 'procedure', 'type', 'var', 'const',
                    'implementation'
            ]:
                break
Пример #9
0
    def _parse_type_declaration(self, the_type):
        '''
        Parse a type from the next token, add details to the_type.
        this is called for each type declaration... type_name = BLAH
        Need to process BLAH and add details to the_type
        '''
        #check what kind of type it is...
        if self._match_lookahead('symbol', '(', True):
            values = []
            while not self._match_lookahead('symbol', ')'):
                temp = self._match_token('id')[1]
                if self._match_lookahead(
                        'operator', '=', True) or self._match_lookahead(
                            'operator', ':=', True):  #assigned value
                    values.append('%s = %s' %
                                  (temp, self._match_token('number')[1]))
                else:
                    values.append(temp)
                self._match_lookahead('symbol', ',', True)  #consume commas
            self._match_token('symbol', ')')  #read close bracket
            the_type.values = tuple(values)
        elif (self._match_lookahead('id', 'packed', True)
              and self._match_lookahead('id', 'record',
                                        True)) or self._match_lookahead(
                                            'id', 'record', True):
            #packed record field: Type end;
            while not self._match_lookahead('id', 'end', True):
                #read field
                variables = self._read_variable_list()
                self._match_token('symbol', ';')
                for name, data_type in variables:
                    field = SGField(name)
                    field.data_type = data_type
                    the_type.fields.append(field)
        elif self._match_lookahead('id', 'array') or self._match_lookahead(
                'symbol', '^'):
            #is pointer or array
            the_type.clone(self._read_type_usage())
        elif self._match_lookahead('id', 'procedure', True):
            #procedure type: read ( params );
            self._match_token('symbol', '(')
            m = SGMethod(the_type.name)
            m.in_file = self._current_file
            self._read_params(m)
            the_type.is_procedure = True
            the_type.method = m
            if self._lookahead(2)[1][1] == 'cdecl':
                self._match_token('symbol', ';')
                self._match_token('id', 'cdecl')
        elif self._match_lookahead('id'):
            other_id = self._match_token('id')[1]
            other_type = find_or_add_type(other_id)
            the_type.related_type = other_type
        else:
            tok = self._next_token()
            logger.error('Parser Error %s: unknown type %s(%s)',
                         self._tokeniser.line_details(), tok[0], tok[1])
            assert False

        if the_type.related_type != None:
            logger.info(' Parser    : Setup type %s = %s', the_type,
                        the_type.related_type)
        elif the_type.is_enum:
            logger.info(' Parser    : Setup type %s = %s', the_type,
                        the_type.values)
        else:
            logger.info(' Parser    : Setup type %s = %s', the_type,
                        the_type.fields)
        self._apply_attributes_to(the_type)
        self._match_token('symbol', ';')
Пример #10
0
    def process_unit(self, token):
        tok = self._match_token('id')
        unit_name = tok[1]
        name = self._get_attribute('module', unit_name)
        self._add_attribute('name', name)

        logger.info('-' * 70)
        logger.info(' Parser    : Processing unit: %s', unit_name)
        logger.info('-' * 70)

        #self._check_attributes(['class','static'],'unit ' + unit_name)
        self._check_meta_comments(1, 'unit ' + unit_name + '\'s declaration')

        #Create the unit
        unit = self._create_model_element(SGCodeModule)
        unit.module_kind = 'module'
        unit.is_static = True
        logger.info(' Parser    : Creating class %s', unit.name)

        self._apply_attributes_to(unit)

        #unit name;
        tok = self._match_token('symbol', ';')

        #interface - ignore comments
        #self._skip_comments('unit ' + unit_name + '\'s interface')
        self._match_token('id', 'interface')

        #check 'uses'
        tok = self._lookahead()[0]
        if tok[0] == 'id' and tok[1] == 'uses':
            tok = self._next_token()
            self.process_uses_clause(tok)
            logger.info('-' * 70)

        while True:
            logger.debug(
                'Parser    : At start of loop to process elements in unit')
            #read comments if they follow this position, otherwise leave
            #  attributes as they are
            if self._match_lookahead('meta comment'):
                self.process_meta_comments()

            #Process the body of the unit's interface
            tok = self._lookahead()[0]  #check the next token

            if tok[0] == 'id' and tok[1] == 'implementation':
                logger.info(' Parser    : Found end of unit\'s interface')
                logger.info('-' * 70)
                break

            #interface contains types, functions, procedures, var, const, operator
            tok = self._match_one_token([['id', 'type'], ['id', 'function'],
                                         ['id', 'procedure'], ['id', 'const'],
                                         ['id', 'operator'], ['id', 'var']])
            self._block_header_processors[tok[1]](unit, tok)

        logger.info(
            ' Parser    : Finished processing unit. Resulting class is:\n%s',
            str(unit))
Пример #11
0
 def process_unit(self, token):
     tok = self._match_token('id')
     unit_name = tok[1]
     name = self._get_attribute('module', unit_name)
     self._add_attribute('name',name)
     
     logger.info('-' * 70)
     logger.info(' Parser    : Processing unit: %s', unit_name)
     logger.info('-' * 70)
     
     #self._check_attributes(['class','static'],'unit ' + unit_name)
     self._check_meta_comments(1, 'unit ' + unit_name + '\'s declaration')
             
     #Create the unit
     unit = self._create_model_element(SGCodeModule)
     unit.module_kind = 'module'
     unit.is_static = True
     logger.info(' Parser    : Creating class %s', unit.name)
     
     self._apply_attributes_to(unit)
     
     #unit name;
     tok = self._match_token('symbol', ';')
     
     #interface - ignore comments
     #self._skip_comments('unit ' + unit_name + '\'s interface')
     self._match_token('id', 'interface')
     
     #check 'uses'
     tok = self._lookahead()[0]
     if tok[0] == 'id' and tok[1] == 'uses':
         tok = self._next_token()
         self.process_uses_clause(tok)
         logger.info('-' * 70)
     
     
     while True:
         logger.debug('Parser    : At start of loop to process elements in unit')
         #read comments if they follow this position, otherwise leave 
         #  attributes as they are
         if self._match_lookahead('meta comment'): self.process_meta_comments()
         
         #Process the body of the unit's interface
         tok = self._lookahead()[0] #check the next token
         
         if tok[0] == 'id' and tok[1] == 'implementation':
             logger.info(' Parser    : Found end of unit\'s interface')
             logger.info('-' * 70)
             break
         
         #interface contains types, functions, procedures, var, const, operator
         tok = self._match_one_token([['id','type'],
             ['id','function'],
             ['id','procedure'],
             ['id','const'],
             ['id','operator'],
             ['id','var']])
         self._block_header_processors[tok[1]](unit, tok);
     
     logger.info(' Parser    : Finished processing unit. Resulting class is:\n%s', str(unit))
Пример #12
0
    def complete_method_processing(self):
        '''
        This is called on methods that are read by the parser from the 
        Pascal file.
        
        Set up the call from the library to this method if marked.
        Check the call's validity
        
        Steps:
            1: Get other methods related to this one
            2: Set parameters on library method (if called)
        '''
        logger.info(' Method    : Completing processing of %s', self)

        #This is 'the' method it has its params
        self.params = self.params

        #Find the length method if it exists
        if self.length_call != None:
            self.length_call = self.in_class.find_method(self.length_call)

        #Convert args to appropriate values...
        self._process_args()
        self._check_args_match_params()

        #Get other methods
        lib_method = self.method_called
        class_method = self.class_method

        #check rules
        if lib_method == None and not self.is_operator:
            logger.error('Method    : Found method %s without lib', self)
            assert False

        if lib_method != None:
            #set up library method
            self.setup_lib_method(lib_method)

            logger.info(' Method    : %s calls %s', self.name, lib_method.name)
            lib_method.called_by.append(self)

        #set up class method
        if class_method != None:
            logger.debug(' Method    : %s is also %s', self.name, class_method)
            self._setup_class_method(class_method)
            logger.info(' Method    : %s calls %s', class_method.name,
                        lib_method.name)
            lib_method.called_by.append(
                class_method)  #library is also called by class
        elif self.is_operator:
            assert self.other_class != None
            self.name = 'operator ' + self.name
            self.other_method = self.in_class.find_method(self['calls'].other)
            self.doc = self.other_method.doc
            self.method_called = self.other_method.method_called
            self.method_called.called_by.append(
                self)  #library is also called by operator
            self.is_static = True

            self.in_class.operators[self.signature] = None
            self.in_class = self.other_class
            self.in_class.add_member(self)
            self.args = list(self.params)  # operators must match directly
Пример #13
0
def post_parse_process(the_file):
    '''Create temporary variables for out/var string parameters, and string 
    return types'''
    logger.info('Post parsing library')

    the_file.members[0].visit_methods(method_process_visitor, None)
Пример #14
0
def visit_all_units(file_visitor):
    logger.info('Processing files')
    files = [unit[0] for unit in all_units] + ['SGSDK']
    for each_file in files:
        logger.debug('Visiting file %s', each_file)
        find_or_add_file(each_file).visit(file_visitor, None)
Пример #15
0
def post_parse_process(the_file):
    '''Create temporary variables for out/var string parameters, and string 
    return types'''
    logger.info('Post parsing library')
    
    the_file.members[0].visit_methods(method_process_visitor, None)
Пример #16
0
def visit_all_units(file_visitor):    
    logger.info('Processing files')
    files = [ unit[0] for unit in all_units ] + ['SGSDK']
    for each_file in files:
        logger.debug('Visiting file %s', each_file)
        find_or_add_file(each_file).visit(file_visitor, None)