PageRenderTime 57ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 1ms

/python/cxxtest/cxx_parser.py

https://github.com/kindkaktus/cxxtest
Python | 2204 lines | 2143 code | 15 blank | 46 comment | 4 complexity | deddbfdf731136d715664b450b5a616c MD5 | raw file
Possible License(s): LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. #-------------------------------------------------------------------------
  2. # CxxTest: A lightweight C++ unit testing library.
  3. # Copyright (c) 2008 Sandia Corporation.
  4. # This software is distributed under the LGPL License v3
  5. # For more information, see the COPYING file in the top CxxTest directory.
  6. # Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  7. # the U.S. Government retains certain rights in this software.
  8. #-------------------------------------------------------------------------
  9. # vim: fileencoding=utf-8
  10. #
  11. # This is a PLY parser for the entire ANSI C++ grammar. This grammar was
  12. # adapted from the FOG grammar developed by E. D. Willink. See
  13. #
  14. # http://www.computing.surrey.ac.uk/research/dsrg/fog/
  15. #
  16. # for further details.
  17. #
  18. # The goal of this grammar is to extract information about class, function and
  19. # class method declarations, along with their associated scope. Thus, this
  20. # grammar can be used to analyze classes in an inheritance heirarchy, and then
  21. # enumerate the methods in a derived class.
  22. #
  23. # This grammar parses blocks of <>, (), [] and {} in a generic manner. Thus,
  24. # There are several capabilities that this grammar does not support:
  25. #
  26. # 1. Ambiguous template specification. This grammar cannot parse template
  27. # specifications that do not have paired <>'s in their declaration. In
  28. # particular, ambiguous declarations like
  29. #
  30. # foo<A, c<3 >();
  31. #
  32. # cannot be correctly parsed.
  33. #
  34. # 2. Template class specialization. Although the goal of this grammar is to
  35. # extract class information, specialization of templated classes is
  36. # not supported. When a template class definition is parsed, it's
  37. # declaration is archived without information about the template
  38. # parameters. Class specializations will be stored separately, and
  39. # thus they can be processed after the fact. However, this grammar
  40. # does not attempt to correctly process properties of class inheritence
  41. # when template class specialization is employed.
  42. #
  43. #
  44. # TODO: document usage of this file
  45. #
  46. from __future__ import division
  47. import os
  48. import ply.lex as lex
  49. import ply.yacc as yacc
  50. import re
  51. try:
  52. from collections import OrderedDict
  53. except ImportError: #pragma: no cover
  54. from ordereddict import OrderedDict
  55. # global data
  56. lexer = None
  57. scope_lineno = 0
  58. identifier_lineno = {}
  59. _parse_info=None
  60. _parsedata=None
  61. noExceptionLogic = True
  62. def ply_init(data):
  63. global _parsedata
  64. _parsedata=data
  65. class Scope(object):
  66. def __init__(self,name,abs_name,scope_t,base_classes,lineno):
  67. self.function=[]
  68. self.name=name
  69. self.scope_t=scope_t
  70. self.sub_scopes=[]
  71. self.base_classes=base_classes
  72. self.abs_name=abs_name
  73. self.lineno=lineno
  74. def insert(self,scope):
  75. self.sub_scopes.append(scope)
  76. class CppInfo(object):
  77. def __init__(self, filter=None):
  78. self.verbose=0
  79. if filter is None:
  80. self.filter=re.compile("[Tt][Ee][Ss][Tt]|createSuite|destroySuite")
  81. else:
  82. self.filter=filter
  83. self.scopes=[""]
  84. self.index=OrderedDict()
  85. self.index[""]=Scope("","::","namespace",[],1)
  86. self.function=[]
  87. def push_scope(self,ns,scope_t,base_classes=[]):
  88. name = self.scopes[-1]+"::"+ns
  89. if self.verbose>=2:
  90. print "-- Starting "+scope_t+" "+name
  91. self.scopes.append(name)
  92. self.index[name] = Scope(ns,name,scope_t,base_classes,scope_lineno-1)
  93. def pop_scope(self):
  94. scope = self.scopes.pop()
  95. if self.verbose>=2:
  96. print "-- Stopping "+scope
  97. return scope
  98. def add_function(self, fn):
  99. fn = str(fn)
  100. if self.filter.search(fn):
  101. self.index[self.scopes[-1]].function.append((fn, identifier_lineno.get(fn,lexer.lineno-1)))
  102. tmp = self.scopes[-1]+"::"+fn
  103. if self.verbose==2:
  104. print "-- Function declaration "+fn+" "+tmp
  105. elif self.verbose==1:
  106. print "-- Function declaration "+tmp
  107. def get_functions(self,name,quiet=False):
  108. if name == "::":
  109. name = ""
  110. scope = self.index[name]
  111. fns=scope.function
  112. for key in scope.base_classes:
  113. cname = self.find_class(key,scope)
  114. if cname is None:
  115. if not quiet:
  116. print "Defined classes: ",list(self.index.keys())
  117. print "WARNING: Unknown class "+key
  118. else:
  119. fns += self.get_functions(cname,quiet)
  120. return fns
  121. def find_class(self,name,scope):
  122. if ':' in name:
  123. if name in self.index:
  124. return name
  125. else:
  126. return None
  127. tmp = scope.abs_name.split(':')
  128. name1 = ":".join(tmp[:-1] + [name])
  129. if name1 in self.index:
  130. return name1
  131. name2 = "::"+name
  132. if name2 in self.index:
  133. return name2
  134. return None
  135. def __repr__(self):
  136. return str(self)
  137. def is_baseclass(self,cls,base):
  138. '''Returns true if base is a base-class of cls'''
  139. if cls in self.index:
  140. bases = self.index[cls]
  141. elif "::"+cls in self.index:
  142. bases = self.index["::"+cls]
  143. else:
  144. return False
  145. #raise IOError, "Unknown class "+cls
  146. if base in bases.base_classes:
  147. return True
  148. for name in bases.base_classes:
  149. if self.is_baseclass(name,base):
  150. return True
  151. return False
  152. def __str__(self):
  153. ans=""
  154. keys = list(self.index.keys())
  155. keys.sort()
  156. for key in keys:
  157. scope = self.index[key]
  158. ans += scope.scope_t+" "+scope.abs_name+"\n"
  159. if scope.scope_t == "class":
  160. ans += " Base Classes: "+str(scope.base_classes)+"\n"
  161. for fn in self.get_functions(scope.abs_name):
  162. ans += " "+fn+"\n"
  163. else:
  164. for fn in scope.function:
  165. ans += " "+fn+"\n"
  166. return ans
  167. def flatten(x):
  168. """Flatten nested list"""
  169. try:
  170. strtypes = basestring
  171. except: # for python3 etc
  172. strtypes = (str, bytes)
  173. result = []
  174. for el in x:
  175. if hasattr(el, "__iter__") and not isinstance(el, strtypes):
  176. result.extend(flatten(el))
  177. else:
  178. result.append(el)
  179. return result
  180. #
  181. # The lexer (and/or a preprocessor) is expected to identify the following
  182. #
  183. # Punctuation:
  184. #
  185. #
  186. literals = "+-*/%^&|~!<>=:()?.\'\"\\@$;,"
  187. #
  188. reserved = {
  189. 'private' : 'PRIVATE',
  190. 'protected' : 'PROTECTED',
  191. 'public' : 'PUBLIC',
  192. 'bool' : 'BOOL',
  193. 'char' : 'CHAR',
  194. 'double' : 'DOUBLE',
  195. 'float' : 'FLOAT',
  196. 'int' : 'INT',
  197. 'long' : 'LONG',
  198. 'short' : 'SHORT',
  199. 'signed' : 'SIGNED',
  200. 'unsigned' : 'UNSIGNED',
  201. 'void' : 'VOID',
  202. 'wchar_t' : 'WCHAR_T',
  203. 'class' : 'CLASS',
  204. 'enum' : 'ENUM',
  205. 'namespace' : 'NAMESPACE',
  206. 'struct' : 'STRUCT',
  207. 'typename' : 'TYPENAME',
  208. 'union' : 'UNION',
  209. 'const' : 'CONST',
  210. 'volatile' : 'VOLATILE',
  211. 'auto' : 'AUTO',
  212. 'explicit' : 'EXPLICIT',
  213. 'export' : 'EXPORT',
  214. 'extern' : 'EXTERN',
  215. '__extension__' : 'EXTENSION',
  216. 'friend' : 'FRIEND',
  217. 'inline' : 'INLINE',
  218. 'mutable' : 'MUTABLE',
  219. 'register' : 'REGISTER',
  220. 'static' : 'STATIC',
  221. 'template' : 'TEMPLATE',
  222. 'typedef' : 'TYPEDEF',
  223. 'using' : 'USING',
  224. 'virtual' : 'VIRTUAL',
  225. 'asm' : 'ASM',
  226. 'break' : 'BREAK',
  227. 'case' : 'CASE',
  228. 'catch' : 'CATCH',
  229. 'const_cast' : 'CONST_CAST',
  230. 'continue' : 'CONTINUE',
  231. 'default' : 'DEFAULT',
  232. 'delete' : 'DELETE',
  233. 'do' : 'DO',
  234. 'dynamic_cast' : 'DYNAMIC_CAST',
  235. 'else' : 'ELSE',
  236. 'false' : 'FALSE',
  237. 'for' : 'FOR',
  238. 'goto' : 'GOTO',
  239. 'if' : 'IF',
  240. 'new' : 'NEW',
  241. 'operator' : 'OPERATOR',
  242. 'reinterpret_cast' : 'REINTERPRET_CAST',
  243. 'return' : 'RETURN',
  244. 'sizeof' : 'SIZEOF',
  245. 'static_cast' : 'STATIC_CAST',
  246. 'switch' : 'SWITCH',
  247. 'this' : 'THIS',
  248. 'throw' : 'THROW',
  249. 'true' : 'TRUE',
  250. 'try' : 'TRY',
  251. 'typeid' : 'TYPEID',
  252. 'while' : 'WHILE',
  253. '"C"' : 'CLiteral',
  254. '"C++"' : 'CppLiteral',
  255. '__attribute__' : 'ATTRIBUTE',
  256. '__cdecl__' : 'CDECL',
  257. '__typeof' : 'uTYPEOF',
  258. 'typeof' : 'TYPEOF',
  259. 'CXXTEST_STD' : 'CXXTEST_STD'
  260. }
  261. tokens = [
  262. "CharacterLiteral",
  263. "FloatingLiteral",
  264. "Identifier",
  265. "IntegerLiteral",
  266. "StringLiteral",
  267. "RBRACE",
  268. "LBRACE",
  269. "RBRACKET",
  270. "LBRACKET",
  271. "ARROW",
  272. "ARROW_STAR",
  273. "DEC",
  274. "EQ",
  275. "GE",
  276. "INC",
  277. "LE",
  278. "LOG_AND",
  279. "LOG_OR",
  280. "NE",
  281. "SHL",
  282. "SHR",
  283. "ASS_ADD",
  284. "ASS_AND",
  285. "ASS_DIV",
  286. "ASS_MOD",
  287. "ASS_MUL",
  288. "ASS_OR",
  289. "ASS_SHL",
  290. "ASS_SHR",
  291. "ASS_SUB",
  292. "ASS_XOR",
  293. "DOT_STAR",
  294. "ELLIPSIS",
  295. "SCOPE",
  296. ] + list(reserved.values())
  297. t_ignore = " \t\r"
  298. t_LBRACE = r"(\{)|(<%)"
  299. t_RBRACE = r"(\})|(%>)"
  300. t_LBRACKET = r"(\[)|(<:)"
  301. t_RBRACKET = r"(\])|(:>)"
  302. t_ARROW = r"->"
  303. t_ARROW_STAR = r"->\*"
  304. t_DEC = r"--"
  305. t_EQ = r"=="
  306. t_GE = r">="
  307. t_INC = r"\+\+"
  308. t_LE = r"<="
  309. t_LOG_AND = r"&&"
  310. t_LOG_OR = r"\|\|"
  311. t_NE = r"!="
  312. t_SHL = r"<<"
  313. t_SHR = r">>"
  314. t_ASS_ADD = r"\+="
  315. t_ASS_AND = r"&="
  316. t_ASS_DIV = r"/="
  317. t_ASS_MOD = r"%="
  318. t_ASS_MUL = r"\*="
  319. t_ASS_OR = r"\|="
  320. t_ASS_SHL = r"<<="
  321. t_ASS_SHR = r">>="
  322. t_ASS_SUB = r"-="
  323. t_ASS_XOR = r"^="
  324. t_DOT_STAR = r"\.\*"
  325. t_ELLIPSIS = r"\.\.\."
  326. t_SCOPE = r"::"
  327. # Discard comments
  328. def t_COMMENT(t):
  329. r'(/\*(.|\n)*?\*/)|(//.*?\n)|(\#.*?\n)'
  330. t.lexer.lineno += t.value.count("\n")
  331. t_IntegerLiteral = r'(0x[0-9A-F]+)|([0-9]+(L){0,1})'
  332. t_FloatingLiteral = r"[0-9]+[eE\.\+-]+[eE\.\+\-0-9]+"
  333. t_CharacterLiteral = r'\'([^\'\\]|\\.)*\''
  334. #t_StringLiteral = r'"([^"\\]|\\.)*"'
  335. def t_StringLiteral(t):
  336. r'"([^"\\]|\\.)*"'
  337. t.type = reserved.get(t.value,'StringLiteral')
  338. return t
  339. def t_Identifier(t):
  340. r"[a-zA-Z_][a-zA-Z_0-9\.]*"
  341. t.type = reserved.get(t.value,'Identifier')
  342. return t
  343. def t_error(t):
  344. print "Illegal character '%s'" % t.value[0]
  345. #raise IOError, "Parse error"
  346. #t.lexer.skip()
  347. def t_newline(t):
  348. r'[\n]+'
  349. t.lexer.lineno += len(t.value)
  350. precedence = (
  351. ( 'right', 'SHIFT_THERE', 'REDUCE_HERE_MOSTLY', 'SCOPE'),
  352. ( 'nonassoc', 'ELSE', 'INC', 'DEC', '+', '-', '*', '&', 'LBRACKET', 'LBRACE', '<', ':', ')')
  353. )
  354. start = 'translation_unit'
  355. #
  356. # The %prec resolves the 14.2-3 ambiguity:
  357. # Identifier '<' is forced to go through the is-it-a-template-name test
  358. # All names absorb TEMPLATE with the name, so that no template_test is
  359. # performed for them. This requires all potential declarations within an
  360. # expression to perpetuate this policy and thereby guarantee the ultimate
  361. # coverage of explicit_instantiation.
  362. #
  363. # The %prec also resolves a conflict in identifier : which is forced to be a
  364. # shift of a label for a labeled-statement rather than a reduction for the
  365. # name of a bit-field or generalised constructor. This is pretty dubious
  366. # syntactically but correct for all semantic possibilities. The shift is
  367. # only activated when the ambiguity exists at the start of a statement.
  368. # In this context a bit-field declaration or constructor definition are not
  369. # allowed.
  370. #
  371. def p_identifier(p):
  372. '''identifier : Identifier
  373. | CXXTEST_STD '(' Identifier ')'
  374. '''
  375. if p[1][0] in ('t','T','c','d'):
  376. identifier_lineno[p[1]] = p.lineno(1)
  377. p[0] = p[1]
  378. def p_id(p):
  379. '''id : identifier %prec SHIFT_THERE
  380. | template_decl
  381. | TEMPLATE id
  382. '''
  383. p[0] = get_rest(p)
  384. def p_global_scope(p):
  385. '''global_scope : SCOPE
  386. '''
  387. p[0] = get_rest(p)
  388. def p_id_scope(p):
  389. '''id_scope : id SCOPE'''
  390. p[0] = get_rest(p)
  391. def p_id_scope_seq(p):
  392. '''id_scope_seq : id_scope
  393. | id_scope id_scope_seq
  394. '''
  395. p[0] = get_rest(p)
  396. #
  397. # A :: B :: C; is ambiguous How much is type and how much name ?
  398. # The %prec maximises the (type) length which is the 7.1-2 semantic constraint.
  399. #
  400. def p_nested_id(p):
  401. '''nested_id : id %prec SHIFT_THERE
  402. | id_scope nested_id
  403. '''
  404. p[0] = get_rest(p)
  405. def p_scoped_id(p):
  406. '''scoped_id : nested_id
  407. | global_scope nested_id
  408. | id_scope_seq
  409. | global_scope id_scope_seq
  410. '''
  411. global scope_lineno
  412. scope_lineno = lexer.lineno
  413. data = flatten(get_rest(p))
  414. if data[0] != None:
  415. p[0] = "".join(data)
  416. #
  417. # destructor_id has to be held back to avoid a conflict with a one's
  418. # complement as per 5.3.1-9, It gets put back only when scoped or in a
  419. # declarator_id, which is only used as an explicit member name.
  420. # Declarations of an unscoped destructor are always parsed as a one's
  421. # complement.
  422. #
  423. def p_destructor_id(p):
  424. '''destructor_id : '~' id
  425. | TEMPLATE destructor_id
  426. '''
  427. p[0]=get_rest(p)
  428. #def p_template_id(p):
  429. # '''template_id : empty
  430. # | TEMPLATE
  431. # '''
  432. # pass
  433. def p_template_decl(p):
  434. '''template_decl : identifier '<' nonlgt_seq_opt '>'
  435. '''
  436. #
  437. # WEH: should we include the lt/gt symbols to indicate that this is a
  438. # template class? How is that going to be used later???
  439. #
  440. #p[0] = [p[1] ,"<",">"]
  441. p[0] = p[1]
  442. def p_special_function_id(p):
  443. '''special_function_id : conversion_function_id
  444. | operator_function_id
  445. | TEMPLATE special_function_id
  446. '''
  447. p[0]=get_rest(p)
  448. def p_nested_special_function_id(p):
  449. '''nested_special_function_id : special_function_id
  450. | id_scope destructor_id
  451. | id_scope nested_special_function_id
  452. '''
  453. p[0]=get_rest(p)
  454. def p_scoped_special_function_id(p):
  455. '''scoped_special_function_id : nested_special_function_id
  456. | global_scope nested_special_function_id
  457. '''
  458. p[0]=get_rest(p)
  459. # declarator-id is all names in all scopes, except reserved words
  460. def p_declarator_id(p):
  461. '''declarator_id : scoped_id
  462. | scoped_special_function_id
  463. | destructor_id
  464. '''
  465. p[0]=p[1]
  466. #
  467. # The standard defines pseudo-destructors in terms of type-name, which is
  468. # class/enum/typedef, of which class-name is covered by a normal destructor.
  469. # pseudo-destructors are supposed to support ~int() in templates, so the
  470. # grammar here covers built-in names. Other names are covered by the lack
  471. # of identifier/type discrimination.
  472. #
  473. def p_built_in_type_id(p):
  474. '''built_in_type_id : built_in_type_specifier
  475. | built_in_type_id built_in_type_specifier
  476. '''
  477. pass
  478. def p_pseudo_destructor_id(p):
  479. '''pseudo_destructor_id : built_in_type_id SCOPE '~' built_in_type_id
  480. | '~' built_in_type_id
  481. | TEMPLATE pseudo_destructor_id
  482. '''
  483. pass
  484. def p_nested_pseudo_destructor_id(p):
  485. '''nested_pseudo_destructor_id : pseudo_destructor_id
  486. | id_scope nested_pseudo_destructor_id
  487. '''
  488. pass
  489. def p_scoped_pseudo_destructor_id(p):
  490. '''scoped_pseudo_destructor_id : nested_pseudo_destructor_id
  491. | global_scope scoped_pseudo_destructor_id
  492. '''
  493. pass
  494. #-------------------------------------------------------------------------------
  495. # A.2 Lexical conventions
  496. #-------------------------------------------------------------------------------
  497. #
  498. def p_literal(p):
  499. '''literal : IntegerLiteral
  500. | CharacterLiteral
  501. | FloatingLiteral
  502. | StringLiteral
  503. | TRUE
  504. | FALSE
  505. '''
  506. pass
  507. #-------------------------------------------------------------------------------
  508. # A.3 Basic concepts
  509. #-------------------------------------------------------------------------------
  510. def p_translation_unit(p):
  511. '''translation_unit : declaration_seq_opt
  512. '''
  513. pass
  514. #-------------------------------------------------------------------------------
  515. # A.4 Expressions
  516. #-------------------------------------------------------------------------------
  517. #
  518. # primary_expression covers an arbitrary sequence of all names with the
  519. # exception of an unscoped destructor, which is parsed as its unary expression
  520. # which is the correct disambiguation (when ambiguous). This eliminates the
  521. # traditional A(B) meaning A B ambiguity, since we never have to tack an A
  522. # onto the front of something that might start with (. The name length got
  523. # maximised ab initio. The downside is that semantic interpretation must split
  524. # the names up again.
  525. #
  526. # Unification of the declaration and expression syntax means that unary and
  527. # binary pointer declarator operators:
  528. # int * * name
  529. # are parsed as binary and unary arithmetic operators (int) * (*name). Since
  530. # type information is not used
  531. # ambiguities resulting from a cast
  532. # (cast)*(value)
  533. # are resolved to favour the binary rather than the cast unary to ease AST
  534. # clean-up. The cast-call ambiguity must be resolved to the cast to ensure
  535. # that (a)(b)c can be parsed.
  536. #
  537. # The problem of the functional cast ambiguity
  538. # name(arg)
  539. # as call or declaration is avoided by maximising the name within the parsing
  540. # kernel. So primary_id_expression picks up
  541. # extern long int const var = 5;
  542. # as an assignment to the syntax parsed as "extern long int const var". The
  543. # presence of two names is parsed so that "extern long into const" is
  544. # distinguished from "var" considerably simplifying subsequent
  545. # semantic resolution.
  546. #
  547. # The generalised name is a concatenation of potential type-names (scoped
  548. # identifiers or built-in sequences) plus optionally one of the special names
  549. # such as an operator-function-id, conversion-function-id or destructor as the
  550. # final name.
  551. #
  552. def get_rest(p):
  553. return [p[i] for i in range(1, len(p))]
  554. def p_primary_expression(p):
  555. '''primary_expression : literal
  556. | THIS
  557. | suffix_decl_specified_ids
  558. | abstract_expression %prec REDUCE_HERE_MOSTLY
  559. '''
  560. p[0] = get_rest(p)
  561. #
  562. # Abstract-expression covers the () and [] of abstract-declarators.
  563. #
  564. def p_abstract_expression(p):
  565. '''abstract_expression : parenthesis_clause
  566. | LBRACKET bexpression_opt RBRACKET
  567. | TEMPLATE abstract_expression
  568. '''
  569. pass
  570. def p_postfix_expression(p):
  571. '''postfix_expression : primary_expression
  572. | postfix_expression parenthesis_clause
  573. | postfix_expression LBRACKET bexpression_opt RBRACKET
  574. | postfix_expression LBRACKET bexpression_opt RBRACKET attributes
  575. | postfix_expression '.' declarator_id
  576. | postfix_expression '.' scoped_pseudo_destructor_id
  577. | postfix_expression ARROW declarator_id
  578. | postfix_expression ARROW scoped_pseudo_destructor_id
  579. | postfix_expression INC
  580. | postfix_expression DEC
  581. | DYNAMIC_CAST '<' nonlgt_seq_opt '>' '(' expression ')'
  582. | STATIC_CAST '<' nonlgt_seq_opt '>' '(' expression ')'
  583. | REINTERPRET_CAST '<' nonlgt_seq_opt '>' '(' expression ')'
  584. | CONST_CAST '<' nonlgt_seq_opt '>' '(' expression ')'
  585. | TYPEID parameters_clause
  586. '''
  587. #print "HERE",str(p[1])
  588. p[0] = get_rest(p)
  589. def p_bexpression_opt(p):
  590. '''bexpression_opt : empty
  591. | bexpression
  592. '''
  593. pass
  594. def p_bexpression(p):
  595. '''bexpression : nonbracket_seq
  596. | nonbracket_seq bexpression_seq bexpression_clause nonbracket_seq_opt
  597. | bexpression_seq bexpression_clause nonbracket_seq_opt
  598. '''
  599. pass
  600. def p_bexpression_seq(p):
  601. '''bexpression_seq : empty
  602. | bexpression_seq bexpression_clause nonbracket_seq_opt
  603. '''
  604. pass
  605. def p_bexpression_clause(p):
  606. '''bexpression_clause : LBRACKET bexpression_opt RBRACKET
  607. '''
  608. pass
  609. def p_expression_list_opt(p):
  610. '''expression_list_opt : empty
  611. | expression_list
  612. '''
  613. pass
  614. def p_expression_list(p):
  615. '''expression_list : assignment_expression
  616. | expression_list ',' assignment_expression
  617. '''
  618. pass
  619. def p_unary_expression(p):
  620. '''unary_expression : postfix_expression
  621. | INC cast_expression
  622. | DEC cast_expression
  623. | ptr_operator cast_expression
  624. | suffix_decl_specified_scope star_ptr_operator cast_expression
  625. | '+' cast_expression
  626. | '-' cast_expression
  627. | '!' cast_expression
  628. | '~' cast_expression
  629. | SIZEOF unary_expression
  630. | new_expression
  631. | global_scope new_expression
  632. | delete_expression
  633. | global_scope delete_expression
  634. '''
  635. p[0] = get_rest(p)
  636. def p_delete_expression(p):
  637. '''delete_expression : DELETE cast_expression
  638. '''
  639. pass
  640. def p_new_expression(p):
  641. '''new_expression : NEW new_type_id new_initializer_opt
  642. | NEW parameters_clause new_type_id new_initializer_opt
  643. | NEW parameters_clause
  644. | NEW parameters_clause parameters_clause new_initializer_opt
  645. '''
  646. pass
  647. def p_new_type_id(p):
  648. '''new_type_id : type_specifier ptr_operator_seq_opt
  649. | type_specifier new_declarator
  650. | type_specifier new_type_id
  651. '''
  652. pass
  653. def p_new_declarator(p):
  654. '''new_declarator : ptr_operator new_declarator
  655. | direct_new_declarator
  656. '''
  657. pass
  658. def p_direct_new_declarator(p):
  659. '''direct_new_declarator : LBRACKET bexpression_opt RBRACKET
  660. | direct_new_declarator LBRACKET bexpression RBRACKET
  661. '''
  662. pass
  663. def p_new_initializer_opt(p):
  664. '''new_initializer_opt : empty
  665. | '(' expression_list_opt ')'
  666. '''
  667. pass
  668. #
  669. # cast-expression is generalised to support a [] as well as a () prefix. This covers the omission of
  670. # DELETE[] which when followed by a parenthesised expression was ambiguous. It also covers the gcc
  671. # indexed array initialisation for free.
  672. #
  673. def p_cast_expression(p):
  674. '''cast_expression : unary_expression
  675. | abstract_expression cast_expression
  676. '''
  677. p[0] = get_rest(p)
  678. def p_pm_expression(p):
  679. '''pm_expression : cast_expression
  680. | pm_expression DOT_STAR cast_expression
  681. | pm_expression ARROW_STAR cast_expression
  682. '''
  683. p[0] = get_rest(p)
  684. def p_multiplicative_expression(p):
  685. '''multiplicative_expression : pm_expression
  686. | multiplicative_expression star_ptr_operator pm_expression
  687. | multiplicative_expression '/' pm_expression
  688. | multiplicative_expression '%' pm_expression
  689. '''
  690. p[0] = get_rest(p)
  691. def p_additive_expression(p):
  692. '''additive_expression : multiplicative_expression
  693. | additive_expression '+' multiplicative_expression
  694. | additive_expression '-' multiplicative_expression
  695. '''
  696. p[0] = get_rest(p)
  697. def p_shift_expression(p):
  698. '''shift_expression : additive_expression
  699. | shift_expression SHL additive_expression
  700. | shift_expression SHR additive_expression
  701. '''
  702. p[0] = get_rest(p)
  703. # | relational_expression '<' shift_expression
  704. # | relational_expression '>' shift_expression
  705. # | relational_expression LE shift_expression
  706. # | relational_expression GE shift_expression
  707. def p_relational_expression(p):
  708. '''relational_expression : shift_expression
  709. '''
  710. p[0] = get_rest(p)
  711. def p_equality_expression(p):
  712. '''equality_expression : relational_expression
  713. | equality_expression EQ relational_expression
  714. | equality_expression NE relational_expression
  715. '''
  716. p[0] = get_rest(p)
  717. def p_and_expression(p):
  718. '''and_expression : equality_expression
  719. | and_expression '&' equality_expression
  720. '''
  721. p[0] = get_rest(p)
  722. def p_exclusive_or_expression(p):
  723. '''exclusive_or_expression : and_expression
  724. | exclusive_or_expression '^' and_expression
  725. '''
  726. p[0] = get_rest(p)
  727. def p_inclusive_or_expression(p):
  728. '''inclusive_or_expression : exclusive_or_expression
  729. | inclusive_or_expression '|' exclusive_or_expression
  730. '''
  731. p[0] = get_rest(p)
  732. def p_logical_and_expression(p):
  733. '''logical_and_expression : inclusive_or_expression
  734. | logical_and_expression LOG_AND inclusive_or_expression
  735. '''
  736. p[0] = get_rest(p)
  737. def p_logical_or_expression(p):
  738. '''logical_or_expression : logical_and_expression
  739. | logical_or_expression LOG_OR logical_and_expression
  740. '''
  741. p[0] = get_rest(p)
  742. def p_conditional_expression(p):
  743. '''conditional_expression : logical_or_expression
  744. | logical_or_expression '?' expression ':' assignment_expression
  745. '''
  746. p[0] = get_rest(p)
  747. #
  748. # assignment-expression is generalised to cover the simple assignment of a braced initializer in order to
  749. # contribute to the coverage of parameter-declaration and init-declaration.
  750. #
  751. # | logical_or_expression assignment_operator assignment_expression
  752. def p_assignment_expression(p):
  753. '''assignment_expression : conditional_expression
  754. | logical_or_expression assignment_operator nonsemicolon_seq
  755. | logical_or_expression '=' braced_initializer
  756. | throw_expression
  757. '''
  758. p[0]=get_rest(p)
  759. def p_assignment_operator(p):
  760. '''assignment_operator : '='
  761. | ASS_ADD
  762. | ASS_AND
  763. | ASS_DIV
  764. | ASS_MOD
  765. | ASS_MUL
  766. | ASS_OR
  767. | ASS_SHL
  768. | ASS_SHR
  769. | ASS_SUB
  770. | ASS_XOR
  771. '''
  772. pass
  773. #
  774. # expression is widely used and usually single-element, so the reductions are arranged so that a
  775. # single-element expression is returned as is. Multi-element expressions are parsed as a list that
  776. # may then behave polymorphically as an element or be compacted to an element.
  777. #
  778. def p_expression(p):
  779. '''expression : assignment_expression
  780. | expression_list ',' assignment_expression
  781. '''
  782. p[0] = get_rest(p)
  783. def p_constant_expression(p):
  784. '''constant_expression : conditional_expression
  785. '''
  786. pass
  787. #---------------------------------------------------------------------------------------------------
  788. # A.5 Statements
  789. #---------------------------------------------------------------------------------------------------
  790. # Parsing statements is easy once simple_declaration has been generalised to cover expression_statement.
  791. #
  792. #
  793. # The use of extern here is a hack. The 'extern "C" {}' block gets parsed
  794. # as a function, so when nested 'extern "C"' declarations exist, they don't
  795. # work because the block is viewed as a list of statements... :(
  796. #
  797. def p_statement(p):
  798. '''statement : compound_statement
  799. | declaration_statement
  800. | try_block
  801. | labeled_statement
  802. | selection_statement
  803. | iteration_statement
  804. | jump_statement
  805. '''
  806. pass
  807. def p_compound_statement(p):
  808. '''compound_statement : LBRACE statement_seq_opt RBRACE
  809. '''
  810. pass
  811. def p_statement_seq_opt(p):
  812. '''statement_seq_opt : empty
  813. | statement_seq_opt statement
  814. '''
  815. pass
  816. #
  817. # The dangling else conflict is resolved to the innermost if.
  818. #
  819. def p_selection_statement(p):
  820. '''selection_statement : IF '(' condition ')' statement %prec SHIFT_THERE
  821. | IF '(' condition ')' statement ELSE statement
  822. | SWITCH '(' condition ')' statement
  823. '''
  824. pass
  825. def p_condition_opt(p):
  826. '''condition_opt : empty
  827. | condition
  828. '''
  829. pass
  830. def p_condition(p):
  831. '''condition : nonparen_seq
  832. | nonparen_seq condition_seq parameters_clause nonparen_seq_opt
  833. | condition_seq parameters_clause nonparen_seq_opt
  834. '''
  835. pass
  836. def p_condition_seq(p):
  837. '''condition_seq : empty
  838. | condition_seq parameters_clause nonparen_seq_opt
  839. '''
  840. pass
  841. def p_labeled_statement(p):
  842. '''labeled_statement : identifier ':' statement
  843. | CASE constant_expression ':' statement
  844. | DEFAULT ':' statement
  845. '''
  846. pass
  847. def p_try_block(p):
  848. '''try_block : TRY compound_statement handler_seq
  849. '''
  850. global noExceptionLogic
  851. noExceptionLogic=False
  852. def p_jump_statement(p):
  853. '''jump_statement : BREAK ';'
  854. | CONTINUE ';'
  855. | RETURN nonsemicolon_seq ';'
  856. | GOTO identifier ';'
  857. '''
  858. pass
  859. def p_iteration_statement(p):
  860. '''iteration_statement : WHILE '(' condition ')' statement
  861. | DO statement WHILE '(' expression ')' ';'
  862. | FOR '(' nonparen_seq_opt ')' statement
  863. '''
  864. pass
  865. def p_declaration_statement(p):
  866. '''declaration_statement : block_declaration
  867. '''
  868. pass
  869. #---------------------------------------------------------------------------------------------------
  870. # A.6 Declarations
  871. #---------------------------------------------------------------------------------------------------
  872. def p_compound_declaration(p):
  873. '''compound_declaration : LBRACE declaration_seq_opt RBRACE
  874. '''
  875. pass
  876. def p_declaration_seq_opt(p):
  877. '''declaration_seq_opt : empty
  878. | declaration_seq_opt declaration
  879. '''
  880. pass
  881. def p_declaration(p):
  882. '''declaration : block_declaration
  883. | function_definition
  884. | template_declaration
  885. | explicit_specialization
  886. | specialised_declaration
  887. '''
  888. pass
  889. def p_specialised_declaration(p):
  890. '''specialised_declaration : linkage_specification
  891. | namespace_definition
  892. | TEMPLATE specialised_declaration
  893. '''
  894. pass
  895. def p_block_declaration(p):
  896. '''block_declaration : simple_declaration
  897. | specialised_block_declaration
  898. '''
  899. pass
  900. def p_specialised_block_declaration(p):
  901. '''specialised_block_declaration : asm_definition
  902. | namespace_alias_definition
  903. | using_declaration
  904. | using_directive
  905. | TEMPLATE specialised_block_declaration
  906. '''
  907. pass
  908. def p_simple_declaration(p):
  909. '''simple_declaration : ';'
  910. | init_declaration ';'
  911. | init_declarations ';'
  912. | decl_specifier_prefix simple_declaration
  913. '''
  914. global _parse_info
  915. if len(p) == 3:
  916. if p[2] == ";":
  917. decl = p[1]
  918. else:
  919. decl = p[2]
  920. if decl is not None:
  921. fp = flatten(decl)
  922. if len(fp) >= 2 and fp[0] is not None and fp[0]!="operator" and fp[1] == '(':
  923. p[0] = fp[0]
  924. _parse_info.add_function(fp[0])
  925. #
  926. # A decl-specifier following a ptr_operator provokes a shift-reduce conflict for * const name which is resolved in favour of the pointer, and implemented by providing versions of decl-specifier guaranteed not to start with a cv_qualifier. decl-specifiers are implemented type-centrically. That is the semantic constraint that there must be a type is exploited to impose structure, but actually eliminate very little syntax. built-in types are multi-name and so need a different policy.
  927. #
  928. # non-type decl-specifiers are bound to the left-most type in a decl-specifier-seq, by parsing from the right and attaching suffixes to the right-hand type. Finally residual prefixes attach to the left.
  929. #
  930. def p_suffix_built_in_decl_specifier_raw(p):
  931. '''suffix_built_in_decl_specifier_raw : built_in_type_specifier
  932. | suffix_built_in_decl_specifier_raw built_in_type_specifier
  933. | suffix_built_in_decl_specifier_raw decl_specifier_suffix
  934. '''
  935. pass
  936. def p_suffix_built_in_decl_specifier(p):
  937. '''suffix_built_in_decl_specifier : suffix_built_in_decl_specifier_raw
  938. | TEMPLATE suffix_built_in_decl_specifier
  939. '''
  940. pass
  941. # | id_scope_seq
  942. # | SCOPE id_scope_seq
  943. def p_suffix_named_decl_specifier(p):
  944. '''suffix_named_decl_specifier : scoped_id
  945. | elaborate_type_specifier
  946. | suffix_named_decl_specifier decl_specifier_suffix
  947. '''
  948. p[0]=get_rest(p)
  949. def p_suffix_named_decl_specifier_bi(p):
  950. '''suffix_named_decl_specifier_bi : suffix_named_decl_specifier
  951. | suffix_named_decl_specifier suffix_built_in_decl_specifier_raw
  952. '''
  953. p[0] = get_rest(p)
  954. #print "HERE",get_rest(p)
  955. def p_suffix_named_decl_specifiers(p):
  956. '''suffix_named_decl_specifiers : suffix_named_decl_specifier_bi
  957. | suffix_named_decl_specifiers suffix_named_decl_specifier_bi
  958. '''
  959. p[0] = get_rest(p)
  960. def p_suffix_named_decl_specifiers_sf(p):
  961. '''suffix_named_decl_specifiers_sf : scoped_special_function_id
  962. | suffix_named_decl_specifiers
  963. | suffix_named_decl_specifiers scoped_special_function_id
  964. '''
  965. #print "HERE",get_rest(p)
  966. p[0] = get_rest(p)
  967. def p_suffix_decl_specified_ids(p):
  968. '''suffix_decl_specified_ids : suffix_built_in_decl_specifier
  969. | suffix_built_in_decl_specifier suffix_named_decl_specifiers_sf
  970. | suffix_named_decl_specifiers_sf
  971. '''
  972. if len(p) == 3:
  973. p[0] = p[2]
  974. else:
  975. p[0] = p[1]
  976. def p_suffix_decl_specified_scope(p):
  977. '''suffix_decl_specified_scope : suffix_named_decl_specifiers SCOPE
  978. | suffix_built_in_decl_specifier suffix_named_decl_specifiers SCOPE
  979. | suffix_built_in_decl_specifier SCOPE
  980. '''
  981. p[0] = get_rest(p)
  982. def p_decl_specifier_affix(p):
  983. '''decl_specifier_affix : storage_class_specifier
  984. | function_specifier
  985. | FRIEND
  986. | TYPEDEF
  987. | cv_qualifier
  988. '''
  989. pass
  990. def p_decl_specifier_suffix(p):
  991. '''decl_specifier_suffix : decl_specifier_affix
  992. '''
  993. pass
  994. def p_decl_specifier_prefix(p):
  995. '''decl_specifier_prefix : decl_specifier_affix
  996. | TEMPLATE decl_specifier_prefix
  997. '''
  998. pass
  999. def p_storage_class_specifier(p):
  1000. '''storage_class_specifier : REGISTER
  1001. | STATIC
  1002. | MUTABLE
  1003. | EXTERN %prec SHIFT_THERE
  1004. | EXTENSION
  1005. | AUTO
  1006. '''
  1007. pass
  1008. def p_function_specifier(p):
  1009. '''function_specifier : EXPLICIT
  1010. | INLINE
  1011. | VIRTUAL
  1012. '''
  1013. pass
  1014. def p_type_specifier(p):
  1015. '''type_specifier : simple_type_specifier
  1016. | elaborate_type_specifier
  1017. | cv_qualifier
  1018. '''
  1019. pass
  1020. def p_elaborate_type_specifier(p):
  1021. '''elaborate_type_specifier : class_specifier
  1022. | enum_specifier
  1023. | elaborated_type_specifier
  1024. | TEMPLATE elaborate_type_specifier
  1025. '''
  1026. pass
  1027. def p_simple_type_specifier(p):
  1028. '''simple_type_specifier : scoped_id
  1029. | scoped_id attributes
  1030. | built_in_type_specifier
  1031. '''
  1032. p[0] = p[1]
  1033. def p_built_in_type_specifier(p):
  1034. '''built_in_type_specifier : Xbuilt_in_type_specifier
  1035. | Xbuilt_in_type_specifier attributes
  1036. '''
  1037. pass
  1038. def p_attributes(p):
  1039. '''attributes : attribute
  1040. | attributes attribute
  1041. '''
  1042. pass
  1043. def p_attribute(p):
  1044. '''attribute : ATTRIBUTE '(' parameters_clause ')'
  1045. '''
  1046. def p_Xbuilt_in_type_specifier(p):
  1047. '''Xbuilt_in_type_specifier : CHAR
  1048. | WCHAR_T
  1049. | BOOL
  1050. | SHORT
  1051. | INT
  1052. | LONG
  1053. | SIGNED
  1054. | UNSIGNED
  1055. | FLOAT
  1056. | DOUBLE
  1057. | VOID
  1058. | uTYPEOF parameters_clause
  1059. | TYPEOF parameters_clause
  1060. '''
  1061. pass
  1062. #
  1063. # The over-general use of declaration_expression to cover decl-specifier-seq_opt declarator in a function-definition means that
  1064. # class X { };
  1065. # could be a function-definition or a class-specifier.
  1066. # enum X { };
  1067. # could be a function-definition or an enum-specifier.
  1068. # The function-definition is not syntactically valid so resolving the false conflict in favour of the
  1069. # elaborated_type_specifier is correct.
  1070. #
  1071. def p_elaborated_type_specifier(p):
  1072. '''elaborated_type_specifier : class_key scoped_id %prec SHIFT_THERE
  1073. | elaborated_enum_specifier
  1074. | TYPENAME scoped_id
  1075. '''
  1076. pass
  1077. def p_elaborated_enum_specifier(p):
  1078. '''elaborated_enum_specifier : ENUM scoped_id %prec SHIFT_THERE
  1079. '''
  1080. pass
  1081. def p_enum_specifier(p):
  1082. '''enum_specifier : ENUM scoped_id enumerator_clause
  1083. | ENUM enumerator_clause
  1084. '''
  1085. pass
  1086. def p_enumerator_clause(p):
  1087. '''enumerator_clause : LBRACE enumerator_list_ecarb
  1088. | LBRACE enumerator_list enumerator_list_ecarb
  1089. | LBRACE enumerator_list ',' enumerator_definition_ecarb
  1090. '''
  1091. pass
  1092. def p_enumerator_list_ecarb(p):
  1093. '''enumerator_list_ecarb : RBRACE
  1094. '''
  1095. pass
  1096. def p_enumerator_definition_ecarb(p):
  1097. '''enumerator_definition_ecarb : RBRACE
  1098. '''
  1099. pass
  1100. def p_enumerator_definition_filler(p):
  1101. '''enumerator_definition_filler : empty
  1102. '''
  1103. pass
  1104. def p_enumerator_list_head(p):
  1105. '''enumerator_list_head : enumerator_definition_filler
  1106. | enumerator_list ',' enumerator_definition_filler
  1107. '''
  1108. pass
  1109. def p_enumerator_list(p):
  1110. '''enumerator_list : enumerator_list_head enumerator_definition
  1111. '''
  1112. pass
  1113. def p_enumerator_definition(p):
  1114. '''enumerator_definition : enumerator
  1115. | enumerator '=' constant_expression
  1116. '''
  1117. pass
  1118. def p_enumerator(p):
  1119. '''enumerator : identifier
  1120. '''
  1121. pass
  1122. def p_namespace_definition(p):
  1123. '''namespace_definition : NAMESPACE scoped_id push_scope compound_declaration
  1124. | NAMESPACE push_scope compound_declaration
  1125. '''
  1126. global _parse_info
  1127. scope = _parse_info.pop_scope()
  1128. def p_namespace_alias_definition(p):
  1129. '''namespace_alias_definition : NAMESPACE scoped_id '=' scoped_id ';'
  1130. '''
  1131. pass
  1132. def p_push_scope(p):
  1133. '''push_scope : empty'''
  1134. global _parse_info
  1135. if p[-2] == "namespace":
  1136. scope=p[-1]
  1137. else:
  1138. scope=""
  1139. _parse_info.push_scope(scope,"namespace")
  1140. def p_using_declaration(p):
  1141. '''using_declaration : USING declarator_id ';'
  1142. | USING TYPENAME declarator_id ';'
  1143. '''
  1144. pass
  1145. def p_using_directive(p):
  1146. '''using_directive : USING NAMESPACE scoped_id ';'
  1147. '''
  1148. pass
  1149. # '''asm_definition : ASM '(' StringLiteral ')' ';'
  1150. def p_asm_definition(p):
  1151. '''asm_definition : ASM '(' nonparen_seq_opt ')' ';'
  1152. '''
  1153. pass
  1154. def p_linkage_specification(p):
  1155. '''linkage_specification : EXTERN CLiteral declaration
  1156. | EXTERN CLiteral compound_declaration
  1157. | EXTERN CppLiteral declaration
  1158. | EXTERN CppLiteral compound_declaration
  1159. '''
  1160. pass
  1161. #---------------------------------------------------------------------------------------------------
  1162. # A.7 Declarators
  1163. #---------------------------------------------------------------------------------------------------
  1164. #
  1165. # init-declarator is named init_declaration to reflect the embedded decl-specifier-seq_opt
  1166. #
  1167. def p_init_declarations(p):
  1168. '''init_declarations : assignment_expression ',' init_declaration
  1169. | init_declarations ',' init_declaration
  1170. '''
  1171. p[0]=get_rest(p)
  1172. def p_init_declaration(p):
  1173. '''init_declaration : assignment_expression
  1174. '''
  1175. p[0]=get_rest(p)
  1176. def p_star_ptr_operator(p):
  1177. '''star_ptr_operator : '*'
  1178. | star_ptr_operator cv_qualifier
  1179. '''
  1180. pass
  1181. def p_nested_ptr_operator(p):
  1182. '''nested_ptr_operator : star_ptr_operator
  1183. | id_scope nested_ptr_operator
  1184. '''
  1185. pass
  1186. def p_ptr_operator(p):
  1187. '''ptr_operator : '&'
  1188. | nested_ptr_operator
  1189. | global_scope nested_ptr_operator
  1190. '''
  1191. pass
  1192. def p_ptr_operator_seq(p):
  1193. '''ptr_operator_seq : ptr_operator
  1194. | ptr_operator ptr_operator_seq
  1195. '''
  1196. pass
  1197. #
  1198. # Independently coded to localise the shift-reduce conflict: sharing just needs another %prec
  1199. #
  1200. def p_ptr_operator_seq_opt(p):
  1201. '''ptr_operator_seq_opt : empty %prec SHIFT_THERE
  1202. | ptr_operator ptr_operator_seq_opt
  1203. '''
  1204. pass
  1205. def p_cv_qualifier_seq_opt(p):
  1206. '''cv_qualifier_seq_opt : empty
  1207. | cv_qualifier_seq_opt cv_qualifier
  1208. '''
  1209. pass
  1210. # TODO: verify that we should include attributes here
  1211. def p_cv_qualifier(p):
  1212. '''cv_qualifier : CONST
  1213. | VOLATILE
  1214. | attributes
  1215. '''
  1216. pass
  1217. def p_type_id(p):
  1218. '''type_id : type_specifier abstract_declarator_opt
  1219. | type_specifier type_id
  1220. '''
  1221. pass
  1222. def p_abstract_declarator_opt(p):
  1223. '''abstract_declarator_opt : empty
  1224. | ptr_operator abstract_declarator_opt
  1225. | direct_abstract_declarator
  1226. '''
  1227. pass
  1228. def p_direct_abstract_declarator_opt(p):
  1229. '''direct_abstract_declarator_opt : empty
  1230. | direct_abstract_declarator
  1231. '''
  1232. pass
  1233. def p_direct_abstract_declarator(p):
  1234. '''direct_abstract_declarator : direct_abstract_declarator_opt parenthesis_clause
  1235. | direct_abstract_declarator_opt LBRACKET RBRACKET
  1236. | direct_abstract_declarator_opt LBRACKET bexpression RBRACKET
  1237. '''
  1238. pass
  1239. def p_parenthesis_clause(p):
  1240. '''parenthesis_clause : parameters_clause cv_qualifier_seq_opt
  1241. | parameters_clause cv_qualifier_seq_opt exception_specification
  1242. '''
  1243. p[0] = ['(',')']
  1244. def p_parameters_clause(p):
  1245. '''parameters_clause : '(' condition_opt ')'
  1246. '''
  1247. p[0] = ['(',')']
  1248. #
  1249. # A typed abstract qualifier such as
  1250. # Class * ...
  1251. # looks like a multiply, so pointers are parsed as their binary operation equivalents that
  1252. # ultimately terminate with a degenerate right hand term.
  1253. #
  1254. def p_abstract_pointer_declaration(p):
  1255. '''abstract_pointer_declaration : ptr_operator_seq
  1256. | multiplicative_expression star_ptr_operator ptr_operator_seq_opt
  1257. '''
  1258. pass
  1259. def p_abstract_parameter_declaration(p):
  1260. '''abstract_parameter_declaration : abstract_pointer_declaration
  1261. | and_expression '&'
  1262. | and_expression '&' abstract_pointer_declaration
  1263. '''
  1264. pass
  1265. def p_special_parameter_declaration(p):
  1266. '''special_parameter_declaration : abstract_parameter_declaration
  1267. | abstract_parameter_declaration '=' assignment_expression
  1268. | ELLIPSIS
  1269. '''
  1270. pass
  1271. def p_parameter_declaration(p):
  1272. '''parameter_declaration : assignment_expression
  1273. | special_parameter_declaration
  1274. | decl_specifier_prefix parameter_declaration
  1275. '''
  1276. pass
  1277. #
  1278. # function_definition includes constructor, destructor, implicit int definitions too. A local destructor is successfully parsed as a function-declaration but the ~ was treated as a unary operator. constructor_head is the prefix ambiguity between a constructor and a member-init-list starting with a bit-field.
  1279. #
  1280. def p_function_definition(p):
  1281. '''function_definition : ctor_definition
  1282. | func_definition
  1283. '''
  1284. pass
  1285. def p_func_definition(p):
  1286. '''func_definition : assignment_expression function_try_block
  1287. | assignment_expression function_body
  1288. | decl_specifier_prefix func_definition
  1289. '''
  1290. global _parse_info
  1291. if p[2] is not None and p[2][0] == '{':
  1292. decl = flatten(p[1])
  1293. #print "HERE",decl
  1294. if decl[-1] == ')':
  1295. decl=decl[-3]
  1296. else:
  1297. decl=decl[-1]
  1298. p[0] = decl
  1299. if decl != "operator":
  1300. _parse_info.add_function(decl)
  1301. else:
  1302. p[0] = p[2]
  1303. def p_ctor_definition(p):
  1304. '''ctor_definition : constructor_head function_try_block
  1305. | constructor_head function_body
  1306. | decl_specifier_prefix ctor_definition
  1307. '''
  1308. if p[2] is None or p[2][0] == "try" or p[2][0] == '{':
  1309. p[0]=p[1]
  1310. else:
  1311. p[0]=p[1]
  1312. def p_constructor_head(p):
  1313. '''constructor_head : bit_field_init_declaration
  1314. | constructor_head ',' assignment_expression
  1315. '''
  1316. p[0]=p[1]
  1317. def p_function_try_block(p):
  1318. '''function_try_block : TRY function_block handler_seq
  1319. '''
  1320. global noExceptionLogic
  1321. noExceptionLogic=False
  1322. p[0] = ['try']
  1323. def p_function_block(p):
  1324. '''function_block : ctor_initializer_opt function_body
  1325. '''
  1326. pass
  1327. def p_function_body(p):
  1328. '''function_body : LBRACE nonbrace_seq_opt RBRACE
  1329. '''
  1330. p[0] = ['{',

Large files files are truncated, but you can click here to view the full file