File indexing completed on 2024-12-08 10:18:18
0001 # -*- coding: utf-8 -*- 0002 # Copyright 2007-8 Jim Bublitz <jbublitz@nwinternet.com> 0003 # Copyright 2009 Simon Edwards <simon@simonzone.com> 0004 # 0005 # This program is free software; you can redistribute it and/or modify 0006 # it under the terms of the GNU General Public License as published by 0007 # the Free Software Foundation; either version 2 of the License, or 0008 # (at your option) any later version. 0009 # 0010 # This program is distributed in the hope that it will be useful, 0011 # but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 # GNU General Public License for more details. 0014 # 0015 # You should have received a copy of the GNU General Public License 0016 # along with this program; if not, write to the 0017 # Free Software Foundation, Inc., 0018 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0019 0020 import sys 0021 import re 0022 from .sealed import sealed 0023 import ply.yacc as yacc 0024 import kbindinggenerator.cpplexer as cpplexer 0025 import kbindinggenerator.pplexer as pplexer 0026 import inspect 0027 0028 def joinp(p, startindex, string=" "): 0029 tmplist = [] 0030 i = startindex 0031 while i < len(p): 0032 tmplist.append(p[i]) 0033 i += 1 0034 return string.join(tmplist) 0035 0036 class CppParser(object): 0037 """Parser for C++ header files.""" 0038 0039 @sealed 0040 def __init__(self): 0041 """Instantiate a new C++ parser.""" 0042 self._bareMacros = [] 0043 self._macros = [] 0044 self._preprocessorValues = {} 0045 self._preprocessorSubstitutionMacros = [] 0046 0047 self.lexer = cpplexer.CppLexer() 0048 self.lexer.begin('variable') 0049 self._resetState() 0050 self.tokens = cpplexer.tokens 0051 yacc.yacc(module = self, tabmodule = "cppParserTab") 0052 self._parse = yacc.parse 0053 0054 def _resetState(self): 0055 self.filename = None 0056 self._scopeStack = [] 0057 self.scope = None 0058 self.access = "public" 0059 self._accessStack = [] 0060 self.currentFunction = None 0061 self.currentClass = None 0062 self.exprElement = None 0063 self.inTypedef = False 0064 0065 self.arguments = [] 0066 self.templateParams = [] 0067 self.storage = '' 0068 self.inline = False 0069 self.template = None 0070 self.exprElements = [] 0071 self.symbolData = None 0072 self.scope = None 0073 0074 @property 0075 def bareMacros(self): 0076 """List of bare macro names. 0077 0078 A bare macro is C++ macro which takes no arguments. Any bare macros 0079 are parsed and recorded in a `ScopedMacro` object.""" 0080 return self._bareMacros 0081 @bareMacros.setter 0082 def bareMacros(self,bareMacroList): 0083 self._bareMacros = bareMacroList 0084 self.lexer.lexmodule.setBareMacros(bareMacroList) 0085 0086 @property 0087 def macros(self): 0088 """List of macro names. 0089 0090 Any macros are parsed and recorded in a `ScopedMacro` object along 0091 with their arguments.""" 0092 return self._macros 0093 @macros.setter 0094 def macros(self,macroList): 0095 self.lexer.lexmodule.setMacros(macroList) 0096 self._macros = macroList 0097 0098 @property 0099 def preprocessorValues(self): 0100 """List of symbols and values to be used by the preprocessor. 0101 0102 This is a dict mapping string values to values which can be used when 0103 evaluating preprocessor expressions.""" 0104 return self._preprocessorValues 0105 @preprocessorValues.setter 0106 def preprocessorValues(self,valueList): 0107 self._preprocessorValues = valueList 0108 0109 @property 0110 def preprocessorSubstitutionMacros(self): 0111 """Macros to be substituated by the C++ preprocessor. 0112 0113 This is a list of tuples. The first value is a string or regular 0114 expression object which is used to match macros in the text, and 0115 the second value is the substituation text.""" 0116 return self._preprocessorSubstitutionMacros 0117 @preprocessorSubstitutionMacros.setter 0118 def preprocessorSubstitutionMacros(self,macroList): 0119 self._preprocessorSubstitutionMacros = macroList 0120 0121 def parse(self, symbolData, text, filename=None, debugLevel = 0): 0122 """Parse the given C++ header text 0123 0124 Keyword arguments: 0125 symbolData -- cppsymboldata.SymbolData instance. The parsed entities are added to this instance. 0126 text -- String, the text to parse. 0127 filename -- The filename belonging to the given text. This is used for error messages and can be None. 0128 debugLevel -- Turns on debug messages from the lexer and parser. 0, the default, means no debug. 2 lists the 0129 tokens as they arrive. 0130 0131 Returns: 0132 -- Newly created `Scope` object containing the parsed data. 0133 0134 All of the top level things in the given text are parsed and placed inside the top scope inside the 0135 symbolData. 0136 0137 If a parse error is encountered, the whole program is exited. Sorry. 0138 """ 0139 self._resetState() 0140 self.filename = filename 0141 0142 self.symbolData = symbolData 0143 self.scope = self.symbolData.newScope() 0144 0145 chewedText = pplexer.preprocess(text, self._preprocessorValues, self.__compileMacros(self._preprocessorSubstitutionMacros)) 0146 0147 self.lexer.input(chewedText) 0148 self.lexer.lineno = 1 0149 self.lexer.lexpos = 0 0150 0151 result = self._parse(debug = debugLevel, lexer = self.lexer) 0152 return self.scope 0153 0154 def __compileMacros(self, macroList): 0155 # Convert the list of macros to regular expressions. Macro which are 0156 # already regexs don't need to changed. Bare string macros and their 0157 # substituation strings are treated as straight string substituations. 0158 compiledMacros = [] 0159 for item in macroList: 0160 if not isinstance(item[0],str): 0161 compiledMacros.append(item) 0162 else: 0163 compiledMacros.append( (re.compile(item[0]), re.escape(item[1])) ) 0164 return compiledMacros 0165 0166 def _pushScope(self, newScope): 0167 self._scopeStack.append(self.scope) 0168 self.scope = newScope 0169 #print("\n_pushScope") 0170 #self._dumpScopeStack() 0171 0172 def _popScope(self): 0173 #print("\n_popScope") 0174 self.scope = self._scopeStack.pop() 0175 #self._dumpScopeStack() 0176 0177 def _dumpScopeStack(self): 0178 print("Scope stack: [" + (", ".join(repr(s) for s in self._scopeStack)) + "]") 0179 for s in inspect.stack()[:4]: 0180 print(repr(s)) 0181 0182 def _pushAccess(self, newAccess): 0183 self._accessStack.append(self.access) 0184 self.access = newAccess 0185 0186 def _popAccess(self): 0187 self.access = self._accessStack.pop() 0188 0189 def object_id_list (self, id_list, obj, objType = None): 0190 idList = id_list.split (',') 0191 if self.inTypedef: 0192 self.stateInfo.currentObject ().name = idList [0] 0193 for id in idList [1:]: 0194 originalObj = self.stateInfo.popObject () 0195 if obj == 'class': 0196 newObj = self.classObject (id, objType) 0197 elif obj == 'enum': 0198 newObj = self.enumObject (id) 0199 newObj.enumerators = originalObj.enumerators 0200 else: 0201 for id in idList: 0202 self.variableObject (id, self.stateInfo.currentObject ().name) 0203 0204 def commentObject(self,value): 0205 comment = self.symbolData.Comment(self.scope, self.filename, self.lexer.lineno) 0206 comment.setValue(value) 0207 return comment 0208 0209 def classObject (self, name, type_): 0210 class_ = self.symbolData.CppClass(self.scope, name, self.filename, self.lexer.lineno) 0211 self.currentClass = class_ 0212 self._pushScope(class_) 0213 class_.setAccess(self.access) 0214 0215 def enumObject (self, name): 0216 enum = self.symbolData.Enum(None, name, self.filename, self.lexer.lineno) 0217 enum.setAccess(self.access) 0218 return enum 0219 0220 def typedefObject(self, typeName, newName): 0221 tdObj = self.symbolData.Typedef(self.scope, newName, self.filename, self.lexer.lineno) 0222 tdObj.setArgumentType(typeName) 0223 # if typeName.startswith('QFlags<'): 0224 # tdObj.template = Template('QFlags', typeName [7:-1]) 0225 # else: 0226 # tdObj.template = self.template 0227 # self.template = None 0228 # self._pushScope(tdObj) 0229 return tdObj 0230 0231 def bareMacro(self,name): 0232 macro = self.symbolData.ScopedMacro(self.scope, name, self.filename, self.lexer.lineno) 0233 return macro 0234 0235 def argument(self, argumentType, argumentName = None, argumentValue = None): 0236 self.arguments.append ((argumentType, argumentName, argumentValue, self.template, self.exprElements)) 0237 self.template = None 0238 self.exprElements = [] 0239 return self.arguments 0240 0241 def argumentList(self): 0242 instanceList = [] 0243 for argTuple in self.arguments: 0244 vtype, name, init, template, exprElements = argTuple 0245 instanceList.append(self.symbolData.Argument(vtype, name, init, template)) 0246 return instanceList 0247 0248 def variableObject(self, name, vtype, init = None): 0249 vObj = self.symbolData.Variable(self.scope, name, self.filename, self.lexer.lineno) 0250 vObj.setArgument(self.symbolData.Argument(vtype, name, init, None, self.template)) 0251 vObj.setStorage(self.storage) 0252 vObj.setAccess(self.access) 0253 0254 self.storage = None 0255 self.template = None 0256 return vObj 0257 0258 def functionObject(self, name, returns): 0259 if returns=='ctor': 0260 functionObj = self.symbolData.Constructor(self.scope, name, self.filename, self.lexer.lineno) 0261 elif returns=='dtor': 0262 functionObj = self.symbolData.Destructor(self.scope, name, self.filename, self.lexer.lineno) 0263 else: 0264 functionObj = self.symbolData.Function(self.scope, name, self.filename, self.lexer.lineno) 0265 returnArg = self.symbolData.Argument(returns) 0266 functionObj.setReturn(returnArg) 0267 functionObj.setAccess(self.access) 0268 0269 functionObj.setTemplate(self.template) 0270 self.template = None 0271 0272 self.exprElements = [] 0273 0274 functionObj.setStorage(self.storage) 0275 self.storage = None 0276 0277 #functionObj.templateParams = self.stateInfo.inTemplate 0278 #self.stateInfo.inTemplate = [] 0279 0280 self.currentFunction = functionObj 0281 0282 if self.lexer.lexstate not in ['stmt', 'operator']: 0283 self.lexer.begin ('function') 0284 return functionObj 0285 0286 precedence = (('right','UMINUS'), ) 0287 #precedence = (('left','+','-'), ('left','*','/'), ('right','UMINUS'), ) 0288 0289 # start 0290 def p_declarations (self, p): 0291 """declarations : member 0292 | member_list member""" 0293 pass 0294 0295 def p_member (self, p): 0296 """member : namespace_decl 0297 | class_decl 0298 | enum_decl 0299 | typedef_decl 0300 | typedef_enum_decl 0301 | function_decl 0302 | variable_decl 0303 | bare_macro 0304 | skip_macro 0305 | doccomment 0306 | SEMI""" 0307 self.lexer.lexstate = 'variable' 0308 self.arguments = [] 0309 self.template = None 0310 self.exprElement = None 0311 0312 def p_member2 (self, p): 0313 """member : template_decl""" 0314 self.lexer.lexstate = 'variable' 0315 self.template = p[1] 0316 self.arguments = [] 0317 self.exprElement = None 0318 0319 def p_member_list (self, p): 0320 """member_list : member 0321 | member_list member""" 0322 pass 0323 0324 def p_namespace_decl0 (self, p): 0325 'namespace_decl : namespace_name LBRACE member_list RBRACE' 0326 self._popScope() 0327 0328 def p_namespace_decl1 (self, p): 0329 'namespace_decl : namespace_name LBRACE RBRACE' 0330 self._popScope() 0331 0332 def p_namespace_decl2 (self, p): 0333 'namespace_decl : namespace LBRACE member_list RBRACE' 0334 pass 0335 0336 def p_namespace_name (self, p): 0337 'namespace_name : namespace ID' 0338 name = p[2] 0339 namespace = self.symbolData.Namespace(self.scope, name, self.filename, self.lexer.lineno) 0340 self._pushScope(namespace) 0341 0342 def p_empty (self, p): 0343 'empty :' 0344 pass 0345 0346 def p_decl_end (self, p): 0347 """decl_end : SEMI 0348 | inline_code""" 0349 pass 0350 0351 def p_class_decl0 (self, p): 0352 """class_decl : class_header class_member_list RBRACE decl_end 0353 | class_header RBRACE decl_end""" 0354 #name, obj = self.stateInfo.popClass () 0355 self._popAccess() 0356 self._popScope() 0357 #if not obj.opaque: 0358 # self.symbolData.objectList.append (EndClassMarker (name, self.lexer.lineno, self.stateInfo)) 0359 def p_class_declopaque(self,p): 0360 """class_decl : opaque_class""" 0361 self._popScope() 0362 0363 def p_class_decl1 (self, p): 0364 'class_decl : class_header class_member_list RBRACE id_list decl_end' 0365 if p [1] in ['class', 'struct', 'union']: 0366 self.object_id_list (p [4], p [1]) 0367 else: 0368 self.object_id_list (p [4], 'class') 0369 name, obj = self.stateInfo.popClass () 0370 self._popAccess() 0371 self._popScope() 0372 0373 def p_class_member (self, p): 0374 """class_member : class_decl 0375 | enum_decl 0376 | typedef_decl 0377 | typedef_enum_decl 0378 | access_specifier 0379 | function_decl 0380 | variable_decl 0381 | doccomment 0382 | bare_macro 0383 | skip_macro 0384 | SEMI""" 0385 self.lexer.lexstate = 'variable' 0386 self.arguments = [] 0387 self.template = None 0388 self.exprElement = None 0389 0390 def p_class_member2 (self, p): 0391 """class_member : template_decl""" 0392 self.lexer.lexstate = 'variable' 0393 self.arguments = [] 0394 self.template = p[1] 0395 self.exprElement = None 0396 0397 def p_access_specifier (self, p): 0398 """access_specifier : public COLON 0399 | public slots COLON 0400 | protected COLON 0401 | protected slots COLON 0402 | private COLON 0403 | private slots COLON 0404 | signals COLON 0405 | slots COLON""" 0406 self.access = p[1] 0407 0408 def p_base_access_specifier (self, p): 0409 """base_access_specifier : public 0410 | protected 0411 | private""" 0412 pass 0413 0414 def p_class_member_list (self, p): 0415 """class_member_list : class_member 0416 | class_member_list class_member""" 0417 pass 0418 0419 0420 def p_class_header0 (self, p): 0421 """class_header : class_name LBRACE 0422 | class_name COLON base_list LBRACE 0423 | class_from_typedef""" 0424 p[0] = p[1] 0425 self._pushAccess('private') 0426 0427 def p_class_header1 (self, p): 0428 """class_header : union LBRACE 0429 | struct LBRACE""" 0430 self.classObject('anonymous', p[1]) 0431 self._pushAccess('private') 0432 0433 def p_class_name (self, p): 0434 """class_name : class ID 0435 | struct ID 0436 | union ID 0437 | class template_type 0438 | struct template_type""" 0439 self.classObject(p[2], p[1]) 0440 0441 def p_class_name1 (self, p): 0442 """class_name : class BAREMACRO ID 0443 | struct BAREMACRO ID 0444 | union BAREMACRO ID 0445 | class BAREMACRO template_type 0446 | struct BAREMACRO template_type""" 0447 self.classObject(p[3], p[1]) 0448 self.currentClass.addMacro(self.symbolData.Macro(p[2])) 0449 0450 def p_opaque_class (self, p): 0451 'opaque_class : class_name SEMI' 0452 self.currentClass.setOpaque(True) 0453 0454 def p_base_list_element0 (self, p): 0455 """base_list_element : base_access_specifier qualified_id 0456 | base_access_specifier template_type""" 0457 self.currentClass.addBase(p[2]) 0458 0459 def p_base_list_element1 (self, p): 0460 """base_list_element : virtual base_access_specifier qualified_id 0461 | virtual base_access_specifier template_type""" 0462 self.currentClass.addBase(p[3]) 0463 0464 def p_base_list_element2 (self, p): 0465 'base_list_element : qualified_id' 0466 self.currentClass.addBase(p[1]) 0467 0468 def p_base_list (self, p): 0469 """base_list : base_list_element 0470 | base_list COMMA base_list_element""" 0471 pass 0472 0473 def p_enum_decl0 (self, p): 0474 """enum_decl : enum_statement SEMI""" 0475 self.scope.append(p[1]) 0476 0477 def p_enum_decl1 (self, p): 0478 """enum_decl : enum_statement id_list SEMI""" 0479 self.scope.append(p[1]) 0480 #self.lexer.begin('variable') 0481 0482 def p_enum_statement0 (self, p): 0483 """enum_statement : enum_name enumerator_list RBRACE""" 0484 for enum in p[2]: 0485 p[1].appendEnumerator(enum) 0486 #self._popScope() 0487 self.lexer.begin ('variable') 0488 p[0] = p[1] 0489 0490 def p_enum_statement1 (self, p): 0491 """enum_statement : enum_name RBRACE""" 0492 p[0] = p[1] 0493 self.lexer.begin ('variable') 0494 0495 def p_enum_name0 (self, p): 0496 """enum_name : enum ID LBRACE 0497 | enum LBRACE""" 0498 if p[2] != "{": 0499 name = p[2] 0500 else: 0501 name = None 0502 p[0] = self.enumObject(name) 0503 0504 def p_typedef_enum (self, p): 0505 """typedef_enum_decl : typedef enum_statement SEMI 0506 | typedef enum_statement id_list SEMI""" 0507 name = p[2].name() 0508 if len(p)==5: 0509 name = p[3] 0510 self.symbolData.EnumTypedef(self.scope, name, p[2], self.filename, self.lexer.lineno) 0511 0512 def p_enumerator0 (self, p): 0513 """enumerator : ID""" 0514 enumerator = self.symbolData.Enumerator(p[1], None) 0515 p[0] = enumerator 0516 0517 def p_enumerator1 (self, p): 0518 """enumerator : ID EQUALS expression""" 0519 enumerator = self.symbolData.Enumerator(p[1], p[3]) 0520 p[0] = enumerator 0521 0522 def p_enumerator2 (self, p): 0523 """enumerator : DOC ID""" 0524 enumerator = self.symbolData.Enumerator(p[2], None) 0525 #enumerator.setDoc(p[1]) 0526 p[0] = enumerator 0527 0528 def p_enumerator3 (self, p): 0529 """enumerator : DOC ID EQUALS expression""" 0530 enumerator = self.symbolData.Enumerator(p[2], p[4]) 0531 #enumerator.setDoc(p[1]) 0532 p[0] = enumerator 0533 0534 def p_enumerator4 (self, p): 0535 """enumerator : ID EQUALS expression enum_doc""" 0536 enumerator = self.symbolData.Enumerator(p[1], p[3]) 0537 #enumerator.setDoc(p[4]) 0538 p[0] = enumerator 0539 0540 def p_enumerator5 (self, p): 0541 """enumerator : ID enum_doc""" 0542 enumerator = self.symbolData.Enumerator(p[1], None) 0543 #enumerator.setDoc(p[2]) 0544 p[0] = enumerator 0545 0546 def p_enumerator_list0 (self, p): 0547 """enumerator_list : enumerator""" 0548 p[0] = [p[1]] 0549 0550 def p_enumerator_list1 (self, p): 0551 """enumerator_list : enumerator_list enum_delim enumerator""" 0552 p[1].append(p[3]) 0553 p[0] = p[1] 0554 0555 def p_enumerator_list2 (self, p): 0556 """enumerator_list : enumerator_list enum_doc""" 0557 p[0] = p[1] 0558 0559 def p_enum_delim0 (self, p): 0560 """enum_delim : COMMA""" 0561 p[0] = (None,None) # (DOC,UPDOC) 0562 0563 def p_enum_delim1 (self, p): 0564 """enum_delim : COMMA enum_doc""" 0565 p[0] = (None,None) # (DOC,UPDOC) 0566 0567 def p_enum_doc(self, p): 0568 """enum_doc : enum_doc DOC 0569 | enum_doc UPDOC 0570 | DOC 0571 | UPDOC""" 0572 pass 0573 0574 def p_id_list_element0 (self, p): 0575 'id_list_element : ID' 0576 p[0] = p[1] 0577 0578 def p_id_list_element1 (self, p): 0579 """id_list_element : ASTERISK ID 0580 | AMPERSAND ID""" 0581 p[0] = p[1] 0582 0583 def p_id_list (self, p): 0584 """id_list : id_list_element 0585 | id_list COMMA id_list_element""" 0586 p[0] = joinp(p, 1, "") 0587 0588 def p_qualified_id (self, p): 0589 """qualified_id : ID 0590 | nested_name_specifier""" 0591 p [0] = p [1] 0592 0593 def p_nested_name_specifier0 (self, p): 0594 """nested_name_specifier : ID COLON2 ID 0595 | nested_name_specifier COLON2 ID 0596 | template_type COLON2 ID""" 0597 p[0] = joinp(p, 1, "") 0598 0599 def p_nested_name_specifier1 (self, p): 0600 """nested_name_specifier : ID COLON2 TILDE ID 0601 | nested_name_specifier COLON2 TILDE ID 0602 | template_type COLON2 TILDE ID""" 0603 p[0] = joinp(p, 1, "") 0604 0605 def p_nested_name_specifier2 (self, p): 0606 'nested_name_specifier : COLON2 ID' 0607 p [0] = p [2] 0608 0609 def p_template_type (self, p): 0610 """template_type : qualified_id LT type_specifier_list GT 0611 | qualified_id LT static_cast_expression GT""" 0612 p[0] = joinp(p, 1, "") 0613 0614 def p_elaborated_type (self, p): 0615 """elaborated_type : enum qualified_id 0616 | class qualified_id 0617 | struct qualified_id 0618 | union qualified_id 0619 | typename qualified_id""" 0620 p [0] = p [2] 0621 0622 def p_type_specifier_base (self, p): 0623 """type_specifier_base : qualified_id 0624 | template_type 0625 | elaborated_type 0626 | int 0627 | unsigned int 0628 | signed int 0629 | char 0630 | unsigned char 0631 | signed char 0632 | float 0633 | double 0634 | long 0635 | long int 0636 | unsigned long 0637 | unsigned long int 0638 | long unsigned int 0639 | signed long 0640 | signed long int 0641 | long long 0642 | unsigned long long 0643 | signed long long 0644 | signed long long int 0645 | short 0646 | unsigned short 0647 | signed short 0648 | short int 0649 | unsigned short int 0650 | signed short int 0651 | unsigned 0652 | signed 0653 | bool 0654 | void 0655 | wchar_t""" 0656 p [0] = joinp(p,1) 0657 0658 def p_type_specifier0 (self, p): 0659 'type_specifier : type_specifier_base ' 0660 p [0] = p [1] 0661 0662 def p_type_specifier1 (self, p): 0663 'type_specifier : CVQUAL type_specifier_base' 0664 p [0] = '%s %s' % (p [1], p[2]) 0665 0666 def p_type_specifier2 (self, p): 0667 'type_specifier : type_specifier_base type_decorator' 0668 p [0] = '%s%s' % (p [1], p[2]) 0669 0670 def p_type_specifier3 (self, p): 0671 'type_specifier : CVQUAL type_specifier_base type_decorator' 0672 p [0] = '%s %s%s' % (p [1], p[2], p[3]) 0673 0674 def p_type_specifier4 (self, p): 0675 'type_specifier : type_specifier_base CVQUAL type_decorator' 0676 p [0] = '%s %s%s' % (p [2], p[1], p[3]) 0677 0678 def p_type_specifier5 (self, p): 0679 'type_specifier : type_specifier_base CVQUAL' 0680 p [0] = '%s %s' % (p [2], p[1]) 0681 0682 def p_type_decorator (self, p): 0683 """type_decorator : ASTERISK 0684 | AMPERSAND 0685 | ASTERISK CVQUAL 0686 | ASTERISK AMPERSAND 0687 | ASTERISK ASTERISK 0688 | ASTERISK ASTERISK ASTERISK 0689 | ARRAYOP""" 0690 p [0] = joinp(p, 1, "") 0691 0692 0693 def p_type_specifier_list (self, p): 0694 """type_specifier_list : type_specifier 0695 | type_specifier_list COMMA type_specifier""" 0696 p [0] = joinp(p, 1, "") 0697 0698 def p_typedef_decl (self, p): 0699 """typedef_decl : typedef_simple SEMI 0700 | typedef_elaborated SEMI 0701 | typedef_function_ptr SEMI""" 0702 self._popScope() 0703 0704 def p_typedef_simple0 (self, p): 0705 'typedef_simple : typedef type_specifier ID' 0706 tdObj = self.typedefObject(p[2], p[3]) 0707 self._pushScope(tdObj) 0708 self.inTypedef = True 0709 0710 def p_typedef_simple1 (self, p): 0711 'typedef_simple : typedef type_specifier ID ARRAYOP' 0712 tdObj = self.typedefObject('%s*' % p [2], p [3]) 0713 self._pushScope(tdObj) 0714 self.inTypedef = True 0715 0716 def p_typedef_elaborated (self, p): 0717 """typedef_elaborated : typedef class qualified_id ID 0718 | typedef struct qualified_id ID 0719 | typedef union qualified_id ID 0720 | typedef enum qualified_id ID""" 0721 tdObj = self.typedefObject(p[3], p[4]) 0722 self._pushScope(tdObj) 0723 self.inTypedef = True 0724 0725 def p_class_from_typedef0 (self, p): 0726 """class_from_typedef : typedef class ID LBRACE 0727 | typedef struct ID LBRACE 0728 | typedef union ID LBRACE""" 0729 p [0] = p [2] 0730 self.classObject (p [3], p [2]) 0731 self.inTypedef = True 0732 0733 def p_class_from_typedef1 (self, p): 0734 """class_from_typedef : typedef struct LBRACE 0735 | typedef union LBRACE""" 0736 p [0] = p [2] 0737 self.classObject ('anonymous', p [2]) 0738 self.inTypedef = True 0739 0740 def p_pointer_to_function_pfx (self, p): 0741 """pointer_to_function_pfx : ASTERISK FUNCPTR 0742 | type_specifier FUNCPTR""" 0743 if p[1] == '*': 0744 p [0] = '*%s' % p[2] 0745 else: 0746 p [0] = p[1] 0747 0748 def p_pointer_to_function_name (self, p): 0749 'pointer_to_function_name : pointer_to_function_pfx ID' 0750 p [0] = "|".join ([p[1], p[2]]) 0751 0752 def p_pointer_to_function_args (self, p): 0753 """pointer_to_function_args : RPAREN LPAREN type_specifier_list 0754 | RPAREN LPAREN empty""" 0755 p [0] = p [3] 0756 0757 def p_pointer_to_function (self, p): 0758 'pointer_to_function : pointer_to_function_name pointer_to_function_args RPAREN' 0759 if p [2]: 0760 p [0] = "|".join ([p [1], p [2]]) 0761 else: 0762 p [0] = "|".join ([p [1], ""]) 0763 0764 def p_typedef_function_ptr (self, p): 0765 'typedef_function_ptr : typedef pointer_to_function' 0766 0767 ptrType, name, args = p [2].split ('|', 2) 0768 0769 fa = self.symbolData.FunctionArgument(name, ptrType, args) 0770 typedefObj = self.symbolData.FunctionPointerTypedef(self.scope, fa, self.filename, self.lexer.lineno) 0771 typedefObj.setAccess(self.access) 0772 self.inTypedef = True 0773 0774 self._pushScope(typedefObj) 0775 0776 def p_array_variable (self, p): 0777 'array_variable : ID ARRAYOP' 0778 p [0] = p[1] + " " + p[2] 0779 0780 def p_argument_specifier0 (self, p): 0781 """argument_specifier : type_specifier 0782 | ELLIPSIS""" 0783 p [0] = self.argument (p [1]) 0784 0785 def p_argument_specifier1 (self, p): 0786 """argument_specifier : type_specifier ID 0787 | type_specifier array_variable""" 0788 p [0] = self.argument (p [1], p [2]) 0789 0790 def p_argument_specifier2 (self, p): 0791 'argument_specifier : type_specifier EQUALS expression' 0792 p [0] = self.argument (p [1], None, p [3]) 0793 0794 def p_argument_specifier3 (self, p): 0795 """argument_specifier : type_specifier ID EQUALS expression 0796 | type_specifier array_variable EQUALS expression""" 0797 p [0] = self.argument (p [1], p [2], p [4]) 0798 0799 def p_argument_specifier4 (self, p): 0800 'argument_specifier : pointer_to_function' 0801 argType, name, args = p [1].split ('|', 2) 0802 p[0] = self.argument('$fp' + argType, name, args) 0803 0804 def p_argument_list0 (self, p): 0805 """argument_list : argument_specifier""" 0806 # | type_specifier""" 0807 p [0] = [p [1]] 0808 0809 def p_argument_list1 (self, p): 0810 """argument_list : argument_list COMMA argument_specifier 0811 | argument_list COMMA type_specifier""" 0812 if p [0]: 0813 p [0].append (p [3]) 0814 else: 0815 p [0] = [p [3]] 0816 0817 def p_decl_starter0 (self, p): 0818 'decl_starter : type_specifier qualified_id' 0819 p [0] = joinp(p, 1, "|") 0820 0821 def p_decl_starter1 (self, p): 0822 'decl_starter : type_specifier bare_macro qualified_id' 0823 p [0] = p[1] + "|" + p[3] 0824 0825 def p_decl_starter2 (self, p): 0826 'decl_starter : STORAGE type_specifier qualified_id' 0827 p [0] = joinp(p, 2, "|") 0828 self.storage = p [1] 0829 0830 def p_decl_starter3 (self, p): 0831 'decl_starter : STORAGE bare_macro type_specifier qualified_id' 0832 p [0] = joinp(3, "|") 0833 self.storage = p [1] 0834 0835 def p_decl_starter4 (self, p): 0836 'decl_starter : STORAGE type_specifier bare_macro qualified_id' 0837 p [0] = p[2] + "|" + p[4] 0838 self.storage = p [1] 0839 0840 def p_variable_decl0 (self, p): 0841 'variable_decl : decl_starter SEMI' 0842 vtype, name = p [1].split ('|') 0843 self.variableObject (name, vtype) 0844 0845 def p_variable_decl1 (self, p): 0846 'variable_decl : argument_specifier SEMI' 0847 vtype, name, init = p[1][0][:3] 0848 self.variableObject (name, vtype, init) 0849 0850 def p_variable_decl2 (self, p): 0851 'variable_decl : STORAGE argument_specifier SEMI' 0852 vtype, name, eqsign, init = p [2][0][:4] 0853 self.variableObject (name, vtype, init) 0854 0855 def p_variable_decl3 (self, p): 0856 'variable_decl : type_specifier id_list SEMI' 0857 vtype = p [1] 0858 names = p[2].split (',') 0859 for name in names: 0860 self.variableObject (name, vtype) 0861 0862 def p_variable_decl4 (self, p): 0863 'variable_decl : STORAGE type_specifier id_list SEMI' 0864 self.storage = p[1] 0865 vtype = p [2] 0866 names = p[3].split (',') 0867 for name in names: 0868 self.variableObject (name, vtype) 0869 0870 def p_variable_decl5 (self, p): 0871 'variable_decl : type_specifier CVQUAL ID SEMI' 0872 vObj = self.variableObject (p [3], p [1]) 0873 vObj.variable.attributes.cv = p [2] 0874 0875 def p_variable_decl6 (self, p): 0876 'variable_decl : type_specifier ID COLON ICONST SEMI' 0877 vObj = self.variableObject (p [2], p [1]) 0878 vObj.setBitfield(p[4]) 0879 0880 def p_variable_decl7 (self, p): 0881 'variable_decl : pointer_to_function SEMI' 0882 varType, name, args = p [1].split ("|", 2) 0883 varObj = self.variableObject (name, varType, None) 0884 0885 if args: 0886 varObj.functionPtr = args.split (',') 0887 else: 0888 varObj.functionPtr = [] 0889 0890 def p_function_name (self, p): 0891 'function_name : decl_starter LPAREN' 0892 returns, name = p [1].split ('|') 0893 func = self.functionObject(name, returns) 0894 func.setAccess(self.access) 0895 self.arguments = [] 0896 0897 def p_operator_pfx (self, p): 0898 'operator_pfx : type_specifier operator' 0899 p [0] = p [1] 0900 0901 def p_operator_pfx2 (self, p): 0902 'operator_pfx : type_specifier bare_macro operator' 0903 p [0] = p [1] 0904 0905 def p_operator_pfx3 (self, p): 0906 'operator_pfx : type_specifier bare_macro type_decorator operator' 0907 p [0] = p [1] 0908 0909 def p_operator_pfx4 (self, p): 0910 'operator_pfx : type_specifier ID COLON2 operator' 0911 p [0] = p[1] + " " + p[2] + p[3] 0912 0913 def p_operatorpfx5(self, p): 0914 'operator_pfx : type_specifier template_type COLON2 operator' 0915 p[0] = p[1] + " " + p[2] + p[3] 0916 0917 def p_operator_name (self, p): 0918 """operator_name : operator_pfx operator_type""" 0919 if p[1] is not None: 0920 self.functionObject ('operator' + p[2], p[1]) 0921 self.arguments = [] 0922 0923 def p_operator_type (self, p): 0924 """operator_type : PLUS LPAREN 0925 | MINUS LPAREN 0926 | ASTERISK LPAREN 0927 | SLASH LPAREN 0928 | PERCENT LPAREN 0929 | VBAR LPAREN 0930 | AMPERSAND LPAREN 0931 | LT LPAREN 0932 | LT LT LPAREN 0933 | GT LPAREN 0934 | GT GT LPAREN 0935 | LOR LPAREN 0936 | LAND LPAREN 0937 | BANG LPAREN 0938 | LE LPAREN 0939 | GE LPAREN 0940 | EQ LPAREN 0941 | EQUALS LPAREN 0942 | TIMESEQUAL LPAREN 0943 | DIVEQUAL LPAREN 0944 | MODEQUAL LPAREN 0945 | PLUSEQUAL LPAREN 0946 | MINUSEQUAL LPAREN 0947 | LSHIFTEQUAL LPAREN 0948 | GT GE LPAREN 0949 | ANDEQUAL LPAREN 0950 | OREQUAL LPAREN 0951 | XOREQUAL LPAREN 0952 | PLUSPLUS LPAREN 0953 | MINUSMINUS LPAREN 0954 | ARRAYOP LPAREN 0955 | LPAREN RPAREN LPAREN 0956 | ARROW LPAREN 0957 | NE LPAREN""" 0958 if len(p) == 3: 0959 p[0] = p[1] 0960 elif len(p) == 4: 0961 p[0] = p[1] + p[2] 0962 0963 def p_cast_operator_operator(self, p): 0964 """cast_operator_keyword : operator""" 0965 self.lexer.begin('function') 0966 0967 def p_cast_operator_name0 (self, p): 0968 'cast_operator_name : cast_operator_keyword type_specifier LPAREN RPAREN' 0969 self.functionObject ('operator ' + p [2], p[2]) 0970 self.arguments = [] 0971 0972 def p_cast_operator_name1 (self, p): 0973 'cast_operator_name : cast_operator_keyword type_specifier LPAREN RPAREN CVQUAL' 0974 fObj = self.functionObject ('operator ' + p [2], p[2]) 0975 fObj.addQualifier(p[5]) 0976 self.arguments = [] 0977 0978 def p_cast_operator_stmt (self, p): 0979 """cast_operator_stmt : cast_operator_name decl_end 0980 | virtual cast_operator_name decl_end""" 0981 self.currentFunction.setArguments(self.argumentList()) 0982 if len(p) == 4: 0983 self.currentFunction.addQualifier('virtual') 0984 0985 def p_operator_primary0 (self, p): 0986 """operator_primary : operator_name argument_list RPAREN 0987 | operator_name RPAREN""" 0988 if self.currentFunction is not None: 0989 self.currentFunction.setArguments(self.argumentList()) 0990 0991 def p_operator_primary1 (self, p): 0992 """operator_primary : virtual operator_name argument_list RPAREN 0993 | virtual operator_name RPAREN""" 0994 self.currentFunction.setArguments(self.argumentList()) 0995 self.currentFunction.addQualifier('virtual') 0996 0997 def p_operator_stmt0 (self, p): 0998 """operator_stmt : operator_primary decl_end 0999 | operator_primary pure_virtual_suffix decl_end""" 1000 pass 1001 1002 def p_operator_stmt1 (self, p): 1003 """operator_stmt : operator_primary CVQUAL decl_end 1004 | operator_primary CVQUAL pure_virtual_suffix""" 1005 if self.currentFunction is not None: 1006 self.currentFunction.addQualifier(p[2]) 1007 1008 def p_ctor_name0 (self, p): 1009 'ctor_name : qualified_id LPAREN' 1010 self.functionObject(p[1], 'ctor') 1011 self.arguments = [] 1012 1013 def p_ctor_name1 (self, p): 1014 'ctor_name : explicit qualified_id LPAREN' 1015 fo = self.functionObject(p[2], 'ctor') 1016 fo.addQualifier('explicit') 1017 self.arguments = [] 1018 1019 def p_dtor_name (self, p): 1020 'dtor_name : TILDE ID' 1021 self.functionObject(p[2], 'dtor') 1022 self.arguments = [] 1023 1024 def p_virtual_dtor_name (self, p): 1025 'virtual_dtor_name : virtual dtor_name' 1026 self.arguments = [] 1027 1028 def p_function_decl (self, p): 1029 """function_decl : ctor_stmt 1030 | dtor_stmt 1031 | function_stmt 1032 | operator_stmt 1033 | cast_operator_stmt 1034 | virtual_stmt 1035 | pure_virtual""" 1036 self.currentFunction = None 1037 1038 def p_function_primary (self, p): 1039 """function_primary : function_name RPAREN 1040 | function_name argument_list RPAREN""" 1041 self.currentFunction.setArguments(self.argumentList()) 1042 1043 def p_function_stmt0 (self, p): 1044 'function_stmt : function_primary decl_end' 1045 pass 1046 1047 def p_function_stmt1 (self, p): 1048 'function_stmt : function_primary CVQUAL decl_end' 1049 self.currentFunction.addQualifier(p[2]) 1050 1051 def p_ctor_primary (self, p): 1052 """ctor_primary : ctor_name RPAREN 1053 | ctor_name argument_list RPAREN""" 1054 self.currentFunction.setArguments(self.argumentList()) 1055 1056 def p_ctor_initializer (self, p): 1057 """ctor_initializer : qualified_id LPAREN expression_list RPAREN 1058 | qualified_id LPAREN RPAREN 1059 | template_type LPAREN expression_list RPAREN 1060 | template_type LPAREN RPAREN""" 1061 pass 1062 1063 def p_ctor_initializer_list (self, p): 1064 """ctor_initializer_list : ctor_initializer 1065 | ctor_initializer_list COMMA ctor_initializer""" 1066 1067 pass 1068 1069 def p_ctor_stmt (self, p): 1070 """ctor_stmt : ctor_primary decl_end 1071 | ctor_primary COLON ctor_initializer_list decl_end""" 1072 pass 1073 1074 def p_dtor_primary0 (self, p): 1075 'dtor_primary : dtor_name LPAREN RPAREN' 1076 pass 1077 1078 def p_dtor_primary1 (self, p): 1079 'dtor_primary_pure : dtor_name LPAREN RPAREN pure_virtual_suffix' 1080 self.currentFunction.addQualifier('pure') 1081 1082 1083 def p_dtor_primary2 (self, p): 1084 'dtor_primary : virtual_dtor_name LPAREN RPAREN' 1085 self.currentFunction.addQualifier('virtual') 1086 1087 def p_dtor_primary3 (self, p): 1088 'dtor_primary_pure_virtual : virtual_dtor_name LPAREN RPAREN pure_virtual_suffix' 1089 self.currentFunction.addQualifier('virtual') 1090 self.currentFunction.addQualifier('pure') 1091 1092 def p_dtor_stmt (self, p): 1093 """dtor_stmt : dtor_primary decl_end 1094 | dtor_primary_pure_virtual 1095 | dtor_primary_pure""" 1096 pass 1097 1098 def p_virtual_primary (self, p): 1099 """virtual_primary : virtual function_name RPAREN 1100 | virtual function_name argument_list RPAREN""" 1101 self.currentFunction.setArguments(self.argumentList()) 1102 self.currentFunction.addQualifier('virtual') 1103 1104 def p_virtual_stmt0 (self, p): 1105 'virtual_stmt : virtual_primary decl_end' 1106 pass 1107 1108 def p_virtual_stmt1 (self, p): 1109 'virtual_stmt : virtual_primary CVQUAL decl_end' 1110 self.currentFunction.addQualifier(p[2]) 1111 1112 def p_pure_virtual_suffix (self, p): 1113 'pure_virtual_suffix : EQUALS PURESFX' 1114 pass 1115 1116 def p_pure_virtual (self, p): 1117 """pure_virtual : virtual_primary pure_virtual_suffix 1118 | virtual_primary CVQUAL pure_virtual_suffix""" 1119 self.currentFunction.addQualifier('pure') 1120 if p[2] in ['const', 'volatile']: 1121 self.currentFunction.addQualifier(p[2]) 1122 1123 def p_template_param (self, p): 1124 """template_param : type_specifier 1125 | type_specifier ID""" 1126 p[0] = joinp(p, 1) 1127 1128 def p_template_param_list (self, p): 1129 """template_param_list : template_param""" 1130 p[0] = [p[1]] 1131 1132 def p_template_param_list2 (self, p): 1133 """template_param_list : template_param_list COMMA template_param""" 1134 p[1].append(p[3]) 1135 p[0] = p[1] 1136 1137 def p_template_decl (self, p): 1138 'template_decl : template LT template_param_list GT' 1139 p[0] = p[3] 1140 1141 def p_template_decl2 (self, p): 1142 'template_decl : template LT GT' 1143 p[0] = [] 1144 1145 # expression handling for argument default values - just parses and 1146 # then reassembles the default value expression (no evaluation) 1147 1148 def p_expression_list (self, p): 1149 """expression_list : expression 1150 | expression_list COMMA expression""" 1151 pass 1152 1153 def p_expression0 (self, p): 1154 """expression : add_expression 1155 | sub_expression 1156 | mult_expression 1157 | div_expression 1158 | mod_expression 1159 | unary_expression 1160 | or_expression 1161 | and_expression 1162 | xor_expression 1163 | bitor_expression 1164 | bitand_expression 1165 | lt_expression 1166 | le_expression 1167 | eq_expression 1168 | ge_expression 1169 | gt_expression 1170 | lshift_expression 1171 | rshift_expression 1172 | ptr_expression 1173 | dot_expression 1174 | new_expression 1175 | static_cast_expression 1176 | ICONST 1177 | FCONST 1178 | HEXCONST 1179 | CCONST 1180 | SCONST""" 1181 p [0] = p [1] 1182 1183 def p_expression1 (self, p): 1184 'expression : LPAREN expression RPAREN' 1185 p [0] = joinp(p, 1, "") 1186 1187 def p_expression2 (self, p): 1188 'expression : qualified_id' 1189 p [0] = p [1] 1190 self.exprElements.append (p [1]) 1191 1192 def p_expression3 (self, p): 1193 """expression : type_specifier LPAREN expression_list RPAREN 1194 | type_specifier LPAREN RPAREN""" 1195 p [0] = joinp(p, 1, "") 1196 self.exprElements.append ('%s()' % p [1]) 1197 1198 def p_expression4 (self, p): 1199 """expression : type_specifier PERIOD ID LPAREN expression_list RPAREN 1200 | type_specifier PERIOD ID LPAREN RPAREN""" 1201 p [0] = joinp(p, 1, "") 1202 self.exprElements.append ('%s.%s()' % (p [1], p [3])) 1203 1204 def p_expression5 (self, p): 1205 'expression : type_specifier PERIOD ID' 1206 p [0] = p [1] 1207 self.exprElements.append ('%s.%s' % (p [1], p [3])) 1208 1209 def p_expression_list (self, p): 1210 """expression_list : expression 1211 | expression_list COMMA expression""" 1212 p [0] = joinp(p, 1, "") 1213 1214 def p_unary_expression (self, p): 1215 """unary_expression : sign_expression 1216 | not_expression 1217 | bitnot_expression 1218 | new_expression""" 1219 p [0] = p [1] 1220 1221 def p_add_expression (self, p): 1222 'add_expression : expression PLUS expression' 1223 p [0] = joinp(p, 1, "") 1224 1225 def p_sub_expression (self, p): 1226 'sub_expression : expression MINUS expression' 1227 p [0] = joinp(p, 1, "") 1228 1229 def p_mult_expression (self, p): 1230 'mult_expression : expression ASTERISK expression' 1231 p [0] = joinp(p, 1, "") 1232 1233 def p_div_expression (self, p): 1234 'div_expression : expression SLASH expression' 1235 p [0] = joinp(p, 1, "") 1236 1237 def p_mod_expression (self, p): 1238 'mod_expression : expression PERCENT expression' 1239 p [0] = joinp(p, 1, "") 1240 1241 def p_sign_expression (self, p): 1242 'sign_expression : MINUS expression %prec UMINUS' 1243 p [0] = joinp(p, 1, "") 1244 1245 def p_or_expression (self, p): 1246 'or_expression : expression LOR expression' 1247 p [0] = joinp(p, 1, "") 1248 1249 def p_and_expression (self, p): 1250 'and_expression : expression LAND expression' 1251 p [0] = joinp(p, 1, "") 1252 1253 def p_xor_expression (self, p): 1254 'xor_expression : expression CARET expression' 1255 p [0] = joinp(p, 1, "") 1256 1257 def p_bitor_expression (self, p): 1258 'bitor_expression : expression VBAR expression' 1259 p [0] = joinp(p, 1, "") 1260 1261 def p_bitand_expression (self, p): 1262 'bitand_expression : expression AMPERSAND expression' 1263 p [0] = joinp(p, 1, "") 1264 1265 def p_lt_expression (self, p): 1266 'lt_expression : expression LT expression' 1267 p [0] = joinp(p, 1, "") 1268 1269 def p_le_expression (self, p): 1270 'le_expression : expression LE expression' 1271 p [0] = joinp(p, 1, "") 1272 1273 def p_eq_expression (self, p): 1274 'eq_expression : expression EQ expression' 1275 p [0] = joinp(p, 1, "") 1276 1277 def p_ge_expression (self, p): 1278 'ge_expression : expression GE expression' 1279 p [0] = joinp(p, 1, "") 1280 1281 def p_gt_expression (self, p): 1282 'gt_expression : expression GT expression' 1283 p [0] = joinp(p, 1, "") 1284 1285 def p_lshift_expression (self, p): 1286 'lshift_expression : expression GT GT expression' 1287 p [0] = joinp(p, 1, "") 1288 1289 def p_rshift_expression (self, p): 1290 'rshift_expression : expression LT LT expression' 1291 p [0] = joinp(p, 1, "") 1292 1293 def p_not_expression (self, p): 1294 'not_expression : BANG expression' 1295 p [0] = joinp(p, 1, "") 1296 1297 def p_bitnot_expression (self, p): 1298 'bitnot_expression : TILDE expression' 1299 p [0] = joinp(p, 1, "") 1300 1301 def p_new_expression (self, p): 1302 'new_expression : new expression' 1303 p [0] = joinp(p, 1, "") 1304 1305 def p_static_cast_expression (self, p): 1306 'static_cast_expression : static_cast LT type_specifier GT LPAREN expression RPAREN' 1307 p [0] = joinp(p, 1) 1308 self.exprElements.append (p [3]) 1309 1310 def p_ptr_expression (self, p): 1311 'ptr_expression : expression ARROW expression' 1312 p [0] = joinp(p, 1, "") 1313 1314 def p_dot_expression (self, p): 1315 'dot_expression : expression PERIOD expression' 1316 p [0] = joinp(p, 1, "") 1317 1318 # inline code/statements 1319 # the second and last cases are incorrect syntax, but show up in KDE 1320 def p_inline_code (self, p): 1321 """inline_code : STMT_BEGIN code_list STMT_END 1322 | STMT_BEGIN code_list STMT_END SEMI 1323 | STMT_BEGIN STMT_END 1324 | STMT_BEGIN STMT_END SEMI""" 1325 pass 1326 1327 def p_code_list_block (self, p): 1328 """code_list_block : CODE_STMT_BEGIN code_list STMT_END 1329 | CODE_STMT_BEGIN STMT_END""" 1330 pass 1331 1332 def p_code_list (self, p): 1333 """code_list : CODE_TOKEN 1334 | code_list_block 1335 | code_list code_list_block 1336 | code_list CODE_TOKEN""" 1337 1338 # calls to mostly ignored macros 1339 def p_skip_macro (self, p): 1340 'skip_macro : MACROCALL MACRO_CALL_BEGIN macro_call_element_list MACRO_CALL_END' 1341 #if p [1] == 'Q_DISABLE_COPY': 1342 # fcn = self.functionObject (p [3], 'ctor') 1343 # fcn.setArguments (self.argument ('const %s&' % p[3])) 1344 # self.stateInfo.popObject () 1345 #else: 1346 # pass 1347 macro = self.bareMacro(p[1]) 1348 macro.setArgument(p[3]) 1349 macro.setAccess(self.access) 1350 1351 def p_bare_macro(self,p): 1352 'bare_macro : BAREMACRO' 1353 macro = self.bareMacro(p[1]) 1354 macro.setAccess(self.access) 1355 1356 def p_macro_call_parens (self, p): 1357 """macro_call_parens : LPAREN RPAREN 1358 | LPAREN macro_call_element_list RPAREN""" 1359 pass 1360 1361 def p_macro_call_element_list0 (self, p): 1362 'macro_call_element_list : MACRO_ELEMENT' 1363 p [0] = p[1] 1364 1365 def p_macro_call_element_list1 (self, p): 1366 'macro_call_element_list : macro_call_element_list MACRO_ELEMENT' 1367 p [0] = joinp(p, 1) 1368 1369 def p_macro_call_element_list2 (self, p): 1370 'macro_call_element_list : macro_call_element_list macro_call_parens' 1371 p [0] = p [1] 1372 1373 def p_macro_call_element_list3 (self, p): 1374 'macro_call_element_list : macro_call_parens' 1375 p [0] = '' 1376 1377 def p_doccomment(self, p): 1378 'doccomment : DOC' 1379 self.commentObject(p[1]) 1380 1381 def p_error(self, p): 1382 if p is not None: 1383 print("File: " + repr(self.filename) + " Line: " + str(self.lexer.lineno) + " Syntax error in input. Token type: %s, token value: %s, lex state: %s" % (p.type, p.value, self.lexer.lexstate)) 1384 else: 1385 print("File: " + repr(self.filename) + " Line: " + str(self.lexer.lineno) + " Syntax error in input. Lex state: %s" % (self.lexer.lexstate,) ) 1386 sys.exit (-1) 1387 1388 if __name__ == '__main__': 1389 1390 text = """ 1391 enum global {earth, orb, globe}; 1392 friend class whatever; 1393 friend int max (int a, int b); 1394 1395 namespace foo 1396 { 1397 enum fooEnum {apples, peaches, pumpkin_pie}; 1398 class bar 1399 { 1400 public: 1401 bar (); 1402 int baz (); 1403 int baz (double, long); 1404 QString method (int foo = 0); 1405 bar (int); 1406 bar (int, QList<QString>); 1407 using dont care what; 1408 enum barEnum { 1409 peas, 1410 carrots, 1411 beans 1412 } veggies; 1413 typedef global::qint inttype; 1414 }; 1415 typedef enum elaborated something; 1416 typedef enum simple {easy, bobsyouruncle, noproblem}; 1417 typedef QList<QPair<QString,QString>> stringpairlist; 1418 typedef QString& stringref; 1419 typedef QObject* objPtr; 1420 typedef QObject** objPtrPtr; 1421 typedef QString*& reftoStringPtr; 1422 enum tail {end, posterior, ass}; 1423 } 1424 int baz (); 1425 virtual int baz (double); 1426 int baz (double, long long); 1427 int baz (double, long, unsigned long = ulong); 1428 virtual const QString& method (int foo = 0) = 0; 1429 QString method (int foo = 0, long fool = 20); 1430 bar (int a[40]); 1431 bar (int, QList<QString>); 1432 char* tmpl (QPair<QString, QString*> pair, const int foo); 1433 const char* string (QObject* object = QObject::type ()); 1434 int varInt; 1435 double varDbl1, varDb12; 1436 QString s = 25; 1437 bar (int); 1438 bar (int a[40]); 1439 char *c[10]; 1440 typedef void (* fptr)(int, double*); 1441 typedef int (* otherptr)(); 1442 Q_OBJECT 1443 Q_SETS (who cares) 1444 double (*doublePtr)(float, QString*); 1445 bool test (int, int); 1446 bool operator == (int); 1447 int operator + (double); 1448 int operator >> (int); 1449 bool operator <<= (int a, int b); 1450 double (*doublePtr)(); 1451 void* foo (int, double (*doublePtr)(float, QString*)); 1452 void* foo (int, double (*doublePtr)()); 1453 Q_DECLARE_FLAGS (Conditions, Condition) 1454 void plug () { 1455 x = 1; 1456 y = 2; 1457 } 1458 class kdecore::KAccel raise (class QWidget elab) { 1459 xyzabc = 1; 1460 y = 2; 1461 { 1462 if (x) 1463 { 1464 abc = 12; 1465 } 1466 } 1467 { 1468 while 1: 1469 x = 0; 1470 } 1471 1472 } 1473 """ 1474 text = """ 1475 1476 namespace Soprano { 1477 1478 class Model; 1479 1480 namespace Client { 1481 1482 class DBusModel; 1483 1484 /** 1485 * \class DBusClient dbusclient.h Soprano/Client/DBusClient 1486 * 1487 * \brief Core class to handle a connection to a Soprano server through the 1488 * DBus interface. 1489 * 1490 * DBusClient creates a connection to a running Soprano Server via its DBus 1491 * interface. All DBus communication is handled internally. 1492 * 1493 * See DBusModel for details about thread-safety. 1494 * 1495 * \author Sebastian Trueg <trueg@kde.org> 1496 * 1497 * \sa \ref soprano_server_dbus 1498 */ 1499 class DBusClient : public QObject, public Error::ErrorCache 1500 { 1501 1502 }; 1503 } 1504 } 1505 1506 """ 1507 text = """ 1508 class Foo { 1509 public: 1510 const KTimeZone::Transition *transition(const QDateTime &dt, const Transition **secondTransition = 0, bool *validTime = 0) const; 1511 }; 1512 """ 1513 1514 from symboldata import Data 1515 from stateInfo import StateInfo 1516 1517 symbolData = Data () 1518 stateInfo = StateInfo () 1519 parser = CppParser () 1520 # print "\n".join (parser.parse (symbolData, stateInfo, text, 2) [1]) 1521 parser.parse (symbolData, stateInfo, text, 2)