PageRenderTime 53ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/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
  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] = ['{','}']
  1331. def p_initializer_clause(p):
  1332. '''initializer_clause : assignment_expression
  1333. | braced_initializer
  1334. '''
  1335. pass
  1336. def p_braced_initializer(p):
  1337. '''braced_initializer : LBRACE initializer_list RBRACE
  1338. | LBRACE initializer_list ',' RBRACE
  1339. | LBRACE RBRACE
  1340. '''
  1341. pass
  1342. def p_initializer_list(p):
  1343. '''initializer_list : initializer_clause
  1344. | initializer_list ',' initializer_clause
  1345. '''
  1346. pass
  1347. #---------------------------------------------------------------------------------------------------
  1348. # A.8 Classes
  1349. #---------------------------------------------------------------------------------------------------
  1350. #
  1351. # An anonymous bit-field declaration may look very like inheritance:
  1352. # const int B = 3;
  1353. # class A : B ;
  1354. # The two usages are too distant to try to create and enforce a common prefix so we have to resort to
  1355. # a parser hack by backtracking. Inheritance is much the most likely so we mark the input stream context
  1356. # and try to parse a base-clause. If we successfully reach a { the base-clause is ok and inheritance was
  1357. # the correct choice so we unmark and continue. If we fail to find the { an error token causes
  1358. # back-tracking to the alternative parse in elaborated_type_specifier which regenerates the : and
  1359. # declares unconditional success.
  1360. #
  1361. def p_class_specifier_head(p):
  1362. '''class_specifier_head : class_key scoped_id ':' base_specifier_list LBRACE
  1363. | class_key ':' base_specifier_list LBRACE
  1364. | class_key scoped_id LBRACE
  1365. | class_key LBRACE
  1366. '''
  1367. global _parse_info
  1368. base_classes=[]
  1369. if len(p) == 6:
  1370. scope = p[2]
  1371. base_classes = p[4]
  1372. elif len(p) == 4:
  1373. scope = p[2]
  1374. elif len(p) == 5:
  1375. base_classes = p[3]
  1376. else:
  1377. scope = ""
  1378. _parse_info.push_scope(scope,p[1],base_classes)
  1379. def p_class_key(p):
  1380. '''class_key : CLASS
  1381. | STRUCT
  1382. | UNION
  1383. '''
  1384. p[0] = p[1]
  1385. def p_class_specifier(p):
  1386. '''class_specifier : class_specifier_head member_specification_opt RBRACE
  1387. '''
  1388. scope = _parse_info.pop_scope()
  1389. def p_member_specification_opt(p):
  1390. '''member_specification_opt : empty
  1391. | member_specification_opt member_declaration
  1392. '''
  1393. pass
  1394. def p_member_declaration(p):
  1395. '''member_declaration : accessibility_specifier
  1396. | simple_member_declaration
  1397. | function_definition
  1398. | using_declaration
  1399. | template_declaration
  1400. '''
  1401. p[0] = get_rest(p)
  1402. #print "Decl",get_rest(p)
  1403. #
  1404. # The generality of constructor names (there need be no parenthesised argument list) means that that
  1405. # name : f(g), h(i)
  1406. # could be the start of a constructor or the start of an anonymous bit-field. An ambiguity is avoided by
  1407. # parsing the ctor-initializer of a function_definition as a bit-field.
  1408. #
  1409. def p_simple_member_declaration(p):
  1410. '''simple_member_declaration : ';'
  1411. | assignment_expression ';'
  1412. | constructor_head ';'
  1413. | member_init_declarations ';'
  1414. | decl_specifier_prefix simple_member_declaration
  1415. '''
  1416. global _parse_info
  1417. decl = flatten(get_rest(p))
  1418. if len(decl) >= 4 and decl[-3] == "(":
  1419. _parse_info.add_function(decl[-4])
  1420. def p_member_init_declarations(p):
  1421. '''member_init_declarations : assignment_expression ',' member_init_declaration
  1422. | constructor_head ',' bit_field_init_declaration
  1423. | member_init_declarations ',' member_init_declaration
  1424. '''
  1425. pass
  1426. def p_member_init_declaration(p):
  1427. '''member_init_declaration : assignment_expression
  1428. | bit_field_init_declaration
  1429. '''
  1430. pass
  1431. def p_accessibility_specifier(p):
  1432. '''accessibility_specifier : access_specifier ':'
  1433. '''
  1434. pass
  1435. def p_bit_field_declaration(p):
  1436. '''bit_field_declaration : assignment_expression ':' bit_field_width
  1437. | ':' bit_field_width
  1438. '''
  1439. if len(p) == 4:
  1440. p[0]=p[1]
  1441. def p_bit_field_width(p):
  1442. '''bit_field_width : logical_or_expression
  1443. | logical_or_expression '?' bit_field_width ':' bit_field_width
  1444. '''
  1445. pass
  1446. def p_bit_field_init_declaration(p):
  1447. '''bit_field_init_declaration : bit_field_declaration
  1448. | bit_field_declaration '=' initializer_clause
  1449. '''
  1450. pass
  1451. #---------------------------------------------------------------------------------------------------
  1452. # A.9 Derived classes
  1453. #---------------------------------------------------------------------------------------------------
  1454. def p_base_specifier_list(p):
  1455. '''base_specifier_list : base_specifier
  1456. | base_specifier_list ',' base_specifier
  1457. '''
  1458. if len(p) == 2:
  1459. p[0] = [p[1]]
  1460. else:
  1461. p[0] = p[1]+[p[3]]
  1462. def p_base_specifier(p):
  1463. '''base_specifier : scoped_id
  1464. | access_specifier base_specifier
  1465. | VIRTUAL base_specifier
  1466. '''
  1467. if len(p) == 2:
  1468. p[0] = p[1]
  1469. else:
  1470. p[0] = p[2]
  1471. def p_access_specifier(p):
  1472. '''access_specifier : PRIVATE
  1473. | PROTECTED
  1474. | PUBLIC
  1475. '''
  1476. pass
  1477. #---------------------------------------------------------------------------------------------------
  1478. # A.10 Special member functions
  1479. #---------------------------------------------------------------------------------------------------
  1480. def p_conversion_function_id(p):
  1481. '''conversion_function_id : OPERATOR conversion_type_id
  1482. '''
  1483. p[0] = ['operator']
  1484. def p_conversion_type_id(p):
  1485. '''conversion_type_id : type_specifier ptr_operator_seq_opt
  1486. | type_specifier conversion_type_id
  1487. '''
  1488. pass
  1489. #
  1490. # Ctor-initialisers can look like a bit field declaration, given the generalisation of names:
  1491. # Class(Type) : m1(1), m2(2) { }
  1492. # NonClass(bit_field) : int(2), second_variable, ...
  1493. # The grammar below is used within a function_try_block or function_definition.
  1494. # See simple_member_declaration for use in normal member function_definition.
  1495. #
  1496. def p_ctor_initializer_opt(p):
  1497. '''ctor_initializer_opt : empty
  1498. | ctor_initializer
  1499. '''
  1500. pass
  1501. def p_ctor_initializer(p):
  1502. '''ctor_initializer : ':' mem_initializer_list
  1503. '''
  1504. pass
  1505. def p_mem_initializer_list(p):
  1506. '''mem_initializer_list : mem_initializer
  1507. | mem_initializer_list_head mem_initializer
  1508. '''
  1509. pass
  1510. def p_mem_initializer_list_head(p):
  1511. '''mem_initializer_list_head : mem_initializer_list ','
  1512. '''
  1513. pass
  1514. def p_mem_initializer(p):
  1515. '''mem_initializer : mem_initializer_id '(' expression_list_opt ')'
  1516. '''
  1517. pass
  1518. def p_mem_initializer_id(p):
  1519. '''mem_initializer_id : scoped_id
  1520. '''
  1521. pass
  1522. #---------------------------------------------------------------------------------------------------
  1523. # A.11 Overloading
  1524. #---------------------------------------------------------------------------------------------------
  1525. def p_operator_function_id(p):
  1526. '''operator_function_id : OPERATOR operator
  1527. | OPERATOR '(' ')'
  1528. | OPERATOR LBRACKET RBRACKET
  1529. | OPERATOR '<'
  1530. | OPERATOR '>'
  1531. | OPERATOR operator '<' nonlgt_seq_opt '>'
  1532. '''
  1533. p[0] = ["operator"]
  1534. #
  1535. # It is not clear from the ANSI standard whether spaces are permitted in delete[]. If not then it can
  1536. # be recognised and returned as DELETE_ARRAY by the lexer. Assuming spaces are permitted there is an
  1537. # ambiguity created by the over generalised nature of expressions. operator new is a valid delarator-id
  1538. # which we may have an undimensioned array of. Semantic rubbish, but syntactically valid. Since the
  1539. # array form is covered by the declarator consideration we can exclude the operator here. The need
  1540. # for a semantic rescue can be eliminated at the expense of a couple of shift-reduce conflicts by
  1541. # removing the comments on the next four lines.
  1542. #
  1543. def p_operator(p):
  1544. '''operator : NEW
  1545. | DELETE
  1546. | '+'
  1547. | '-'
  1548. | '*'
  1549. | '/'
  1550. | '%'
  1551. | '^'
  1552. | '&'
  1553. | '|'
  1554. | '~'
  1555. | '!'
  1556. | '='
  1557. | ASS_ADD
  1558. | ASS_SUB
  1559. | ASS_MUL
  1560. | ASS_DIV
  1561. | ASS_MOD
  1562. | ASS_XOR
  1563. | ASS_AND
  1564. | ASS_OR
  1565. | SHL
  1566. | SHR
  1567. | ASS_SHR
  1568. | ASS_SHL
  1569. | EQ
  1570. | NE
  1571. | LE
  1572. | GE
  1573. | LOG_AND
  1574. | LOG_OR
  1575. | INC
  1576. | DEC
  1577. | ','
  1578. | ARROW_STAR
  1579. | ARROW
  1580. '''
  1581. p[0]=p[1]
  1582. # | IF
  1583. # | SWITCH
  1584. # | WHILE
  1585. # | FOR
  1586. # | DO
  1587. def p_reserved(p):
  1588. '''reserved : PRIVATE
  1589. | CLiteral
  1590. | CppLiteral
  1591. | IF
  1592. | SWITCH
  1593. | WHILE
  1594. | FOR
  1595. | DO
  1596. | PROTECTED
  1597. | PUBLIC
  1598. | BOOL
  1599. | CHAR
  1600. | DOUBLE
  1601. | FLOAT
  1602. | INT
  1603. | LONG
  1604. | SHORT
  1605. | SIGNED
  1606. | UNSIGNED
  1607. | VOID
  1608. | WCHAR_T
  1609. | CLASS
  1610. | ENUM
  1611. | NAMESPACE
  1612. | STRUCT
  1613. | TYPENAME
  1614. | UNION
  1615. | CONST
  1616. | VOLATILE
  1617. | AUTO
  1618. | EXPLICIT
  1619. | EXPORT
  1620. | EXTERN
  1621. | FRIEND
  1622. | INLINE
  1623. | MUTABLE
  1624. | REGISTER
  1625. | STATIC
  1626. | TEMPLATE
  1627. | TYPEDEF
  1628. | USING
  1629. | VIRTUAL
  1630. | ASM
  1631. | BREAK
  1632. | CASE
  1633. | CATCH
  1634. | CONST_CAST
  1635. | CONTINUE
  1636. | DEFAULT
  1637. | DYNAMIC_CAST
  1638. | ELSE
  1639. | FALSE
  1640. | GOTO
  1641. | OPERATOR
  1642. | REINTERPRET_CAST
  1643. | RETURN
  1644. | SIZEOF
  1645. | STATIC_CAST
  1646. | THIS
  1647. | THROW
  1648. | TRUE
  1649. | TRY
  1650. | TYPEID
  1651. | ATTRIBUTE
  1652. | CDECL
  1653. | TYPEOF
  1654. | uTYPEOF
  1655. '''
  1656. if p[1] in ('try', 'catch', 'throw'):
  1657. global noExceptionLogic
  1658. noExceptionLogic=False
  1659. #---------------------------------------------------------------------------------------------------
  1660. # A.12 Templates
  1661. #---------------------------------------------------------------------------------------------------
  1662. def p_template_declaration(p):
  1663. '''template_declaration : template_parameter_clause declaration
  1664. | EXPORT template_declaration
  1665. '''
  1666. pass
  1667. def p_template_parameter_clause(p):
  1668. '''template_parameter_clause : TEMPLATE '<' nonlgt_seq_opt '>'
  1669. '''
  1670. pass
  1671. #
  1672. # Generalised naming makes identifier a valid declaration, so TEMPLATE identifier is too.
  1673. # The TEMPLATE prefix is therefore folded into all names, parenthesis_clause and decl_specifier_prefix.
  1674. #
  1675. # explicit_instantiation: TEMPLATE declaration
  1676. #
  1677. def p_explicit_specialization(p):
  1678. '''explicit_specialization : TEMPLATE '<' '>' declaration
  1679. '''
  1680. pass
  1681. #---------------------------------------------------------------------------------------------------
  1682. # A.13 Exception Handling
  1683. #---------------------------------------------------------------------------------------------------
  1684. def p_handler_seq(p):
  1685. '''handler_seq : handler
  1686. | handler handler_seq
  1687. '''
  1688. pass
  1689. def p_handler(p):
  1690. '''handler : CATCH '(' exception_declaration ')' compound_statement
  1691. '''
  1692. global noExceptionLogic
  1693. noExceptionLogic=False
  1694. def p_exception_declaration(p):
  1695. '''exception_declaration : parameter_declaration
  1696. '''
  1697. pass
  1698. def p_throw_expression(p):
  1699. '''throw_expression : THROW
  1700. | THROW assignment_expression
  1701. '''
  1702. global noExceptionLogic
  1703. noExceptionLogic=False
  1704. def p_exception_specification(p):
  1705. '''exception_specification : THROW '(' ')'
  1706. | THROW '(' type_id_list ')'
  1707. '''
  1708. global noExceptionLogic
  1709. noExceptionLogic=False
  1710. def p_type_id_list(p):
  1711. '''type_id_list : type_id
  1712. | type_id_list ',' type_id
  1713. '''
  1714. pass
  1715. #---------------------------------------------------------------------------------------------------
  1716. # Misc productions
  1717. #---------------------------------------------------------------------------------------------------
  1718. def p_nonsemicolon_seq(p):
  1719. '''nonsemicolon_seq : empty
  1720. | nonsemicolon_seq nonsemicolon
  1721. '''
  1722. pass
  1723. def p_nonsemicolon(p):
  1724. '''nonsemicolon : misc
  1725. | '('
  1726. | ')'
  1727. | '<'
  1728. | '>'
  1729. | LBRACKET nonbracket_seq_opt RBRACKET
  1730. | LBRACE nonbrace_seq_opt RBRACE
  1731. '''
  1732. pass
  1733. def p_nonparen_seq_opt(p):
  1734. '''nonparen_seq_opt : empty
  1735. | nonparen_seq_opt nonparen
  1736. '''
  1737. pass
  1738. def p_nonparen_seq(p):
  1739. '''nonparen_seq : nonparen
  1740. | nonparen_seq nonparen
  1741. '''
  1742. pass
  1743. def p_nonparen(p):
  1744. '''nonparen : misc
  1745. | '<'
  1746. | '>'
  1747. | ';'
  1748. | LBRACKET nonbracket_seq_opt RBRACKET
  1749. | LBRACE nonbrace_seq_opt RBRACE
  1750. '''
  1751. pass
  1752. def p_nonbracket_seq_opt(p):
  1753. '''nonbracket_seq_opt : empty
  1754. | nonbracket_seq_opt nonbracket
  1755. '''
  1756. pass
  1757. def p_nonbracket_seq(p):
  1758. '''nonbracket_seq : nonbracket
  1759. | nonbracket_seq nonbracket
  1760. '''
  1761. pass
  1762. def p_nonbracket(p):
  1763. '''nonbracket : misc
  1764. | '<'
  1765. | '>'
  1766. | '('
  1767. | ')'
  1768. | ';'
  1769. | LBRACKET nonbracket_seq_opt RBRACKET
  1770. | LBRACE nonbrace_seq_opt RBRACE
  1771. '''
  1772. pass
  1773. def p_nonbrace_seq_opt(p):
  1774. '''nonbrace_seq_opt : empty
  1775. | nonbrace_seq_opt nonbrace
  1776. '''
  1777. pass
  1778. def p_nonbrace(p):
  1779. '''nonbrace : misc
  1780. | '<'
  1781. | '>'
  1782. | '('
  1783. | ')'
  1784. | ';'
  1785. | LBRACKET nonbracket_seq_opt RBRACKET
  1786. | LBRACE nonbrace_seq_opt RBRACE
  1787. '''
  1788. pass
  1789. def p_nonlgt_seq_opt(p):
  1790. '''nonlgt_seq_opt : empty
  1791. | nonlgt_seq_opt nonlgt
  1792. '''
  1793. pass
  1794. def p_nonlgt(p):
  1795. '''nonlgt : misc
  1796. | '('
  1797. | ')'
  1798. | LBRACKET nonbracket_seq_opt RBRACKET
  1799. | '<' nonlgt_seq_opt '>'
  1800. | ';'
  1801. '''
  1802. pass
  1803. def p_misc(p):
  1804. '''misc : operator
  1805. | identifier
  1806. | IntegerLiteral
  1807. | CharacterLiteral
  1808. | FloatingLiteral
  1809. | StringLiteral
  1810. | reserved
  1811. | '?'
  1812. | ':'
  1813. | '.'
  1814. | SCOPE
  1815. | ELLIPSIS
  1816. | EXTENSION
  1817. '''
  1818. pass
  1819. def p_empty(p):
  1820. '''empty : '''
  1821. pass
  1822. #
  1823. # Compute column.
  1824. # input is the input text string
  1825. # token is a token instance
  1826. #
  1827. def _find_column(input,token):
  1828. ''' TODO '''
  1829. i = token.lexpos
  1830. while i > 0:
  1831. if input[i] == '\n': break
  1832. i -= 1
  1833. column = (token.lexpos - i)+1
  1834. return column
  1835. def p_error(p):
  1836. if p is None:
  1837. tmp = "Syntax error at end of file."
  1838. else:
  1839. tmp = "Syntax error at token "
  1840. if p.type is "":
  1841. tmp = tmp + "''"
  1842. else:
  1843. tmp = tmp + str(p.type)
  1844. tmp = tmp + " with value '"+str(p.value)+"'"
  1845. tmp = tmp + " in line " + str(lexer.lineno-1)
  1846. tmp = tmp + " at column "+str(_find_column(_parsedata,p))
  1847. raise IOError( tmp )
  1848. #
  1849. # The function that performs the parsing
  1850. #
  1851. def parse_cpp(data=None, filename=None, debug=0, optimize=0, verbose=False, func_filter=None):
  1852. #
  1853. # Reset global data
  1854. #
  1855. global lexer
  1856. lexer = None
  1857. global scope_lineno
  1858. scope_lineno = 0
  1859. global indentifier_lineno
  1860. identifier_lineno = {}
  1861. global _parse_info
  1862. _parse_info=None
  1863. global _parsedata
  1864. _parsedata=None
  1865. global noExceptionLogic
  1866. noExceptionLogic = True
  1867. #
  1868. if debug > 0:
  1869. print "Debugging parse_cpp!"
  1870. #
  1871. # Always remove the parser.out file, which is generated to create debugging
  1872. #
  1873. if os.path.exists("parser.out"):
  1874. os.remove("parser.out")
  1875. #
  1876. # Remove the parsetab.py* files. These apparently need to be removed
  1877. # to ensure the creation of a parser.out file.
  1878. #
  1879. if os.path.exists("parsetab.py"):
  1880. os.remove("parsetab.py")
  1881. if os.path.exists("parsetab.pyc"):
  1882. os.remove("parsetab.pyc")
  1883. global debugging
  1884. debugging=True
  1885. #
  1886. # Build lexer
  1887. #
  1888. lexer = lex.lex()
  1889. #
  1890. # Initialize parse object
  1891. #
  1892. _parse_info = CppInfo(filter=func_filter)
  1893. _parse_info.verbose=verbose
  1894. #
  1895. # Build yaccer
  1896. #
  1897. write_table = not os.path.exists("parsetab.py")
  1898. yacc.yacc(debug=debug, optimize=optimize, write_tables=write_table)
  1899. #
  1900. # Parse the file
  1901. #
  1902. if not data is None:
  1903. _parsedata=data
  1904. ply_init(_parsedata)
  1905. yacc.parse(data,debug=debug)
  1906. elif not filename is None:
  1907. f = open(filename)
  1908. data = f.read()
  1909. f.close()
  1910. _parsedata=data
  1911. ply_init(_parsedata)
  1912. yacc.parse(data, debug=debug)
  1913. else:
  1914. return None
  1915. #
  1916. if not noExceptionLogic:
  1917. _parse_info.noExceptionLogic = False
  1918. else:
  1919. for key in identifier_lineno:
  1920. if 'ASSERT_THROWS' in key:
  1921. _parse_info.noExceptionLogic = False
  1922. break
  1923. _parse_info.noExceptionLogic = True
  1924. #
  1925. return _parse_info
  1926. import sys
  1927. if __name__ == '__main__': #pragma: no cover
  1928. #
  1929. # This MAIN routine parses a sequence of files provided at the command
  1930. # line. If '-v' is included, then a verbose parsing output is
  1931. # generated.
  1932. #
  1933. for arg in sys.argv[1:]:
  1934. if arg == "-v":
  1935. continue
  1936. print "Parsing file '"+arg+"'"
  1937. if '-v' in sys.argv:
  1938. parse_cpp(filename=arg,debug=2,verbose=2)
  1939. else:
  1940. parse_cpp(filename=arg,verbose=2)
  1941. #
  1942. # Print the _parse_info object summary for this file.
  1943. # This illustrates how class inheritance can be used to
  1944. # deduce class members.
  1945. #
  1946. print str(_parse_info)