File indexing completed on 2024-03-24 16:16:34

0001 # -*- coding: utf-8 -*-
0002 #     Copyright 2007-8 Jim Bublitz <jbublitz@nwinternet.com>
0003 #     Copyright 2008-9 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 from .sealed import sealed
0022 import ply.yacc as yacc
0023 from .siplexer import sipLexer, tokens
0024 
0025 def joinp(p, startindex, string=" "):
0026     tmplist = []
0027     i = startindex
0028     while i < len(p):
0029         tmplist.append(p[i])
0030         i += 1
0031     return string.join(tmplist)
0032 
0033 class SipParser(object):
0034     """Parser for SIP files
0035     
0036     See parse()."""
0037     @sealed
0038     def __init__ (self):
0039         """Create a new parser instance."""
0040         self.lexer = sipLexer
0041         self.lexer.begin('variable')
0042         self._resetState()
0043 
0044         self.tokens = tokens        
0045         yacc.yacc(module = self, tabmodule = "sipParserTab")
0046         self._parse = yacc.parse 
0047         
0048     def _resetState(self):
0049         self._scopeStack = []
0050         self.scope = None
0051         
0052         self.access = "public"
0053         self._accessStack = []
0054         
0055         self.storage = None
0056 
0057         self.versionStack = [(None, None, None)]
0058 
0059         self.inTemplate = None
0060         self.lexState = 'variable'
0061         self.currentClass = None
0062         self.currentFunction = None
0063         self.currentEnum = None
0064         self.currentTypedef = None
0065         self.exprElements = None
0066         self.annotation = []
0067         self.versionLow = ""
0068         self.versionHigh = ""
0069         self.platform = ""
0070         self.ignore = False
0071         self.force = False
0072         self.templateParams = []
0073         self.template = None
0074         self.inTypedef = False
0075         self.symbolData = None
0076         self.scope = None
0077         self.filename = None
0078         
0079     def parse(self, symbolData, text, filename=None, debugLevel = 0):
0080         """Parse the given SIP text
0081         
0082         Keyword arguments:
0083         symbolData -- cppsymboldata.SymbolData instance. The parsed entities are added to this instance.
0084         text -- String, the text to parse. It should be a valid SIP file / grammar.
0085         filename -- The filename belonging to the given text. This is used for error messages and can be None.
0086         debugLevel -- Turns on debug messages from the lexer and parser. 0, the default, means no debug. 2 lists the
0087                       tokens as they arrive.
0088 
0089         Returns:
0090         -- Newly created `Scope` object containing the parsed data.
0091 
0092         All of the top level things in the given text are parsed and placed inside the top scope inside the
0093         symbolData. 
0094         
0095         If a parse error is encountered, the whole program is exited. Sorry.
0096         """
0097         self._resetState()
0098 
0099         self.symbolData = symbolData
0100         topScope = self.scope = self.symbolData.newScope()
0101         
0102         self.filename = filename
0103         sipLexer.input (text)
0104         sipLexer.lineno = 1
0105         sipLexer.lexpos = 0
0106     
0107         result = self._parse(debug = debugLevel, lexer = self.lexer)
0108         # FIXME topScope should equal self.scope now. But there is a bug in the template parsing somewhere.
0109         return topScope
0110         
0111     def _pushScope(self, newScope):
0112         self._scopeStack.append(self.scope)
0113         self.scope = newScope
0114 
0115     def _popScope(self):
0116         self.scope = self._scopeStack.pop()
0117 
0118     def _pushAccess(self, newAccess):
0119         self._accessStack.append(self.access)
0120         self.access = newAccess
0121         
0122     def _popAccess(self):
0123         self.access = self._accessStack.pop()
0124         
0125     def _lastEntity(self):
0126         for i in range(len(self.scope)-1,-1,-1):
0127             if not isinstance(self.scope[i], (self.symbolData.Comment, self.symbolData.SipDirective)):
0128                 return self.scope[i]
0129         return self.scope.lastMember()
0130 
0131     def _pushVersion(self, version):
0132         self.versionStack.append(version)
0133         
0134     def _popVersion(self):
0135         if len(self.versionStack)==0:
0136             return (None, None, None)
0137         return self.versionStack.pop()
0138 
0139     def object_id_list (self, id_list, obj, objType = None):
0140         idList = id_list.split (',')
0141         if self.stateInfo.inTypedef:
0142             self.stateInfo.currentObject ().name = idList [0]
0143             for id in idList [1:]:
0144                 originalObj = self.stateInfo.popObject ()
0145                 if obj == 'class':
0146                     newObj = self.classObject (id, objType)
0147                 elif obj == 'enum':
0148                     newObj = self.enumObject (id)
0149                     newObj.enumerators = originalObj.enumerators
0150         else:
0151             for id in idList:
0152                 self.variableObject (id, self.stateInfo.currentObject ().name)
0153     
0154     def commentObject(self,value):
0155         comment = self.symbolData.Comment(self.scope, self.filename, self.lexer.lineno)
0156         comment.setValue(value)
0157         return comment
0158 
0159     def classObject (self, name, type_):
0160         class_ = self.symbolData.SipClass(self.scope, name, self.filename, self.lexer.lineno)
0161         class_.setAccess(self.access)    
0162         class_.setIgnore(self.ignore)
0163         self.ignore = False
0164         class_.setForce(self.force)
0165         self.currentClass = class_
0166         self._pushScope(class_)
0167         return class_
0168         
0169     def enumObject (self, name):
0170         enum = self.symbolData.Enum(self.scope, name, self.filename, self.lexer.lineno)
0171         enum.setAccess(self.access)
0172         self.lexer.begin('enum')
0173         self.currentEnum = enum
0174         return enum
0175         
0176     def typedefObject(self, typeName, newName):
0177         tdObj = self.symbolData.Typedef(self.scope, newName, self.filename, self.lexer.lineno)
0178         tdObj.setArgumentType(typeName)
0179         tdObj.setIgnore(self.ignore)
0180         self.ignore = False
0181         tdObj.setForce(self.force)
0182         
0183 #        if typeName.startswith('QFlags<'):
0184 #            tdObj.template = Template('QFlags', typeName [7:-1])
0185 #       else:
0186 #            tdObj.template = self.template
0187 #        self.template = None
0188         tdObj.setAccess(self.access)
0189         self._pushScope(tdObj)
0190         self.currentTypedef = tdObj
0191             
0192         return tdObj
0193 
0194     def variableObject (self, name, vtype, init = None):
0195         vObj = self.symbolData.Variable(self.scope, name, self.filename, self.lexer.lineno)
0196         vObj.setArgument(self.symbolData.Argument(vtype, name, init, None, self.template))
0197         vObj.setStorage(self.storage)
0198         vObj.setAccess(self.access)
0199         vObj.setAnnotations(self.annotation)
0200         vObj.setIgnore(self.ignore)
0201         self.ignore = False
0202         vObj.setForce(self.force)
0203         
0204         self._pushScope(vObj)
0205         
0206         self.template = None
0207         self.annotation = []
0208         return vObj
0209     
0210     def functionObject (self, name, returns):
0211         if returns=='ctor':
0212             functionObj = self.symbolData.Constructor(self.scope, name, self.filename, self.lexer.lineno)
0213         elif returns=='dtor':
0214             functionObj = self.symbolData.Destructor(self.scope, name, self.filename, self.lexer.lineno)
0215         else:
0216             functionObj = self.symbolData.Function(self.scope, name, self.filename, self.lexer.lineno)
0217             returnArg = self.symbolData.Argument(returns)
0218             functionObj.setReturn(returnArg)
0219         functionObj.setAccess(self.access)
0220         functionObj.setIgnore(self.ignore)
0221         self.ignore = False
0222         functionObj.setForce(self.force)
0223         
0224         self.currentFunction = functionObj
0225         
0226         #functionObj.templateParams = self.stateInfo.inTemplate
0227         #self.inTemplate = []
0228         self.lexer.begin ('function')
0229         return functionObj
0230         
0231     def argument(self, vtype, name = None, init = None, annotation = []):
0232         arg = self.symbolData.Argument(vtype, name, init, None)
0233         arg.setAnnotations(annotation)
0234         return arg
0235 
0236     def sipBlockObject(self, name):
0237         blockObj = self.symbolData.SipBlock(name)
0238         return blockObj
0239 
0240     def sipDirectiveObject(self, name):
0241         obj = self.symbolData.SipDirective(self.scope, name, self.filename, self.lexer.lineno)
0242         #obj.argument = arg
0243         #self.symbolData.objectList.append (obj)
0244         obj.setForce(self.force)
0245         return obj
0246       
0247     precedence = (('left','PLUS','MINUS'), ('left','ASTERISK','SLASH'), ('right','UMINUS'), )
0248     
0249     # start
0250     def p_declarations (self, p):
0251         """declarations : member
0252                         | member_list member
0253                         | empty"""
0254         pass
0255         
0256     def p_member (self, p):
0257         """member : namespace_decl
0258                   | class_decl
0259                   | enum_decl
0260                   | typedef_decl
0261                   | function_decl
0262                   | variable_decl
0263                   | template_decl
0264                   | sip_stmt
0265                   | sip_block
0266                   | cmodule
0267                   | comp_module
0268                   | cons_module
0269                   | sip_end
0270                   | feature
0271                   | plugin
0272                   | defaultencoding
0273                   | defaultmetatype
0274                   | defaultsupertype
0275                   | sip_if
0276                   | import
0277                   | include
0278                   | license
0279                   | module
0280                   | optional_include
0281                   | platforms
0282                   | sipOptions
0283                   | timeline
0284                   | object_ignore
0285                   | object_force
0286                   | object_end
0287                   | api"""
0288         pass       
0289         #self.lexer.begin (self.stateInfo.lexState)
0290         #self.stateInfo.lexState  = 'variable'
0291         #self.stateInfo.inTypedef = False
0292         #self.stateInfo.ignore    = self.ignore           
0293         #self.annotation = []
0294     
0295     def p_member_comment (self, p):
0296         """member : LINECOMMENT
0297                   | CCOMMENT
0298                   | BLANKLINE"""
0299         self.commentObject(p[1])
0300     
0301     def p_member_list (self, p):
0302         """member_list : member
0303                        | member_list member"""
0304         pass
0305 
0306     def p_namespace_decl (self, p):
0307         'namespace_decl : namespace_name LBRACE member_list RBRACE SEMI'
0308         self._popScope()
0309         
0310     def p_namespace_decl1 (self, p):
0311         'namespace_decl : namespace_name SEMI'
0312         self._popScope()
0313         self.ignore = False
0314         
0315     def p_namespace_name (self, p):
0316         'namespace_name : namespace ID'
0317         name = p[2]
0318         namespace = self.symbolData.Namespace(self.scope, name, self.filename, self.lexer.lineno)
0319         namespace.setIgnore(self.ignore)
0320         self._pushScope(namespace)
0321                 
0322     def p_empty (self, p):
0323         'empty :'
0324         pass
0325  
0326     def p_stmt_end (self, p):
0327         """stmt_end : SEMI"""
0328         pass
0329 
0330     def p_annotation_element1 (self, p):
0331         """annotation_element : ID
0332                               | ID EQUALS ID
0333                               | ID EQUALS ICONST
0334                               | ID EQUALS SCONST
0335                               | ID EQUALS HEXCONST"""
0336         p[0] = joinp(p, 1, "")
0337         
0338     def p_annotation_element2 (self, p):
0339         """annotation_element : ID EQUALS ID COLON MINUS ICONST"""
0340         p[0] = ''.join( [p[i] for i in range(1,5) ] ) + ' ' + p[5] + ' ' + p[6]
0341         
0342     def p_annotation_element3 (self, p):
0343         """annotation_element : ID EQUALS ID COLON ICONST MINUS"""
0344         p[0] = ''.join( [p[i] for i in range(1,5) ] ) + p[5] + ' ' + p[6] + ' '
0345 
0346     def p_annotation_list0 (self, p):
0347         """annotation_list : annotation_element"""
0348         p[0] = [p[1]]
0349         
0350     def p_annotation_list1 (self, p):
0351         """annotation_list : annotation_list COMMA annotation_element"""
0352         p[1].append(p[3])
0353         p[0] = p[1]
0354         
0355     def p_annotation (self, p):
0356         'annotation : SLASH annotation_list SLASH'
0357         self.annotation = p[2]
0358         p[0] = p[2]
0359             
0360     def p_class_decl0 (self, p):
0361         """class_decl : class_header class_member_list RBRACE stmt_end
0362                       | opaque_class
0363                       | class_header RBRACE stmt_end"""
0364         self._popAccess()
0365         self._popScope()
0366 
0367     def p_class_decl1 (self, p):
0368         'class_decl : class_header class_member_list RBRACE id_list stmt_end'
0369         if p[1] in ['class', 'struct', 'union']:
0370             self.object_id_list (p [4], p [1])
0371         else:
0372             self.object_id_list (p [4], 'class')
0373         self._popScope()
0374         self._popScope()
0375         
0376     def p_class_member (self, p):
0377         """class_member : class_decl
0378                         | enum_decl
0379                         | typedef_decl
0380                         | access_specifier
0381                         | function_decl
0382                         | variable_decl
0383                         | template_decl
0384                         | sip_stmt
0385                         | sip_block
0386                         | sip_end
0387                         | sip_if
0388                         | object_ignore
0389                         | object_force
0390                         | object_end"""
0391 
0392         self.lexer.begin(self.lexState)
0393         self.lexState  = 'variable'
0394         self.inTypedef = False
0395         self.template   = None
0396         
0397     def p_class_member_comment (self, p):
0398         """class_member : LINECOMMENT
0399                   | CCOMMENT
0400                   | BLANKLINE"""
0401         self.commentObject(p[1])
0402         
0403     def p_access_specifier (self, p):
0404         """access_specifier : public COLON
0405                             | public slots COLON
0406                             | protected COLON
0407                             | protected slots COLON
0408                             | private COLON
0409                             | signals COLON
0410                             | slots COLON"""
0411                             
0412         self.access = p[1]
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         p [0] = p [1]
0424         self._pushAccess('private')
0425     
0426     def p_class_header1 (self, p):
0427         """class_header : class_name annotation LBRACE
0428                         | class_name COLON base_list annotation LBRACE"""
0429         p[0] = p[1]
0430         self.currentClass.setAnnotations(self.annotation)
0431         self.annotation = []
0432         self._pushAccess('private')
0433         
0434     def p_class_name (self, p):
0435         """class_name : class ID
0436                       | struct ID
0437                       | union ID"""
0438         if self.inTemplate is None:
0439             self.classObject(p[2], p[1])
0440         else:
0441             template = self.symbolData.Template(self.scope, self.filename, self.lexer.lineno)
0442             template.setParameters(self.inTemplate)
0443             
0444             self._pushScope(template)
0445             classObj = self.classObject(p[2], p[1])
0446             self._popScope()
0447             self._popScope()
0448             self._pushScope(classObj)
0449             
0450             self.inTemplate = None
0451         
0452     def p_opaque_class (self, p):
0453         """opaque_class : class qualified_id SEMI
0454                         | class qualified_id annotation SEMI
0455                         | class_name SEMI
0456                         | class_name annotation SEMI"""
0457         self._pushAccess('private')
0458         self.currentClass.setOpaque(True)
0459     
0460     def p_base_list_element (self, p):
0461         """base_list_element : qualified_id
0462                              | template_type"""
0463         self.currentClass.addBase(p[1])
0464      
0465     def p_base_list (self, p):
0466         """base_list : base_list_element
0467                      | base_list COMMA base_list_element"""
0468         pass
0469        
0470     def p_enum_decl0 (self, p):
0471         'enum_decl : enum_statement SEMI'
0472         self.currentEnum = None
0473         self.lexer.begin('variable')
0474 
0475     def p_enum_decl1 (self, p):
0476         'enum_decl : enum_statement id_list SEMI'
0477         self.currentEnum = None
0478         self.lexer.begin('variable')
0479         
0480     def p_enum_statement0 (self, p):
0481         """enum_statement : enum_name enumerator_list RBRACE"""
0482         for enumerator in p[2]:
0483             self.currentEnum.appendEnumerator(enumerator)
0484         
0485     def p_enum_statement1 (self, p):
0486         """enum_statement : enum_name RBRACE"""
0487         pass
0488         
0489     def p_enum_name0 (self, p):
0490         """enum_name : enum ID LBRACE
0491                      | enum LBRACE"""                     
0492         if p[2] != "{":
0493             name = p [2]
0494         else:
0495             name = None
0496         self.enumObject(name)
0497     
0498     # The enumerator_list grammar is quite permissive and doesn't enforce
0499     # much in the way of ordering and commas.
0500     
0501     def p_enumerator_list0 (self, p):
0502         """enumerator_list : enumerator
0503                            | enumeratorcomment
0504                            | versioned_enumerator_list
0505         """
0506         p[0] = p[1]
0507 
0508     def p_enumerator_list1 (self, p):
0509         """enumerator_list : COMMA"""
0510         p[0] = []
0511 
0512     def p_enumerator_list2 (self, p):
0513         """enumerator_list : enumerator_list enumerator
0514                            | enumerator_list enumeratorcomment
0515                            | enumerator_list versioned_enumerator_list
0516                            """
0517         p[1].extend(p[2])
0518         p[0] = p[1]
0519 
0520     def p_enumerator_list3 (self, p):
0521         """enumerator_list : enumerator_list COMMA"""
0522         p[0] = p[1]
0523 
0524     def p_enumerator1 (self, p):
0525         """enumerator : ID"""
0526         enumerator = self.symbolData.Enumerator(p[1], None)
0527         p[0] = [enumerator]
0528     
0529     def p_enumerator2 (self, p):
0530         """enumerator : ID EQUALS ID"""
0531         enumerator = self.symbolData.Enumerator(p[1], "=" + p[3])
0532         p[0] = [enumerator]
0533         
0534     def p_enumerator3 (self, p):
0535         """enumerator : ID annotation"""
0536         enumerator = self.symbolData.Enumerator(p[1], None)
0537         p[0] = [enumerator]
0538         
0539     def p_enumeratorcomment(self, p):
0540         """enumeratorcomment : LINECOMMENT
0541                              | CCOMMENT
0542                              | BLANKLINE"""
0543         p[0] = [self.symbolData.EnumeratorComment(p[1])]
0544         
0545     def p_versioned_enumerator_list (self, p):
0546         """versioned_enumerator_list : sip_if enumerator_list sip_end"""
0547         p[0] = p[2]
0548 
0549     def p_id_list_element (self, p):
0550         'id_list_element : ID'
0551         p [0] = p [1]
0552         
0553     def p_id_list (self, p):
0554         """id_list : id_list_element
0555                    | id_list COMMA id_list_element"""
0556         p [0] = joinp(p, 1, "")
0557                    
0558     def p_qualified_id (self, p):
0559         """qualified_id : ID
0560                         | nested_name_specifier"""
0561         p [0] = p [1]
0562                         
0563     def p_nested_name_specifier (self, p):
0564         """nested_name_specifier : ID COLON2 ID
0565                                  | nested_name_specifier COLON2 ID
0566                                  | template_type COLON2 ID"""
0567         p [0] = joinp(p, 1, "")
0568 
0569     def p_template_type (self, p):
0570         'template_type : qualified_id LT type_specifier_list GT'
0571         p [0] = joinp(p, 1, "")
0572         #self.template = Template (p [1], p [3], self.template)
0573        
0574     def p_elaborated_type (self, p):
0575         """elaborated_type : enum qualified_id
0576                           | class qualified_id
0577                           | struct qualified_id
0578                           | union qualified_id"""
0579         p [0] = '%s %s' % (p [1], p [2])
0580     
0581     def p_type_specifier_base (self, p):
0582         """type_specifier_base : qualified_id
0583                                | template_type
0584                                | elaborated_type
0585                                | int
0586                                | unsigned int
0587                                | signed int
0588                                | char
0589                                | unsigned char
0590                                | signed char
0591                                | float
0592                                | double
0593                                | long
0594                                | long int
0595                                | unsigned long
0596                                | unsigned long int
0597                                | signed long
0598                                | signed long int
0599                                | long long
0600                                | unsigned long long
0601                                | short
0602                                | unsigned short
0603                                | signed short
0604                                | short int
0605                                | unsigned short int
0606                                | signed short int
0607                                | unsigned
0608                                | signed
0609                                | bool
0610                                | void
0611                                | wchar_t"""
0612         p[0] = joinp(p, 1)
0613 
0614     def p_type_specifier0 (self, p):
0615         'type_specifier : type_specifier_base '
0616         p [0] = p [1]
0617 
0618     def p_type_specifier1 (self, p):
0619         'type_specifier : CVQUAL type_specifier_base'
0620         p [0] = '%s %s' % (p [1], p[2])
0621                           
0622     def p_type_specifier2 (self, p):
0623         'type_specifier : type_specifier_base type_decorator'
0624         p [0] = '%s%s' % (p [1], p[2])
0625         
0626     def p_type_specifier3 (self, p):
0627         'type_specifier : CVQUAL type_specifier_base type_decorator'
0628         p [0] = '%s %s%s' % (p [1], p[2], p[3])
0629         
0630     def p_type_decorator (self, p):
0631         """type_decorator : ASTERISK CVQUAL
0632                           | AMPERSAND
0633                           | ASTERISK AMPERSAND
0634                           | ASTERISK ASTERISK
0635                           | ASTERISK ASTERISK ASTERISK
0636                           | ASTERISK"""
0637         p[0] = joinp(p, 1, "")
0638 
0639     def p_type_specifier_list (self, p):
0640         """type_specifier_list : type_specifier
0641                                | type_specifier_list COMMA type_specifier"""
0642         p[0] = joinp(p, 1, "")
0643 
0644     def p_typedef_decl (self, p):
0645         """typedef_decl : typedef_simple SEMI
0646                         | typedef_simple annotation SEMI
0647                         | typedef_function_ptr SEMI"""
0648         self._popScope()
0649         self.currentTypedef = None
0650 
0651     def p_typedef_simple (self, p):
0652         'typedef_simple : typedef type_specifier ID'
0653         self.typedefObject(p [2], p [3])
0654         self.inTypedef = True
0655         
0656     def p_pointer_to_function_args1(self, p):
0657         """pointer_to_function_args : RPAREN LPAREN type_specifier_list"""
0658         p[0] = p[3]
0659                 
0660     def p_pointer_to_function_args2(self, p):
0661         """pointer_to_function_args : RPAREN LPAREN empty"""
0662         p[0] = ""
0663                 
0664     def p_pointer_to_function2(self, p):
0665         """pointer_to_function : type_specifier FUNCPTR ID pointer_to_function_args RPAREN"""
0666         p[0] = self.symbolData.FunctionArgument(p[3], p[1], p[4])
0667 
0668     def p_typedef_function_ptr (self, p):
0669         'typedef_function_ptr : typedef pointer_to_function'
0670         tdObj = self.symbolData.FunctionPointerTypedef(self.scope, p[2], self.filename, self.lexer.lineno)
0671         tdObj.setIgnore(self.ignore)
0672         self.ignore = False
0673         tdObj.setAccess(self.access)
0674         tdObj.setForce(self.force)
0675 
0676         self.inTypedef = True
0677         
0678         self._pushScope(tdObj)
0679         self.currentTypedef = tdObj
0680         
0681     def p_array_variable (self, p):
0682         'array_variable : ID ARRAYOP'
0683         p [0] = joinp(p, 1)
0684 
0685     def p_argument_specifier0 (self, p):
0686         """argument_specifier : type_specifier
0687                               | ELLIPSIS"""
0688         p [0] = self.argument (p [1])
0689         
0690     def p_argument_specifier1 (self, p):
0691         """argument_specifier : type_specifier ID
0692                               | type_specifier array_variable"""
0693         p [0] = self.argument (p [1], p [2])
0694 
0695     def p_argument_specifier2 (self, p):
0696         'argument_specifier : type_specifier EQUALS expression'
0697         p [0] = self.argument (p [1], None, p [3])
0698         
0699     def p_argument_specifier3 (self, p):
0700         """argument_specifier : type_specifier ID EQUALS expression
0701                               | type_specifier array_variable EQUALS expression"""
0702         p [0] = self.argument (p [1], p [2], p [4])
0703         
0704     def p_argument_specifier4 (self, p):
0705         'argument_specifier : pointer_to_function'
0706         p[0] = p[1]
0707         
0708     def p_argument_specifier5 (self, p):
0709         'argument_specifier : type_specifier annotation'
0710         p [0] = self.argument (p [1], None, None, self.annotation)
0711         self.annotation  = []
0712         
0713     def p_argument_specifier6 (self, p):
0714         'argument_specifier : type_specifier ID annotation'
0715         p [0] = self.argument (p [1], p [2], None, self.annotation)
0716         self.annotation = []
0717         
0718     def p_argument_specifier7 (self, p):
0719         'argument_specifier : type_specifier annotation EQUALS expression'
0720         p [0] = self.argument (p [1], None, p [4], self.annotation)
0721         self.annotation = []
0722                
0723     def p_argument_specifier8 (self, p):
0724         'argument_specifier : type_specifier ID annotation EQUALS expression'
0725         p [0] = self.argument (p [1], p [2], p [5], self.annotation)
0726         self.annotation = []
0727                               
0728     def p_argument_list0 (self, p):
0729         """argument_list : argument_specifier"""
0730         p [0] = [p[1]]
0731         
0732     def p_argument_list1 (self, p):
0733         """argument_list : argument_list COMMA argument_specifier"""
0734         p[0] = p[1]
0735         p[1].append(p[3])
0736             
0737     def p_argument_list2 (self, p):
0738         """argument_list : argument_list COMMA type_specifier"""
0739         p[0] = p[1]
0740         p[1].append(self.argument(p[3]))
0741             
0742     def p_exception_element (self, p):
0743         'exception_element : qualified_id'
0744         p [0] = p [1]
0745         
0746     def p_exception_list (self, p):
0747         """exception_list : exception_element
0748                           | exception_list COMMA exception_element"""
0749         p [0] = joinp(p, 1, "")
0750 
0751     def p_exception (self, p):
0752         'exception : throw LPAREN exception_list RPAREN'
0753         self.stateInfo.currentObject ().exceptions = p [3]       
0754 
0755     def p_variable_decl0 (self, p):
0756         """variable_decl : argument_specifier SEMI
0757                          | argument_specifier annotation SEMI"""
0758         self.variableObject(p[1].name(), p[1].argumentType(), p[1].defaultValue())
0759         self._popScope()
0760 
0761     def p_variable_decl1 (self, p):
0762         """variable_decl : STORAGE argument_specifier SEMI
0763                          | STORAGE argument_specifier annotation SEMI"""
0764         varObj = self.variableObject(p[2].name(), p[2].argumentType(), p[2].defaultValue())
0765         varObj.setStorage(p[1])
0766         self._popScope()
0767                 
0768     def p_variable_decl2(self, p):
0769         """variable_decl : STORAGE argument_specifier LBRACE declarations RBRACE SEMI"""
0770         varObj = self.variableObject(p[2].name(), p[2].argumentType(), p[2].defaultValue())
0771         varObj.setStorage(p[1])
0772         self._popScope()
0773 
0774     def p_variable_decl3(self, p):
0775         """variable_decl : argument_specifier LBRACE declarations RBRACE SEMI"""
0776         varObj = self.variableObject(p[1].name(), p[1].argumentType(), p[1].defaultValue())
0777         self._popScope()
0778                 
0779     def p_function_name0 (self, p):
0780         'function_name : type_specifier type_specifier LPAREN'
0781         self.functionObject (p [2], p[1])
0782 
0783     def p_function_name1 (self, p):
0784         'function_name : STORAGE type_specifier ID LPAREN'
0785         fObj = self.functionObject (p [3], p[2])
0786         fObj.setStorage(p[1])
0787 
0788     def p_operator_pfx (self, p):
0789         """operator_pfx : type_specifier operator"""
0790         p [0] = p [1]
0791         
0792     def p_cast_operator_name0 (self, p):
0793         """cast_operator_name : operator_pfx type_specifier LPAREN RPAREN"""
0794         fObj = self.functionObject('operator ' + p[2], p[1])
0795         p[0] = fObj
0796 
0797     def p_cast_operator_name1 (self, p):
0798         """cast_operator_name : operator_pfx type_specifier LPAREN RPAREN CVQUAL"""
0799         fObj = self.functionObject('operator ' + p [2], p[2])
0800         fObj.addQualifier(p[5])
0801         p[0] = fObj
0802         
0803     def p_cast_operator_name2 (self, p):
0804         """cast_operator_name : operator type_specifier LPAREN RPAREN"""
0805         fObj = self.functionObject ('operator ' + p [2], p[2])
0806         p[0] = fObj        
0807         
0808     def p_operator_name (self, p):
0809         """operator_name : operator_pfx PLUS LPAREN
0810                          | operator_pfx MINUS LPAREN
0811                          | operator_pfx ASTERISK LPAREN
0812                          | operator_pfx SLASH LPAREN
0813                          | operator_pfx PERCENT LPAREN
0814                          | operator_pfx VBAR LPAREN
0815                          | operator_pfx AMPERSAND LPAREN
0816                          | operator_pfx LT LPAREN
0817                          | operator_pfx LT LT LPAREN
0818                          | operator_pfx GT LPAREN
0819                          | operator_pfx GT GT LPAREN
0820                          | operator_pfx LOR LPAREN
0821                          | operator_pfx LAND LPAREN
0822                          | operator_pfx CARET LPAREN
0823                          | operator_pfx TILDE LPAREN
0824                          | operator_pfx BANG LPAREN
0825                          | operator_pfx LE LPAREN
0826                          | operator_pfx GE LPAREN
0827                          | operator_pfx EQ LPAREN
0828                          | operator_pfx EQUALS LPAREN
0829                          | operator_pfx TIMESEQUAL LPAREN
0830                          | operator_pfx DIVEQUAL LPAREN
0831                          | operator_pfx MODEQUAL LPAREN
0832                          | operator_pfx PLUSEQUAL LPAREN
0833                          | operator_pfx MINUSEQUAL LPAREN
0834                          | operator_pfx LSHIFTEQUAL LPAREN
0835                          | operator_pfx GT GE LPAREN
0836                          | operator_pfx ANDEQUAL LPAREN
0837                          | operator_pfx OREQUAL LPAREN
0838                          | operator_pfx XOREQUAL LPAREN
0839                          | operator_pfx CARET EQUALS LPAREN
0840                          | operator_pfx PLUSPLUS LPAREN
0841                          | operator_pfx MINUSMINUS LPAREN
0842                          | operator_pfx ARRAYOP LPAREN
0843                          | operator_pfx LPAREN RPAREN LPAREN
0844                          | operator_pfx ARROW LPAREN
0845                          | operator_pfx NE LPAREN"""
0846         if len(p) == 4:
0847             self.functionObject ('operator ' + p[2], p[1])
0848         elif len(p) == 5:
0849             self.functionObject ('operator ' + p[2] + p[3], p[1])
0850 
0851     def p_operator_primary0 (self, p):
0852         """operator_primary : operator_name argument_list RPAREN"""
0853         self.currentFunction.setArguments(p[2])
0854 
0855     def p_operator_primary1 (self, p):
0856         """operator_primary : operator_name RPAREN
0857                             | cast_operator_name"""
0858         pass
0859         
0860     def p_operator_primary2 (self, p):
0861         """operator_primary : virtual operator_name RPAREN
0862                             | virtual cast_operator_name"""
0863         self.currentFunction.addQualifier('virtual')
0864 
0865     def p_operator_primary3 (self, p):
0866         """operator_primary : virtual operator_name argument_list RPAREN"""
0867         self.currentFunction.setArguments(p[3])
0868         self.currentFunction.addQualifier('virtual')
0869 
0870     def p_operator_stmt0 (self, p):
0871         """operator_stmt : operator_primary SEMI
0872                          | operator_primary exception SEMI
0873                          | operator_primary annotation SEMI
0874                          | operator_primary exception annotation SEMI
0875                          | operator_primary cpp_args SEMI
0876                          | operator_primary exception cpp_args SEMI
0877                          | operator_primary annotation cpp_args  SEMI
0878                          | operator_primary exception annotation cpp_args SEMI"""
0879         self.currentFunction.setAnnotations(self.annotation)
0880         self.annotation = []
0881         
0882     def p_operator_stmt1 (self, p):
0883         """operator_stmt : operator_primary CVQUAL SEMI
0884                          | operator_primary CVQUAL pure_virtual_suffix SEMI
0885                          | operator_primary CVQUAL exception SEMI
0886                          | operator_primary CVQUAL annotation SEMI
0887                          | operator_primary CVQUAL exception annotation SEMI
0888                          | operator_primary CVQUAL cpp_args SEMI
0889                          | operator_primary CVQUAL exception cpp_args SEMI
0890                          | operator_primary CVQUAL annotation cpp_args SEMI
0891                          | operator_primary CVQUAL exception annotation cpp_args SEMI"""
0892         self.currentFunction.setAnnotations(self.annotation)
0893         self.annotation = []
0894         self.currentFunction.addQualifier(p[2])
0895 
0896     def p_ctor_name0 (self, p):
0897         'ctor_name : ID LPAREN'
0898         self.functionObject(p[1], 'ctor')
0899         
0900     def p_ctor_name1 (self, p):
0901         'ctor_name : explicit ID LPAREN'
0902         fo = self.functionObject (p [2], 'ctor')
0903         fo.addQualifier('explicit')
0904 
0905     def p_dtor_name (self, p):
0906         'dtor_name : TILDE ID'
0907         self.functionObject(p [2], 'dtor')
0908         
0909     def p_virtual_dtor_name (self, p):
0910         'virtual_dtor_name : virtual dtor_name'
0911                             
0912     def p_function_decl (self, p):
0913         """function_decl : ctor_stmt
0914                          | dtor_stmt
0915                          | function_stmt
0916                          | operator_stmt
0917                          | virtual_stmt
0918                          | pure_virtual"""
0919         pass
0920                                  
0921     def p_function_primary0(self, p):
0922         """function_primary : function_name argument_list RPAREN"""
0923         self.currentFunction.setArguments(p[2])
0924  
0925     def p_function_primary1(self, p):
0926         """function_primary : function_name RPAREN"""
0927         pass
0928 
0929     def p_cpp_args (self, p):
0930         'cpp_args : LBRACKET type_specifier cpp_arg_list RBRACKET'
0931         p[0] = (p[2],p[3])
0932         
0933     def p_cpp_arg_list1 (self, p):
0934         """cpp_arg_list : LPAREN argument_list RPAREN"""
0935         p[0] = p[2]
0936         
0937     def p_cpp_arg_list2 (self, p):
0938         """cpp_arg_list : LPAREN RPAREN"""
0939         p[0] = []
0940         
0941     def p_cpp_ctor_args (self, p):
0942         'cpp_ctor_args : LBRACKET cpp_arg_list RBRACKET'
0943         p[0] = p[2]
0944                 
0945     def p_function_stmt0(self, p):
0946         """function_stmt : function_primary stmt_end
0947                          | function_primary exception stmt_end
0948                          | function_primary annotation stmt_end
0949                          | function_primary exception annotation stmt_end"""
0950         self.currentFunction.setAnnotations(self.annotation)
0951         self.annotation = []
0952                          
0953     def p_function_stmt1(self, p):
0954         """function_stmt : function_primary cpp_args stmt_end
0955                          | function_primary exception cpp_args stmt_end
0956                          | function_primary annotation cpp_args stmt_end
0957                          | function_primary exception annotation cpp_args stmt_end"""
0958         self.currentFunction.setAnnotations(self.annotation)
0959         self.annotation = []
0960         tp = [x for x in p]
0961         self.currentFunction.setCppReturn(tp[-2][0])
0962         self.currentFunction.setCppArgs(tp[-2][1])
0963         
0964     def p_function_stmt2(self, p):
0965         """function_stmt : function_primary CVQUAL stmt_end
0966                          | function_primary CVQUAL exception stmt_end
0967                          | function_primary CVQUAL annotation stmt_end
0968                          | function_primary CVQUAL exception annotation stmt_end"""
0969         self.currentFunction.addQualifier(p[2])
0970         self.currentFunction.setAnnotations(self.annotation)
0971         self.annotation = []
0972                          
0973     def p_function_stmt3(self, p):
0974         """function_stmt : function_primary CVQUAL cpp_args stmt_end
0975                          | function_primary CVQUAL exception cpp_args stmt_end
0976                          | function_primary CVQUAL annotation cpp_args stmt_end
0977                          | function_primary CVQUAL exception annotation cpp_args stmt_end"""
0978         self.currentFunction.addQualifier(p[2])
0979         self.currentFunction.setAnnotations(self.annotation)
0980         self.annotation = []
0981         tp = [x for x in p]
0982         self.currentFunction.setCppReturn(tp[-2][0])
0983         self.currentFunction.setCppArgs(tp[-2][1])
0984         
0985     def p_function_stmt4(self, p):
0986         'function_stmt : function_primary EQUALS ICONST stmt_end'
0987         self.currentFunction.setAnnotations(self.annotation)
0988         self.annotation = []
0989         self.currentFunction.addQualifier('virtual')
0990 
0991     def p_ctor_primary0(self, p):
0992         """ctor_primary : ctor_name RPAREN"""
0993         pass
0994 
0995     def p_ctor_primary1(self, p):
0996         """ctor_primary : ctor_name argument_list RPAREN"""
0997         self.currentFunction.setArguments(p[2])
0998         
0999     def p_ctor_stmt1 (self, p):
1000         """ctor_stmt : ctor_primary stmt_end
1001                      | ctor_primary annotation stmt_end"""
1002         self.currentFunction.setAnnotations(self.annotation)
1003         self.annotation = []
1004         
1005     def p_ctor_stmt2 (self, p):
1006         """ctor_stmt : ctor_primary cpp_ctor_args stmt_end
1007                      | ctor_primary annotation cpp_ctor_args stmt_end"""
1008         self.currentFunction.setAnnotations(self.annotation)
1009         self.annotation = []
1010         tp = [x for x in p]
1011         self.currentFunction.setCppArgs(tp[-2])
1012         
1013     def p_dtor_primary0 (self, p):
1014         'dtor_primary : dtor_name LPAREN RPAREN'
1015         pass
1016         
1017     def p_dtor_primary1 (self, p):
1018         """dtor_primary : virtual_dtor_name LPAREN RPAREN"""
1019         self.currentFunction.addQualifier('virtual')
1020 
1021     def p_dtor_primary2 (self, p):
1022         """dtor_primary : virtual_dtor_name LPAREN RPAREN pure_virtual_suffix"""
1023         self.currentFunction.addQualifier('pure')
1024         self.currentFunction.addQualifier('virtual')
1025         
1026     def p_dtor_stmt (self, p):
1027         'dtor_stmt : dtor_primary stmt_end'
1028         pass
1029         
1030     def p_virtual_primary0(self, p):
1031         """virtual_primary : virtual function_name RPAREN
1032                            | STORAGE virtual function_name RPAREN"""
1033         if p [1] != 'virtual':
1034             self.currentFunction.setStorage(p[1])
1035             
1036     def p_virtual_primary1(self, p):
1037         """virtual_primary : virtual function_name argument_list RPAREN
1038                            | STORAGE virtual function_name argument_list RPAREN"""
1039         if p[1] != 'virtual':
1040             self.currentFunction.setStorage(p[1])
1041             self.currentFunction.setArguments(p[4])
1042         else:
1043             self.currentFunction.setArguments(p[3])
1044         
1045     def p_virtual_stmt0 (self, p):
1046         """virtual_stmt : virtual_primary SEMI
1047                         | virtual_primary exception SEMI"""
1048         self.currentFunction.addQualifier('virtual')
1049 
1050     def p_virtual_stmt1 (self, p):
1051         """virtual_stmt : virtual_primary CVQUAL SEMI
1052                         | virtual_primary CVQUAL exception SEMI"""
1053         self.currentFunction.addQualifier('virtual')
1054         self.currentFunction.addQualifier(p[2])
1055 
1056     def p_virtual_stmt2 (self, p):
1057         """virtual_stmt : virtual_primary annotation SEMI
1058                         | virtual_primary exception annotation SEMI"""
1059         self.currentFunction.setAnnotations(self.annotation)
1060         self.annotation = []
1061         self.currentFunction.addQualifier('virtual')
1062 
1063     def p_virtual_stmt3 (self, p):
1064         """virtual_stmt : virtual_primary annotation cpp_args SEMI
1065                         | virtual_primary cpp_args SEMI
1066                         | virtual_primary exception annotation cpp_args SEMI
1067                         | virtual_primary exception cpp_args SEMI"""
1068         self.currentFunction.setAnnotations(self.annotation)
1069         self.annotation = []
1070         self.currentFunction.addQualifier('virtual')
1071         tp = [x for x in p]
1072         self.currentFunction.setCppReturn(tp[-2][0])
1073         self.currentFunction.setCppArgs(tp[-2][1])
1074         
1075     def p_virtual_stmt4 (self, p):
1076         """virtual_stmt : virtual_primary CVQUAL annotation SEMI
1077                         | virtual_primary CVQUAL exception annotation SEMI"""
1078         self.currentFunction.setAnnotations(self.annotation)
1079         self.annotation = []
1080         self.currentFunction.addQualifier('virtual')
1081         self.currentFunction.addQualifier(p[2])
1082 
1083     def p_virtual_stmt5 (self, p):
1084         """virtual_stmt : virtual_primary CVQUAL annotation cpp_args SEMI
1085                         | virtual_primary CVQUAL cpp_args SEMI
1086                         | virtual_primary CVQUAL exception annotation cpp_args SEMI
1087                         | virtual_primary CVQUAL exception cpp_args SEMI"""
1088         self.currentFunction.setAnnotations(self.annotation)
1089         self.annotation = []
1090         self.currentFunction.addQualifier('virtual')
1091         self.currentFunction.addQualifier(p[2])
1092         tp = [x for x in p]
1093         self.currentFunction.setCppReturn(tp[-2][0])
1094         self.currentFunction.setCppArgs(tp[-2][1])
1095         
1096     def p_pure_virtual_suffix1(self, p):
1097         """pure_virtual_suffix : EQUALS ICONST
1098                                | EQUALS ICONST annotation"""
1099         self.currentFunction.setAnnotations(self.annotation)
1100         self.annotation = []
1101 
1102     def p_pure_virtual_suffix2(self, p):
1103         """pure_virtual_suffix : EQUALS ICONST annotation cpp_args
1104                                | EQUALS ICONST cpp_args"""
1105         self.currentFunction.setAnnotations(self.annotation)
1106         self.annotation = []
1107         tp = [x for x in p]
1108         self.currentFunction.setCppReturn(tp[-1][0])
1109         self.currentFunction.setCppArgs(tp[-1][1])
1110         
1111     def p_pure_virtual (self, p):
1112         """pure_virtual : virtual_primary pure_virtual_suffix SEMI
1113                         | virtual_primary CVQUAL pure_virtual_suffix SEMI
1114                         | virtual_primary exception pure_virtual_suffix SEMI
1115                         | virtual_primary CVQUAL exception pure_virtual_suffix SEMI"""
1116         self.currentFunction.addQualifier('pure')
1117         self.currentFunction.addQualifier('virtual')
1118         if p [2] in ['const', 'volatile']:
1119             self.currentFunction.addQualifier(p[2])
1120         
1121     def p_template_param (self, p):
1122         """template_param : type_specifier
1123                          | type_specifier ID"""
1124         self.templateParams.append (joinp(p, 1))
1125 
1126     def p_template_param_list (self, p):
1127         """template_param_list : template_param
1128                               | template_param_list COMMA template_param"""
1129         pass
1130         
1131     def p_template_decl (self, p):
1132         'template_decl : template LT template_param_list GT'
1133         self.inTemplate = ','.join (self.templateParams)
1134         self.templateParams = []
1135 
1136 ##    def p_template_decl (self, p):
1137 ##        'template_decl : template LT type_specifier_list GT'
1138 ##        self.stateInfo.inTemplate = p [3]
1139         
1140     def p_sip_block (self, p):
1141         'sip_block : sip_block_header BLOCK_BODY'
1142         body = p[1] + p[2]
1143         if p[1]=='%MethodCode':
1144             blockObj = self.sipBlockObject(p[1])
1145             blockObj.setBody(body)
1146             self._lastEntity().addBlock(blockObj)
1147         else:
1148             sipDirectiveObj = self.sipDirectiveObject(p[1])
1149             sipDirectiveObj.setBody(body)
1150         
1151     def p_sip_block_header (self, p):
1152         'sip_block_header : PERCENT BLOCK'
1153         p[0] = joinp(p, 1, "")
1154 
1155     def p_sip_stmt (self, p):
1156         'sip_stmt : sip_stmt_header SIPSTMT_BODY'
1157         p[0] = joinp(p, 1, "\n")
1158         self._lastEntity().setBody(joinp(p, 1, "\n"))
1159         
1160     def p_sip_stmt_header (self, p):
1161         """sip_stmt_header : PERCENT SIPSTMT type_specifier
1162                            | PERCENT SIPSTMT type_specifier annotation
1163                            | PERCENT SIPSTMT qualified_id LPAREN qualified_id RPAREN"""
1164         if len(p)==5:
1165             p[0] = '%%%s %s /%s/' % (p[2], p[3], ''.join(p[4]))
1166         else:
1167             p[0] = '%%%s %s' % (p[2], joinp(p, 3, ""))
1168         #if len(p) == 7:
1169         #    sipTypeObj.base = p [5]
1170         if not self.inTemplate:
1171             self.symbolData.SipType(self.scope, self.filename, self.lexer.lineno)
1172         else:
1173             template = self.symbolData.Template(self.scope, self.filename, self.lexer.lineno)
1174             template.setParameters(self.inTemplate)
1175             
1176             self.scope = template
1177             sipType = self.symbolData.SipType(self.scope, self.filename, self.lexer.lineno)
1178             self.inTemplate = None
1179                 
1180     def p_cmodule (self, p):
1181         """cmodule : PERCENT CModule ID
1182                    | PERCENT CModule ID ICONST"""
1183         directive = self.sipDirectiveObject ('CModule')
1184         directive.setBody('%CModule' + joinp(p, 2, ","))
1185 
1186     def p_comp_module (self, p):
1187         'comp_module : PERCENT CompositeModule ID'
1188         directive = self.sipDirectiveObject ('CompositeModule')
1189         directive.setBody('%CompositeModule ' + p[2])
1190 
1191     def p_cons_module (self, p):
1192         'cons_module : PERCENT ConsolidatedModule ID'
1193         directive = self.sipDirectiveObject ('ConsolidatedModule')
1194         directive.setBody('%ConsolidatedModule ' +p[2])
1195         
1196     def p_feature (self, p):
1197         'feature : PERCENT Feature ID'
1198         directive = self.sipDirectiveObject ('Feature')
1199         directive.setBody('%Feature ' + p[3])
1200 
1201     def p_plugin (self, p):
1202         'plugin : PERCENT Plugin ID'
1203         directive = self.sipDirectiveObject ('Plugin')
1204         directive.setBody('%Plugin ' + p[3])
1205 
1206     def p_defaultencoding (self, p):
1207         'defaultencoding : PERCENT DefaultEncoding STRING'
1208 
1209     def p_defaultmetatype (self, p):
1210         'defaultmetatype : PERCENT DefaultMetatype DOTTEDNAME'
1211 
1212     def p_defaultsupertype (self, p):
1213         'defaultsupertype : PERCENT DefaultSupertype DOTTEDNAME'
1214 
1215     def p_if_expression (self, p):
1216         """if_expression : ored_qualifiers
1217                          | range"""
1218         self._pushVersion( (self.versionLow, self.versionHigh, self.platform) )
1219 
1220     def p_ored_qualifiers (self, p):
1221         """ored_qualifiers : if_qualifier
1222                            | ored_qualifiers VBAR VBAR if_qualifier
1223                            | ored_qualifiers LOR if_qualifier"""
1224         p [0] = joinp(p, 1, "")
1225         self.platform = p [0]
1226 
1227     def p_if_qualifier (self, p):
1228         """if_qualifier : ID
1229                         | BANG ID"""
1230         p [0] = p [1]
1231 
1232     def p_range0 (self, p):
1233         'range : ID MINUS'
1234         self.versionLow  = p [1]
1235         self.versionHigh = ''
1236         
1237     def p_range1 (self, p):
1238         'range : MINUS ID'
1239         self.versionHigh = p [2]
1240         self.versionLow  = ''
1241         
1242     def p_range2 (self, p):
1243         'range : ID MINUS ID'
1244         self.versionLow  = p [1]
1245         self.versionHigh = p [3]
1246         
1247     def p_sip_if (self, p):
1248         """sip_if : PERCENT If LPAREN if_expression RPAREN"""
1249         pass
1250     
1251     def p_api (self, p):
1252         """api : PERCENT API ID ICONST
1253                | PERCENT API keypairs"""
1254         pass
1255         
1256     def p_sip_end (self, p):
1257         'sip_end : PERCENT End'
1258         self.versionLow, self.versionHigh, self.platform = self._popVersion()
1259 
1260     def p_import (self, p):
1261         'import : PERCENT Import FILENAME'
1262         directive = self.sipDirectiveObject('Import')
1263         directive.setBody('%Import ' + p[3])
1264         
1265     def p_include (self, p):
1266         """include : PERCENT Include FILENAME"""
1267         directive = self.sipDirectiveObject('Include')
1268         directive.setBody('%Include ' + p[3])
1269         
1270     def p_include2(self, p):    
1271         """include : PERCENT Include keypairs"""
1272         directive = self.sipDirectiveObject('Include')
1273         directive.setKeypairs(p[3])
1274         directive.setBody("%" + p[2] + "(" + ", ".join( (x[0]+"="+x[1] for x in p[3]) ) + ")")
1275         
1276     def p_license_annot (self, p):
1277         'license_annot : licenseAnnotation'
1278         p [0] = p [1]
1279         
1280     def p_license_annot_list (self, p):
1281         """license_annot_list : license_annot
1282                               | license_annot_list COMMA license_annot"""
1283         p[0] = joinp(p, 1, "")
1284 
1285     def p_license (self, p):
1286         'license : PERCENT License SLASH license_annot_list SLASH'
1287         directive = self.sipDirectiveObject('License')
1288         directive.setBody(p[4])
1289         
1290     def p_module(self, p):
1291         """module : PERCENT Module FILENAME
1292                   | PERCENT Module FILENAME ICONST"""
1293         directive = self.sipDirectiveObject('Module')
1294         directive.setBody("%" + joinp(p, 2))
1295 
1296     def p_module2(self, p):
1297         """module : PERCENT Module keypairs
1298                   | PERCENT Module keypairs ICONST"""
1299         directive = self.sipDirectiveObject('Module')
1300         directive.setKeypairs(p[3])
1301         directive.setBody("%" + p[2] + "(" + ", ".join( (x[0]+"="+x[1] for x in p[3]) ) + ")")
1302 
1303     def p_keypairs(self, p):
1304         """keypairs : LPAREN keypair_list RPAREN"""
1305         p[0] = p[2]
1306         
1307     def p_keypairlist2(self, p):
1308         """keypair_list : keypair"""
1309         p[0] = [p[1]]
1310         
1311     def p_keypair(self, p):
1312         """keypair : FILENAME EQUALS FILENAME
1313                    | FILENAME EQUALS STRING"""
1314         p[0] = (p[1],p[3])
1315 
1316     def p_keypairlist(self, p):
1317         """keypair_list : keypair_list COMMA keypair"""
1318         new_list = list(p[1])
1319         new_list.append(p[3])
1320         p[0] = new_list
1321 
1322     def p_optional_include (self, p):
1323         'optional_include : PERCENT OptionalInclude FILENAME'
1324         directive = self.sipDirectiveObject('OptionalInclude')
1325         directive.setBody('%OptionalInclude ' + p[3])
1326 
1327     def p_undelimited_id_list (self, p):
1328         """undelimited_id_list : ID
1329                                | undelimited_id_list ID"""
1330         p[0] = joinp(p, 1)
1331 
1332     def p_platforms (self, p):
1333         'platforms : PERCENT Platforms LBRACE undelimited_id_list RBRACE'
1334         directive = self.sipDirectiveObject('Platforms')
1335         directive.setBody('%Platforms {' + p[4] + '}')
1336         
1337     def p_sipOptions (self, p):
1338         'sipOptions : PERCENT SIPOptions LPAREN id_list RPAREN'
1339         directive = self.sipDirectiveObject('SIPOptions')
1340         directive.setBody('%SIPOptions {' + p[4] + '}')
1341                     
1342     def p_timeline (self, p):
1343         'timeline : PERCENT Timeline LBRACE undelimited_id_list RBRACE'
1344         directive = self.sipDirectiveObject('Timeline')
1345         directive.setBody('%Timeline {' + p[4] + '}')
1346         
1347     def p_object_ignore (self, p):
1348         'object_ignore : IG'
1349         self.ignore = True
1350 
1351     def p_object_force (self, p):
1352         'object_force : FORCE'
1353         self.force = True
1354 
1355     def p_object_end (self, p):
1356         'object_end : END'
1357         self.force = False
1358 
1359 # expression handling for argument default values - just parses and
1360 # then reassembles the default value expression (no evaluation)
1361 
1362     def p_expression0 (self, p):
1363         """expression : add_expression
1364                       | sub_expression
1365                       | mult_expression
1366                       | div_expression
1367                       | mod_expression
1368                       | unary_expression
1369                       | or_expression
1370                       | and_expression
1371                       | xor_expression
1372                       | bitor_expression
1373                       | bitand_expression
1374                       | lt_expression
1375                       | le_expression
1376                       | eq_expression
1377                       | ge_expression
1378                       | gt_expression
1379                       | lshift_expression
1380                       | rshift_expression
1381                       | arrow_expression
1382                       | ICONST
1383                       | FCONST
1384                       | HEXCONST
1385                       | CCONST
1386                       | SCONST"""      
1387         p [0] = p [1]
1388             
1389     def p_expression1 (self, p):
1390         'expression : LPAREN expression RPAREN'
1391         p[0] = joinp(p, 1, "")
1392 
1393     def p_expression2 (self, p):
1394         'expression : qualified_id'
1395         p [0] = p [1]
1396     
1397     def p_expression3 (self, p):
1398         """expression : type_specifier LPAREN expression_list RPAREN
1399                       | type_specifier LPAREN RPAREN"""
1400         p[0] = joinp(p, 1, "")
1401 
1402     def p_expression_list (self, p):
1403         """expression_list : expression
1404                            | expression_list COMMA expression"""
1405         p[0] = joinp(p, 1, "")
1406 
1407     def p_unary_expression (self, p):
1408         """unary_expression : sign_expression
1409                             | not_expression
1410                             | bitnot_expression"""
1411         p [0] = p [1]
1412 
1413     def p_add_expression (self, p):
1414         'add_expression : expression PLUS expression'
1415         p[0] = joinp(p, 1, "")
1416 
1417     def p_sub_expression (self, p):
1418         'sub_expression : expression MINUS expression'
1419         p[0] = joinp(p, 1, "")
1420 
1421     def p_mult_expression (self, p):
1422         'mult_expression : expression ASTERISK expression'
1423         p[0] = joinp(p, 1, "")
1424 
1425     def p_div_expression (self, p):
1426         'div_expression : expression SLASH expression'
1427         p[0] = joinp(p, 1, "")
1428 
1429     def p_mod_expression (self, p):
1430         'mod_expression : expression PERCENT expression'
1431         p[0] = joinp(p, 1, "")
1432 
1433     def p_sign_expression (self, p):
1434         'sign_expression : MINUS expression %prec UMINUS'
1435         p[0] = joinp(p, 1, "")
1436 
1437     def p_or_expression (self, p):
1438         'or_expression : expression LOR expression'
1439         p[0] = joinp(p, 1, "")
1440 
1441     def p_and_expression (self, p):
1442         'and_expression : expression LAND expression'
1443         p[0] = joinp(p, 1, "")
1444 
1445     def p_xor_expression (self, p):
1446         'xor_expression : expression CARET expression'
1447         p[0] = joinp(p, 1, "")
1448 
1449     def p_bitor_expression (self, p):
1450         'bitor_expression : expression VBAR expression'
1451         p[0] = joinp(p, 1, "")
1452 
1453     def p_bitand_expression (self, p):
1454         'bitand_expression : expression AMPERSAND expression'
1455         p[0] = joinp(p, 1, "")
1456 
1457     def p_lt_expression (self, p):
1458         'lt_expression : expression LT expression'
1459         p[0] = joinp(p, 1, "")
1460 
1461     def p_le_expression (self, p):
1462         'le_expression : expression LE expression'
1463         p[0] = joinp(p, 1, "")
1464 
1465     def p_eq_expression (self, p):
1466         'eq_expression : expression EQ expression'
1467         p[0] = joinp(p, 1, "")
1468 
1469     def p_ge_expression (self, p):
1470         'ge_expression : expression GE expression'
1471         p[0] = joinp(p, 1, "")
1472 
1473     def p_gt_expression (self, p):
1474         'gt_expression : expression GT expression'
1475         p[0] = joinp(p, 1, "")
1476 
1477     def p_lshift_expression (self, p):
1478         'lshift_expression : expression GT GT expression'
1479         p[0] = joinp(p, 1, "")
1480 
1481     def p_rshift_expression (self, p):
1482         'rshift_expression : expression LT LT expression'
1483         p[0] = joinp(p, 1, "")
1484 
1485     def p_not_expression (self, p):
1486         'not_expression : BANG expression'
1487         p[0] = joinp(p, 1, "")
1488 
1489     def p_bitnot_expression (self, p):
1490         'bitnot_expression : TILDE expression'
1491         p[0] = joinp(p, 1, "")
1492 
1493     def p_arrow_expression (self, p):
1494         'arrow_expression : expression ARROW expression'
1495         p[0] = joinp(p, 1, "")
1496 
1497     def p_error(self, p):
1498         if p is not None:
1499             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))
1500         else:
1501             print("File: " + repr(self.filename) + " Line: " + str(self.lexer.lineno) + " Syntax error in input. Lex state: %s" % (self.lexer.lexstate,) )
1502         sys.exit (-1)
1503 
1504         
1505 if __name__ == '__main__':
1506 
1507     text = """
1508 enum global {earth, orb, globe};    
1509 
1510 namespace foo
1511 {    
1512 enum fooEnum {apples, peaches, pumpkin_pie};
1513 class bar
1514 {
1515 public:
1516     bar ();
1517     explict bar(int x);
1518     int baz ();
1519     int baz (double, long) [int (double, long)];
1520     QString method (int foo = 0);
1521     bar (int);
1522     bar (int, QList<QString>);
1523     QTextStream &operator<<(double f /Constrained/);
1524 //    QTextStream &operator<<(bool b /Constrained/) [QTextStream & (QBool b /Constrained/)];
1525     QTextStream &foosiggy(bool b /Constrained/) [QTextStream & (QBool b /Constrained/)];
1526 
1527 enum barEnum {
1528     peas,
1529     carrots,
1530     beans
1531     } veggies;
1532 typedef global::qint inttype;    
1533 };
1534 typedef QList<QPair<QString,QString>> stringpairlist;
1535 typedef QString& stringref;
1536 typedef QObject* objPtr;
1537 typedef QObject** objPtrPtr;
1538 typedef QString*& reftoStringPtr;
1539 enum tail {end, posterior, ass};
1540 };
1541     int baz ();
1542     virtual int baz (double);
1543     int baz (double, long long);
1544     int baz (double, long, unsigned long = ulong);
1545     virtual const QString& method (int foo = 0) = 0;
1546     QString method (int foo = 0, long fool = 20);
1547     bar (int, QList<QString>);
1548     char* tmpl (QPair<QString, QString*> pair, const int foo);
1549     const char* string (QObject* object = QObject::type ());
1550     int varInt;
1551     bar (int);
1552     bar (int a[40]);
1553     char *c[10];
1554     typedef void (* fptr)(int, double*);
1555     typedef int (* otherptr)();
1556     bool test (int, int);
1557     bool operator == (int);
1558     int operator + (double);
1559     int operator >> (int);
1560     bool operator <<= (int a, int b);
1561     double (*doublePtr)();
1562     void* foo (int, double (*doublePtr)(float, QString*));
1563     void* foo (int, double (*doublePtr)());
1564     void plug ();
1565 kdecore::KAccel raise (QWidget elab);
1566     typedef QList<QPair<int,QString*>>\
1567     (* seven)();
1568 %MappedType FooBar
1569 {
1570 %ConvertToTypeCode
1571 %End
1572 %ConverFromTypeCode
1573 %End
1574 };
1575 %AccessCode
1576 something goes in here
1577 for a few lines
1578 %End
1579 """
1580 
1581 #    text = """virtual bool operator<(const QListWidgetItem &other) const;
1582 #    """
1583 ##    void update(const QRectF & = QRectF(0.0, 0.0, 1.0e+9, 1.0e+9));
1584 ##    static void singleShot(int msec, SIP_RXOBJ_CON receiver, SIP_SLOT_CON() member);    
1585 ##    %MappedType QList<TYPE>
1586 ##    QCoreApplication(SIP_PYLIST argv) /PostHook=__pyQtQAppHook/ [(int &argc, char **argv)];
1587 ##    mutable virtual KAccel raise (float** zero /In, Out/) volatile  throw (bar, baz)/PyName=foo_bar/;"""
1588 ##    virtual bool open(QFlags<QIODevice::OpenModeFlag> openMode) /ReleaseGIL/;
1589 ##    static QAbstractEventDispatcher *instance(QThread *thread = 0);
1590 ##    QFlags &operator^=(QFlags f);
1591 ##    %Timeline {Qt_4_1_0  Qt_4_1_1  Qt_4_1_2  Qt_4_2_0}
1592 ##    // hello - I'm a C++ comment
1593 ##    static virtual unsigned short has_icon (someEnum zero /Transfer/ = flags(abc) | flags(xyz)) volatile/PyName=foo_bar, Transfer/;
1594 ##    """