PageRenderTime 46ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/cpp/src/main/antlr/cppparser.g

http://testability-explorer.googlecode.com/
Unknown | 2273 lines | 2067 code | 206 blank | 0 comment | 0 complexity | 817f19aceb922d7cb54e0a5b35fa2250 MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * PUBLIC DOMAIN PCCTS-BASED C++ GRAMMAR (cplusplus.g, stat.g, expr.g)
  3. *
  4. * Authors: Sumana Srinivasan, NeXT Inc.; sumana_srinivasan@next.com
  5. * Terence Parr, Parr Research Corporation; parrt@parr-research.com
  6. * Russell Quong, Purdue University; quong@ecn.purdue.edu
  7. *
  8. * VERSION 1.2
  9. *
  10. * SOFTWARE RIGHTS
  11. *
  12. * This file is a part of the ANTLR-based C++ grammar and is free
  13. * software. We do not reserve any LEGAL rights to its use or
  14. * distribution, but you may NOT claim ownership or authorship of this
  15. * grammar or support code. An individual or company may otherwise do
  16. * whatever they wish with the grammar distributed herewith including the
  17. * incorporation of the grammar or the output generated by ANTLR into
  18. * commerical software. You may redistribute in source or binary form
  19. * without payment of royalties to us as long as this header remains
  20. * in all source distributions.
  21. *
  22. * We encourage users to develop parsers/tools using this grammar.
  23. * In return, we ask that credit is given to us for developing this
  24. * grammar. By "credit", we mean that if you incorporate our grammar or
  25. * the generated code into one of your programs (commercial product,
  26. * research project, or otherwise) that you acknowledge this fact in the
  27. * documentation, research report, etc.... In addition, you should say nice
  28. * things about us at every opportunity.
  29. *
  30. * As long as these guidelines are kept, we expect to continue enhancing
  31. * this grammar. Feel free to send us enhancements, fixes, bug reports,
  32. * suggestions, or general words of encouragement at parrt@parr-research.com.
  33. *
  34. * NeXT Computer Inc.
  35. * 900 Chesapeake Dr.
  36. * Redwood City, CA 94555
  37. * 12/02/1994
  38. *
  39. * Restructured for public consumption by Terence Parr late February, 1995.
  40. *
  41. * DISCLAIMER: we make no guarantees that this grammar works, makes sense,
  42. * or can be used to do anything useful.
  43. */
  44. /* 2001-2002
  45. * Version 1.0
  46. * This C++ grammar file has been converted from PCCTS to run under
  47. * ANTLR to generate lexer and parser in C++ code by
  48. * Jianguo Zuo and David Wigg at
  49. * The Centre for Systems and Software Engineering
  50. * London South Bank University
  51. * London, UK.
  52. *
  53. */
  54. /* 2003
  55. * Version 2.0 was published by David Wigg in September 2003
  56. */
  57. /* 2004
  58. * Version 3.0 July 2004
  59. * This is version 3.0 of the C++ grammar definition for ANTLR to
  60. * generate lexer and parser in C++ code updated by
  61. * David Wigg at
  62. * The Centre for Systems and Software Engineering
  63. * London South Bank University
  64. * London, UK.
  65. *
  66. * wiggjd@bcs.ac.uk
  67. * blackse@lsbu.ac.uk
  68. *
  69. * See MyReadMe.txt for further information
  70. *
  71. * This file is best viewed in courier font with tabs set to 4 spaces
  72. */
  73. /* 2005
  74. * Version 0.01 February 2005
  75. * This is version 0.01 of the C++ grammar definition for ANTLR to
  76. * generate lexer and parser in Java code. This grammar was based
  77. * in the above version of the grammar by David Wigg, having been
  78. * ported to work in java programs.
  79. * The grammar file name is now different to enable diferentiation
  80. * from the original C++ grammar for C++ output. Many of the original
  81. * C++ grammar support files were removed, being for now the only
  82. * needed file the CPPvariables.java.
  83. *
  84. * This grammar is being developed in the context of the ArgoUML
  85. * project, being the basis for the C++ reverse engineering
  86. * functionalities of the C++ module.
  87. *
  88. * TODO: provide more documentation.
  89. * TODO: send to the ANTLR users list to enable review.
  90. * TODO: improve stand-alone use.
  91. *
  92. * www.argouml.org
  93. */
  94. header
  95. {
  96. /*REMOVE_BEGIN*/
  97. package com.google.test.metric.cpp;
  98. /*REMOVE_END*/
  99. import java.util.Hashtable;
  100. import java.util.List;
  101. import java.util.ArrayList;
  102. }
  103. class InternalParser extends Parser;
  104. options
  105. {
  106. k = 2;
  107. exportVocab = STDC;
  108. codeGenMakeSwitchThreshold = 2;
  109. codeGenBitsetTestThreshold = 3;
  110. defaultErrorHandler=false;
  111. //analyzerDebug = true;
  112. }
  113. {
  114. private Builder b;
  115. String enclosingClass="";//name of current class
  116. boolean _td=false; // is type declaration?
  117. Hashtable symbols=new Hashtable();
  118. public boolean qualifiedItemIsOneOf(java.util.BitSet qiFlags, int lookahead_offset) throws TokenStreamException
  119. {
  120. java.util.BitSet qi = qualifiedItemIs(lookahead_offset);
  121. java.util.BitSet aux=(java.util.BitSet) qi.clone();
  122. aux.and(qiFlags);
  123. return (!aux.isEmpty());
  124. }
  125. // This is an important function, but will be replaced with
  126. // an enhanced predicate in the future, once predicates
  127. // and/or predicate guards can contain loops.
  128. //
  129. // Scan past the ::T::B:: to see what lies beyond.
  130. // Return QI_TYPE if the qualified item can pose as type name.
  131. // Note that T::T is NOT a type; it is a constructor. Also,
  132. // class T { ... T...} yields the enclosed T as a ctor. This
  133. // is probably a type as I separate out the constructor defs/decls,
  134. // I want it consistent with T::T.
  135. //
  136. // In the below examples, I use A,B,T and example types, and
  137. // a,b as example ids.
  138. // In the below examples, any A or B may be a
  139. // qualified template, i.e., A<...>
  140. //
  141. // T::T outside of class T yields QI_CTOR.
  142. // T<...>::T outside of class T yields QI_CTOR.
  143. // T inside of class T {...} yields QI_CTOR.
  144. // T, ::T, A::T outside of class T yields QI_TYPE.
  145. // a, ::a, A::B::a yields qiId
  146. // a::b yields QI_INVALID
  147. // ::operator, operator, A::B::operator yield qiOPerator
  148. // A::*, A::B::* yield QI_PTR_MEMBER
  149. // ::*, * yields QI_INVALID
  150. // ::~T, ~T, A::~T yield QI_DTOR
  151. // ~a, ~A::a, A::~T::, ~T:: yield QI_INVALID
  152. public java.util.BitSet qualifiedItemIs(int lookahead_offset) throws TokenStreamException
  153. {
  154. int value;
  155. int k = lookahead_offset + 1;
  156. int final_type_idx = 0;
  157. boolean scope_found = false;
  158. // Skip leading "::"
  159. if (LT(k).getType() == SCOPE)
  160. {
  161. k++;
  162. scope_found = true;
  163. }
  164. // Skip sequences of T:: or T<...>::
  165. //printf("support.cpp qualifiedItemIs while reached k %d type %d isType %d, isClass %d, guessing %d\n",
  166. // k,LT(k)->getType(),isTypeName((LT(k)->getText()).data()),isClassName((LT(k)->getText()).data()),inputState->guessing);
  167. while ((LT(k).getType() == ID) && (isTypeName(LT(k).getText())))
  168. {// If this type is the same as the last type, then ctor
  169. if ((final_type_idx != 0) && (LT(final_type_idx).getText().equals(LT(k).getText())))
  170. {// Like T::T
  171. // As an extra check, do not allow T::T::
  172. if (LT(k+1).getType() == SCOPE)
  173. { //printf("support.cpp qualifiedItemIs QI_INVALID returned\n");
  174. return CPPvariables.QI_INVALID;
  175. }
  176. else
  177. {//printf("support.cpp qualifiedItemIs QI_CTOR returned\n");
  178. return CPPvariables.QI_CTOR;
  179. }
  180. }
  181. // Record this as the most recent type seen in the series
  182. final_type_idx = k;
  183. //printf("support.cpp qualifiedItemIs if step reached final_type_idx %d\n",final_type_idx);
  184. // Skip this token
  185. k++;
  186. // Skip over any template qualifiers <...>
  187. // I believe that "T<..." cannot be anything valid but a template
  188. if (LT(k).getType() == LESSTHAN)
  189. {
  190. value=skipTemplateQualifiers(k);
  191. if (value==k)
  192. {//printf("support.cpp qualifiedItemIs QI_INVALID(2) returned\n");
  193. return CPPvariables.QI_INVALID;
  194. }
  195. else
  196. k=value;
  197. //printf("support.cpp qualifiedItemIs template skipped, k %d\n",k);
  198. // k has been updated to token following <...>
  199. }
  200. if (LT(k).getType() == SCOPE)
  201. // Skip the "::" and keep going
  202. {
  203. k++;
  204. scope_found = true;
  205. }
  206. else
  207. {// Series terminated -- last ID in the sequence was a type
  208. // Return ctor if last type is in containing class
  209. // We already checked for T::T inside loop
  210. if ( enclosingClass.equals(LT(final_type_idx).getText()))
  211. { // Like class T T()
  212. //printf("support.cpp qualifiedItemIs QI_CTOR(2) returned\n");
  213. return CPPvariables.QI_CTOR;
  214. }
  215. else
  216. {//printf("support.cpp qualifiedItemIs QI_TYPE returned\n");
  217. return CPPvariables.QI_TYPE;
  218. }
  219. }
  220. }
  221. // LT(k) is not an ID, or it is an ID but not a typename.
  222. //printf("support.cpp qualifiedItemIs second switch reached\n");
  223. switch (LT(k).getType())
  224. {
  225. case ID:
  226. // ID but not a typename
  227. // Do not allow id::
  228. if (LT(k+1).getType() == SCOPE)
  229. {
  230. //printf("support.cpp qualifiedItemIs QI_INVALID(3) returned\n");
  231. return CPPvariables.QI_INVALID;
  232. }
  233. if (enclosingClass.equals(LT(k).getText()))
  234. { // Like class T T()
  235. //printf("support.cpp qualifiedItemIs QI_CTOR(3) returned\n");
  236. return CPPvariables.QI_CTOR;
  237. }
  238. else
  239. {
  240. if (scope_found)
  241. // DW 25/10/03 Assume type if at least one SCOPE present (test12.i)
  242. return CPPvariables.QI_TYPE;
  243. else
  244. //printf("support.cpp qualifiedItemIs QI_VAR returned\n");
  245. return CPPvariables.QI_VAR; // DW 19/03/04 was QI_ID Could be function?
  246. }
  247. case TILDE:
  248. // check for dtor
  249. if ((LT(k+1).getType() == ID) && (isTypeName(LT(k+1).getText())) &&(LT(k+2).getType() != SCOPE))
  250. { // Like ~B or A::B::~B
  251. // Also (incorrectly?) matches ::~A.
  252. //printf("support.cpp qualifiedItemIs QI_DTOR returned\n");
  253. return CPPvariables.QI_DTOR;
  254. }
  255. else
  256. { // ~a or ~A::a is QI_INVALID
  257. //printf("support.cpp qualifiedItemIs QI_INVALID(4) returned\n");
  258. return CPPvariables.QI_INVALID;
  259. }
  260. case STAR:
  261. // Like A::*
  262. // Do not allow * or ::*
  263. if (final_type_idx == 0)
  264. { // Haven't seen a type yet
  265. //printf("support.cpp qualifiedItemIs QI_INVALID(5) returned\n");
  266. return CPPvariables.QI_INVALID;
  267. }
  268. else
  269. { //printf("support.cpp qualifiedItemIs QI_PTR_MEMBER returned\n");
  270. return CPPvariables.QI_PTR_MEMBER;
  271. }
  272. case OPERATOR:
  273. // Like A::operator, ::operator, or operator
  274. //printf("support.cpp qualifiedItemIs QI_OPERATOR returned\n");
  275. return CPPvariables.QI_OPERATOR;
  276. default:
  277. // Something that neither starts with :: or ID, or
  278. // a :: not followed by ID, operator, ~, or *
  279. //printf("support.cpp qualifiedItemIs QI_INVALID(6) returned\n");
  280. return CPPvariables.QI_INVALID;
  281. }
  282. }
  283. // Skip over <...>. This correctly handles nested <> and (), e.g:
  284. // <T>
  285. // < (i>3) >
  286. // < T2<...> >
  287. // but not
  288. // < i>3 >
  289. //
  290. // On input, kInOut is the index of the "<"
  291. // On output, if the return is true, then
  292. // kInOut is the index of the token after ">"
  293. // else
  294. // kInOut is unchanged
  295. public int skipTemplateQualifiers(int kInOut) throws TokenStreamException
  296. {
  297. // Start after "<"
  298. int k = kInOut + 1;
  299. int value;
  300. while (LT(k).getType() != GREATERTHAN) // scan to end of <...>
  301. {
  302. switch (LT(k).getType())
  303. {
  304. case EOF:
  305. return kInOut;
  306. case LESSTHAN:
  307. value=skipTemplateQualifiers(k);
  308. if (value==k)
  309. {
  310. return kInOut;
  311. }
  312. else
  313. k=value;
  314. break;
  315. case LPAREN:
  316. value=skipNestedParens(k);
  317. if (value==k)
  318. {
  319. return kInOut;
  320. }
  321. else
  322. k=value;
  323. break;
  324. default:
  325. k++; // skip everything else
  326. break;
  327. }
  328. if (k > CPPvariables.MAX_TEMPLATE_TOKEN_SCAN)
  329. {
  330. return kInOut;
  331. }
  332. }
  333. // Update output argument to point past ">"
  334. kInOut = k + 1;
  335. return kInOut;
  336. }
  337. // Skip over (...). This correctly handles nested (), e.g:
  338. // (i>3, (i>5))
  339. //
  340. // On input, kInOut is the index of the "("
  341. // On output, if the return is true, then
  342. // kInOut is the index of the token after ")"
  343. // else
  344. // kInOut is unchanged
  345. public int skipNestedParens(int kInOut) throws TokenStreamException
  346. {
  347. // Start after "("
  348. int k = kInOut + 1;
  349. int value;
  350. while (LT(k).getType() != RPAREN) // scan to end of (...)
  351. {
  352. switch (LT(k).getType())
  353. {
  354. case EOF:
  355. return kInOut;
  356. case LPAREN:
  357. value=skipNestedParens(k);
  358. if (value==k)
  359. {
  360. return kInOut;
  361. }
  362. else
  363. k=value;
  364. break;
  365. default:
  366. k++; // skip everything else
  367. break;
  368. }
  369. if (k > CPPvariables.MAX_TEMPLATE_TOKEN_SCAN)
  370. {
  371. return kInOut;
  372. }
  373. }
  374. // Update output argument to point past ")"
  375. kInOut = k + 1;
  376. return kInOut;
  377. }
  378. // Return true if "::blah" or "fu::bar<args>::..." found.
  379. public boolean scopedItem(int k) throws TokenStreamException
  380. {
  381. //printf("support.cpp scopedItem k %d\n",k);
  382. return (LT(k).getType()==SCOPE ||
  383. (LT(k).getType()==ID && !finalQualifier(k)));
  384. }
  385. // Return true if ID<...> or ID is last item in qualified item list.
  386. // Return false if LT(k) is not an ID.
  387. // ID must be a type to check for ID<...>,
  388. // or else we would get confused by "i<3"
  389. public boolean finalQualifier(int k) throws TokenStreamException
  390. {
  391. if (LT(k).getType()==ID)
  392. {
  393. if ((isTypeName(LT(k).getText())) && (LT(k+1).getType()==LESSTHAN))
  394. {
  395. // Starts with "T<". Skip <...>
  396. k++;
  397. k=skipTemplateQualifiers(k);
  398. }
  399. else
  400. {
  401. // skip ID;
  402. k++;
  403. }
  404. return (LT(k).getType() != SCOPE );
  405. }
  406. else
  407. { // not an ID
  408. return false;
  409. }
  410. }
  411. /*
  412. * Return true if 's' can pose as a type name
  413. */
  414. public boolean isTypeName(String s)
  415. {
  416. String type="";
  417. if (!symbols.containsKey(s))
  418. {
  419. //printf("support.cpp isTypeName %s not found\n",s);
  420. return false;
  421. }
  422. else
  423. type=(String) symbols.get(s);
  424. if (type.equals(CPPvariables.OT_TYPE_DEF)||
  425. type.equals(CPPvariables.OT_ENUM)||
  426. type.equals(CPPvariables.OT_CLASS)||
  427. type.equals(CPPvariables.OT_STRUCT)||
  428. type.equals(CPPvariables.OT_UNION))
  429. {
  430. return true;
  431. }
  432. return false;
  433. }
  434. public void declaratorID(String id, java.util.BitSet qi)
  435. {
  436. if ((qi.equals(CPPvariables.QI_TYPE)) || (_td)) // Check for type declaration
  437. {
  438. if (!symbols.containsKey(id))
  439. symbols.put(id, CPPvariables.OT_TYPE_DEF);
  440. }
  441. }
  442. }
  443. translation_unit [Builder builder]
  444. {
  445. if(!symbols.containsKey("std"))
  446. symbols.put("std",CPPvariables.OT_TYPE_DEF);
  447. b = builder;
  448. }
  449. : {b.beginTranslationUnit();}
  450. (external_declaration)+ EOF
  451. {b.endTranslationUnit();}
  452. ;
  453. external_declaration
  454. {String s="";}
  455. :
  456. (
  457. // Template explicit specialisation (DW 14/04/03)
  458. ("template" LESSTHAN GREATERTHAN)=>"template" LESSTHAN GREATERTHAN declaration
  459. |
  460. // Class definition (templates too)
  461. // This is separated out otherwise the next alternative
  462. // would look for "class A { ... } f() {...}" which is
  463. // an unacceptable level of backtracking.
  464. // JEL Note: Rule body does not need typedef, because
  465. // that is internal to "declaration", and it is invalid
  466. // to say "typedef template..."
  467. // Class definition
  468. (("typedef")? class_head)=> declaration
  469. |
  470. // Class template definition
  471. (template_head class_head)=>template_head declaration
  472. |
  473. // Enum definition (don't want to backtrack over this in other alts)
  474. ("enum" (ID)? LCURLY)=>enum_specifier (init_declarator_list)? SEMICOLON
  475. |
  476. // Destructor DEFINITION (templated or non-templated)
  477. ((template_head)? dtor_head LCURLY)=>(template_head)? dtor_head dtor_body
  478. |
  479. // Constructor DEFINITION (non-templated)
  480. // JEL 4/3/96 Added predicate that works, once the
  481. // restriction is added that ctor cannot be virtual
  482. // and ctor_declarator uses a more restrictive id
  483. ( (options {warnWhenFollowAmbig = false;}:
  484. ctor_decl_spec)?
  485. {qualifiedItemIsOneOf(CPPvariables.QI_CTOR,0)}?)=>ctor_definition
  486. /*(ID SCOPE)=>ctor_definition*/
  487. |
  488. // User-defined type cast
  489. (("inline")? scope_override conversion_function_decl_or_def)=>
  490. ("inline")? s = scope_override conversion_function_decl_or_def
  491. |
  492. // Function declaration
  493. (declaration_specifiers function_declarator SEMICOLON)=>
  494. {b.beginFunctionDeclaration();}
  495. declaration
  496. {b.endFunctionDeclaration();}
  497. |
  498. // Function definition
  499. (declaration_specifiers function_declarator LCURLY)=>
  500. {b.beginFunctionDefinition(LT(2).getLine());}
  501. function_definition
  502. {b.endFunctionDefinition();}
  503. |
  504. // K & R Function definition
  505. (declaration_specifiers function_declarator declaration)=>function_definition
  506. |
  507. // templated forward class decl, init/decl of static member in template
  508. (template_head declaration_specifiers (init_declarator_list)? SEMICOLON )=>
  509. template_head declaration_specifiers (init_declarator_list)? SEMICOLON
  510. |
  511. // Templated FUNCTIONS and CONSTRUCTORS matched here.
  512. template_head
  513. (
  514. // Templated CONSTRUCTOR definition
  515. // JEL 4/3/96 Added predicate that works once the
  516. // restriction is added that ctor cannot be virtual
  517. ( ctor_decl_spec {qualifiedItemIsOneOf(CPPvariables.QI_CTOR,0)}?)=>ctor_definition
  518. |
  519. // Templated function declaration
  520. (declaration_specifiers function_declarator SEMICOLON)=> declaration
  521. |
  522. // Templated function definition
  523. (declaration_specifiers function_declarator LCURLY)=> function_definition
  524. )
  525. |
  526. decl_namespace
  527. |
  528. // everything else (except templates)
  529. declaration
  530. |
  531. SEMICOLON
  532. )
  533. ; // end of external_declaration
  534. decl_namespace
  535. {String qid="";}
  536. :
  537. "namespace"
  538. (
  539. (ns:ID{ _td = true;declaratorID(ns.getText(),CPPvariables.QI_TYPE);})?
  540. // The following statement can be invoked to trigger selective antlr trace
  541. // Also see below
  542. //{if (strcmp((ns->getText()).data(),"xyz")==0) antlrTrace(true);} // Used for diagnostic trigger
  543. LCURLY
  544. {if(ns == null) { b.enterNamespaceScope(null); }
  545. else { b.enterNamespaceScope(ns.getText()); }}
  546. (external_declaration)*
  547. {b.exitNamespaceScope();}
  548. RCURLY
  549. // The following should be implemented to match the optional statement above
  550. //{antlrTrace(false);}
  551. |
  552. ns2:ID {_td=true;declaratorID(ns2.getText(),CPPvariables.QI_TYPE);}
  553. ASSIGNEQUAL qid = qualified_id SEMICOLON
  554. {b.makeNamespaceAlias(qid, ns2.getText());}
  555. )
  556. ;
  557. member_declaration
  558. {String q="";}
  559. :
  560. {b.beginMemberDeclaration();}
  561. (
  562. // Class definition
  563. // This is separated out otherwise the next alternative
  564. // would look for "class A { ... } f() {...}" which is
  565. // an unacceptable level of backtracking.
  566. ( ("typedef")? class_head) => declaration
  567. |
  568. // Enum definition (don't want to backtrack over this in other alts)
  569. ("enum" (ID)? LCURLY)=>enum_specifier (member_declarator_list)? SEMICOLON
  570. |
  571. (template_head class_head)=>template_head declaration
  572. |
  573. // Constructor declarator
  574. ( ctor_decl_spec {qualifiedItemIsOneOf(CPPvariables.QI_CTOR,0)}? ctor_declarator SEMICOLON)=>
  575. ctor_decl_spec ctor_declarator SEMICOLON // Constructor declarator
  576. |
  577. // JEL Predicate to distinguish ctor from function
  578. // This works now that ctor cannot have VIRTUAL
  579. // It unfortunately matches A::A where A is not enclosing
  580. // class -- this will have to be checked semantically
  581. ( ctor_decl_spec
  582. {qualifiedItemIsOneOf(CPPvariables.QI_CTOR,0)}?
  583. ctor_declarator
  584. (COLON // DEFINITION :ctor_initializer
  585. |LCURLY // DEFINITION (compound Statement) ?
  586. )
  587. )=>ctor_definition
  588. |
  589. // No template_head allowed for dtor member
  590. // Backtrack if not a dtor (no TILDE)
  591. (dtor_head SEMICOLON)=>dtor_head SEMICOLON // Declaration
  592. |
  593. // No template_head allowed for dtor member
  594. // Backtrack if not a dtor (no TILDE)
  595. (dtor_head LCURLY)=>dtor_head dtor_body // Definition
  596. |
  597. // Function declaration
  598. (declaration_specifiers function_declarator SEMICOLON)=>
  599. {b.beginFunctionDeclaration();}
  600. declaration
  601. {b.endFunctionDeclaration();}
  602. |
  603. // Function definition
  604. (declaration_specifiers function_declarator LCURLY)=>
  605. {b.beginFunctionDefinition(LT(2).getLine());}
  606. function_definition
  607. {b.endFunctionDefinition();}
  608. |
  609. // User-defined type cast
  610. (("inline")? conversion_function_decl_or_def)=>("inline")? conversion_function_decl_or_def
  611. |
  612. // Hack to handle decls like "superclass::member",
  613. // to redefine access to private base class public members
  614. (qualified_id SEMICOLON)=>q = qualified_id SEMICOLON
  615. |
  616. // Member with a type or just a type def
  617. // A::T a(), ::T a, ::B a, void a, E a (where E is the enclosing class)
  618. (declaration_specifiers)=>declaration_specifiers (member_declarator_list)? SEMICOLON
  619. |
  620. // Member without a type (I guess it can only be a function declaration or definition)
  621. (function_declarator SEMICOLON)=> function_declarator SEMICOLON
  622. | // Member without a type (I guess it can only be a function definition)
  623. function_declarator compound_statement
  624. |
  625. // templated forward class decl, init/decl of static member in template
  626. // DW 27/06/03 Copied here from external_declaration since templates can now be nested
  627. (template_head declaration_specifiers (init_declarator_list)? SEMICOLON)=>
  628. template_head declaration_specifiers (init_declarator_list)? SEMICOLON
  629. |
  630. // Templated FUNCTIONS and CONSTRUCTORS matched here.
  631. // DW 27/06/03 Copied here from external_declaration since templates can now be nested
  632. template_head
  633. (
  634. // Templated CONSTRUCTOR definition
  635. // JEL 4/3/96 Added predicate that works once the
  636. // restriction is added that ctor cannot be virtual
  637. (ctor_decl_spec {qualifiedItemIsOneOf(CPPvariables.QI_CTOR,0)}?)=>ctor_definition
  638. |
  639. // Templated function declaration
  640. (declaration_specifiers function_declarator SEMICOLON)=>declaration
  641. |
  642. // Templated function definition
  643. // Function definition DW 2/6/97
  644. (declaration_specifiers function_declarator LCURLY)=> function_definition
  645. |
  646. conversion_function_decl_or_def
  647. )
  648. |
  649. access_specifier COLON
  650. |
  651. SEMICOLON
  652. )
  653. {b.endMemberDeclaration();}
  654. ; // end member_declaration
  655. function_definition
  656. {java.util.BitSet auxBitSet=(java.util.BitSet)CPPvariables.QI_TYPE.clone(); auxBitSet.or(CPPvariables.QI_CTOR);}
  657. : // don't want next action as an init-action due to (...)=> caller
  658. ( // Next line is equivalent to guarded predicate in PCCTS
  659. // (SCOPE | ID)? => <<qualifiedItemisOneOf(QI_TYPE|QI_CTOR)>>?
  660. {( !(LA(1)==SCOPE||LA(1)==ID) || qualifiedItemIsOneOf(auxBitSet,0) )}?
  661. declaration_specifiers function_declarator
  662. ( options{warnWhenFollowAmbig = false;}:
  663. (declaration)* // Possible for K & R definition
  664. )? compound_statement
  665. | // Next line is equivalent to guarded predicate in PCCTS
  666. // (SCOPE | ID)? => <<qualifiedItemisOneOf(QI_PTR_MEMBER)>>?
  667. //{( !(LA(1)==SCOPE||LA(1)==ID) || (qualifiedItemIsOneOf(QI_PTR_MEMBER)) )}?
  668. function_declarator
  669. ( options{warnWhenFollowAmbig = false;}:
  670. (declaration)* // Possible for K & R definition
  671. )? compound_statement
  672. )
  673. ;
  674. declaration
  675. :
  676. ("extern" StringLiteral)=> linkage_specification
  677. |
  678. // LL 31/1/97: added (COMMA) ? below. This allows variables to typedef'ed more than once. DW 18/08/03 ?
  679. declaration_specifiers ((COMMA)? init_declarator_list)? SEMICOLON
  680. |
  681. using_declaration // DW 19/04/04
  682. ;
  683. linkage_specification
  684. : "extern"
  685. StringLiteral
  686. (LCURLY (external_declaration)* RCURLY
  687. |declaration
  688. )
  689. ;
  690. declaration_specifiers
  691. {_td=false; boolean td=false; List declSpecs = new ArrayList();}
  692. :
  693. ( (options {warnWhenFollowAmbig = false;}
  694. : storage_class_specifier
  695. | type_qualifier
  696. | ("inline"|"_inline"|"__inline") {declSpecs.add("inline");}
  697. | "virtual" {declSpecs.add("virtual");}
  698. | "explicit" {declSpecs.add("explicit");}
  699. | "typedef" {td=true; declSpecs.add("typedef");}
  700. | "friend" {declSpecs.add("friend");}
  701. | ("_stdcall"|"__stdcall") {declSpecs.add("__stdcall");}
  702. | ("_declspec"|"__declspec") LPAREN ID RPAREN // euluis: ignore
  703. )* {if (!declSpecs.isEmpty()) b.declarationSpecifiers(declSpecs);}
  704. type_specifier
  705. |
  706. "typename" {td=true;} direct_declarator
  707. )
  708. {_td=td;}
  709. ;
  710. storage_class_specifier
  711. : "auto" {b.storageClassSpecifier("auto");}
  712. | "register" {b.storageClassSpecifier("register");}
  713. | "static" {b.storageClassSpecifier("static");}
  714. | "extern" {b.storageClassSpecifier("extern");}
  715. | "mutable" {b.storageClassSpecifier("mutable");}
  716. ;
  717. type_qualifier // aka cv_qualifier
  718. : ("const"|"const_cast") {b.typeQualifier("const");} // euluis TODO: const_cast ?!?
  719. | "volatile" {b.typeQualifier("volatile");}
  720. ;
  721. type_specifier
  722. : simple_type_specifier
  723. | class_specifier
  724. | enum_specifier
  725. ;
  726. simple_type_specifier
  727. { String s="";
  728. java.util.BitSet auxBitSet=(java.util.BitSet)CPPvariables.QI_TYPE.clone();
  729. auxBitSet.or(CPPvariables.QI_CTOR);
  730. List sts = new ArrayList();
  731. }
  732. : ( {qualifiedItemIsOneOf(auxBitSet,0)}?
  733. s = qualified_type
  734. {sts.add(s); b.simpleTypeSpecifier(sts);}
  735. |
  736. ( "char" {sts.add("char");}
  737. | "wchar_t" {sts.add("wchar_t");}
  738. | "bool" {sts.add("bool");}
  739. | "short" {sts.add("short");}
  740. | "int" {sts.add("int");}
  741. | ("_int64"|"__int64") {sts.add("__int64");}
  742. | "__w64" {sts.add("__w64");}
  743. | "long" {sts.add("long");}
  744. | "signed" {sts.add("signed");}
  745. | "unsigned" {sts.add("unsigned");}
  746. | "float" {sts.add("float");}
  747. | "double" {sts.add("double");}
  748. | "void" {sts.add("void");}
  749. | ("_declspec"|"__declspec") LPAREN ID RPAREN //euluis: ignore
  750. )+ {b.simpleTypeSpecifier(sts);}
  751. )
  752. ;
  753. qualified_type returns [String q=""]
  754. {String s=""; String qitem="";}
  755. :
  756. // JEL 3/29/96 removed this predicate and moved it upwards to
  757. // simple_type_specifier. This was done to allow parsing of ~ID to
  758. // be a unary_expression, which was never reached with this
  759. // predicate on
  760. //{qualifiedItemIsOneOf(QI_TYPE|QI_CTOR,0)}?
  761. s = scope_override
  762. id:ID
  763. (options {warnWhenFollowAmbig = false;}:
  764. LESSTHAN template_argument_list GREATERTHAN)?
  765. {
  766. qitem=s;
  767. qitem=qitem+id.getText();
  768. q=qitem;
  769. }
  770. ;
  771. class_specifier
  772. {String saveClass="";String id="";String type="";}
  773. : ("class" {type=CPPvariables.OT_CLASS;}
  774. |"struct" {type=CPPvariables.OT_STRUCT;}
  775. |"union" {type=CPPvariables.OT_UNION;}
  776. )
  777. ( id = qualified_id
  778. (options{generateAmbigWarnings = false;}:
  779. { saveClass = enclosingClass;
  780. enclosingClass = id;
  781. }
  782. {b.beginClassDefinition(type, id);}
  783. (base_clause)?
  784. LCURLY
  785. {
  786. if(!symbols.containsKey(id))
  787. symbols.put(id,type);
  788. }
  789. (member_declaration )*
  790. {b.endClassDefinition();}
  791. RCURLY
  792. { enclosingClass = saveClass;}
  793. |
  794. {
  795. String auxName=id;
  796. int pos = auxName.indexOf("::");
  797. while(pos>=0)
  798. {
  799. if(!symbols.containsKey(auxName.substring(0,pos)))
  800. symbols.put(auxName.substring(0,pos),type);
  801. auxName=auxName.substring(pos+2,auxName.length());
  802. pos=auxName.indexOf("::");
  803. }
  804. if(!symbols.containsKey(auxName))
  805. symbols.put(auxName,type);
  806. }
  807. )
  808. |
  809. LCURLY
  810. { id="anonymous";
  811. saveClass = enclosingClass; enclosingClass = "anonymous";
  812. if(!symbols.containsKey(id))
  813. symbols.put(id,type);
  814. }
  815. (member_declaration)* RCURLY
  816. {enclosingClass = saveClass;}
  817. )
  818. ;
  819. enum_specifier
  820. : "enum"
  821. ( LCURLY
  822. enumerator_list RCURLY
  823. | id:ID // DW 22/04/03 Suggest qualified_id here to satisfy elaborated_type_specifier
  824. { if(!symbols.containsKey(id.getText()))
  825. symbols.put(id.getText(),CPPvariables.OT_ENUM);
  826. }
  827. ( LCURLY enumerator_list RCURLY)?
  828. )
  829. ;
  830. enumerator_list
  831. : enumerator (COMMA enumerator)*
  832. ;
  833. enumerator
  834. : id:ID (ASSIGNEQUAL constant_expression)?
  835. ;
  836. /* This matches a generic qualified identifier ::T::B::foo
  837. * (including OPERATOR).
  838. * It might be a good idea to put T::~dtor in here
  839. * as well, but id_expression in expr.g puts it in manually.
  840. * Maybe not, 'cause many people use this assuming only A::B.
  841. * How about a 'qualified_complex_id'?
  842. */
  843. qualified_id returns [String q=""]
  844. {
  845. String so="";
  846. String qitem="";
  847. }
  848. :
  849. so = scope_override
  850. {qitem=so; }
  851. (
  852. id:ID
  853. (options{warnWhenFollowAmbig = false;}:
  854. LESSTHAN template_argument_list GREATERTHAN)?
  855. {
  856. qitem=qitem+id.getText();
  857. }
  858. |
  859. OPERATOR optor
  860. {qitem=qitem+"operator"+"NYI";}
  861. |
  862. "this" // DW 21/07/03 fix to pass test8.i
  863. |
  864. ("true"|"false") // DW 21/07/03 fix to pass test8.i
  865. )
  866. {q = qitem;}
  867. ;
  868. typeID
  869. : {isTypeName(LT(1).getText())}?
  870. ID
  871. ;
  872. init_declarator_list
  873. : {b.beginInitDeclaratorList();}
  874. init_declarator (COMMA init_declarator)*
  875. {b.endInitDeclaratorList();}
  876. ;
  877. init_declarator
  878. : declarator
  879. (
  880. ASSIGNEQUAL
  881. // check for initialisation and assignment (e.g. int x = 10;)
  882. initializer
  883. |
  884. LPAREN expression_list RPAREN
  885. )?
  886. ;
  887. initializer
  888. :
  889. {b.beginInitializer();}
  890. (
  891. remainder_expression // DW 18/4/01 assignment_expression
  892. |
  893. LCURLY initializer (COMMA initializer)* RCURLY
  894. )
  895. {b.endInitializer();}
  896. ;
  897. class_head
  898. : // Used only by predicates
  899. ("struct"
  900. |"union"
  901. |"class"
  902. )
  903. (ID
  904. (LESSTHAN template_argument_list GREATERTHAN)?
  905. (base_clause)?
  906. )? LCURLY
  907. ;
  908. base_clause
  909. :
  910. COLON base_specifier (COMMA base_specifier)*
  911. ;
  912. base_specifier
  913. {String qt=""; b.beginBaseSpecifier();}
  914. : // DW 13/08/03 Should check qualified_type for class-name?
  915. ( "virtual" ( access_specifier)? qt = qualified_type {b.baseSpecifier(qt, true);}
  916. | access_specifier "virtual" qt = qualified_type {b.baseSpecifier(qt, true);}
  917. | access_specifier qt = qualified_type {b.baseSpecifier(qt, false);}
  918. | qt = qualified_type {b.baseSpecifier(qt, false);}
  919. )
  920. {b.endBaseSpecifier();}
  921. ;
  922. access_specifier
  923. : "public" {b.accessSpecifier("public");}
  924. | "protected" {b.accessSpecifier("protected");}
  925. | "private" {b.accessSpecifier("private");}
  926. ;
  927. member_declarator_list
  928. : member_declarator (ASSIGNEQUAL OCTALINT)? // The value must be 0 (pure virt.)
  929. (COMMA member_declarator (ASSIGNEQUAL OCTALINT)? )*
  930. ;
  931. member_declarator
  932. :
  933. ((ID)? COLON constant_expression)=>(ID)? COLON constant_expression
  934. |
  935. declarator
  936. ;
  937. conversion_function_decl_or_def
  938. : OPERATOR
  939. declaration_specifiers
  940. (STAR | AMPERSAND)? // DW 01/08/03 Use type_specifier here? see syntax
  941. (LESSTHAN template_parameter_list GREATERTHAN)?
  942. LPAREN (parameter_list)? RPAREN
  943. (type_qualifier)?
  944. (exception_specification)?
  945. ( compound_statement
  946. | SEMICOLON
  947. )
  948. ;
  949. // JEL note: does not use (const|volatile)* to avoid lookahead problems
  950. cv_qualifier_seq
  951. :
  952. (type_qualifier)*
  953. ;
  954. declarator
  955. :
  956. //{( !(LA(1)==SCOPE||LA(1)==ID) || qualifiedItemIsOneOf(QI_PTR_MEMBER) )}?
  957. (ptr_operator)=>ptr_operator // AMPERSAND or STAR
  958. declarator
  959. |
  960. direct_declarator
  961. ;
  962. direct_declarator
  963. {String id="";}
  964. :
  965. (qualified_id LPAREN (RPAREN|declaration_specifiers) )=> // Must be function declaration
  966. id = qualified_id {declaratorID(id,CPPvariables.QI_FUN); b.directDeclarator(id);}
  967. LPAREN (parameter_list)? RPAREN (type_qualifier)* (exception_specification)?
  968. | (qualified_id LPAREN qualified_id)=> // Must be class instantiation
  969. id = qualified_id {declaratorID(id,CPPvariables.QI_VAR);}LPAREN expression_list RPAREN
  970. |
  971. (qualified_id LSQUARE)=> // Must be array declaration
  972. id = qualified_id
  973. {
  974. if (_td==true)
  975. declaratorID(id,CPPvariables.QI_TYPE);
  976. else
  977. declaratorID(id,CPPvariables.QI_VAR);
  978. }
  979. (options {warnWhenFollowAmbig = false;}:
  980. LSQUARE (constant_expression)? RSQUARE)+
  981. |
  982. id = qualified_id
  983. {
  984. if (_td==true)
  985. declaratorID(id,CPPvariables.QI_TYPE);
  986. else {
  987. declaratorID(id,CPPvariables.QI_VAR);
  988. b.directDeclarator(id);
  989. }
  990. }
  991. |
  992. // DW 24/05/04 This block probably never entered as dtor selected out earlier
  993. // Note In fact no dictionary entries for ctor or dtor
  994. TILDE dtor:ID {declaratorID(dtor.getText(),CPPvariables.QI_DTOR);}// Note "class" not recorded in CPPSymbol
  995. LPAREN (parameter_list)? RPAREN
  996. |
  997. LPAREN declarator RPAREN declarator_suffixes
  998. ;
  999. declarator_suffixes
  1000. {java.util.BitSet auxBitSet=(java.util.BitSet)CPPvariables.QI_TYPE.clone(); auxBitSet.or(CPPvariables.QI_CTOR);}
  1001. :
  1002. (
  1003. (options {warnWhenFollowAmbig = false;}:
  1004. LSQUARE (constant_expression)? RSQUARE)+
  1005. | {(!((LA(1)==LPAREN)&&(LA(2)==ID))||(qualifiedItemIsOneOf(auxBitSet,1)))}?
  1006. LPAREN (parameter_list)? RPAREN (type_qualifier)* (exception_specification)?
  1007. // | // DW 28/06/04 deleted Assume either following bracketed declaration
  1008. // // empty
  1009. )
  1010. ;
  1011. /* I think something is weird with the context-guards for predicates;
  1012. * as a result I manually hoist the appropriate pred from ptr_to_member
  1013. *
  1014. * TER: warning: seems that "ID::" will always bypass and go to 2nd alt :(
  1015. */
  1016. function_declarator
  1017. :
  1018. //{( !(LA(1)==SCOPE||LA(1)==ID) || qualifiedItemIsOneOf(QI_PTR_MEMBER) )}?
  1019. (ptr_operator)=> ptr_operator function_declarator
  1020. |
  1021. function_direct_declarator
  1022. ;
  1023. function_direct_declarator
  1024. { String q="";}
  1025. :
  1026. /* predicate indicate that plain ID is ok here; this counteracts any
  1027. * other predicate that gets hoisted (along with this one) that
  1028. * indicates that an ID is a type or whatever. E.g.,
  1029. * another rule testing isTypeName() alone, implies that the
  1030. * the ID *MUST* be a type name. Combining isTypeName() and
  1031. * this predicate in an OR situation like this one:
  1032. * ( declaration_specifiers ... | function_declarator ... )
  1033. * would imply that ID can be a type name OR a plain ID.
  1034. */
  1035. ( // fix prompted by (isdigit)() in xlocnum
  1036. LPAREN
  1037. q = qualified_id
  1038. {
  1039. declaratorID(q,CPPvariables.QI_FUN);
  1040. }
  1041. RPAREN
  1042. |
  1043. q = qualified_id
  1044. {
  1045. declaratorID(q,CPPvariables.QI_FUN);
  1046. }
  1047. )
  1048. {b.functionDirectDeclarator(q);}
  1049. LPAREN (parameter_list)? RPAREN
  1050. (options{warnWhenFollowAmbig = false;}:
  1051. type_qualifier)*
  1052. (ASSIGNEQUAL OCTALINT)? // The value of the octal must be 0
  1053. (exception_specification)?
  1054. ;
  1055. ctor_definition
  1056. :
  1057. {b.beginCtorDefinition();}
  1058. ctor_head
  1059. ctor_body
  1060. {b.endCtorDefinition();}
  1061. ;
  1062. ctor_head
  1063. :
  1064. ctor_decl_spec ctor_declarator
  1065. ;
  1066. ctor_decl_spec
  1067. {List declSpecs = new ArrayList();}
  1068. :
  1069. ( ("inline"|"_inline"|"__inline") {declSpecs.add("inline");}
  1070. |
  1071. "explicit" {declSpecs.add("explicit");}
  1072. )*
  1073. {b.declarationSpecifiers(declSpecs);}
  1074. ;
  1075. ctor_declarator
  1076. { String q="";}
  1077. :
  1078. // JEL 4/3/96 qualified_id too broad DW 10/06/03 ?
  1079. q = qualified_ctor_id {b.qualifiedCtorId(q);}
  1080. LPAREN (parameter_list)? RPAREN (exception_specification)?
  1081. ;
  1082. // This matches a generic qualified identifier ::T::B::foo
  1083. // that is satisfactory for a ctor (no operator, no trailing <>)
  1084. qualified_ctor_id returns [String q=""]
  1085. {
  1086. String so="";
  1087. String qitem="";
  1088. }
  1089. :
  1090. so = scope_override
  1091. {qitem=so;}
  1092. id:ID // DW 24/05/04 Note. Neither Ctor or Dtor recorded in dictionary
  1093. {qitem=qitem+id.getText();
  1094. q = qitem;}
  1095. ;
  1096. ctor_body
  1097. :
  1098. (ctor_initializer)? compound_statement
  1099. ;
  1100. ctor_initializer
  1101. :
  1102. COLON superclass_init (COMMA superclass_init)*
  1103. ;
  1104. superclass_init
  1105. {String q="";}
  1106. :
  1107. q = qualified_id LPAREN (expression_list)? RPAREN
  1108. ;
  1109. dtor_head
  1110. :
  1111. {b.beginDtorHead();}
  1112. dtor_decl_spec dtor_declarator
  1113. {b.endDtorHead();}
  1114. ;
  1115. dtor_decl_spec
  1116. {List declSpecs = new ArrayList();}
  1117. :
  1118. (
  1119. ("inline"|"_inline"|"__inline") {declSpecs.add("inline");}
  1120. |
  1121. "virtual" {declSpecs.add("virtual");}
  1122. )*
  1123. {b.declarationSpecifiers(declSpecs);}
  1124. ;
  1125. dtor_declarator
  1126. {String s="";}
  1127. :
  1128. s = scope_override
  1129. TILDE id:ID
  1130. {b.dtorDeclarator(s+"~"+id.getText());}
  1131. LPAREN RPAREN (exception_specification)?
  1132. ;
  1133. dtor_body
  1134. :
  1135. compound_statement
  1136. ;
  1137. parameter_list
  1138. : parameter_declaration_list (ELLIPSIS)?
  1139. ;
  1140. parameter_declaration_list
  1141. :
  1142. ( parameter_declaration
  1143. (// Have not been able to find way of stopping warning of non-determinism between alt 1 and exit branch of block
  1144. COMMA parameter_declaration
  1145. )*
  1146. )
  1147. ;
  1148. parameter_declaration
  1149. {java.util.BitSet auxBitSet=(java.util.BitSet)CPPvariables.QI_TYPE.clone(); auxBitSet.or(CPPvariables.QI_CTOR);}
  1150. : {b.beginParameterDeclaration();}
  1151. (
  1152. {!((LA(1)==SCOPE) && (LA(2)==STAR||LA(2)==OPERATOR))&&( !(LA(1)==SCOPE||LA(1)==ID) || qualifiedItemIsOneOf(auxBitSet,0) )}?
  1153. declaration_specifiers // DW 24/3/98 Mods for K & R
  1154. (
  1155. (declarator)=> declarator // if arg name given
  1156. |
  1157. abstract_declarator // if arg name not given // can be empty
  1158. )
  1159. |
  1160. (declarator)=> declarator // DW 24/3/98 Mods for K & R
  1161. |
  1162. ELLIPSIS
  1163. )
  1164. (ASSIGNEQUAL
  1165. remainder_expression // DW 18/4/01 assignment_expression
  1166. )?
  1167. {b.endParameterDeclaration();}
  1168. ;
  1169. type_name // aka type_id
  1170. :
  1171. declaration_specifiers abstract_declarator
  1172. ;
  1173. /* This rule looks a bit weird because (...) can happen in two
  1174. * places within the declaration such as "void (*)()" (ptr to
  1175. * function returning nothing). However, the () of a function
  1176. * can only occur after having seen either a (abstract_declarator)
  1177. * and not after a [..] or simple '*'. These are the only two
  1178. * valid () func-groups:
  1179. * int (*)(); // ptr to func
  1180. * int (*[])(); // array of ptr to func
  1181. */
  1182. abstract_declarator
  1183. : //{( !(LA(1)==SCOPE||LA(1)==ID) || qualifiedItemIsOneOf(QI_PTR_MEMBER) )}?
  1184. ptr_operator abstract_declarator
  1185. |
  1186. LPAREN abstract_declarator RPAREN
  1187. (abstract_declarator_suffix)+
  1188. |
  1189. (LSQUARE (constant_expression )? RSQUARE )+
  1190. |
  1191. /* empty */
  1192. ;
  1193. abstract_declarator_suffix
  1194. :
  1195. LSQUARE (constant_expression)? RSQUARE
  1196. |
  1197. LPAREN (parameter_list)? RPAREN cv_qualifier_seq (exception_specification)?
  1198. ;
  1199. exception_specification
  1200. {String so="";}
  1201. : "throw" LPAREN
  1202. ( (so = scope_override ID (COMMA so = scope_override ID)* )?
  1203. | ELLIPSIS
  1204. )
  1205. RPAREN
  1206. ;
  1207. template_head
  1208. :
  1209. "template"
  1210. LESSTHAN template_parameter_list GREATERTHAN
  1211. ;
  1212. template_parameter_list
  1213. :
  1214. template_parameter (COMMA template_parameter)*
  1215. ;
  1216. /* Rule requires >2 lookahead tokens. The ambiguity is resolved
  1217. * correctly, however. According to the manual "...A template argument
  1218. * that can be interpreted either as a parameter-declaration or a
  1219. * type-argument (because its identifier is the name of an
  1220. * already existing class) is taken as type-argument."
  1221. * Therefore, any "class ID" that is seen on the input, should
  1222. * match the first alternative here (it should be a type-argument).
  1223. */
  1224. template_parameter
  1225. :
  1226. (options{generateAmbigWarnings = false;}:
  1227. ("class"|"typename")
  1228. (id:ID (ASSIGNEQUAL assigned_type_name)? )?
  1229. { if(!symbols.containsKey(id.getText()))
  1230. symbols.put(id.getText(),CPPvariables.OT_TYPE_DEF);
  1231. }
  1232. |
  1233. parameter_declaration // DW 30/06/03 This doesn't seem to match the current standard
  1234. )
  1235. ;
  1236. /* This is to allow an assigned type_name in a template parameter
  1237. * list to be defined previously in the same parameter list,
  1238. * as type setting is ineffective whilst guessing
  1239. */
  1240. assigned_type_name
  1241. {String s=""; }
  1242. :
  1243. (options{generateAmbigWarnings = false;}:
  1244. s = qualified_type abstract_declarator
  1245. |
  1246. simple_type_specifier abstract_declarator
  1247. )
  1248. ;
  1249. // This rule refers to an instance of a template class or function
  1250. template_id // aka template_class_name
  1251. : ID LESSTHAN template_argument_list GREATERTHAN
  1252. ;
  1253. template_argument_list
  1254. : template_argument (COMMA template_argument)*
  1255. ;
  1256. /* Here assignment_expression was changed to shift_expression to rule out
  1257. * x< 1<2 > which causes ambiguities. As a result, these can be used only
  1258. * by enclosing parentheses x<(1<2)>. This is true for x<1+2> ==> bad,
  1259. * x<(1+2)> ==> ok.
  1260. */
  1261. template_argument
  1262. {java.util.BitSet auxBitSet=(java.util.BitSet)CPPvariables.QI_TYPE.clone(); auxBitSet.or(CPPvariables.QI_CTOR);}
  1263. :
  1264. {( !(LA(1)==SCOPE||LA(1)==ID) || qualifiedItemIsOneOf(auxBitSet,0) )}?
  1265. type_name
  1266. |
  1267. shift_expression // failed in iosfwd
  1268. // | assignment_expression // Inserted as per grammar summary
  1269. ;
  1270. ///////////////////////////////////////////////////////////////////////
  1271. ///////////////////////////////////////////////////////////////////////
  1272. ////////////////////////////// STATEMENTS ////////////////////////////
  1273. ///////////////////////////////////////////////////////////////////////
  1274. ///////////////////////////////////////////////////////////////////////
  1275. statement_list
  1276. : (statement)+
  1277. ;
  1278. statement
  1279. :
  1280. ( (declaration)=>declaration
  1281. | labeled_statement
  1282. | case_statement
  1283. | default_statement
  1284. |
  1285. {b.beginExpressionStatement();}
  1286. expression SEMICOLON
  1287. {b.endExpressionStatement();}
  1288. | compound_statement
  1289. | selection_statement
  1290. | iteration_statement
  1291. | jump_statement
  1292. | SEMICOLON
  1293. | try_block
  1294. | throw_statement
  1295. | asm_block
  1296. )
  1297. ;
  1298. labeled_statement
  1299. : ID COLON statement
  1300. ;
  1301. case_statement
  1302. : {b.beginCaseStatement();}
  1303. "case"
  1304. constant_expression COLON statement
  1305. {b.endCaseStatement();}
  1306. ;
  1307. default_statement
  1308. : {b.beginDefaultStatement();}
  1309. "default" COLON statement
  1310. {b.endDefaultStatement();}
  1311. ;
  1312. compound_statement
  1313. :
  1314. {b.beginCompoundStatement();}
  1315. LCURLY (statement_list)? RCURLY
  1316. {b.endCompoundStatement();}
  1317. ;
  1318. /* NOTE: cannot remove ELSE ambiguity, but it parses correctly.
  1319. * The warning is removed with the options statement
  1320. */
  1321. selection_statement
  1322. :
  1323. {b.beginIfStatement();}
  1324. "if" LPAREN expression RPAREN statement
  1325. {b.endIfStatement();}
  1326. (options {warnWhenFollowAmbig = false;}:
  1327. {b.beginElseStatement();}
  1328. "else" statement
  1329. {b.endElseStatement();}
  1330. )?
  1331. |
  1332. {b.beginSwitchStatement();}
  1333. "switch" LPAREN expression RPAREN statement
  1334. {b.endSwitchStatement();}
  1335. ;
  1336. iteration_statement
  1337. :
  1338. {b.beginWhileStatement();}
  1339. "while" LPAREN expression RPAREN statement
  1340. {b.endWhileStatement();}
  1341. |
  1342. {b.beginDoStatement();}
  1343. "do" statement "while" LPAREN expression RPAREN SEMICOLON
  1344. {b.endDoStatement();}
  1345. |
  1346. {b.beginForStatement();}
  1347. "for" LPAREN
  1348. ( (declaration)=> declaration
  1349. | expression SEMICOLON
  1350. | SEMICOLON
  1351. )
  1352. (expression)? SEMICOLON
  1353. (expression)?
  1354. RPAREN statement
  1355. {b.endForStatement();}
  1356. ;
  1357. jump_statement
  1358. :
  1359. ( "goto" ID SEMICOLON
  1360. {b.gotoStatement();}
  1361. | "continue" SEMICOLON
  1362. {b.continueStatement();}
  1363. | "break" SEMICOLON
  1364. {b.breakStatement();}
  1365. // DW 16/05/03 May be problem here if return is followed by a cast expression
  1366. | {b.beginReturnStatement(LT(1).getLine());}
  1367. "return"
  1368. ( options{warnWhenFollowAmbig = false;}:
  1369. (LPAREN {(qualifiedItemIsOneOf(CPPvariables.QI_TYPE,0) )}? ID RPAREN)=>
  1370. LPAREN ID RPAREN (expression)? // This is an unsatisfactory fix for problem in xstring re "return (allocator);"
  1371. // and in xlocale re return (_E)(_Tolower((unsigned char)_C, &_Ctype));
  1372. //{printf("%d CPP_parser.g jump_statement Return fix used\n",LT(1)->getLine());}
  1373. | expression
  1374. )? SEMICOLON
  1375. {b.endReturnStatement();}
  1376. )
  1377. ;
  1378. try_block
  1379. : "try" compound_statement (handler)*
  1380. ;
  1381. handler
  1382. : "catch" LPAREN exception_declaration RPAREN compound_statement
  1383. ;
  1384. exception_declaration
  1385. : parameter_declaration_list
  1386. ;
  1387. /* This is an expression of type void according to the ARM, which
  1388. * to me means "statement"; it removes some ambiguity to put it in
  1389. * as a statement also.
  1390. */
  1391. throw_statement
  1392. : "throw" (assignment_expression) ? SEMICOLON
  1393. ;
  1394. using_declaration
  1395. {String qid="";}
  1396. : "using"
  1397. ("namespace" qid = qualified_id // Using-directive
  1398. |qid = qualified_id // Using-declaration
  1399. )
  1400. SEMICOLON
  1401. ;
  1402. asm_block
  1403. : ("_asm"|"__asm") LCURLY (~RCURLY)* RCURLY
  1404. ;
  1405. ///////////////////////////////////////////////////////////////////////
  1406. ///////////////////////////////////////////////////////////////////////
  1407. ////////////////////////////// EXPRESSIONS ///////////////////////////
  1408. ///////////////////////////////////////////////////////////////////////
  1409. ///////////////////////////////////////////////////////////////////////
  1410. expression
  1411. :
  1412. {b.beginExpression();}
  1413. assignment_expression (COMMA assignment_expression)*
  1414. {b.endExpression();}
  1415. ;
  1416. expression_list
  1417. : assignment_expression (COMMA assignment_expression)*
  1418. ;
  1419. /* right-to-left for assignment op */
  1420. assignment_expression
  1421. :
  1422. conditional_expression
  1423. (
  1424. {b.beginAssignmentExpression(LT(1).getLine());}
  1425. (ASSIGNEQUAL
  1426. |TIMESEQUAL|DIVIDEEQUAL|MINUSEQUAL|PLUSEQUAL
  1427. |MODEQUAL
  1428. |SHIFTLEFTEQUAL
  1429. |SHIFTRIGHTEQUAL
  1430. |BITWISEANDEQUAL
  1431. |BITWISEXOREQUAL
  1432. |BITWISEOREQUAL
  1433. )
  1434. remainder_expression
  1435. {b.endAssignmentExpression();}
  1436. )?
  1437. ;
  1438. remainder_expression
  1439. :
  1440. ( (conditional_expression (COMMA|SEMICOLON|RPAREN)
  1441. )=>
  1442. assignment_expression
  1443. |
  1444. assignment_expression
  1445. )
  1446. ;
  1447. conditional_expression
  1448. :
  1449. logical_or_expression
  1450. (
  1451. {b.beginTernaryOperator();}
  1452. QUESTIONMARK expression COLON conditional_expression
  1453. {b.endTernaryOperator();}
  1454. )?
  1455. ;
  1456. constant_expression
  1457. :
  1458. conditional_expression
  1459. ;
  1460. logical_or_expression
  1461. :
  1462. logical_and_expression (OR logical_and_expression)*
  1463. ;
  1464. logical_and_expression
  1465. :
  1466. inclusive_or_expression (AND inclusive_or_expression)*
  1467. ;
  1468. inclusive_or_expression
  1469. :
  1470. exclusive_or_expression (BITWISEOR exclusive_or_expression)*
  1471. ;
  1472. exclusive_or_expression
  1473. :
  1474. and_expression (BITWISEXOR and_expression)*
  1475. ;
  1476. and_expression
  1477. :
  1478. equality_expression (AMPERSAND equality_expression)*
  1479. ;
  1480. equality_expression
  1481. :
  1482. relational_expression ((NOTEQUAL | EQUAL) relational_expression)*
  1483. ;
  1484. relational_expression
  1485. : shift_expression
  1486. (options {warnWhenFollowAmbig = false;}:
  1487. ( LESSTHAN
  1488. | GREATERTHAN
  1489. | LESSTHANOREQUALTO
  1490. | GREATERTHANOREQUALTO
  1491. )
  1492. shift_expression
  1493. )*
  1494. ;
  1495. shift_expression
  1496. : additive_expression ((SHIFTLEFT | SHIFTRIGHT) additive_expression)*
  1497. ;
  1498. /* See comment for multiplicative_expression regarding #pragma */
  1499. additive_expression
  1500. : multiplicative_expression
  1501. (options{warnWhenFollowAmbig = false;}:
  1502. (PLUS | MINUS) multiplicative_expression
  1503. )*
  1504. ;
  1505. /* ANTLR has trouble dealing with the analysis of the confusing unary/binary
  1506. * operators such as STAR, AMPERSAND, PLUS, etc... With the #pragma (now "(options{warnWhenFollowAmbig = false;}:" etc.)
  1507. * we simply tell ANTLR to use the "quick-to-analyze" approximate lookahead
  1508. * as full LL(k) lookahead will not resolve the ambiguity anyway. Might
  1509. * as well not bother. This has the side-benefit that ANTLR doesn't go
  1510. * off to lunch here (take infinite time to read grammar).
  1511. */
  1512. multiplicative_expression
  1513. : pm_expression
  1514. (options{warnWhenFollowAmbig = false;}:
  1515. (STAR | DIVIDE | MOD) pm_expression
  1516. )*
  1517. ;
  1518. pm_expression
  1519. : cast_expression ((DOTMBR | POINTERTOMBR) cast_expression)*
  1520. ;
  1521. /* The string "( ID" can be either the start of a cast or
  1522. * the start of a unary_expression. However, the ID must
  1523. * be a type name for it to be a cast. Since ANTLR can only hoist
  1524. * semantic predicates that are visible without consuming a token,
  1525. * the semantic predicate in rule type_name is not hoisted--hence, the
  1526. * rule is reported to be ambiguous. I am manually putting in the
  1527. * correctly hoisted predicate.
  1528. *
  1529. * Ack! Actually "( ID" might be the start of "(T(expr))" which makes
  1530. * the first parens just an ordinary expression grouping. The solution
  1531. * is to look at what follows the type, T. Note, this could be a
  1532. * qualified type. Yucko. I believe that "(T(" can only imply
  1533. * function-style type cast in an expression (...) grouping.
  1534. *
  1535. * We DO NOT handle the following situation correctly at the moment:
  1536. * Suppose you have
  1537. * struct rusage rusage;
  1538. * return (rusage.fp);
  1539. * return (rusage*)p;
  1540. * Now essentially there is an ambiguity here. If rusage is followed by any
  1541. * postix operators then it is an identifier else it is a type name. This
  1542. * problem does not occur in C because, unless the tag struct is attached,
  1543. * rusage is not a type name. However in C++ that restriction is removed.
  1544. * No *real* programmer would do this, but it's in the C++ standard just for
  1545. * fun..
  1546. *
  1547. * Another fun one (from an LL standpoint):
  1548. *
  1549. * (A::B::T *)v; // that's a cast of v to type A::B::T
  1550. * (A::B::foo); // that's a simple member access
  1551. *
  1552. * The qualifiedItemIs(1) function scans ahead to what follows the
  1553. * final "::" and returns QI_TYPE if the item is a type. The offset of
  1554. * '1' makes it ignore the initial LPAREN; normally, the offset is 0.
  1555. */
  1556. cast_expression
  1557. :
  1558. // DW 23/06/03
  1559. (LPAREN (type_qualifier)? simple_type_specifier (ptr_operator)? RPAREN)=>
  1560. LPAREN (type_qualifier)? simple_type_specifier (ptr_operator)? RPAREN cast_expression
  1561. |
  1562. unary_expression // handles outer (...) of "(T(expr))"
  1563. ;
  1564. unary_expression
  1565. :
  1566. ( //{!(LA(1)==TILDE && LA(2)==ID)||qualifiedItemIsOneOf(QI_VAR|QI_FUN|QI_DTOR|QI_CTOR)}?
  1567. (postfix_expression)=> postfix_expression
  1568. | PLUSPLUS unary_expression
  1569. | MINUSMINUS unary_expression
  1570. | unary_operator cast_expression
  1571. | "sizeof"
  1572. (// see comment for rule cast_expression for info on predicate
  1573. // JEL NOTE 3/31/96 -- This won't work -- you really need to
  1574. // call qualifiedItemIsOneOf(QI_TYPE|QI_CTOR,1)
  1575. // The context should also be ( LPAREN (SCOPE|ID) )
  1576. // ( LPAREN ID ) => {isTypeName((LT(2)->getText()).data())}?
  1577. {(!(((LA(1)==LPAREN&&(LA(2)==ID))))||(isTypeName(LT(2).getText())))}?
  1578. LPAREN type_name RPAREN
  1579. | unary_expression
  1580. )
  1581. |
  1582. (SCOPE)?
  1583. (new_expression
  1584. |delete_expression
  1585. )
  1586. )
  1587. ;
  1588. postfix_expression
  1589. {String function_name="";}
  1590. :
  1591. (
  1592. options {warnWhenFollowAmbig = false;}:
  1593. // Function-style cast must have a leading type
  1594. {!(LA(1)==LPAREN)}?
  1595. (simple_type_specifier LPAREN RPAREN LPAREN)=> // DW 01/08/03 To cope with problem in xtree (see test10.i)
  1596. simple_type_specifier LPAREN RPAREN LPAREN (expression_list)? RPAREN
  1597. |
  1598. {!(LA(1)==LPAREN)}?
  1599. (simple_type_specifier LPAREN)=>
  1600. simple_type_specifier LPAREN (expression_list)? RPAREN
  1601. |
  1602. {b.beginPostfixExpression();}
  1603. primary_expression
  1604. (options {warnWhenFollowAmbig = false;}:
  1605. LSQUARE expression RSQUARE
  1606. | LPAREN
  1607. {b.beginParameterList();}
  1608. (expression_list)?
  1609. {b.endParameterList();}
  1610. RPAREN
  1611. | DOT
  1612. {b.beginMemberAccess();}
  1613. id_expression
  1614. {b.endMemberAccess();}
  1615. | POINTERTO
  1616. {b.beginMemberAccess();}
  1617. id_expression
  1618. {b.endMemberAccess();}
  1619. | PLUSPLUS
  1620. | MINUSMINUS
  1621. )*
  1622. {b.endPostfixExpression();}
  1623. |
  1624. ("dynamic_cast"|"static_cast"|"reinterpret_cast"|"const_cast") // Note const_cast in elsewhere
  1625. LESSTHAN type_specifier (ptr_operator)? GREATERTHAN
  1626. LPAREN expression RPAREN
  1627. )
  1628. ;
  1629. primary_expression
  1630. :
  1631. {b.beginPrimaryExpression();}
  1632. id_expression
  1633. | constant
  1634. | "this"
  1635. | LPAREN expression RPAREN
  1636. {b.endPrimaryExpression();}
  1637. ;
  1638. id_expression
  1639. {String s="";}
  1640. :
  1641. s = scope_override
  1642. (
  1643. t:ID
  1644. {b.idExpression(t.getText());}
  1645. | OPERATOR optor
  1646. | TILDE (STAR)? ID // DW 29/07/03 STAR included to allow for *_S = ~*_S; seen in vector
  1647. )
  1648. ;
  1649. unary_operator
  1650. : AMPERSAND
  1651. | STAR
  1652. | PLUS
  1653. | MINUS
  1654. | TILDE
  1655. | NOT
  1656. ;
  1657. /* JEL The first ()? is used to resolve "new (expr) (type)" because both
  1658. * (expr) and (type) look identical until you've seen the whole thing.
  1659. *
  1660. * new_initializer appears to be conflicting with function arguments as
  1661. * function arguments can follow a primary_expression. [This is a full
  1662. * LL(k) versus LALL(k) problem. Enhancing context by duplication of
  1663. * some rules might handle this.]
  1664. */
  1665. new_expression
  1666. :
  1667. (
  1668. "new"
  1669. ((LPAREN expression_list RPAREN)=>
  1670. LPAREN expression_list RPAREN)?
  1671. (new_type_id | LPAREN type_name RPAREN)
  1672. (options{warnWhenFollowAmbig = false;}:
  1673. (new_initializer)=> new_initializer)?
  1674. )
  1675. ;
  1676. new_initializer
  1677. : LPAREN (expression_list)? RPAREN
  1678. ;
  1679. new_type_id
  1680. : declaration_specifiers
  1681. (options {warnWhenFollowAmbig = false;}:
  1682. //{( !(LA(1)==SCOPE||LA(1)==ID) || qualifiedItemIsOneOf(QI_PTR_MEMBER) )}?
  1683. new_declarator
  1684. )?
  1685. ;
  1686. new_declarator
  1687. : //{( !(LA(1)==SCOPE||LA(1)==ID) || qualifiedItemIsOneOf(QI_PTR_MEMBER) )}?
  1688. //ptr_to_member cv_qualifier_seq
  1689. ptr_operator
  1690. (options {warnWhenFollowAmbig = false;}:
  1691. new_declarator ) ?
  1692. | direct_new_declarator
  1693. ;
  1694. ptr_operator
  1695. :
  1696. {b.beginPtrOperator();}
  1697. ( AMPERSAND {b.ptrOperator("&");}
  1698. | ("_cdecl"|"__cdecl")
  1699. | ("_near"|"__near")
  1700. | ("_far"|"__far")
  1701. | "__interrupt"
  1702. | ("pascal"|"_pascal"|"__pascal")
  1703. | ("_stdcall"|"__stdcall")
  1704. | ptr_to_member // e.g. STAR; euluis (2005-07-13): calls
  1705. // b.ptrOperator("*") or b.ptrToMember(s, "*").
  1706. )
  1707. {b.endPtrOperator();}
  1708. ;
  1709. // Match A::B::*
  1710. ptr_to_member
  1711. {String s="";}
  1712. :
  1713. s = scope_override STAR
  1714. {
  1715. if (s.length() != 0) b.ptrToMember(s, "*");
  1716. else b.ptrOperator("*");
  1717. }
  1718. cv_qualifier_seq
  1719. ;
  1720. // Match the A::B::C:: or nothing
  1721. scope_override returns [String s=""]
  1722. {
  1723. String sitem="";
  1724. }
  1725. :
  1726. //{!(qualifiedItemIsOneOf(QI_TYPE))}?
  1727. (SCOPE {sitem=sitem+"::";})?
  1728. ( options {warnWhenFollowAmbig = false;}:
  1729. {scopedItem(1)}?
  1730. id:ID (LESSTHAN template_argument_list GREATERTHAN)? SCOPE
  1731. {
  1732. sitem=sitem+id.getText();
  1733. sitem=sitem+"::";
  1734. }
  1735. )*
  1736. {s = sitem;}
  1737. ;
  1738. /* The "[expression]" construct conflicts with the "new []" construct
  1739. * (and possibly others). We used approximate lookahead for the "new []"
  1740. * construct so that it would not try to compute full LL(2) lookahead.
  1741. * Here, we use #pragma approx again because anytime we see a [ followed
  1742. * by token that can begin an expression, we always want to loop.
  1743. * Approximate lookahead handles this correctly. In fact, approximate
  1744. * lookahead is the same as full lookahead when all but the last lookahead
  1745. * depth are singleton sets; e.g., {"["} followed by FIRST(expression).
  1746. */
  1747. direct_new_declarator
  1748. :
  1749. (options {warnWhenFollowAmbig = false;}:
  1750. LSQUARE expression RSQUARE
  1751. )+
  1752. ;
  1753. delete_expression
  1754. : "delete" (LSQUARE RSQUARE)? cast_expression
  1755. ;
  1756. constant
  1757. : OCTALINT
  1758. | DECIMALINT
  1759. | HEXADECIMALINT
  1760. | CharLiteral
  1761. | (StringLiteral)+
  1762. | FLOATONE
  1763. | FLOATTWO
  1764. | "true"
  1765. | "false"
  1766. ;
  1767. optor
  1768. :
  1769. "new"
  1770. (options {warnWhenFollowAmbig = false;}:
  1771. LSQUARE RSQUARE | ) // check syntax
  1772. |
  1773. "delete"
  1774. (options {warnWhenFollowAmbig = false;}:
  1775. LSQUARE RSQUARE | ) // check syntax
  1776. | LPAREN RPAREN
  1777. | LSQUARE RSQUARE
  1778. | optor_simple_tokclass //OPTOR_SIMPLE_TOKCLASS
  1779. ;
  1780. //Zuo 5/11/2001
  1781. // This is the equivalent to "#tokclass OPTOR_SIMPLE_TOKCLASS" in cplusplus.g
  1782. optor_simple_tokclass
  1783. :
  1784. (PLUS
  1785. |MINUS
  1786. |STAR
  1787. |DIVIDE
  1788. |MOD
  1789. |BITWISEXOR
  1790. |AMPERSAND
  1791. |BITWISEOR
  1792. |TILDE
  1793. |NOT
  1794. |SHIFTLEFT
  1795. |SHIFTRIGHT
  1796. |ASSIGNEQUAL
  1797. |TIMESEQUAL
  1798. |DIVIDEEQUAL
  1799. |MODEQUAL
  1800. |PLUSEQUAL
  1801. |MINUSEQUAL
  1802. |SHIFTLEFTEQUAL
  1803. |SHIFTRIGHTEQUAL
  1804. |BITWISEANDEQUAL
  1805. |BITWISEXOREQUAL
  1806. |BITWISEOREQUAL
  1807. |EQUAL
  1808. |NOTEQUAL
  1809. |LESSTHAN
  1810. |GREATERTHAN
  1811. |LESSTHANOREQUALTO
  1812. |GREATERTHANOREQUALTO
  1813. |OR
  1814. |AND
  1815. |PLUSPLUS
  1816. |MINUSMINUS
  1817. |COMMA
  1818. |POINTERTO
  1819. |POINTERTOMBR
  1820. )
  1821. ;
  1822. // Zuo 19/11/01 from next line, the Lexer is derived from stdCParser.g
  1823. class InternalLexer extends Lexer;
  1824. options
  1825. {
  1826. k = 3;
  1827. exportVocab = STDC;
  1828. testLiterals = true;
  1829. }
  1830. // DW 4/11/02 put in to support manual hoisting
  1831. tokens
  1832. {
  1833. OPERATOR = "operator";
  1834. }
  1835. /* Operators: */
  1836. ASSIGNEQUAL : '=' ;
  1837. COLON : ':' ;
  1838. COMMA : ',' ;
  1839. QUESTIONMARK : '?' ;
  1840. SEMICOLON : ';' ;
  1841. POINTERTO : "->" ;
  1842. /*
  1843. // DOT & ELLIPSIS are commented out since they are generated as part of
  1844. // the Number rule below due to some bizarre lexical ambiguity shme.
  1845. // DOT : '.' ;
  1846. // ELLIPSIS : "..." ;
  1847. */
  1848. LPAREN : '(' ;
  1849. RPAREN : ')' ;
  1850. LSQUARE : '[' ;
  1851. RSQUARE : ']' ;
  1852. LCURLY : '{' ;
  1853. RCURLY : '}' ;
  1854. EQUAL : "==" ;
  1855. NOTEQUAL : "!=" ;
  1856. LESSTHANOREQUALTO : "<=" ;
  1857. LESSTHAN : "<" ;
  1858. GREATERTHANOREQUALTO : ">=" ;
  1859. GREATERTHAN : ">" ;
  1860. DIVIDE : '/' ;
  1861. DIVIDEEQUAL : "/=" ;
  1862. PLUS : '+' ;
  1863. PLUSEQUAL : "+=" ;
  1864. PLUSPLUS : "++" ;
  1865. MINUS : '-' ;
  1866. MINUSEQUAL : "-=" ;
  1867. MINUSMINUS : "--" ;
  1868. STAR : '*' ;
  1869. TIMESEQUAL : "*=" ;
  1870. MOD : '%' ;
  1871. MODEQUAL : "%=" ;
  1872. SHIFTRIGHT : ">>" ;
  1873. SHIFTRIGHTEQUAL : ">>=" ;
  1874. SHIFTLEFT : "<<" ;
  1875. SHIFTLEFTEQUAL : "<<=" ;
  1876. AND : "&&" ;
  1877. NOT : '!' ;
  1878. OR : "||" ;
  1879. AMPERSAND : '&' ;
  1880. BITWISEANDEQUAL : "&=" ;
  1881. TILDE : '~' ;
  1882. BITWISEOR : '|' ;
  1883. BITWISEOREQUAL : "|=" ;
  1884. BITWISEXOR : '^' ;
  1885. BITWISEXOREQUAL : "^=" ;
  1886. //Zuo: the following tokens are come from cplusplus.g
  1887. POINTERTOMBR : "->*" ;
  1888. DOTMBR : ".*" ;
  1889. SCOPE : "::" ;
  1890. // DW 10/10/02
  1891. // Whitespace -- ignored
  1892. Whitespace
  1893. : ( (' ' |'\t' | '\f')
  1894. // handle newlines
  1895. | ( "\r\n" // MS
  1896. | '\r' // Mac
  1897. | '\n' // Unix
  1898. ) { newline(); }
  1899. // handle continuation lines
  1900. | ( "\\\r\n" // MS
  1901. | "\\\r" // Mac
  1902. | "\\\n" // Unix
  1903. )
  1904. )
  1905. {$setType(Token.SKIP); }
  1906. ;
  1907. Comment
  1908. : "/*"
  1909. ( {LA(2) != '/'}? '*'
  1910. | EndOfLine {newline();}
  1911. | ~('*'| '\r' | '\n')
  1912. )*
  1913. "*/"
  1914. {$setType(Token.SKIP);}
  1915. ;
  1916. CPPComment
  1917. : "//" (~('\n' | '\r'))* EndOfLine
  1918. {$setType(Token.SKIP);newline();}
  1919. ;
  1920. DIRECTIVE
  1921. : '#' ld:LineDirective
  1922. { $setType(Token.SKIP); newline();}
  1923. ;
  1924. protected
  1925. LineDirective
  1926. :
  1927. (~('\r'|'\n'))* EndOfLine
  1928. ;
  1929. /* Literals: */
  1930. /*
  1931. * Note that we do NOT handle tri-graphs nor multi-byte sequences.
  1932. */
  1933. /*
  1934. * Note that we can't have empty character constants (even though we
  1935. * can have empty strings :-).
  1936. */
  1937. CharLiteral
  1938. : '\'' (Escape | ~( '\'' )) '\''
  1939. ;
  1940. /*
  1941. * Can't have raw imbedded newlines in string constants. Strict reading of
  1942. * the standard gives odd dichotomy between newlines & carriage returns.
  1943. * Go figure.
  1944. */
  1945. StringLiteral
  1946. : '"'
  1947. ( Escape
  1948. | ( "\\\r\n" // MS
  1949. | "\\\r" // MAC
  1950. | "\\\n" // Unix
  1951. ) {newline();}
  1952. | ~('"' | '\r' | '\n' | '\\')
  1953. )*
  1954. '"'
  1955. ;
  1956. protected
  1957. EndOfLine
  1958. : ( options{generateAmbigWarnings = false;}:
  1959. "\r\n" // MS
  1960. | '\r' // Mac
  1961. | '\n' // Unix
  1962. )
  1963. ;
  1964. /*
  1965. * Handle the various escape sequences.
  1966. *
  1967. * Note carefully that these numeric escape *sequences* are *not* of the
  1968. * same form as the C language numeric *constants*.
  1969. *
  1970. * There is no such thing as a binary numeric escape sequence.
  1971. *
  1972. * Octal escape sequences are either 1, 2, or 3 octal digits exactly.
  1973. *
  1974. * There is no such thing as a decimal escape sequence.
  1975. *
  1976. * Hexadecimal escape sequences are begun with a leading \x and continue
  1977. * until a non-hexadecimal character is found.
  1978. *
  1979. * No real handling of tri-graph sequences, yet.
  1980. */
  1981. protected
  1982. Escape
  1983. : '\\'
  1984. ( options{warnWhenFollowAmbig=false;}:
  1985. 'a'
  1986. | 'b'
  1987. | 'f'
  1988. | 'n'
  1989. | 'r'
  1990. | 't'
  1991. | 'v'
  1992. | '"'
  1993. | '\''
  1994. | '\\'
  1995. | '?'
  1996. | ('0'..'3') (options{warnWhenFollowAmbig=false;}: Digit (options{warnWhenFollowAmbig=false;}: Digit)? )?
  1997. | ('4'..'7') (options{warnWhenFollowAmbig=false;}: Digit)?
  1998. | 'x' (options{warnWhenFollowAmbig=false;}: Digit | 'a'..'f' | 'A'..'F')+
  1999. )
  2000. ;
  2001. /* Numeric Constants: */
  2002. protected
  2003. Digit
  2004. : '0'..'9'
  2005. ;
  2006. protected
  2007. Decimal
  2008. : ('0'..'9')+
  2009. ;
  2010. protected
  2011. LongSuffix
  2012. : 'l'
  2013. | 'L'
  2014. ;
  2015. protected
  2016. UnsignedSuffix
  2017. : 'u'
  2018. | 'U'
  2019. ;
  2020. protected
  2021. FloatSuffix
  2022. : 'f'
  2023. | 'F'
  2024. ;
  2025. protected
  2026. Exponent
  2027. : ('e' | 'E') ('+' | '-')? (Digit)+
  2028. ;
  2029. protected
  2030. Vocabulary
  2031. : '\3'..'\377'
  2032. ;
  2033. Number
  2034. : ( (Digit)+ ('.' | 'e' | 'E') )=> (Digit)+
  2035. ( '.' (Digit)* (Exponent)? {$setType ( FLOATONE);} //Zuo 3/12/01
  2036. | Exponent {$setType (FLOATTWO);} //Zuo 3/12/01
  2037. )
  2038. (FloatSuffix
  2039. |LongSuffix
  2040. )?
  2041. | ("...")=> "..." {$setType (ELLIPSIS);}
  2042. | '.' {$setType (DOT);}
  2043. ( (Digit)+ (Exponent)? {$setType (FLOATONE);} //Zuo 3/12/01
  2044. //{_ttype = DoubleDoubleConst;}
  2045. (FloatSuffix //{_ttype = FloatDoubleConst;}
  2046. |LongSuffix //{_ttype = LongDoubleConst;}
  2047. )?
  2048. )?
  2049. | '0' ('0'..'7')* //{_ttype = IntOctalConst;}
  2050. (LongSuffix //{_ttype = LongOctalConst;}
  2051. |UnsignedSuffix //{_ttype = UnsignedOctalConst;}
  2052. )* {$setType( OCTALINT);}
  2053. | '1'..'9' (Digit)* //{_ttype = IntIntConst;}
  2054. (LongSuffix //{_ttype = LongIntConst;}
  2055. |UnsignedSuffix //{_ttype = UnsignedIntConst;}
  2056. )* {$setType( DECIMALINT);}
  2057. | '0' ('x' | 'X') ('a'..'f' | 'A'..'F' | Digit)+
  2058. //{_ttype = IntHexConst;}
  2059. (LongSuffix //{_ttype = LongHexConst;}
  2060. |UnsignedSuffix //{_ttype = UnsignedHexConst;}
  2061. )* {$setType( HEXADECIMALINT);}
  2062. ;
  2063. ID
  2064. options {testLiterals = true;}
  2065. : ( 'a'..'z' | 'A'..'Z' | '_' )
  2066. ( 'a'..'z' | 'A'..'Z' | '_' | '0'..'9' )*
  2067. ;