Changeset 983


Ignore:
Timestamp:
Jun 28, 2012 4:34:54 PM (11 years ago)
Author:
jemian
Message:

refs #8, now parses most macro definitions (just the initial declaration, not the muiltiline content, for now)

Location:
specdomain/trunk/src/specdomain
Files:
2 added
4 edited
3 copied

Legend:

Unmodified
Added
Removed
  • specdomain/trunk/src/specdomain/macros/test-battery.mac

    r966 r983  
    122122
    123123    # EPICS PV of the binary output which controls the shutter
    124     #
     124   
    125125    global SHUTTER_CONTROL_PV
    126126           SHUTTER_CONTROL_PV = "X04SA-ES3-SC:FPS"
     
    134134    # EPICS PV of the binary input which monitors the state of the shutter
    135135    # if SHUTTER_MONITOR_PV = "", no monitoring is performed
    136     #
     136   
    137137    global SHUTTER_MONITOR_PV
    138138           SHUTTER_MONITOR_PV = ""
  • specdomain/trunk/src/specdomain/sphinxcontrib/specmacrofileparser.py

    r982 r983  
    3030non_greedy_filler           = match_all + r'?'
    3131non_greedy_whitespace       = r'\s*?'
    32 double_quote_string_match   = r'("' + non_greedy_filler + r'")'
    33 prog_name_match             = r'([a-z_]\w*)'
    34 word_match                  = r'((?:[a-z_]\w*))'
    35 cdef_match                  = r'(cdef)'
     32#double_quote_string_match   = r'("' + non_greedy_filler + r'")'
     33#prog_name_match             = r'([a-z_]\w*)'
     34#word_match                  = r'((?:[a-z_]\w*))'
     35#cdef_match                  = r'(cdef)'
    3636extended_comment_marker     = r'\"{3}'
    3737extended_comment_match      = r'(' + extended_comment_marker + r')'
     
    113113
    114114            if self.state == 'global':
    115                 if self._is_lgc_variable(line, line_number):
    116                     continue
    117                 if self._is_one_line_extended_comment(line, line_number):
    118                     continue
    119                 if self._is_multiline_start_extended_comment(line, line_number):
    120                     continue
     115                for thing in (self._is_def_macro,
     116                              self._is_cdef_macro,
     117                              self._is_function_macro,
     118                              self._is_lgc_variable,
     119                              self._is_one_line_extended_comment,
     120                              self._is_multiline_start_extended_comment
     121                              ):
     122                    if thing(line, line_number):
     123                        break
    121124            elif self.state == 'extended comment':
    122125                if not self._is_multiline_end_extended_comment(line, line_number):
     
    134137            fmt = "encountered EOF while parsing %s, line %d, in state %s, stack=%s"
    135138            msg = fmt % (self.filename, line_number, self.state, self.state_stack)
    136             raise RuntimeWarning, msg
     139            #raise RuntimeWarning, msg
     140            print msg
    137141
    138142        self.state = 'parsed'
     
    159163        m['objtype'] = objtype
    160164        m['start_line'] = m['end_line'] = line_number
    161         del m['start'], m['end'], m['line']
     165        del m['start'], m['end']
    162166        if objtype == 'constant':
     167            if not len(args.split()) == 2:
     168                print "line_number, args: ", line_number, args
    163169            var, _ = args.split()
    164170            m['text'] = var.rstrip(',')
     
    187193        if m is None:
    188194            return False
    189         del m['start'], m['end'], m['line']
     195        line = m['line']
     196        del m['start'], m['end']
    190197        m['objtype'] = 'extended comment'
    191198        m['start_line'] = m['end_line'] = line_number
     
    203210        if m is None:
    204211            return False
     212        line = m['line']
    205213        text = m['line'][m['end']:]
    206         del m['start'], m['end'], m['line']
     214        del m['start'], m['end']
    207215        m['objtype'] = 'extended comment'
    208216        m['start_line'] = line_number
     
    232240        del self.ec
    233241        return True
    234    
     242
     243    spec_macro_declaration_match_re = re.compile(
     244                              r'^'                      # line start
     245                            + r'\s*?'                   # optional blank space
     246                            + r'(r?def)'                # 0: def_type (rdef | def)
     247                            + r'\s*?'                   # optional blank space
     248                            + r'([a-zA-Z_][\w_]*)'      # 1: macro_name
     249                            + r'(.*?)'                  # 2: optional arguments
     250                            + r'(#.*?)?'                # 3: optional comment
     251                            + r'$'                      # line end
     252                        )
     253
     254    def _is_def_macro(self, line, line_number):
     255        m = self._search(self.spec_macro_declaration_match_re, line)
     256        if m is None:
     257            return False
     258        self.ec = dict(m)
     259        del self.ec['text']
     260        m = self.spec_macro_declaration_match_re.match(line)
     261        macrotype, name, args, comment = m.groups()
     262        self.ec['start_line'] = line_number
     263        self.ec['end_line'] = line_number       # TODO: consider the multiline definition later
     264        self.ec['objtype'] = macrotype
     265        self.ec['name'] = name
     266        self.ec['args'] = args
     267        self.ec['comment'] = comment
     268        self.findings.append(dict(self.ec))
     269        del self.ec
     270        return True
     271
     272    spec_cdef_declaration_match_re = re.compile(
     273                              r'^'                      # line start
     274                            + r'.*?'                    # optional any kind of preceding stuff, was \s*? (optional blank space)
     275                            + r'(cdef)'                 # 0: cdef
     276                            + r'\('                     # opening parenthesis
     277                            + r'(.*?)'                  # 1: args (anything between the parentheses)
     278                            + r'\)'                     # closing parenthesis
     279                            + r'.*?'                    # optional any kind of stuff
     280                            + r'(#.*?)?'                # 2: optional comment with content
     281                            + r'$'                      # line end
     282                        )
     283
     284    def _is_cdef_macro(self, line, line_number):
     285        m = self._search(self.spec_cdef_declaration_match_re, line)
     286        if m is None:
     287            return False
     288        self.ec = dict(m)
     289        del self.ec['text']
     290        m = self.spec_cdef_declaration_match_re.match(line)
     291        macrotype, args, comment = m.groups()
     292        name = args.split(',')[0].strip('"')
     293        self.ec['start_line'] = line_number
     294        self.ec['end_line'] = line_number       # TODO: consider the multiline definition later
     295        self.ec['objtype'] = macrotype
     296        self.ec['name'] = name
     297        self.ec['args'] = args
     298        self.ec['comment'] = comment
     299        self.findings.append(dict(self.ec))
     300        del self.ec
     301        return True
     302
     303    spec_function_declaration_match_re = re.compile(
     304                              r'^'                      # line start
     305                            + r'\s*?'                   # optional blank space
     306                            + r'(r?def)'                # 0: def_type (rdef | def)
     307                            + r'\s*?'                   # optional blank space
     308                            + r'([a-zA-Z_][\w_]*)'      # 1: function_name
     309                            + r'\('                     # opening parenthesis
     310                            + r'(.*?)'                  # 2: args (anything between the parentheses)
     311                            + r'\)'                     # closing parenthesis
     312                            + r'\s*?'                   # optional blank space
     313                            + r'\''                     # open macro content
     314                            + r'(.*?)'                  # 3: content, optional
     315                            + r'(#.*?)?'                # 4: optional comment
     316                            + r'$'                      # line end
     317                        )
     318
     319    def _is_function_macro(self, line, line_number):
     320        m = self._search(self.spec_function_declaration_match_re, line)
     321        if m is None:
     322            return False
     323        self.ec = dict(m)
     324        del self.ec['text']
     325        m = self.spec_function_declaration_match_re.match(line)
     326        macrotype, name, args, content, comment = m.groups()
     327        self.ec['start_line'] = line_number
     328        self.ec['end_line'] = line_number       # TODO: consider the multiline definition later
     329        self.ec['objtype'] = 'function ' + macrotype
     330        self.ec['name'] = name
     331        self.ec['args'] = args
     332        self.ec['content'] = content
     333        self.ec['comment'] = comment
     334        self.findings.append(dict(self.ec))
     335        del self.ec
     336        return True
     337
    235338    def _search(self, regexp, line):
    236339        '''regular expression search of line, returns a match as a dictionary or None'''
     
    268371           
    269372        s = []
    270         declarations = []
     373        declarations = []       # variables and constants
     374        macros = []             # def, cdef, and rdef macros
     375        functions = []          # def and rdef function macros
    271376        for r in self.findings:
    272377            if r['objtype'] == 'extended comment':
     
    278383                s.append( '' )
    279384                s.append(r['text'])
     385            elif r['objtype'] in ('def', 'rdef', 'cdef'):
     386                macros.append(r)
     387            elif r['objtype'] in ('function def', 'function rdef',):
     388                functions.append(r)
    280389            elif r['objtype'] in ('local', 'global', 'constant'):
    281                 declarations.append(r)      # remember, show this later
    282             # TODO: other objtypes
    283         if len(declarations) > 0:
    284             col_keys = ('text', 'objtype', 'start_line', 'end_line', )
    285             widths = dict([( key, len(str(key)) ) for key in col_keys])
    286             for d in declarations:
    287                 widths = dict([( key, max(w, len(str(d[key])))) for key, w in widths.items()])
    288             separator = " ".join( ["="*widths[key] for key in col_keys] )
    289             fmt = " ".join( ["%%-%ds"%widths[key] for key in col_keys] )
    290             s.append( '' )
    291 #            s.append( '.. rubric:: Variable Declarations:' )
    292             s.append( 'Variable Declarations' )
    293             s.append( '=====================' )
    294             s.append( '' )
    295             s.append( separator )
    296             s.append( fmt % tuple([str(key) for key in col_keys]) )
    297             s.append( separator )
    298             for d in declarations:
    299                 s.append( fmt % tuple([str(d[key]) for key in col_keys]) )
    300             s.append( separator )
     390                declarations.append(r)
     391
     392        s += self._report_table('Variable Declarations', declarations)
     393        s += self._report_table('Macro Declarations', macros)
     394        s += self._report_table('Function Macro Declarations', functions)
     395
    301396        return '\n'.join(s)
     397   
     398    def _report_table(self, title, itemlist):
     399        """ return the itemlist as a reST table """
     400        s = []
     401        if len(itemlist) == 0:
     402            return s
     403        col_keys = ('start_line', 'line',)  # TODO: temporary
     404        widths = dict([( key, len(str(key)) ) for key in col_keys])
     405        for d in itemlist:
     406            widths = dict([( key, max(w, len(str(d[key])))) for key, w in widths.items()])
     407        separator = " ".join( ["="*widths[key] for key in col_keys] )
     408        fmt = " ".join( ["%%-%ds"%widths[key] for key in col_keys] )
     409        s.append( '' )
     410        s.append( title )
     411        s.append( '='*len(title) )
     412        s.append( '' )
     413        s.append( separator )
     414        s.append( fmt % tuple([str(key.strip()) for key in col_keys]) )
     415        s.append( separator )
     416        last_line = -1
     417        for d in itemlist:
     418            if d['start_line'] != last_line:
     419                s.append( fmt % tuple([str(d[key]).strip() for key in col_keys]) )
     420            last_line = d['start_line']
     421        s.append( separator )
     422        return s
     423
     424
     425TEST_DIR = os.path.join('..', 'macros')
    302426
    303427
    304428if __name__ == '__main__':
    305     filelist = [
    306         '../macros/test-battery.mac',
    307         '../macros/cdef-examples.mac',
    308         '../macros/shutter.mac',
    309     ]
     429    filelist = [f for f in sorted(os.listdir(TEST_DIR)) if f.endswith('.mac')]
    310430    for item in filelist:
    311         p = SpecMacrofileParser(item)
    312         #print p
     431        filename = os.path.join(TEST_DIR, item)
     432        print filename
     433        p = SpecMacrofileParser(filename)
    313434        print p.ReST()
  • specdomain/trunk/src/specdomain/test/test_doc.rst

    r963 r983  
    141141.. toctree::
    142142   :maxdepth: 2
     143   :glob:
    143144
    144    cdef-examples.mac
    145    test-battery.mac
    146    shutter.mac
     145   *.mac
    147146   python-example-source
  • specdomain/trunk/src/specdomain/test/tester4.py

    r982 r983  
    3333                            + r'(.*?)'                  # 1: args (anything between the parentheses)
    3434                            + r'\)'                     # closing parenthesis
    35                             + r'.*?'                    # optional blank space
    36                             + r'(#.*?)?'                # 2: optional comment
     35                            + r'.*?'                    # optional any kind of stuff
     36                            + r'(#.*?)?'                # 2: optional comment with content
    3737                            + r'$'                      # line end
    3838                        )
     
    5050                            + r'\''                     # open macro content
    5151                            + r'(.*?)'                  # 3: args (anything between the parentheses)
    52                             + r'(#.*?)?'                # 4: more_content
     52                            + r'(#.*?)?'                # 4: optional comment
    5353                            + r'$'                      # line end
    5454                        )
Note: See TracChangeset for help on using the changeset viewer.