PageRenderTime 54ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/mkoeppe-1-3-mzscheme/SWIG/Source/LParse/parser.y

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

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