PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/ttn-post-xml-patch/SWIG/Source/LParse/parser.y

#
Happy | 1859 lines | 1681 code | 178 blank | 0 comment | 0 complexity | a6fd3ae97b7e7f77d0c637e2e14594ad MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0

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

  1. %{
  2. /* -----------------------------------------------------------------------------
  3. * parser.y
  4. *
  5. * YACC grammar for Dave's lame C parser. Based loosely on the SWIG1.1 parser
  6. *
  7. * Author(s) : David Beazley (beazley@cs.uchicago.edu)
  8. *
  9. * Copyright (C) 1999-2000. The University of Chicago
  10. * See the file LICENSE for information on usage and redistribution.
  11. * ----------------------------------------------------------------------------- */
  12. /* These defines are to move the bison generated functions into their own namespace */
  13. #define yylex lparse_yylex
  14. #define yyerror lparse_yyerror
  15. #define yyparse lparse_yyparse
  16. #define yylval lparse_yylval
  17. #define yychar lparse_yychar
  18. #define yynerrs lparse_yynerrs
  19. static char cvsroot[] = "$Header$";
  20. extern int lparse_yylex();
  21. extern void LParse_strict_type(int);
  22. void yyerror (char *s);
  23. #include "lparse.h"
  24. #include "preprocessor.h"
  25. static DOH *top = 0;
  26. static Hash *class_hash = 0;
  27. /* Pre-created attribute name objects. Used to improve parsing performance */
  28. static DOH *ATTR_TAG = 0;
  29. static DOH *ATTR_CHILD = 0;
  30. static DOH *ATTR_PARENT = 0;
  31. static DOH *ATTR_NEXT = 0;
  32. static DOH *ATTR_PREV = 0;
  33. static DOH *ATTR_NAME = 0;
  34. static DOH *ATTR_VALUE = 0;
  35. static DOH *ATTR_TYPE = 0;
  36. static DOH *ATTR_PARMS = 0;
  37. static DOH *ATTR_PARM = 0;
  38. static DOH *ATTR_STORAGE = 0;
  39. static DOH *TAG_ENUMVALUE = 0;
  40. static DOH *TAG_FUNCTION = 0;
  41. static DOH *TAG_VARIABLE = 0;
  42. static int pure_virtual = 0;
  43. /* Set parent node of a collection of children */
  44. static void setparent(DOH *parent, DOH *child) {
  45. DOH *o;
  46. o = child;
  47. while (o) {
  48. Setattr(o,ATTR_PARENT,parent);
  49. o = Getattr(o,ATTR_NEXT);
  50. }
  51. }
  52. /* Create all back links so we get a doubly-linked lists */
  53. static void create_backlinks(DOH *top) {
  54. DOH *prev = 0;
  55. DOH *obj;
  56. if (!top) return;
  57. obj = top;
  58. while (obj) {
  59. if (prev) {
  60. Setattr(obj,ATTR_PREV,prev);
  61. }
  62. create_backlinks(Getattr(obj,ATTR_CHILD));
  63. prev = obj;
  64. obj = Getattr(obj,ATTR_NEXT);
  65. }
  66. }
  67. /* LParse_parse() - Main entry point to the C parser */
  68. DOH *LParse_parse(DOH *str) {
  69. int yyparse();
  70. DOH *tp;
  71. if (!ATTR_NEXT) {
  72. ATTR_PARENT = NewString("parent");
  73. DohIntern(ATTR_PARENT);
  74. ATTR_NEXT = NewString("next");
  75. DohIntern(ATTR_NEXT);
  76. ATTR_PREV = NewString("prev");
  77. DohIntern(ATTR_PREV);
  78. ATTR_CHILD = NewString("child");
  79. DohIntern(ATTR_CHILD);
  80. ATTR_TAG = NewString("tag");
  81. DohIntern(ATTR_TAG);
  82. ATTR_NAME = NewString("name");
  83. DohIntern(ATTR_NAME);
  84. ATTR_VALUE = NewString("value");
  85. DohIntern(ATTR_VALUE);
  86. ATTR_TYPE = NewString("type");
  87. DohIntern(ATTR_TYPE);
  88. ATTR_PARMS = NewString("parms");
  89. DohIntern(ATTR_PARMS);
  90. ATTR_PARM = NewString("parm");
  91. DohIntern(ATTR_PARM);
  92. ATTR_STORAGE = NewString("storage");
  93. DohIntern(ATTR_STORAGE);
  94. TAG_ENUMVALUE = NewString("c:enumvalue");
  95. DohIntern(TAG_ENUMVALUE);
  96. TAG_FUNCTION = NewString("c:function");
  97. DohIntern(TAG_FUNCTION);
  98. TAG_VARIABLE = NewString("c:variable");
  99. DohIntern(TAG_VARIABLE);
  100. }
  101. LParse_push(str);
  102. top = 0;
  103. class_hash = NewHash();
  104. tp = NewHash();
  105. Setattr(tp, "tag", "swig:top");
  106. Setattr(tp, ATTR_NAME, Getfile(str));
  107. yyparse();
  108. Setattr(tp, ATTR_CHILD, top);
  109. setparent(tp,top);
  110. create_backlinks(tp);
  111. {
  112. DOH *key;
  113. key = Firstkey(class_hash);
  114. while (key) {
  115. DOH *node, *tag;
  116. node = Getattr(class_hash,key);
  117. tag = Gettag(node);
  118. if (Cmp(tag,"swig:addmethods") == 0) {
  119. Printf(stderr,"%s:%d. Warning. Added methods for '%s' ignored.\n", Getfile(node),Getline(node),Getname(node));
  120. }
  121. key = Nextkey(class_hash);
  122. }
  123. }
  124. return tp;
  125. }
  126. static DOH *new_node(char *tag, DOH *file, int line) {
  127. DOH *o;
  128. o = NewHash();
  129. Setattr(o,ATTR_TAG,tag);
  130. Setline(o,line);
  131. Setfile(o,file);
  132. return o;
  133. }
  134. #ifdef NEED_ALLOC
  135. void *alloca(unsigned n) {
  136. return((void *) malloc(n));
  137. }
  138. #else
  139. /* This redefinition is apparently needed on a number of machines */
  140. #undef alloca
  141. #define alloca malloc
  142. #endif
  143. /* Promote the type of arithmetic expressions */
  144. static int promote(int t1, int t2) {
  145. if ((t1 == LPARSE_T_ERROR) || (t2 == LPARSE_T_ERROR)) return LPARSE_T_ERROR;
  146. if ((t1 == LPARSE_T_DOUBLE) || (t2 == LPARSE_T_DOUBLE)) return LPARSE_T_DOUBLE;
  147. if ((t1 == LPARSE_T_FLOAT) || (t2 == LPARSE_T_FLOAT)) return LPARSE_T_FLOAT;
  148. if ((t1 == LPARSE_T_ULONG) || (t2 == LPARSE_T_ULONG)) return LPARSE_T_ULONG;
  149. if ((t1 == LPARSE_T_LONG) || (t2 == LPARSE_T_LONG)) return LPARSE_T_LONG;
  150. if ((t1 == LPARSE_T_UINT) || (t2 == LPARSE_T_UINT)) return LPARSE_T_UINT;
  151. if ((t1 == LPARSE_T_INT) || (t2 == LPARSE_T_INT)) return LPARSE_T_INT;
  152. if ((t1 == LPARSE_T_USHORT) || (t2 == LPARSE_T_USHORT)) return LPARSE_T_SHORT;
  153. if ((t1 == LPARSE_T_SHORT) || (t2 == LPARSE_T_SHORT)) return LPARSE_T_SHORT;
  154. if ((t1 == LPARSE_T_UCHAR) || (t2 == LPARSE_T_UCHAR)) return LPARSE_T_UCHAR;
  155. if ((t1 == LPARSE_T_CHAR) || (t2 == LPARSE_T_CHAR)) return LPARSE_T_INT;
  156. if (t1 != t2) {
  157. LParse_error(0,0,"Type mismatch in constant expression.\n");
  158. }
  159. return t1;
  160. }
  161. %}
  162. %union {
  163. struct {
  164. DOH *filename;
  165. int line;
  166. DOH *text;
  167. int ivalue;
  168. void *data;
  169. } tok;
  170. DOH *node;
  171. struct {
  172. DOH *node;
  173. DOH *last;
  174. } nodelist;
  175. struct {
  176. DOH *id;
  177. DOH *decl;
  178. } decl;
  179. struct {
  180. DOH *name;
  181. DOH *value;
  182. DOH *array;
  183. } pname;
  184. struct {
  185. DOH *name;
  186. DOH *array;
  187. DOH *parms;
  188. } tmname;
  189. };
  190. /* Literals */
  191. %token <tok> ID TYPE_TYPEDEF
  192. %token <tok> HBLOCK
  193. %token <tok> STRING
  194. %token <tok> NUM_INT NUM_FLOAT CHARCONST NUM_UNSIGNED NUM_LONG NUM_ULONG
  195. /* C Symbols */
  196. %token <tok> LPAREN RPAREN LBRACE RBRACE COMMA SEMI PERIOD LBRACKET RBRACKET EQUAL COLON
  197. /* C keywords */
  198. %token <tok> CONST ENUM EXTERN SIZEOF STATIC STRUCT TYPEDEF UNION
  199. /* C++ keywords */
  200. %token <tok> VIRTUAL CLASS FRIEND OPERATOR PRIVATE PROTECTED PUBLIC TEMPLATE THROW
  201. /* Objective C keywords */
  202. %token <tok> OC_INTERFACE OC_END OC_PUBLIC OC_PRIVATE OC_PROTECTED OC_CLASS OC_IMPLEMENT OC_PROTOCOL
  203. /* C Types */
  204. %token <tok> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL
  205. /* SWIG directives */
  206. %token <tok> ADDMETHODS APPLY CLEAR CONSTANT ECHO EXCEPT SCOPE
  207. %token <tok> ILLEGAL FILEDIRECTIVE INLINE MACRO MODULE NAME PRAGMA INSERT
  208. %token <tok> TYPEMAP TYPES
  209. /* Operators */
  210. %left <tok> LOR
  211. %left <tok> LAND
  212. %left <tok> EQUALTO NOTEQUAL GREATERTHAN LESSTHAN LTEQUAL GTEQUAL
  213. %left <tok> OR
  214. %left <tok> XOR
  215. %left <tok> AND
  216. %left <tok> LSHIFT RSHIFT
  217. %left <tok> PLUS MINUS
  218. %left <tok> STAR SLASH
  219. %left <tok> UMINUS NOT LNOT
  220. %left <tok> DCOLON
  221. %type <tok> idstring template_decl cpptype expr definetype def_args storage_spec pragma_arg ename tm_code
  222. %type <node> parm parms ptail stars
  223. %type <node> array array2
  224. %type <node> type strict_type opt_signed opt_unsigned
  225. %type <decl> declaration
  226. %type <pname> pname
  227. %type <node> tm_args tm_parm tm_tail tm_list
  228. %type <tmname> tm_name
  229. %type <tok> tm_method
  230. %type <node> statement swig_directive c_declaration constant_directive
  231. %type <node> file_include code_block except_directive pragma_directive typemap_directive scope_directive type_directive
  232. %type <node> variable_decl function_decl enum_decl typedef_decl stail edecl typedeflist
  233. %type <nodelist> enumlist interface
  234. %type <node> inherit base_list
  235. %type <tok> base_specifier access_specifier cpp_end ctor_end opt_id
  236. %type <node> cpp_decl cpp_class cpp_other
  237. %%
  238. /* The productions of the grammar with their
  239. associated semantic actions. */
  240. program : interface {
  241. top = $1.node;
  242. }
  243. ;
  244. interface : interface statement {
  245. DOH *o, *o2 = 0;
  246. if (!$1.node) {
  247. $$.node = $2;
  248. o = $2;
  249. while (o) {
  250. o2 = o;
  251. o = Getattr(o,ATTR_NEXT);
  252. }
  253. $$.last = o2;
  254. } else {
  255. if ($2) {
  256. o = $1.last;
  257. if (o) {
  258. Setattr(o,ATTR_NEXT,$2);
  259. } else {
  260. Setattr($1.node,ATTR_NEXT,$2);
  261. }
  262. o = $2;
  263. while (o) {
  264. o2 = o;
  265. o = Getattr(o,ATTR_NEXT);
  266. }
  267. $1.last = o2;
  268. }
  269. $$ = $1;
  270. }
  271. }
  272. | empty { $$.node = 0; $$.last = 0; }
  273. ;
  274. statement : swig_directive { $$ = $1; }
  275. | c_declaration { $$ = $1; }
  276. | SEMI { $$ = 0; }
  277. | error { $$ = 0; }
  278. ;
  279. /* =============================================================================
  280. * -- SWIG DIRECTIVES --
  281. * ============================================================================= */
  282. swig_directive : MODULE idstring {
  283. $$ = new_node("swig:module",$1.filename,$1.line);
  284. Setattr($$,ATTR_NAME,$2.text);
  285. }
  286. | MACRO ID COMMA STRING COMMA NUM_INT LBRACE {
  287. LParse_macro_location($2.text,$1.filename,$1.line);
  288. LParse_set_location($4.text, atoi(Char($6.text))-1);
  289. } interface RBRACE {
  290. LParse_macro_location(0,0,0);
  291. LParse_set_location($7.filename,$7.line-1);
  292. $$ = $9.node;
  293. }
  294. | constant_directive {
  295. $$ = $1;
  296. }
  297. | echo_directive { $$ = 0; }
  298. | file_include { $$ = $1; }
  299. | code_block { $$ = $1; }
  300. | except_directive { $$ = $1; }
  301. | pragma_directive { $$ = $1; }
  302. | typemap_directive { $$ = $1; }
  303. | scope_directive {$$ = $1; }
  304. | type_directive { $$ = $1; }
  305. ;
  306. constant_directive:
  307. CONSTANT ID EQUAL definetype SEMI {
  308. $$ = new_node("swig:constant",$2.filename, $2.line);
  309. Setattr($$,ATTR_NAME,$2.text);
  310. Setattr($$,ATTR_VALUE,$4.text);
  311. switch($4.ivalue) {
  312. case LPARSE_T_DOUBLE:
  313. Setattr($$,ATTR_TYPE,"double");
  314. break;
  315. case LPARSE_T_FLOAT:
  316. Setattr($$,ATTR_TYPE,"float");
  317. break;
  318. case LPARSE_T_ULONG:
  319. Setattr($$,ATTR_TYPE,"unsigned long");
  320. break;
  321. case LPARSE_T_LONG:
  322. Setattr($$,ATTR_TYPE,"long");
  323. break;
  324. case LPARSE_T_UINT:
  325. Setattr($$,ATTR_TYPE,"unsigned int");
  326. break;
  327. case LPARSE_T_INT:
  328. Setattr($$,ATTR_TYPE,"int");
  329. break;
  330. case LPARSE_T_USHORT:
  331. Setattr($$,ATTR_TYPE,"unsigned short");
  332. break;
  333. case LPARSE_T_SHORT:
  334. Setattr($$,ATTR_TYPE,"short");
  335. break;
  336. case LPARSE_T_UCHAR:
  337. Setattr($$,ATTR_TYPE,"unsigned char");
  338. break;
  339. case LPARSE_T_CHAR:
  340. Setattr($$,ATTR_TYPE,"char");
  341. Delitem($4.text,0);
  342. Delitem($4.text,DOH_END);
  343. break;
  344. case LPARSE_T_STRING:
  345. Setattr($$,ATTR_TYPE,"p.char");
  346. break;
  347. default:
  348. break;
  349. }
  350. }
  351. | CONSTANT LPAREN parm RPAREN ID def_args SEMI {
  352. $$ = new_node("swig:constant", $5.filename, $5.line);
  353. Setattr($$,ATTR_NAME,$5.text);
  354. Setattr($$,ATTR_VALUE,$6.text);
  355. Setattr($$,ATTR_TYPE,Gettype($3));
  356. }
  357. ;
  358. scope_directive: SCOPE LBRACE interface RBRACE {
  359. $$ = new_node("swig:scope",$1.filename,$1.line);
  360. if ($3.node) {
  361. Setattr($$,ATTR_CHILD,$3.node);
  362. setparent($$,$3.node);
  363. }
  364. }
  365. | SCOPE LPAREN idstring RPAREN LBRACE interface RBRACE {
  366. $$ = new_node("swig:scope",$1.filename,$1.line);
  367. if ($6.node) {
  368. Setattr($$,ATTR_CHILD,$6.node);
  369. Setattr($$,ATTR_NAME,$3.text);
  370. setparent($$,$6.node);
  371. }
  372. }
  373. ;
  374. echo_directive: ECHO HBLOCK {
  375. char line[32];
  376. sprintf(line,"%d",Getline($2.text));
  377. Replace($2.text,"$file",Getfile($2.text),DOH_REPLACE_ANY);
  378. Replace($2.text,"$line",line, DOH_REPLACE_ANY);
  379. Printf(stderr,"%s\n", $2.text);
  380. }
  381. | ECHO STRING {
  382. char line[32];
  383. sprintf(line,"%d",Getline($2.text));
  384. Replace($2.text,"$file",Getfile($2.text),DOH_REPLACE_ANY);
  385. Replace($2.text,"$line",line, DOH_REPLACE_ANY);
  386. Printf(stderr,"%s\n", $2.text);
  387. }
  388. ;
  389. /* -- File inclusion directives -- */
  390. file_include : FILEDIRECTIVE LPAREN STRING RPAREN STRING LBRACE {
  391. $1.data = new_node("swig:file",$1.filename,$1.line);
  392. Setattr($1.data,ATTR_NAME,$5.text);
  393. Setattr($1.data,ATTR_TYPE,$3.text);
  394. LParse_set_location($5.text,0);
  395. } interface RBRACE {
  396. LParse_set_location($6.filename,$6.line + 1);
  397. $$ = $1.data;
  398. if ($8.node) {
  399. Setattr($$,ATTR_CHILD,$8.node);
  400. setparent($$,$8.node);
  401. }
  402. }
  403. ;
  404. /* -- Code inclusion directives -- */
  405. code_block : INSERT LPAREN idstring RPAREN STRING {
  406. $$ = new_node("swig:insert", $1.filename, $1.line);
  407. Setattr($$,"filename", $5.text);
  408. Setattr($$,"section",$3.text);
  409. }
  410. | INSERT LPAREN idstring RPAREN HBLOCK {
  411. $$ = new_node("swig:insert",$1.filename, $1.line);
  412. Setattr($$,"section",$3.text);
  413. Setattr($$,"code",$5.text);
  414. }
  415. | HBLOCK {
  416. $$ = new_node("swig:insert",$1.filename, $1.line);
  417. Setattr($$,"code",$1.text);
  418. }
  419. | INLINE HBLOCK {
  420. DOH *pp;
  421. $$ = new_node("swig:insert",$2.filename,$2.line);
  422. Setattr($$,"code", $2.text);
  423. Seek($2.text,0,SEEK_SET);
  424. pp = Preprocessor_parse($2.text);
  425. Seek(pp,0,SEEK_SET);
  426. LParse_push(pp);
  427. }
  428. ;
  429. idstring : ID { $$ = $1; }
  430. | TYPE_TYPEDEF { $$ = $1; }
  431. | STRING { $$ = $1; }
  432. ;
  433. /* -- Exceptions -- */
  434. except_directive: EXCEPT LPAREN ID RPAREN LBRACE {
  435. DOH *t;
  436. t = LParse_skip_balanced('{','}');
  437. $$ = new_node("swig:exception",$1.filename,$1.line);
  438. Setattr($$,"lang",$3.text);
  439. Setattr($$,"code",t);
  440. LParse_error($1.filename,$1.line,"Warning. Language specifier in %except is now ignored.\n");
  441. }
  442. /* A Generic Exception (no language specified) */
  443. | EXCEPT LBRACE {
  444. DOH *t;
  445. t = LParse_skip_balanced('{','}');
  446. $$ = new_node("swig:exception",$1.filename,$1.line);
  447. Setattr($$,"code",t);
  448. }
  449. /* Clear an exception */
  450. | EXCEPT LPAREN ID RPAREN SEMI {
  451. $$ = new_node("swig:exception",$1.filename,$1.line);
  452. Setattr($$,"lang",$3.text);
  453. LParse_error($1.filename,$1.line,"Warning. Language specifier in %except is now ignored.\n");
  454. }
  455. /* Generic clear */
  456. | EXCEPT SEMI {
  457. $$ = new_node("swig:exception",$1.filename,$1.line);
  458. }
  459. ;
  460. pragma_directive : PRAGMA idstring pragma_arg SEMI {
  461. $$ = new_node("swig:pragma",$1.filename,$1.line);
  462. Setattr($$,ATTR_NAME,$2.text);
  463. Setattr($$,ATTR_VALUE,$3.text);
  464. }
  465. | PRAGMA LPAREN idstring RPAREN idstring pragma_arg SEMI {
  466. $$ = new_node("swig:pragma",$1.filename,$1.line);
  467. Setattr($$,ATTR_NAME,$5.text);
  468. Setattr($$,"lang",$3.text);
  469. Setattr($$,ATTR_VALUE,$6.text);
  470. }
  471. ;
  472. pragma_arg : idstring {
  473. $$.text = $1.text;
  474. }
  475. | EQUAL idstring {
  476. $$.text = $2.text;
  477. /* print warning message here */
  478. }
  479. | HBLOCK {
  480. $$.text = $1.text;
  481. }
  482. | empty {
  483. $$.text = 0;
  484. }
  485. ;
  486. /* -- Typemap directives -- */
  487. typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list tm_code {
  488. DOH *o, *prev = 0, *t, *l;
  489. t = $8.text;
  490. $$ = 0;
  491. for (l = $7; l; l = Getnext(l)) {
  492. o = new_node("swig:typemap",$1.filename, $1.line);
  493. Setattr(o,"lang",$3.text);
  494. Setattr(o,"method",$5.text);
  495. Setattr(o,"code",t);
  496. Setattr(o,ATTR_NAME,Getattr(l,ATTR_NAME));
  497. Setattr(o,ATTR_TYPE,Getattr(l,ATTR_TYPE));
  498. Setattr(o,ATTR_PARMS,Getattr(l,ATTR_PARMS));
  499. if (!$$) $$ = o;
  500. if (prev) {
  501. Setattr(prev,ATTR_NEXT,o);
  502. }
  503. prev = o;
  504. }
  505. }
  506. /* Create a new typemap in current language */
  507. | TYPEMAP LPAREN tm_method RPAREN tm_list tm_code {
  508. DOH *o, *t, *l, *prev = 0;
  509. /* t = LParse_skip_balanced('{','}');*/
  510. t = $6.text;
  511. $$ = 0;
  512. for (l = $5; l; l = Getnext(l)) {
  513. o = new_node("swig:typemap",$1.filename, $1.line);
  514. Setattr(o,"method",$3.text);
  515. Setattr(o,"code",t);
  516. Setattr(o,ATTR_NAME,Getattr(l,ATTR_NAME));
  517. Setattr(o,ATTR_TYPE,Getattr(l,ATTR_TYPE));
  518. Setattr(o,ATTR_PARMS,Getattr(l,ATTR_PARMS));
  519. if (!$$) $$ = o;
  520. if (prev) Setattr(prev,ATTR_NEXT,o);
  521. prev = o;
  522. }
  523. }
  524. /* Clear a typemap */
  525. | TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list SEMI {
  526. DOH *o, *l, *prev = 0;
  527. $$ = 0;
  528. for (l = $7; l; l = Getnext(l)) {
  529. o = new_node("swig:typemap",$1.filename, $1.line);
  530. Setattr(o,"lang",$3.text);
  531. Setattr(o,"method",$5.text);
  532. Setattr(o,ATTR_NAME,Getattr(l,ATTR_NAME));
  533. Setattr(o,ATTR_TYPE,Getattr(l,ATTR_TYPE));
  534. if (!$$) $$ = o;
  535. if (prev) Setattr(prev,ATTR_NEXT,o);
  536. prev = o;
  537. }
  538. }
  539. /* Clear a typemap in current language */
  540. | TYPEMAP LPAREN tm_method RPAREN tm_list SEMI {
  541. DOH *o, *l, *prev = 0;
  542. $$ = 0;
  543. for (l = $5; l; l = Getnext(l)) {
  544. o = new_node("swig:typemap",$1.filename, $1.line);
  545. Setattr(o,"method",$3.text);
  546. Setattr(o,ATTR_NAME,Getattr(l,ATTR_NAME));
  547. Setattr(o,ATTR_TYPE,Getattr(l,ATTR_TYPE));
  548. if (!$$) $$ = o;
  549. if (prev) Setattr(prev,ATTR_NEXT,o);
  550. prev = o;
  551. }
  552. }
  553. /* Copy a typemap */
  554. | TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list EQUAL tm_parm SEMI {
  555. DOH *o, *l, *prev = 0;
  556. $$ = 0;
  557. for (l = $7; l ; l = Getnext(l)) {
  558. o = new_node("swig:typemap",$1.filename, $1.line);
  559. Setattr(o,"method", $5.text);
  560. Setattr(o,"lang", $3.text);
  561. Setattr(o,ATTR_NAME, Getattr(l,ATTR_NAME));
  562. Setattr(o,ATTR_TYPE, Getattr(l,ATTR_TYPE));
  563. Setattr(o,ATTR_PARMS,Getattr(l,ATTR_PARMS));
  564. Setattr(o,"srcname",Getattr($9,ATTR_NAME));
  565. Setattr(o,"srctype",Getattr($9,ATTR_TYPE));
  566. if (!$$) $$ = o;
  567. if (prev) Setattr(prev,ATTR_NEXT,o);
  568. prev = o;
  569. }
  570. }
  571. /* Copy typemap in current language */
  572. | TYPEMAP LPAREN tm_method RPAREN tm_list EQUAL tm_parm SEMI {
  573. DOH *o, *l, *prev = 0;
  574. $$ = 0;
  575. for (l = $5; l; l = Getnext(l)) {
  576. o = new_node("swig:typemap",$1.filename, $1.line);
  577. Setattr(o,"method", $3.text);
  578. Setattr(o,ATTR_NAME, Getattr(l,ATTR_NAME));
  579. Setattr(o,ATTR_TYPE, Getattr(l,ATTR_TYPE));
  580. Setattr(o,ATTR_PARMS,Getattr(l,ATTR_PARMS));
  581. Setattr(o,"srcname",Getattr($7,ATTR_NAME));
  582. Setattr(o,"srctype",Getattr($7,ATTR_TYPE));
  583. if (!$$) $$ = o;
  584. if (prev) Setattr(prev,ATTR_NEXT,o);
  585. prev = o;
  586. }
  587. }
  588. /* Apply directive */
  589. | APPLY tm_parm LBRACE tm_list RBRACE {
  590. $$ = new_node("swig:apply",$1.filename, $1.line);
  591. Setattr($$,ATTR_NAME,Getattr($2,ATTR_NAME));
  592. Setattr($$,ATTR_TYPE,Getattr($2,ATTR_TYPE));
  593. Setattr($$,ATTR_PARMS,$4);
  594. }
  595. /* Clear directive */
  596. | CLEAR tm_list SEMI {
  597. $$ = new_node("swig:clear",$1.filename, $1.line);
  598. Setattr($$,ATTR_PARMS,$2);
  599. }
  600. ;
  601. tm_code : STRING {
  602. $$.text = $1.text;
  603. }
  604. | LBRACE {
  605. $$.text = LParse_skip_balanced('{','}');
  606. }
  607. ;
  608. tm_method : ID {
  609. $$ = $1;
  610. }
  611. | CONST {
  612. $$.text = NewString("const");
  613. }
  614. ;
  615. tm_list : tm_parm tm_tail {
  616. if ($2) {
  617. Setattr($1,ATTR_NEXT,$2);
  618. Setattr($2,ATTR_PREV,$1);
  619. }
  620. $$ = $1;
  621. }
  622. ;
  623. tm_tail : COMMA tm_parm tm_tail {
  624. if ($3) {
  625. Setattr($2,ATTR_NEXT,$3);
  626. Setattr($3,ATTR_PREV,$2);
  627. }
  628. $$ = $2;
  629. }
  630. | empty { $$ = 0; }
  631. ;
  632. tm_parm : type tm_name {
  633. $$ = NewHash();
  634. if ($2.array) {
  635. SwigType_push($1,$2.array);
  636. }
  637. Setattr($$,ATTR_TYPE,$1);
  638. if ($2.name)
  639. Setattr($$,ATTR_NAME,$2.name);
  640. if ($2.parms)
  641. Setattr($$,ATTR_PARMS,$2.parms);
  642. }
  643. | type stars tm_name {
  644. $$ = NewHash();
  645. SwigType_push($1,$2);
  646. if ($3.array) {
  647. SwigType_push($1,$3.array);
  648. }
  649. Setattr($$,ATTR_TYPE,$1);
  650. if ($3.name)
  651. Setattr($$,ATTR_NAME,$3.name);
  652. if ($3.parms)
  653. Setattr($$,ATTR_PARMS,$3.parms);
  654. }
  655. | type AND tm_name {
  656. $$ = NewHash();
  657. SwigType_add_reference($1);
  658. if ($3.array) {
  659. SwigType_push($1,$3.array);
  660. }
  661. Setattr($$,ATTR_TYPE,$1);
  662. if ($3.name)
  663. Setattr($$,ATTR_NAME,$3.name);
  664. if ($3.parms)
  665. Setattr($$,ATTR_PARMS,$3.parms);
  666. }
  667. ;
  668. tm_name : ID tm_args {
  669. $$.parms = $2;
  670. $$.name = $1.text;
  671. $$.array = 0;
  672. }
  673. | ID array tm_args {
  674. $$.name = $1.text;
  675. $$.array = $2;
  676. $$.parms = $3;
  677. }
  678. | array tm_args {
  679. $$.name = 0;
  680. $$.array = $1;
  681. $$.parms = $2;
  682. }
  683. | tm_args {
  684. $$.name = 0;
  685. $$.array = 0;
  686. $$.parms = $1;
  687. }
  688. ;
  689. tm_args : LPAREN parms RPAREN {
  690. $$ = $2;
  691. }
  692. | empty {
  693. $$ = 0;
  694. }
  695. ;
  696. type_directive : TYPES LPAREN parms RPAREN SEMI {
  697. $$ = new_node("swig:types",$1.filename,$1.line);
  698. Setattr($$,"parms",$3);
  699. }
  700. ;
  701. /* =============================================================================
  702. * -- C Declarations --
  703. * ============================================================================= */
  704. c_declaration : variable_decl { $$ = $1; }
  705. | function_decl { $$ = $1; }
  706. | enum_decl { $$ = $1; }
  707. | typedef_decl { $$ = $1; }
  708. | cpp_decl { $$ = $1; }
  709. ;
  710. /* A variable declaration */
  711. variable_decl : storage_spec type declaration array2 def_args stail {
  712. DOH *o, *t;
  713. $$ = new_node(TAG_VARIABLE,Getfile($3.id),Getline($3.id));
  714. t = Copy($2);
  715. SwigType_push(t,$3.decl);
  716. SwigType_push(t,$4);
  717. Setattr($$,ATTR_NAME,$3.id);
  718. Setattr($$,ATTR_TYPE,t);
  719. if ($1.ivalue) {
  720. Setattr($$,ATTR_STORAGE,$1.text);
  721. }
  722. if ($5.text) {
  723. Setattr($$,ATTR_VALUE,$5.text);
  724. }
  725. if ($6) {
  726. Setattr($$,ATTR_NEXT,$6);
  727. o = $6;
  728. while (o) {
  729. t = Copy($2);
  730. SwigType_push(t,Getattr(o,ATTR_TYPE));
  731. Setattr(o,ATTR_TYPE,t);
  732. if ($1.ivalue) {
  733. Setattr(o,ATTR_STORAGE,$1.text);
  734. }
  735. o = Getattr(o,ATTR_NEXT);
  736. }
  737. }
  738. }
  739. /* Global variable that smells like a function pointer */
  740. | storage_spec strict_type LPAREN STAR {
  741. LParse_error($3.filename,$3.line,"Pointer to function not currently supported.\n");
  742. LParse_skip_decl();
  743. $$ = 0;
  744. }
  745. ;
  746. /* A function declaration */
  747. function_decl : storage_spec type declaration LPAREN parms RPAREN cpp_const stail {
  748. DOH *o, *t;
  749. t = Copy($2);
  750. SwigType_push(t,$3.decl);
  751. $$ = new_node(TAG_FUNCTION,Getfile($3.id),Getline($3.id));
  752. Setattr($$,ATTR_NAME,$3.id);
  753. Setattr($$,ATTR_TYPE,t);
  754. Setattr($$,ATTR_PARMS,$5);
  755. if ($1.ivalue) {
  756. Setattr($$,ATTR_STORAGE, $1.text);
  757. }
  758. if ($8) {
  759. Setattr($$,ATTR_NEXT,$8);
  760. o = $8;
  761. while (o) {
  762. t = Copy($2);
  763. SwigType_push(t,Getattr(o,ATTR_TYPE));
  764. Setattr(o,ATTR_TYPE,t);
  765. if ($1.ivalue) {
  766. Setattr(o,ATTR_STORAGE,$1.text);
  767. }
  768. o = Getattr(o,ATTR_NEXT);
  769. }
  770. }
  771. }
  772. /* A function declaration with code after it */
  773. | storage_spec type declaration LPAREN parms RPAREN cpp_end {
  774. SwigType_push($2,$3.decl);
  775. $$ = new_node(TAG_FUNCTION,Getfile($3.id),Getline($3.id));
  776. Setattr($$,ATTR_NAME,$3.id);
  777. Setattr($$,ATTR_TYPE,$2);
  778. Setattr($$,ATTR_PARMS,$5);
  779. if ($1.ivalue) {
  780. Setattr($$,ATTR_STORAGE, $1.text);
  781. }
  782. if ($7.text)
  783. Setattr($$,"code",$7.text);
  784. if (pure_virtual) {
  785. SetInt($$,"abstract",1);
  786. pure_virtual = 0;
  787. }
  788. }
  789. /* Possibly a constructor */
  790. | storage_spec ID LPAREN parms RPAREN ctor_end {
  791. DOH *t = NewString("int");
  792. $$ = new_node(TAG_FUNCTION,$2.filename,$2.line);
  793. Setattr($$,ATTR_NAME,$2.text);
  794. Setattr($$,ATTR_TYPE,t);
  795. Setattr($$,ATTR_PARMS,$4);
  796. if ($1.ivalue) {
  797. Setattr($$,ATTR_STORAGE,$1.text);
  798. }
  799. if ($6.text) {
  800. Setattr($$,"code",$6.text);
  801. }
  802. }
  803. /* A C++ destructor */
  804. | storage_spec NOT ID LPAREN parms RPAREN cpp_end {
  805. $$ = new_node("c:destructor",$3.filename,$3.line);
  806. Setattr($$,ATTR_NAME,$3.text);
  807. if ($7.text) {
  808. Setattr($$,"code",$7.text);
  809. }
  810. if (pure_virtual) {
  811. SetInt($$,"abstract",1);
  812. pure_virtual = 0;
  813. }
  814. if ($1.ivalue) {
  815. Setattr($$,ATTR_STORAGE,$1.text);
  816. }
  817. }
  818. | storage_spec NOT ID LPAREN parms RPAREN cpp_const SEMI {
  819. $$ = new_node("c:destructor",$3.filename,$3.line);
  820. Setattr($$,ATTR_NAME,$3.text);
  821. if ($1.ivalue) {
  822. Setattr($$,ATTR_STORAGE,$1.text);
  823. }
  824. }
  825. ;
  826. /* Allow lists of variables and functions to be built up */
  827. stail : SEMI { $$ = 0; }
  828. | COMMA declaration array2 def_args stail {
  829. DOH *t = NewString("");
  830. SwigType_push(t,$2.decl);
  831. SwigType_push(t,$3);
  832. $$ = new_node(TAG_VARIABLE, Getfile($2.id),Getline($2.id));
  833. Setattr($$,ATTR_NAME,$2.id);
  834. Setattr($$,ATTR_TYPE,t);
  835. if ($4.text)
  836. Setattr($$,ATTR_VALUE,$4.text);
  837. if ($5)
  838. Setattr($$,ATTR_NEXT, $5);
  839. }
  840. | COMMA declaration LPAREN parms RPAREN stail {
  841. DOH *t = NewString("");
  842. SwigType_push(t,$2.decl);
  843. $$ = new_node(TAG_FUNCTION, Getfile($2.id), Getline($2.id));
  844. Setattr($$,ATTR_NAME,$2.id);
  845. Setattr($$,ATTR_PARMS,$4);
  846. Setattr($$,ATTR_TYPE, t);
  847. if ($6)
  848. Setattr($$,ATTR_NEXT,$6);
  849. }
  850. ;
  851. storage_spec : EXTERN {
  852. $$.ivalue = 1;
  853. $$.text = NewString("extern");
  854. }
  855. | EXTERN STRING {
  856. $$.ivalue = 1;
  857. $$.text = NewStringf("extern \"%s\"", $2.text);
  858. }
  859. | VIRTUAL {
  860. $$.ivalue = 1;
  861. $$.text = NewString("virtual");
  862. }
  863. | STATIC {
  864. $$.ivalue = 1;
  865. $$.text = NewString("static");
  866. }
  867. | empty {
  868. $$.ivalue = 0;
  869. $$.text = 0;
  870. }
  871. ;
  872. cpp_const : CONST {}
  873. | THROW LPAREN { LParse_skip_balanced('(',')'); }
  874. | empty {}
  875. ;
  876. /* Enumerations */
  877. enum_decl : storage_spec ENUM ename LBRACE enumlist RBRACE SEMI {
  878. $$ = new_node("c:enum", $2.filename,$2.line);
  879. Setattr($$,ATTR_NAME,$3.text);
  880. Setattr($$,ATTR_CHILD,$5.node);
  881. setparent($$,$5.node);
  882. /* Add typename */
  883. }
  884. /* A typdef'd enum. Pretty common in C headers */
  885. | TYPEDEF ENUM ename LBRACE enumlist RBRACE ID SEMI {
  886. $$ = new_node("c:enum",$2.filename,$2.line);
  887. Setattr($$,ATTR_NAME,$3.text);
  888. Setattr($$,ATTR_CHILD,$5.node);
  889. setparent($$,$5.node);
  890. /* Add typedef for enum */
  891. {
  892. DOH *o;
  893. o = new_node("c:typedef",$7.filename,$7.line);
  894. Setattr(o,ATTR_NAME,$7.text);
  895. Setattr(o,ATTR_TYPE,$3.text);
  896. Setattr($$,ATTR_NEXT,o);
  897. }
  898. }
  899. ;
  900. /* Some stuff for handling enums */
  901. ename : ID { $$ = $1; }
  902. | empty { $$.text = NewString(""); }
  903. ;
  904. enumlist : enumlist COMMA edecl {
  905. Setattr($1.last,ATTR_NEXT,$3);
  906. $1.last = $3;
  907. $$ = $1;
  908. }
  909. | edecl {
  910. $$.node = $1;
  911. $$.last = $1;
  912. }
  913. ;
  914. edecl : ID {
  915. $$ = new_node(TAG_ENUMVALUE,$1.filename,$1.line);
  916. Setattr($$,ATTR_NAME,$1.text);
  917. }
  918. | ID EQUAL expr {
  919. $$ = new_node(TAG_ENUMVALUE,$1.filename,$1.line);
  920. Setattr($$,ATTR_NAME,$1.text);
  921. Setattr($$,ATTR_VALUE,$1.text);
  922. }
  923. | empty { $$ = 0; }
  924. ;
  925. typedef_decl : TYPEDEF type declaration array2 typedeflist SEMI {
  926. DOH *t, *d, *o, *prev;
  927. int i;
  928. $$ = new_node("c:typedef", $1.filename,$1.line);
  929. t = Copy($2);
  930. SwigType_push($2,$3.decl);
  931. if ($4) SwigType_push($2,$4);
  932. Setattr($$,ATTR_NAME,$3.id);
  933. Setattr($$,ATTR_TYPE,$2);
  934. /* Go create more typedefs */
  935. prev = $$;
  936. for (i = 0; i < Len($5); i++) {
  937. DOH *ty;
  938. d = Getitem($5,i);
  939. o = new_node("c:typedef",$1.filename,$1.line);
  940. ty = Copy(t);
  941. SwigType_push(ty,Getattr(d,"decl"));
  942. SwigType_push(ty,Getattr(d,"array"));
  943. Setattr(o,ATTR_TYPE,ty);
  944. Setattr(o,ATTR_NAME,Getattr(d,ATTR_NAME));
  945. Setattr(prev,ATTR_NEXT,o);
  946. prev = o;
  947. }
  948. Delete($5);
  949. }
  950. /* A rudimentary typedef involving function pointers */
  951. | TYPEDEF type LPAREN stars pname RPAREN LPAREN parms RPAREN SEMI {
  952. $$ = new_node("c:typedef", $1.filename,$1.line);
  953. SwigType_add_function($2,$8);
  954. SwigType_push($2,$4);
  955. if ($5.array)
  956. SwigType_push($2,$5.array);
  957. Setattr($$,ATTR_NAME,$5.name);
  958. Setattr($$,ATTR_TYPE,$2);
  959. }
  960. /* A typedef involving function pointers again */
  961. | TYPEDEF type stars LPAREN stars pname RPAREN LPAREN parms RPAREN SEMI {
  962. $$ = new_node("c:typedef", $1.filename,$1.line);
  963. SwigType_push($2,$3);
  964. SwigType_add_function($2,$9);
  965. SwigType_push($2,$5);
  966. if ($6.array)
  967. SwigType_push($2,$6.array);
  968. Setattr($$,ATTR_NAME,$6.name);
  969. Setattr($$,ATTR_TYPE,$2);
  970. }
  971. ;
  972. typedeflist : COMMA declaration typedeflist {
  973. DOH *o = NewHash();
  974. Setattr(o,ATTR_NAME,$2.id);
  975. Setattr(o,"decl",$2.decl);
  976. Insert($3,0,o);
  977. $$ = $3;
  978. }
  979. | COMMA declaration array typedeflist {
  980. DOH *o;
  981. $$ = $4;
  982. o = NewHash();
  983. Setattr(o,ATTR_NAME,$2.id);
  984. Setattr(o,"decl",$2.decl);
  985. if ($3)
  986. Setattr(o,"array",$3);
  987. Append($$,o);
  988. }
  989. | empty {
  990. $$ = NewList();
  991. }
  992. ;
  993. /* =============================================================================
  994. * -- Feeble C++ (yuck) Parsing --
  995. * ============================================================================= */
  996. cpp_decl : cpp_class {
  997. String *name;
  998. DOH *cls;
  999. $$ = $1;
  1000. /* Save a copy of the class */
  1001. name = Getattr($$,"altname");
  1002. if (!name) {
  1003. name = Getname($$);
  1004. }
  1005. cls = Getattr(class_hash,name);
  1006. if (cls) {
  1007. /* We already saw this class. If the previous class really was a class,
  1008. we'll generate an error. If the class was an added method instead,
  1009. we'll add those methods to our class */
  1010. String *tag = Gettag(cls);
  1011. if (Cmp(tag,"c:class") == 0) {
  1012. /* Already saw this */
  1013. Printf(stderr,"%s:%d. Class '%s' previously defined.\n", Getfile($$),Getline($$),name);
  1014. $$ = 0;
  1015. } else {
  1016. /* Hmmm. Must have been an added method. Attach to the end of my children */
  1017. Swig_node_append_child($$,cls);
  1018. Setattr(class_hash,name,$$);
  1019. }
  1020. } else {
  1021. Setattr(class_hash,name,$$);
  1022. }
  1023. }
  1024. | cpp_other { $$ = $1; }
  1025. ;
  1026. cpp_class : storage_spec cpptype ID inherit LBRACE interface RBRACE opt_id SEMI {
  1027. $$ = new_node("c:class",$3.filename,$3.line);
  1028. Setattr($$,"classtype",$2.text);
  1029. Setattr($$,ATTR_NAME,$3.text);
  1030. Setattr($$,"bases", $4);
  1031. Setattr($$,"namespace",$3.text);
  1032. if ($6.node) {
  1033. Setattr($$,ATTR_CHILD,$6.node);
  1034. setparent($$,$6.node);
  1035. }
  1036. if ($8.text) {
  1037. Setattr($$,TAG_VARIABLE,$8.text);
  1038. }
  1039. }
  1040. | storage_spec cpptype LBRACE interface RBRACE opt_id SEMI {
  1041. $$ = new_node("c:class",$3.filename,$3.line);
  1042. Setattr($$,"classtype",$2.text);
  1043. if ($4.node) {
  1044. Setattr($$,ATTR_CHILD,$4.node);
  1045. setparent($$,$4.node);
  1046. }
  1047. if ($6.text)
  1048. Setattr($$,TAG_VARIABLE,$6.text);
  1049. }
  1050. /* Class with a typedef */
  1051. | TYPEDEF cpptype ID inherit LBRACE interface RBRACE declaration typedeflist {
  1052. $$ = new_node("c:class",$3.filename,$3.line);
  1053. Setattr($$,"classtype",$2.text);
  1054. Setattr($$,ATTR_NAME,$3.text);
  1055. Setattr($$,"bases",$4);
  1056. Setattr($$,"namespace",$3.text);
  1057. if ($6.node) {
  1058. Setattr($$,ATTR_CHILD,$6.node);
  1059. setparent($$,$6.node);
  1060. }
  1061. if (Len($8.decl) == 0)
  1062. Setattr($$,"altname",$8.id);
  1063. {
  1064. /* Go add a bunch of typedef declarations */
  1065. DOH *o, *t, *prev, *d;
  1066. int i;
  1067. o = new_node("c:typedef",$3.filename,$3.line);
  1068. Setattr(o,ATTR_NAME,$8.id);
  1069. t = Copy($3.text);
  1070. SwigType_push(t,$8.decl);
  1071. Setattr(o,ATTR_TYPE,t);
  1072. Setattr($$,ATTR_NEXT,o);
  1073. prev = o;
  1074. for (i = 0; i < Len($9); i++) {
  1075. d = Getitem($9,i);
  1076. o = new_node("c:typedef",$3.filename,$3.line);
  1077. t = Copy($3.text);
  1078. SwigType_push(t,Getattr(d,"decl"));
  1079. SwigType_push(t,Getattr(d,"array"));
  1080. Setattr(o,ATTR_TYPE,t);
  1081. Setattr(o,ATTR_NAME,Getattr(d,ATTR_NAME));
  1082. Setattr(prev,ATTR_NEXT,o);
  1083. prev = o;
  1084. }
  1085. Delete($9);
  1086. }
  1087. }
  1088. /* An unnamed struct with a typedef */
  1089. | TYPEDEF cpptype LBRACE interface RBRACE declaration typedeflist {
  1090. $$ = new_node("c:class",$3.filename,$3.line);
  1091. Setattr($$,"classtype",$2.text);
  1092. if ($4.node) {
  1093. Setattr($$,ATTR_CHILD,$4.node);
  1094. setparent($$,$4.node);
  1095. }
  1096. if (Len($6.decl) == 0)
  1097. Setattr($$,"altname",$6.id);
  1098. }
  1099. ;
  1100. inherit : COLON base_list {
  1101. $$ = $2;
  1102. }
  1103. | empty {
  1104. $$ = 0;
  1105. }
  1106. ;
  1107. base_list : base_specifier {
  1108. $$ = NewList();
  1109. Append($$,$1.text);
  1110. }
  1111. | base_list COMMA base_specifier {
  1112. $$ = $1;
  1113. if ($3.text)
  1114. Append($$,$3.text);
  1115. }
  1116. ;
  1117. base_specifier : ID {
  1118. LParse_error($1.filename,$1.line,"No access specifier given for base class %s (ignored).\n", $1.text);
  1119. $$.text = 0;
  1120. }
  1121. | access_specifier ID {
  1122. if (Cmp($1.text,"public") == 0) {
  1123. $$ = $2;
  1124. } else {
  1125. LParse_error($2.filename,$2.line,"%s inheritance not supported (ignored).\n", $1.text);
  1126. $$.text = 0;
  1127. }
  1128. }
  1129. ;
  1130. access_specifier : PUBLIC { $$.text = NewString("public"); }
  1131. | PRIVATE { $$.text = NewString("private"); }
  1132. | PROTECTED { $$.text = NewString("protected"); }
  1133. ;
  1134. cpp_end : cpp_const LBRACE {
  1135. $$.text = LParse_skip_balanced('{','}');
  1136. pure_virtual = 0;
  1137. }
  1138. | EQUAL definetype SEMI {
  1139. $$.text = 0;
  1140. pure_virtual = 1;
  1141. }
  1142. /* | cpp_const {
  1143. $$.text = 0;
  1144. pure_virtual = 0;
  1145. }
  1146. */
  1147. ;
  1148. type_extra : stars {}
  1149. | AND {}
  1150. | empty {}
  1151. ;
  1152. /* Constructor initializer */
  1153. ctor_end : cpp_const ctor_initializer SEMI { $$.text = 0; }
  1154. | cpp_const ctor_initializer LBRACE { $$.text = LParse_skip_balanced('{','}'); }
  1155. ;
  1156. ctor_initializer : COLON mem_initializer_list {}
  1157. | empty {}
  1158. ;
  1159. mem_initializer_list : mem_initializer { }
  1160. | mem_initializer_list COMMA mem_initializer { }
  1161. ;
  1162. mem_initializer : ID LPAREN { LParse_skip_balanced('(',')'); }
  1163. ;
  1164. cpp_other :/* A dummy class name */
  1165. storage_spec cpptype ID SEMI {
  1166. DOH *o = new_node("c:classdecl",$4.filename,$4.line);
  1167. Setattr(o,ATTR_NAME,$3.text);
  1168. }
  1169. | PUBLIC COLON {
  1170. $$ = new_node("c:access",$1.filename,$1.line);
  1171. Setattr($$,ATTR_NAME,"public");
  1172. }
  1173. | PRIVATE COLON {
  1174. $$ = new_node("c:access",$1.filename,$1.line);
  1175. Setattr($$,ATTR_NAME,"private");
  1176. }
  1177. | PROTECTED COLON {
  1178. $$ = new_node("c:access",$1.filename,$1.line);
  1179. Setattr($$,ATTR_NAME,"protected");
  1180. }
  1181. | FRIEND {
  1182. LParse_skip_decl();
  1183. }
  1184. | storage_spec type type_extra OPERATOR {
  1185. LParse_skip_decl();
  1186. }
  1187. /* Any sort of out-of-class C++ declaration */
  1188. | storage_spec type declaration DCOLON {
  1189. LParse_skip_decl();
  1190. }
  1191. /* Template catch */
  1192. | TEMPLATE {
  1193. LParse_skip_decl();
  1194. }
  1195. /* %addmethods directive */
  1196. | ADDMETHODS opt_id LBRACE interface RBRACE {
  1197. $$ = new_node("swig:addmethods",$1.filename,$1.line);
  1198. if ($4.node) {
  1199. Setattr($$,ATTR_CHILD,$4.node);
  1200. setparent($$,$4.node);
  1201. }
  1202. if ($2.text) {
  1203. DOH *cls;
  1204. Setattr($$,ATTR_NAME,$2.text);
  1205. /* A named addmethods directive. If not in a class. We have to save */
  1206. cls = Getattr(class_hash,$2.text);
  1207. if (cls) {
  1208. /* Hmmm. A class or addmethods directive was already found */
  1209. String *tag = Gettag(cls);
  1210. if (Cmp(tag,"swig:addmethods") == 0) {
  1211. /* We need to append our methods to previous methods */
  1212. Swig_node_append_child(cls,$4.node);
  1213. setparent(cls,$4.node);
  1214. $$ = 0;
  1215. } else {
  1216. /* No. This must be a class. We'll add ourselves to it */
  1217. Swig_node_append_child(cls,$$);
  1218. $$ = 0;
  1219. }
  1220. } else {
  1221. /* Nothing previously defined. Save ourselves */
  1222. Setattr(class_hash,$2.text,$$);
  1223. $$ = 0;
  1224. }
  1225. }
  1226. }
  1227. ;
  1228. opt_id : ID { $$ = $1; }
  1229. | empty { $$.text = 0; }
  1230. ;
  1231. /* =============================================================================
  1232. * -- Generic (admittedly poor) C Parsing --
  1233. * ============================================================================= */
  1234. /* -- Function parameter lists -- */
  1235. parms : parm ptail {
  1236. if ($2) {
  1237. Setattr($1,ATTR_NEXT,$2);
  1238. Setattr($2,ATTR_PREV,$1);
  1239. }
  1240. $$ = $1;
  1241. }
  1242. | empty { $$ = 0; }
  1243. ;
  1244. ptail : COMMA parm ptail {
  1245. if ($3) {
  1246. Setattr($2,ATTR_NEXT,$3);
  1247. Setattr($3,ATTR_PREV,$2);
  1248. }
  1249. $$ = $2;
  1250. }
  1251. | empty { $$ = 0; }
  1252. ;
  1253. parm : type pname {
  1254. $$ = new_node("parm",Getfile($2.name),Getline($2.name));
  1255. Setattr($$,ATTR_NAME,$2.name);
  1256. SwigType_push($1,$2.array);
  1257. if ($2.value)
  1258. Setattr($$,ATTR_VALUE,$2.value);
  1259. Setattr($$,ATTR_TYPE,$1);
  1260. }
  1261. | type stars pname {
  1262. $$ = new_node("parm",Getfile($3.name),Getline($3.name));
  1263. Setattr($$,ATTR_NAME,$3.name);
  1264. SwigType_push($1,$2);
  1265. SwigType_push($1,$3.array);
  1266. if ($3.value) {
  1267. Setattr($$,ATTR_VALUE,$3.value);
  1268. }
  1269. Setattr($$,ATTR_TYPE,$1);
  1270. }
  1271. | type AND pname {
  1272. $$ = new_node("parm",Getfile($3.name),Getline($3.name));
  1273. SwigType_add_reference($1);
  1274. SwigType_push($1,$3.array);
  1275. Setattr($$,ATTR_NAME,$3.name);
  1276. if ($3.value) {
  1277. Setattr($$,ATTR_VALUE,$3.value);
  1278. }
  1279. Setattr($$,ATTR_TYPE,$1);
  1280. }
  1281. | type LPAREN stars pname RPAREN LPAREN parms RPAREN {
  1282. $$ = new_node("parm",$2.filename, $2.line);
  1283. SwigType_add_function($1,$7);
  1284. SwigType_push($1,$3);
  1285. if ($4.array)
  1286. SwigType_push($1,$4.array);
  1287. Setattr($$,ATTR_NAME,$4.name);
  1288. if ($4.value)
  1289. Setattr($$,ATTR_VALUE,$4.value);
  1290. Setattr($$,ATTR_TYPE,$1);
  1291. }
  1292. | type stars LPAREN stars pname RPAREN LPAREN parms RPAREN {
  1293. $$ = new_node("parm",$3.filename, $3.line);
  1294. SwigType_push($1,$2);
  1295. SwigType_add_function($1,$8);
  1296. SwigType_push($1,$4);
  1297. if ($5.array)
  1298. SwigType_push($1,$5.array);
  1299. Setattr($$,ATTR_NAME,$5.name);
  1300. if ($5.value)
  1301. Setattr($$,ATTR_VALUE,$5.value);
  1302. Setattr($$,ATTR_TYPE,$1);
  1303. }
  1304. | PERIOD PERIOD PERIOD {
  1305. $$ = new_node("parm",$1.filename,$1.line);
  1306. Setattr($$,ATTR_NAME,"...");
  1307. Setattr($$,ATTR_TYPE,"?");
  1308. }
  1309. ;
  1310. pname : ID def_args {
  1311. $$.name = $1.text;
  1312. $$.value = $2.text;
  1313. $$.array = 0;
  1314. }
  1315. | ID array {
  1316. $$.name = $1.text;
  1317. $$.value = 0;
  1318. $$.array = $2;
  1319. }
  1320. | array {
  1321. $$.name = NewString("");
  1322. $$.value = 0;
  1323. $$.array = $1;
  1324. }
  1325. | empty {
  1326. $$.name = NewString("");
  1327. $$.value = 0;
  1328. $$.array = 0;
  1329. }
  1330. ;
  1331. def_args : EQUAL definetype { $$ = $2; }
  1332. | EQUAL AND ID {
  1333. $$.text = NewStringf("&%s", $3.text);
  1334. $$.ivalue = LPARSE_T_USER;
  1335. }
  1336. | EQUAL LBRACE {
  1337. LParse_skip_balanced('{','}');
  1338. $$.text = 0;
  1339. $$.ivalue = 0;
  1340. }
  1341. | COLON NUM_INT {
  1342. $$.text = 0;
  1343. $$.ivalue = 0;
  1344. }
  1345. | empty {
  1346. $$.text = 0;
  1347. $$.ivalue = 0;
  1348. }
  1349. ;
  1350. /* Declaration must be an identifier, possibly preceded by a * for pointer types */
  1351. declaration : ID {
  1352. $$.id = $1.text;
  1353. $$.decl = NewString("");
  1354. }
  1355. | stars ID {
  1356. $$.id = $2.text;
  1357. $$.decl = $1;
  1358. }
  1359. | AND ID {
  1360. $$.id = $2.text;
  1361. $$.decl = NewString("");
  1362. SwigType_add_reference($$.decl);
  1363. }
  1364. | AND stars ID {
  1365. $$.id = $3.text;
  1366. $$.decl = $2;
  1367. SwigType_add_reference($$.decl);
  1368. }
  1369. ;
  1370. stars : STAR empty {
  1371. $$ = NewString("");
  1372. SwigType_add_pointer($$);
  1373. }
  1374. | STAR stars {
  1375. $$ = $2;
  1376. SwigType_add_pointer($$);
  1377. }
  1378. ;
  1379. array : LBRACKET RBRACKET array2 {
  1380. $$ = $3;
  1381. SwigType_add_array($$,"");
  1382. }
  1383. | LBRACKET expr RBRACKET array2 {
  1384. $$ = $4;
  1385. SwigType_add_array($$,$2.text);
  1386. }
  1387. ;
  1388. array2 : array {
  1389. $$ = $1;
  1390. }
  1391. | empty { $$ = NewString(""); }
  1392. ;
  1393. type : TYPE_INT { $$ = NewString("int"); }
  1394. | TYPE_SHORT opt_int { $$ = NewString("short"); }
  1395. | TYPE_LONG opt_int { $$ = NewString("long"); }
  1396. | TYPE_CHAR { $$ = NewString("char"); }
  1397. | TYPE_BOOL { $$ = NewString("bool"); }
  1398. | TYPE_FLOAT { $$ = NewString("float"); }
  1399. | TYPE_DOUBLE { $$ = NewString("double"); }
  1400. | TYPE_VOID { $$ = NewString("void"); }
  1401. | TYPE_SIGNED opt_signed {
  1402. if ($2) $$ = $2;
  1403. else {
  1404. $$ = NewString("signed");
  1405. }
  1406. }
  1407. | TYPE_UNSIGNED opt_unsigned {
  1408. if ($2) $$ = $2;
  1409. else {
  1410. $$ = NewString("unsigned");
  1411. }
  1412. }
  1413. | ID template_decl {
  1414. if ($2.text)
  1415. $$ = NewStringf("%s%s",$1.text,$2.text);
  1416. else
  1417. $$ = NewString($1.text);
  1418. }
  1419. | CONST type {
  1420. SwigType_add_qualifier($2,"const");
  1421. $$ = $2;
  1422. }
  1423. | cpptype ID {
  1424. $$ = NewStringf("%s %s", $1.text, $2.text);
  1425. }
  1426. | ID DCOLON ID {
  1427. $$ = NewStringf("%s::%s",$1.text,$3.text);
  1428. }
  1429. /* This declaration causes a shift-reduce conflict. Unresolved for now */
  1430. | DCOLON ID {
  1431. $$ = Copy($2.text);
  1432. }
  1433. | ENUM ID {
  1434. $$ = NewStringf("enum %s", $2.text);
  1435. }
  1436. ;
  1437. strict_type : TYPE_INT { $$ = NewString("int"); }
  1438. | TYPE_SHORT opt_int { $$ = NewString("short"); }
  1439. | TYPE_LONG opt_int { $$ = NewString("long"); }
  1440. | TYPE_CHAR { $$ = NewString("char"); }
  1441. | TYPE_BOOL { $$ = NewString("bool"); }
  1442. | TYPE_FLOAT { $$ = NewString("float"); }
  1443. | TYPE_DOUBLE { $$ = NewString("double"); }
  1444. | TYPE_VOID { $$ = NewString("void"); }
  1445. | TYPE_SIGNED opt_signed {
  1446. if ($2) $$ = $2;
  1447. else {
  1448. $$ = NewString("signed");
  1449. }
  1450. }
  1451. | TYPE_UNSIGNED opt_unsigned {
  1452. if ($2) $$ = $2;
  1453. else {
  1454. $$ = NewString("unsigned");
  1455. }
  1456. }
  1457. | TYPE_TYPEDEF template_decl {
  1458. if ($2.text) {
  1459. $$ = NewStringf("%s%s",$1.text,$2.text);
  1460. } else {
  1461. $$ = NewString($1.text);
  1462. }
  1463. }
  1464. | CONST type {
  1465. $$ = $2;
  1466. SwigType_add_qualifier($$,"const");
  1467. }
  1468. | cpptype ID {
  1469. $$ = NewStringf("%s %s", $1.text, $2.text);
  1470. }
  1471. | ENUM ID {
  1472. $$ = NewStringf("enum %s", $2.text);
  1473. }
  1474. ;
  1475. template_decl : LESSTHAN {
  1476. $$.text = LParse_skip_balanced('<','>');
  1477. }
  1478. | empty { $$.text = 0; }
  1479. ;
  1480. /* Optional signed types */
  1481. opt_signed : empty { $$ = 0; }
  1482. | TYPE_INT {
  1483. $$ = NewString("signed int");
  1484. }
  1485. | TYPE_SHORT opt_int {
  1486. $$ = NewString("signed short");
  1487. }
  1488. | TYPE_LONG opt_int {
  1489. $$ = NewString("signed long");
  1490. }
  1491. | TYPE_CHAR {
  1492. $$ = NewString("signed char");
  1493. }
  1494. ;
  1495. /* Optional unsigned types */
  1496. opt_unsigned : empty { $$ = 0;}
  1497. | TYPE_INT {
  1498. $$ = NewString("unsigned int");
  1499. }
  1500. | TYPE_SHORT opt_int {
  1501. $$ = NewString("unsigned short");
  1502. }
  1503. | TYPE_LONG opt_int {
  1504. $$ = NewString("unsigned long");
  1505. }
  1506. | TYPE_CHAR {
  1507. $$ = NewString("unsigned char");
  1508. }
  1509. ;
  1510. opt_int : TYPE_INT { }
  1511. | empty { }
  1512. ;
  1513. cpptype : CLASS { $$ = $1; }
  1514. | STRUCT { $$ = $1; }
  1515. | UNION { $$ = $1; }
  1516. ;
  1517. /* -----------------------------------------------------------------------------
  1518. * -- Expressions --
  1519. * ----------------------------------------------------------------------------- */
  1520. definetype : expr {
  1521. $$ = $1;
  1522. }
  1523. | STRING {
  1524. $$.text = $1.text;
  1525. $$.ivalue = LPARSE_T_STRING;
  1526. }
  1527. | ID {
  1528. $$.text = $1.text;
  1529. $$.ivalue = LPARSE_T_ERROR;
  1530. }
  1531. ;
  1532. expr : NUM_INT {
  1533. $$.text = $1.text;
  1534. $$.ivalue = LPARSE_T_INT;
  1535. }
  1536. | NUM_FLOAT {
  1537. $$.text = $1.text;
  1538. $$.ivalue = LPARSE_T_DOUBLE;
  1539. }
  1540. | NUM_UNSIGNED {
  1541. $$.text = $1.text;
  1542. $$.ivalue = LPARSE_T_UINT;
  1543. }
  1544. | NUM_LONG {
  1545. $$.text = $1.text;
  1546. $$.ivalue = LPARSE_T_LONG;
  1547. }
  1548. | NUM_ULONG {
  1549. $$.text = $1.text;
  1550. $$.ivalue = LPARSE_T_ULONG;
  1551. }
  1552. | CHARCONST {
  1553. $$.text = NewString("");
  1554. Printf($$.text,"\'%s\'", $1.text);
  1555. $$.ivalue = LPARSE_T_CHAR;
  1556. }
  1557. | SIZEOF LPAREN {
  1558. $$.text = NewString("sizeof(");
  1559. Append($$.text,LParse_skip_balanced('(',')'));
  1560. $$.ivalue = LPARSE_T_INT;
  1561. }
  1562. /* | LPAREN strict_type RPAREN expr %prec UMINUS {
  1563. $$.id = new char[strlen($4.id)+strlen($2->name)+3];
  1564. sprintf($$.id,"(%s)%s",$2->name,$4.id);
  1565. $$.type = $2->type;
  1566. }
  1567. | ID {
  1568. $$.id = lookup_symvalue($1);
  1569. if ($$.id == (char *) 0)
  1570. $$.id = $1;
  1571. else {
  1572. $$.id = new char[strlen($$.id)+3];
  1573. sprintf($$.id,"(%s)",lookup_symvalue($1));
  1574. }
  1575. temp_typeptr = lookup_symtype($1);
  1576. if (temp_typeptr) $$.type = temp_typeptr->type;
  1577. else $$.type = LPARSE_T_INT;
  1578. }
  1579. | ID DCOLON ID {
  1580. $$.id = new char[strlen($1)+strlen($…

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