| %{ |
| /* ----------------------------------------------------------------------------- |
| * parser.yxx |
| * |
| * YACC parser for SWIG1.1. This grammar is a broken subset of C/C++. |
| * This file is in the process of being deprecated. |
| * |
| * Author(s) : David Beazley (beazley@cs.uchicago.edu) |
| * |
| * Copyright (C) 1998-2000. The University of Chicago |
| * Copyright (C) 1995-1998. The University of Utah and The Regents of the |
| * University of California. |
| * |
| * See the file LICENSE for information on usage and redistribution. |
| * ----------------------------------------------------------------------------- */ |
| |
| #define yylex yylex |
| |
| static char cvsroot[] = "$Header$"; |
| |
| extern "C" int yylex(); |
| void yyerror (char *s); |
| |
| extern int line_number; |
| extern int start_line; |
| extern void skip_brace(void); |
| extern void skip_define(void); |
| extern void skip_decl(void); |
| extern int skip_cond(int); |
| extern void skip_to_end(void); |
| extern void skip_template(void); |
| extern void scanner_check_typedef(void); |
| extern void scanner_ignore_typedef(void); |
| extern void scanner_clear_start(void); |
| extern void start_inline(char *, int); |
| extern void swig_pragma(char *, char *); |
| char *typemap_lang = 0; |
| |
| #include "internal.h" |
| extern "C" { |
| #include "preprocessor.h" |
| } |
| |
| #ifdef NEED_ALLOC |
| void *alloca(unsigned n) { |
| return((void *) malloc(n)); |
| } |
| #else |
| // This redefinition is apparently needed on a number of machines, |
| // particularly HPUX |
| #undef alloca |
| #define alloca malloc |
| #endif |
| |
| // Initialization flags. These indicate whether or not certain |
| // features have been initialized. These were added to allow |
| // interface files without the block (required in previous |
| // versions). |
| |
| static int module_init = 0; /* Indicates whether the %module name was given */ |
| static int lang_init = 0; /* Indicates if the language has been initialized */ |
| |
| static int i; |
| int Error = 0; |
| static char temp_name[128]; |
| static SwigType *temp_typeptr, *temp_type = 0; |
| static char yy_rename[256]; |
| static int Rename_true = 0; |
| static SwigType *Active_type = 0; // Used to support variable lists |
| static int Active_extern = 0; // Whether or not list is external |
| static int Active_static = 0; |
| static SwigType *Active_typedef = 0; // Used for typedef lists |
| static int InArray = 0; // Used when an array declaration is found |
| static DOHString *ArrayString = 0; // Array type attached to parameter names |
| static DOHString *ArrayBackup = 0; |
| static char *DefArg = 0; // Default argument hack |
| static String *ConstChar = 0; // Used to store raw character constants |
| static ParmList *tm_parm = 0; // Parameter list used to hold typemap parameters |
| static DOHHash *name_hash = 0; // Hash table containing renamings |
| char *objc_construct = (char *) "new"; // Objective-C constructor |
| char *objc_destruct = (char *) "free"; // Objective-C destructor |
| |
| static DOHHash *symbols = 0; |
| |
| /* Some macros for building constants */ |
| |
| #define E_BINARY(TARGET, SRC1, SRC2, OP) \ |
| TARGET = (char *) malloc(strlen(SRC1) + strlen(SRC2) +strlen(OP)+1);\ |
| sprintf(TARGET,"%s%s%s",SRC1,OP,SRC2); |
| |
| /* C++ modes */ |
| |
| #define CPLUS_PUBLIC 1 |
| #define CPLUS_PRIVATE 2 |
| #define CPLUS_PROTECTED 3 |
| |
| int cplus_mode; |
| |
| // Declarations of some functions for handling C++ |
| |
| extern void cplus_open_class(char *name, char *rname, char *ctype); |
| extern void cplus_member_func(char *, char *, SwigType *, ParmList *, int); |
| extern void cplus_constructor(char *, char *, ParmList *); |
| extern void cplus_destructor(char *, char *); |
| extern void cplus_variable(char *, char *, SwigType *); |
| extern void cplus_static_func(char *, char *, SwigType *, ParmList *); |
| extern void cplus_declare_const(char *, char *, SwigType *, char *); |
| extern void cplus_class_close(char *); |
| extern void cplus_inherit(int, char **); |
| extern void cplus_cleanup(void); |
| extern void cplus_static_var(char *, char *, SwigType *); |
| extern void cplus_register_type(char *); |
| extern void cplus_register_scope(void *); |
| extern void cplus_inherit_scope(int, char **); |
| extern void cplus_add_pragma(char *, char *, char *); |
| extern void cplus_set_class(char *); |
| extern void cplus_unset_class(); |
| extern void cplus_abort(); |
| |
| void parser_init() { |
| ArrayString = NewString(""); |
| temp_type = NewString(""); |
| } |
| |
| static void my_cplus_declare_const(char *name, char *iname, SwigType *type, char *value) { |
| String *tval; |
| if (value) { |
| tval = NewStringf("%(escape)s",value); |
| cplus_declare_const(name,iname,type,Char(tval)); |
| Delete(tval); |
| } else { |
| cplus_declare_const(name,iname,type,value); |
| } |
| } |
| |
| static TMParm *NewTMParm() { |
| TMParm *tmp = (TMParm *) malloc(sizeof(TMParm)); |
| tmp->next = 0; |
| return tmp; |
| } |
| |
| static void add_pointers(SwigType *t, int npointer) { |
| int i; |
| for (i = 0; i < npointer; i++) { |
| SwigType_add_pointer(t); |
| } |
| } |
| |
| // Emit an external function declaration |
| |
| static void emit_extern_func(char *decl, SwigType *t, ParmList *L, int extern_type, DOHFile *f) { |
| |
| switch(extern_type) { |
| case 0: |
| Printf(f,"%s", SwigType_str(t,0)); |
| Printf(f,"%s(%s);\n", decl, ParmList_protostr(L)); |
| break; |
| case 1: |
| Printf(f,"extern %s", SwigType_str(t,0)); |
| Printf(f,"%s(%s);\n", decl, ParmList_protostr(L)); |
| break; |
| case 2: |
| /* A C++ --- > C Extern */ |
| Printf(f,"extern \"C\" %s", SwigType_str(t,0)); |
| Printf(f,"%s(%s);\n", decl, ParmList_protostr(L)); |
| break; |
| case 3: |
| Printf(f,"%s", SwigType_str(t,0)); |
| Printf(f,"%s(%s)\n", decl, ParmList_str(L)); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| // ---------------------------------------------------------------------- |
| // static init_language() |
| // |
| // Initialize the target language. |
| // Does nothing if this function has already been called. |
| // ---------------------------------------------------------------------- |
| |
| static void init_language() { |
| if (!lang_init) { |
| lang->initialize(); |
| } |
| lang_init = 1; |
| } |
| |
| /* Add a symbol to the symbol table. Return -1 if it already exists */ |
| int add_symbol(char *name) { |
| if (!symbols) symbols = NewHash(); |
| if (Getattr(symbols,name)) return -1; |
| Setattr(symbols,name,name); |
| return 0; |
| } |
| |
| // ---------------------------------------------------------------------- |
| // int promote(int t1, int t2) |
| // |
| // Promote types (for constant expressions) |
| // ---------------------------------------------------------------------- |
| |
| int promote(int t1, int t2) { |
| |
| if ((t1 == T_ERROR) || (t2 == T_ERROR)) return T_ERROR; |
| if ((t1 == T_DOUBLE) || (t2 == T_DOUBLE)) return T_DOUBLE; |
| if ((t1 == T_FLOAT) || (t2 == T_FLOAT)) return T_FLOAT; |
| if ((t1 == T_ULONG) || (t2 == T_ULONG)) return T_ULONG; |
| if ((t1 == T_LONG) || (t2 == T_LONG)) return T_LONG; |
| if ((t1 == T_UINT) || (t2 == T_UINT)) return T_UINT; |
| if ((t1 == T_INT) || (t2 == T_INT)) return T_INT; |
| if ((t1 == T_USHORT) || (t2 == T_USHORT)) return T_SHORT; |
| if ((t1 == T_SHORT) || (t2 == T_SHORT)) return T_SHORT; |
| if ((t1 == T_UCHAR) || (t2 == T_UCHAR)) return T_UCHAR; |
| if (t1 != t2) { |
| Printf(stderr,"%s : Line %d. Type mismatch in constant expression\n", |
| input_file, line_number); |
| FatalError(); |
| } |
| return t1; |
| } |
| |
| /* Generate the scripting name of an object. Takes %name directive into |
| account among other things */ |
| |
| static char *make_name(char *name) { |
| // Check to see if the name is in the hash |
| if (!name_hash) name_hash = NewHash(); |
| char *nn = GetChar(name_hash,name); |
| |
| if (nn) return nn; // Yep, return it. |
| |
| if (Rename_true) { |
| Rename_true = 0; |
| return yy_rename; |
| } else { |
| // Now check to see if the name contains a $ |
| if (strchr(name,'$')) { |
| static DOHString *temp = 0; |
| if (!temp) temp= NewString(""); |
| Clear(temp); |
| Append(temp,name); |
| Replace(temp,"$","_S_",DOH_REPLACE_ANY); |
| return Char(temp); |
| } else { |
| return name; |
| } |
| } |
| } |
| |
| // ---------------------------------------------------------------------- |
| // create_function(int ext, char *name, DataType *t, ParmList *l) |
| // |
| // Creates a function and manages documentation creation. Really |
| // only used internally to the parser. |
| // ---------------------------------------------------------------------- |
| |
| void create_function(int ext, char *name, SwigType *t, ParmList *l) { |
| if (Active_static) return; // Static declaration. Ignore |
| |
| init_language(); |
| if (WrapExtern) return; // External wrapper file. Ignore |
| |
| char *iname = make_name(name); |
| |
| // Check if symbol already exists |
| |
| if (add_symbol(iname)) { |
| Printf(stderr,"%s : Line %d. Function %s multiply defined (2nd definition ignored).\n", |
| input_file, line_number, iname); |
| } else { |
| |
| // If extern, make an extern declaration in the SWIG wrapper file |
| |
| if (ext) |
| emit_extern_func(name, t, l, ext, f_header); |
| else if (ForceExtern) { |
| emit_extern_func(name, t, l, 1, f_header); |
| } |
| |
| // If this function has been declared inline, produce a function |
| lang->create_function(name, iname, t, l); |
| } |
| scanner_clear_start(); |
| } |
| |
| // ------------------------------------------------------------------- |
| // create_variable(int ext, char *name, DataType *t) |
| // |
| // Create a link to a global variable. |
| // ------------------------------------------------------------------- |
| |
| void create_variable(int ext, char *name, SwigType *t) { |
| |
| if (WrapExtern) return; // External wrapper file. Ignore |
| if (Active_static) return; // If static ignore |
| |
| init_language(); |
| |
| char *iname = make_name(name); |
| if (add_symbol(iname)) { |
| Printf(stderr,"%s : Line %d. Variable %s multiply defined (2nd definition ignored).\n", |
| input_file, line_number, iname); |
| } else { |
| |
| // If externed, output an external declaration |
| |
| if (ext || ForceExtern) { |
| Printf(f_header,"extern %s;\n", SwigType_str(t,name)); |
| } |
| |
| // Now dump it out |
| lang->link_variable(name, iname, t); |
| } |
| scanner_clear_start(); |
| } |
| |
| // ------------------------------------------------------------------ |
| // create_constant(char *name, DataType *type, char *value) |
| // |
| // Creates a new constant. |
| // ------------------------------------------------------------------- |
| |
| void create_constant(char *name, SwigType *type, char *value) { |
| |
| if (Active_static) return; |
| if (WrapExtern) return; // External wrapper file. Ignore |
| init_language(); |
| |
| if (Rename_true) { |
| Printf(stderr,"%s : Line %d. %%name directive ignored with #define\n", |
| input_file, line_number); |
| Rename_true = 0; |
| } |
| |
| if (SwigType_type(type) == T_CHAR) { |
| SwigType_add_pointer(type); |
| } |
| if (!value) value = Swig_copy_string(name); |
| sprintf(temp_name,"const:%s", name); |
| if (add_symbol(temp_name)) { |
| Printf(stderr,"%s : Line %d. Constant %s multiply defined. (2nd definition ignored)\n", |
| input_file, line_number, name); |
| } else { |
| if (!WrapExtern) { // Only wrap the constant if not in %extern mode |
| String *tval = NewStringf("%(escape)s",value); |
| lang->declare_const(name, name, type, Char(tval)); |
| Delete(tval); |
| } |
| } |
| scanner_clear_start(); |
| } |
| |
| |
| /* Print out array brackets */ |
| void print_array() { |
| int i; |
| for (i = 0; i < InArray; i++) |
| Printf(stderr,"[]"); |
| } |
| |
| // Structures for handling code fragments built for nested classes |
| |
| struct Nested { |
| DOHString *code; // Associated code fragment |
| int line; // line number where it starts |
| char *name; // Name associated with this nested class |
| SwigType *type; // Datatype associated with the name |
| Nested *next; // Next code fragment in list |
| }; |
| |
| // Some internal variables for saving nested class information |
| |
| static Nested *nested_list = 0; |
| |
| // Add a function to the nested list |
| |
| static void add_nested(Nested *n) { |
| Nested *n1; |
| if (!nested_list) nested_list = n; |
| else { |
| n1 = nested_list; |
| while (n1->next) n1 = n1->next; |
| n1->next = n; |
| } |
| } |
| |
| // Dump all of the nested class declarations to the inline processor |
| // However. We need to do a few name replacements and other munging |
| // first. This function must be called before closing a class! |
| |
| static void dump_nested(char *parent) { |
| Nested *n,*n1; |
| n = nested_list; |
| int oldstatus = Status; |
| |
| Status = STAT_READONLY; |
| while (n) { |
| char temp[256]; |
| // Token replace the name of the parent class |
| Replace(n->code, "$classname", parent, DOH_REPLACE_ANY); |
| |
| // Fix up the name of the datatype (for building typedefs and other stuff) |
| sprintf(temp,"%s_%s", parent,n->name); |
| |
| Append(n->type,parent); |
| Append(n->type,"_"); |
| Append(n->type,n->name); |
| |
| // Add the appropriate declaration to the C++ processor |
| cplus_variable(n->name,(char *) 0, n->type); |
| |
| // Dump the code to the scanner |
| |
| Printf(f_header,"\n%s\n", Char(n->code)); |
| start_inline(Char(n->code),n->line); |
| |
| n1 = n->next; |
| Delete(n->code); |
| free(n); |
| n = n1; |
| } |
| nested_list = 0; |
| Status = oldstatus; |
| } |
| |
| static DOHList *typelist(Parm *p) { |
| DOHList *l = NewList(); |
| while (p) { |
| Append(l,Gettype(p)); |
| p = Getnext(p); |
| } |
| return l; |
| } |
| |
| %} |
| |
| /* The type of each node in the parse tree |
| must be one of the elements of the union |
| given below. This is used to derive the |
| C++ declaration for "yylval" that appears |
| in parser.tab.h. */ |
| |
| %union { |
| char *id; |
| struct Declaration { |
| char *id; |
| int is_pointer; |
| int is_reference; |
| } decl; |
| struct InitList { |
| char **names; |
| int count; |
| } ilist; |
| struct DocList { |
| char **names; |
| char **values; |
| int count; |
| } dlist; |
| struct Define { |
| char *id; |
| int type; |
| } dtype; |
| struct { |
| char *filename; |
| int line; |
| int flag; |
| } loc; |
| SwigType *type; |
| Parm *p; |
| TMParm *tmparm; |
| ParmList *pl; |
| int ivalue; |
| }; |
| |
| %token <id> ID |
| %token <id> HBLOCK WRAPPER POUND RUNTIME HEADER |
| %token <id> STRING |
| %token <loc> INCLUDE IMPORT WEXTERN SWIGMACRO INSERT |
| %token <id> NUM_INT NUM_FLOAT CHARCONST NUM_UNSIGNED NUM_LONG NUM_ULONG |
| %token <ivalue> TYPEDEF |
| %token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_TYPEDEF TYPE_RAW |
| %token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD |
| %token CONST STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET |
| %token ILLEGAL CONSTANT |
| %token READONLY READWRITE NAME RENAME ADDMETHODS PRAGMA |
| %token ENUM |
| %token CLASS PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND OPERATOR THROW TEMPLATE |
| %token NATIVE INLINE |
| %token TEXT DOC_DISABLE DOC_ENABLE STYLE LOCALSTYLE |
| %token TYPEMAP EXCEPT ECHO NEW APPLY CLEAR DOCONLY |
| %token <ivalue> TITLE SECTION SUBSECTION SUBSUBSECTION |
| %token LESSTHAN GREATERTHAN |
| %token TYPES |
| |
| /* Objective C tokens */ |
| |
| %token OC_INTERFACE OC_END OC_PUBLIC OC_PRIVATE OC_PROTECTED OC_CLASS OC_IMPLEMENT OC_PROTOCOL |
| |
| %left OR |
| %left XOR |
| %left AND |
| %left LSHIFT RSHIFT |
| %left PLUS MINUS |
| %left STAR SLASH |
| %left UMINUS NOT LNOT |
| %left DCOLON |
| |
| %type <ivalue> extern array array2; |
| %type <pl> parms ptail; |
| %type <p> parm parm_type; |
| %type <tmparm> typemap_parm tm_list tm_tail; |
| %type <id> pname cpptype base_specifier access_specifier typemap_name tm_method; |
| %type <type> type opt_signed opt_unsigned strict_type; |
| %type <decl> declaration nested_decl; |
| %type <ivalue> stars maybestars cpp_vend; |
| %type <ilist> initlist base_list inherit; |
| %type <dtype> definetype def_args; |
| %type <dtype> etype; |
| %type <dtype> expr; |
| %type <id> ename stylearg objc_inherit; |
| %type <dlist> stylelist styletail; |
| %type <type> objc_ret_type objc_arg_type; |
| %type <id> objc_protolist objc_separator; |
| %type <pl> objc_args; |
| |
| %% |
| |
| /* The productions of the grammar with their |
| associated semantic actions. */ |
| |
| program : command { |
| cplus_cleanup(); |
| if (lang_init) { |
| lang->close(); |
| } |
| } |
| ; |
| |
| command : command statement { |
| scanner_clear_start(); |
| Error = 0; |
| } |
| | empty { |
| } |
| ; |
| |
| statement : INCLUDE STRING LBRACE { |
| $1.filename = Swig_copy_string(input_file); |
| $1.line = line_number; |
| input_file = Swig_copy_string($2); |
| line_number = 0; |
| } command RBRACE { |
| input_file = $1.filename; |
| line_number = $1.line; |
| } |
| |
| /* %extern directive */ |
| |
| | WEXTERN STRING LBRACE { |
| $1.flag = WrapExtern; |
| WrapExtern = 1; |
| $1.filename = Swig_copy_string(input_file); |
| $1.line = line_number; |
| input_file = Swig_copy_string($2); |
| line_number = 0; |
| } command RBRACE { |
| input_file = $1.filename; |
| line_number = $1.line; |
| WrapExtern = $1.flag; |
| } |
| |
| /* %import directive. Like %extern but calls out to a language module */ |
| |
| | IMPORT STRING LBRACE { |
| $1.flag = WrapExtern; |
| WrapExtern = 1; |
| $1.filename = Swig_copy_string(input_file); |
| $1.line = line_number; |
| input_file = Swig_copy_string($2); |
| line_number = 0; |
| lang->import($2); |
| } command RBRACE { |
| input_file = $1.filename; |
| line_number = $1.line; |
| WrapExtern = $1.flag; |
| } |
| |
| | SWIGMACRO ID COMMA STRING COMMA NUM_INT LBRACE { |
| $1.filename = Swig_copy_string(input_file); |
| $1.line = line_number; |
| input_file = Swig_copy_string($4); |
| line_number = atoi($6) - 1; |
| } command RBRACE { |
| input_file = $1.filename; |
| line_number = $1.line; |
| } |
| |
| /* An unknown C preprocessor statement. Just throw it away */ |
| |
| | POUND { |
| } |
| |
| /* A variable declaration */ |
| |
| | extern type declaration array2 def_args { |
| init_language(); |
| if (Active_type) Delete(Active_type); |
| Active_type = Copy($2); |
| Active_extern = $1; |
| add_pointers($2,$3.is_pointer); |
| if ($4 > 0) { |
| SwigType_push($2,ArrayString); |
| } |
| if ($3.is_reference) { |
| Printf(stderr,"%s : Line %d. Error. Linkage to C++ reference not allowed.\n", input_file, line_number); |
| FatalError(); |
| } else { |
| if (SwigType_isconst($2)) { |
| create_constant($3.id, $2, $5.id); |
| } else { |
| create_variable($1,$3.id,$2); |
| } |
| } |
| Delete($2); |
| } stail { } |
| |
| /* Global variable that smells like a function pointer */ |
| |
| | extern strict_type LPAREN STAR { |
| skip_decl(); |
| Printf(stderr,"%s : Line %d. Function pointers not currently supported.\n", |
| input_file, line_number); |
| } |
| |
| /* A static variable declaration (Ignored) */ |
| |
| | STATIC type declaration array2 def_args { |
| Active_static = 1; |
| Delete($2); |
| } stail { |
| Active_static = 0; |
| } |
| |
| /* Global variable that smells like a function pointer */ |
| |
| | STATIC strict_type LPAREN STAR { |
| skip_decl(); |
| Printf(stderr,"%s : Line %d. Function pointers not currently supported.\n", |
| input_file, line_number); |
| } |
| |
| |
| /* A function declaration */ |
| |
| | extern type declaration LPAREN parms RPAREN cpp_const { |
| init_language(); |
| if (Active_type) Delete(Active_type); |
| Active_type = Copy($2); |
| Active_extern = $1; |
| add_pointers($2,$3.is_pointer); |
| if ($3.is_reference) SwigType_add_reference($2); |
| create_function($1, $3.id, $2, $5); |
| Delete($2); |
| Delete($5); |
| } stail { } |
| |
| /* A function declaration with code after it */ |
| |
| | extern type declaration LPAREN parms RPAREN func_end { |
| init_language(); |
| add_pointers($2,$3.is_pointer); |
| if ($3.is_reference) SwigType_add_reference($2); |
| create_function($1, $3.id, $2, $5); |
| Delete($2); |
| Delete($5); |
| }; |
| |
| /* A function declared without any return datatype */ |
| |
| | extern declaration LPAREN parms RPAREN cpp_const { |
| init_language(); |
| SwigType *t = NewString("int"); |
| add_pointers(t,$2.is_pointer); |
| if ($2.is_reference) SwigType_add_reference(t); |
| create_function($1,$2.id,t,$4); |
| Delete(t); |
| } stail { }; |
| |
| /* A static function declaration code after it */ |
| |
| | STATIC type declaration LPAREN parms RPAREN func_end { |
| if (Inline) { |
| if (strlen(Char(CCode))) { |
| init_language(); |
| add_pointers($2, $3.is_pointer); |
| if ($3.is_reference) SwigType_add_reference($2); |
| create_function(0, $3.id, $2, $5); |
| } |
| } |
| Delete($2); |
| Delete($5); |
| }; |
| |
| /* A function with an explicit inline directive. Not safe to use inside a %inline block */ |
| |
| | INLINE type declaration LPAREN parms RPAREN func_end { |
| init_language(); |
| add_pointers($2,$3.is_pointer); |
| if ($3.is_reference) SwigType_add_reference($2); |
| if (Inline) { |
| Printf(stderr,"%s : Line %d. Repeated %%inline directive.\n",input_file,line_number); |
| FatalError(); |
| } else { |
| if (strlen(Char(CCode))) { |
| Printf(f_header,"static "); |
| emit_extern_func($3.id,$2,$5,3,f_header); |
| Printf(f_header,"%s\n",Char(CCode)); |
| } |
| create_function(0, $3.id, $2, $5); |
| } |
| Delete($2); |
| Delete($5); |
| }; |
| |
| /* A static function declaration (ignored) */ |
| |
| | STATIC type declaration LPAREN parms RPAREN cpp_const { |
| Active_static = 1; |
| Delete($2); |
| Delete($5); |
| } stail { |
| Active_static = 0; |
| } |
| |
| /* Enable Read-only mode */ |
| |
| | READONLY { |
| Status = Status | STAT_READONLY; |
| } |
| |
| /* Enable Read-write mode */ |
| |
| | READWRITE { |
| Status = Status & ~STAT_READONLY; |
| } |
| |
| /* New %name directive */ |
| | NAME LPAREN ID RPAREN { |
| strcpy(yy_rename,$3); |
| Rename_true = 1; |
| } |
| |
| /* and its string version */ |
| |
| | NAME LPAREN STRING RPAREN { |
| strcpy(yy_rename,$3); |
| Rename_true = 1; |
| } |
| |
| /* %rename directive */ |
| | RENAME ID ID SEMI { |
| if (!name_hash) name_hash = NewHash(); |
| Setattr(name_hash,$2,$3); |
| } |
| |
| /* and its string version */ |
| |
| | RENAME ID STRING SEMI { |
| if (!name_hash) name_hash = NewHash(); |
| Setattr(name_hash,$2,$3); |
| } |
| |
| /* %new directive */ |
| |
| | NEW { |
| NewObject = 1; |
| } statement { |
| NewObject = 0; |
| } |
| |
| /* Empty name directive. No longer allowed */ |
| |
| | NAME LPAREN RPAREN { |
| Printf(stderr,"%s : Lind %d. Empty %%name() is no longer supported.\n", |
| input_file, line_number); |
| FatalError(); |
| } cpp { |
| Rename_true = 0; |
| } |
| |
| /* A native wrapper function */ |
| |
| | NATIVE LPAREN ID RPAREN extern ID SEMI { |
| if (!WrapExtern) { |
| init_language(); |
| if (add_symbol($3)) { |
| Printf(stderr,"%s : Line %d. Name of native function %s conflicts with previous declaration (ignored)\n", |
| input_file, line_number, $3); |
| } else { |
| lang->add_native($3,$6,0,0); |
| } |
| } |
| } |
| | NATIVE LPAREN ID RPAREN extern type declaration LPAREN parms RPAREN SEMI { |
| if (!WrapExtern) { |
| init_language(); |
| add_pointers($6,$7.is_pointer); |
| if (add_symbol($3)) { |
| Printf(stderr,"%s : Line %d. Name of native function %s conflicts with previous declaration (ignored)\n", |
| input_file, line_number, $3); |
| } else { |
| if ($5) { |
| emit_extern_func($7.id, $6, $9, $5, f_header); |
| } |
| lang->add_native($3,$7.id,$6,$9); |
| } |
| } |
| Delete($6); |
| Delete($9); |
| } |
| |
| /* %title directive */ |
| |
| | TITLE STRING styletail { |
| } |
| |
| |
| /* %section directive */ |
| |
| | SECTION STRING styletail { |
| } |
| |
| /* %subsection directive */ |
| | SUBSECTION STRING styletail { |
| } |
| |
| /* %subsubsection directive */ |
| | SUBSUBSECTION STRING styletail { |
| } |
| |
| | doc_enable { } |
| |
| /* %text directive */ |
| |
| | TEXT HBLOCK { |
| } |
| |
| |
| | typedef_decl { } |
| |
| /* Code insertion block */ |
| |
| | HBLOCK { |
| if (!WrapExtern) { |
| $1[strlen($1) - 1] = 0; |
| Printf(f_header, "%s\n", $1); |
| } |
| } |
| |
| | HEADER HBLOCK { |
| if (!WrapExtern) { |
| $2[strlen($1) - 2] = 0; |
| Printf(f_header, "%s\n", $2); |
| } |
| } |
| |
| /* Super-secret undocumented for people who really know what's going on feature */ |
| |
| | WRAPPER HBLOCK { |
| if (!WrapExtern) { |
| $2[strlen($2) - 1] = 0; |
| Printf(f_wrappers,"%s\n",$2); |
| } |
| } |
| |
| | RUNTIME HBLOCK { |
| if (!WrapExtern) { |
| $2[strlen($2) - 1] = 0; |
| Printf(f_runtime,"%s\n", $2); |
| } |
| } |
| |
| /* Initialization code */ |
| |
| | INIT HBLOCK { |
| if (!WrapExtern) { |
| $2[strlen($2) -1] = 0; |
| Printf(f_init,"%s\n", $2); |
| } |
| } |
| |
| | INSERT LPAREN ID RPAREN STRING { |
| if (!WrapExtern) { |
| File *f = 0; |
| if (strcmp($3,"headers") == 0) { |
| f = f_header; |
| } else if (strcmp($3,"runtime") == 0) { |
| f = f_runtime; |
| } else if (strcmp($3,"wrappers") == 0) { |
| f = f_wrappers; |
| } else if (strcmp($3,"init") == 0) { |
| f = f_init; |
| } |
| if (!f) { |
| Printf(stderr,"%s:%d: Unknown target '%s' for %%insert directive.\n", input_file, line_number, $3); |
| } else { |
| if (Swig_insert_file($5,f) < 0) { |
| Printf(stderr,"%s:%d: Couldn't find '%s'. Possible installation problem.\n", input_file, line_number, $5); |
| SWIG_exit (EXIT_FAILURE); |
| } |
| } |
| } |
| } |
| /* Inline block */ |
| | INLINE HBLOCK { |
| if (!WrapExtern) { |
| init_language(); |
| $2[strlen($2) - 1] = 0; |
| Printf(f_header, "%s\n", $2); |
| { |
| /* Need to run through the preprocessor */ |
| DOH *cpps; |
| DOH *s = NewString($2); |
| Setline(s,start_line); |
| Setfile(s,input_file); |
| Seek(s,0,SEEK_SET); |
| cpps = Preprocessor_parse(s); |
| start_inline(Char(cpps), start_line); |
| Delete(s); |
| Delete(cpps); |
| } |
| } |
| } |
| |
| /* Echo mode */ |
| | ECHO HBLOCK { |
| if (!WrapExtern) { |
| Printf(stderr,"%s\n", $2); |
| } |
| } |
| |
| | ECHO STRING { |
| if (!WrapExtern) { |
| Printf(stderr,"%s\n", $2); |
| } |
| } |
| |
| /* Disable code generation */ |
| | DOCONLY { |
| } |
| |
| /* Init directive--to avoid errors in other modules */ |
| |
| | INIT ID initlist { |
| Printf(stderr,"%s : Line %d. Warning. %%init directive is deprecated (ignored).\n", input_file,line_number); |
| for (i = 0; i < $3.count; i++) |
| if ($3.names[i]) free($3.names[i]); |
| free($3.names); |
| } |
| /* Module directive */ |
| |
| | MODULE ID initlist { |
| lang->set_module($2); |
| module_init = 1; |
| init_language(); |
| for (i = 0; i < $3.count; i++) |
| if ($3.names[i]) free($3.names[i]); |
| free($3.names); |
| } |
| |
| /* constant directive */ |
| |
| | CONSTANT ID definetype SEMI { |
| if (($3.type != T_ERROR) && ($3.type != T_SYMBOL)) { |
| init_language(); |
| temp_typeptr = NewSwigType($3.type); |
| create_constant($2, temp_typeptr, $3.id); |
| Delete(temp_typeptr); |
| } else if ($3.type == T_SYMBOL) { |
| // Add a symbol to the SWIG symbol table |
| if (add_symbol($2)) { |
| Printf(stderr,"%s : Line %d. Warning. Symbol %s already defined.\n", |
| input_file,line_number, $2); |
| } |
| } |
| } |
| |
| | CONSTANT LPAREN parm RPAREN ID def_args SEMI { |
| if (($6.type != T_ERROR) && ($6.type != T_SYMBOL)) { |
| init_language(); |
| create_constant($5,Gettype($3), $6.id); |
| Delete($3); |
| } |
| } |
| |
| /* Enumerations */ |
| |
| | extern ENUM ename LBRACE { scanner_clear_start(); } enumlist RBRACE SEMI { |
| init_language(); |
| if ($3) { |
| if (temp_type) Delete(temp_type); |
| temp_type = NewStringf("enum %s", $3); |
| /* String *ts = NewSwigType(T_INT); */ |
| SwigType_typedef(temp_type,$3); |
| lang->add_typedef(temp_type,$3); |
| } |
| } |
| |
| /* A typdef'd enum. Pretty common in C headers */ |
| |
| | TYPEDEF ENUM ename LBRACE { scanner_clear_start(); } enumlist RBRACE ID { |
| init_language(); |
| if (temp_type) Delete(temp_type); |
| temp_type = NewStringf("enum %s", $3); |
| /* temp_type= NewSwigType(T_INT);*/ |
| Active_typedef = Copy(temp_type); |
| if ($3) { |
| SwigType_typedef(temp_type,$3); |
| lang->add_typedef(temp_type,$3); |
| } |
| if ($8) { |
| SwigType_typedef(temp_type,$8); |
| lang->add_typedef(temp_type,$8); |
| } |
| } typedeflist { } |
| |
| /* ----------------------------------------------------------------- |
| typemap support. |
| |
| These constructs are used to support type-maps. |
| ----------------------------------------------------------------- */ |
| |
| /* Create a new typemap */ |
| |
| | TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE { |
| TMParm *p; |
| skip_brace(); |
| p = $7; |
| while (p) { |
| if (strcmp($3,typemap_lang) == 0) |
| Swig_typemap_register($5,Gettype(p->p),Getname(p->p), CCode, p->args); |
| p = p->next; |
| } |
| free($3); |
| free($5); |
| } |
| |
| /* Create a new typemap in current language */ |
| | TYPEMAP LPAREN tm_method RPAREN tm_list LBRACE { |
| if (!typemap_lang) { |
| Printf(stderr,"SWIG internal error. No typemap_lang specified.\n"); |
| Printf(stderr,"typemap on %s : Line %d. will be ignored.\n",input_file,line_number); |
| FatalError(); |
| } else { |
| TMParm *p; |
| skip_brace(); |
| p = $5; |
| while (p) { |
| Swig_typemap_register($3,Gettype(p->p),Getname(p->p), CCode, p->args); |
| p = p->next; |
| } |
| } |
| free($3); |
| } |
| |
| /* Create a new typemap */ |
| |
| | TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list STRING { |
| TMParm *p; |
| p = $7; |
| while (p) { |
| if (strcmp($3,typemap_lang) == 0) |
| Swig_typemap_register($5,Gettype(p->p),Getname(p->p), $8, p->args); |
| p = p->next; |
| } |
| free($3); |
| free($5); |
| } |
| |
| /* Create a new typemap in current language */ |
| | TYPEMAP LPAREN tm_method RPAREN tm_list STRING { |
| if (!typemap_lang) { |
| Printf(stderr,"SWIG internal error. No typemap_lang specified.\n"); |
| Printf(stderr,"typemap on %s : Line %d. will be ignored.\n",input_file,line_number); |
| FatalError(); |
| } else { |
| TMParm *p; |
| p = $5; |
| while (p) { |
| Swig_typemap_register($3,Gettype(p->p),Getname(p->p), $6, p->args); |
| p = p->next; |
| } |
| } |
| free($3); |
| } |
| |
| /* Clear a typemap */ |
| |
| | TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list SEMI { |
| TMParm *p; |
| p = $7; |
| while (p) { |
| if (strcmp($3,typemap_lang) == 0) { |
| Printf(stderr,"%s:%d. Warning. Typemap deletion is temporary disabled in this release.\n", input_file, line_number); |
| /* Swig_typemap_clear($5,Gettype(p->p),Getname(p->p)); */ |
| } |
| p = p->next; |
| } |
| free($3); |
| free($5); |
| } |
| /* Clear a typemap in current language */ |
| |
| | TYPEMAP LPAREN tm_method RPAREN tm_list SEMI { |
| if (!typemap_lang) { |
| Printf(stderr,"SWIG internal error. No typemap_lang specified.\n"); |
| Printf(stderr,"typemap on %s : Line %d. will be ignored.\n",input_file,line_number); |
| FatalError(); |
| } else { |
| TMParm *p; |
| p = $5; |
| while (p) { |
| Printf(stderr,"%s:%d. Warning. Typemap deletion is temporary disabled in this release.\n", input_file, line_number); |
| /* Swig_typemap_clear($3,Gettype(p->p),Getname(p->p)); */ |
| p = p->next; |
| } |
| } |
| free($3); |
| } |
| |
| /* Copy a typemap */ |
| |
| | TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list EQUAL typemap_parm SEMI { |
| TMParm *p; |
| p = $7; |
| while (p) { |
| if (strcmp($3,typemap_lang) == 0) { |
| Swig_typemap_copy($5,Gettype($9->p),Getname($9->p),Gettype(p->p),Getname(p->p)); |
| } |
| p = p->next; |
| } |
| free($3); |
| free($5); |
| Delete($9->p); |
| free($9); |
| } |
| |
| /* Copy typemap in current language */ |
| |
| | TYPEMAP LPAREN tm_method RPAREN tm_list EQUAL typemap_parm SEMI { |
| if (!typemap_lang) { |
| Printf(stderr,"SWIG internal error. No typemap_lang specified.\n"); |
| Printf(stderr,"typemap on %s : Line %d. will be ignored.\n",input_file,line_number); |
| FatalError(); |
| } else { |
| TMParm *p; |
| p = $5; |
| while (p) { |
| Swig_typemap_copy($3,Gettype($7->p),Getname($7->p),Gettype(p->p),Getname(p->p)); |
| p = p->next; |
| } |
| } |
| free($3); |
| Delete($7->p); |
| free($7); |
| } |
| /* ----------------------------------------------------------------- |
| apply and clear support (for typemaps) |
| ----------------------------------------------------------------- */ |
| |
| | APPLY typemap_parm LBRACE tm_list RBRACE { |
| TMParm *p; |
| p = $4; |
| while(p) { |
| Swig_typemap_apply(Gettype($2->p),Getname($2->p),Gettype(p->p),Getname(p->p)); |
| p = p->next; |
| } |
| free($4); |
| Delete($2->args); |
| free($2); |
| } |
| | CLEAR tm_list SEMI { |
| TMParm *p; |
| p = $2; |
| while (p) { |
| Printf(stderr,"%s:%d. Warning. %%clear directive is temporarily disabled in this release. Ignored.\n", input_file, line_number); |
| /* Swig_typemap_clear_apply(Gettype(p->p), Getname(p->p)); */ |
| p = p->next; |
| } |
| } |
| |
| |
| /* ----------------------------------------------------------------- |
| exception support |
| |
| These constructs are used to define exceptions |
| ----------------------------------------------------------------- */ |
| |
| /* An exception definition */ |
| | EXCEPT LPAREN ID RPAREN LBRACE { |
| skip_brace(); |
| if (strcmp($3,typemap_lang) == 0) { |
| Swig_except_register(CCode); |
| } |
| free($3); |
| } |
| |
| /* A Generic Exception (no language specified */ |
| | EXCEPT LBRACE { |
| skip_brace(); |
| Swig_except_register(CCode); |
| } |
| |
| /* Clear an exception */ |
| |
| | EXCEPT LPAREN ID RPAREN SEMI { |
| Swig_except_clear(); |
| } |
| |
| /* Generic clear */ |
| | EXCEPT SEMI { |
| Swig_except_clear(); |
| } |
| |
| /* Miscellaenous stuff */ |
| |
| | SEMI { } |
| | cpp { } |
| | objective_c { } |
| | error { |
| if (!Error) { |
| { |
| static int last_error_line = -1; |
| if (last_error_line != line_number) { |
| Printf(stderr,"%s : Line %d. Syntax error in input.\n", input_file, line_number); |
| FatalError(); |
| last_error_line = line_number; |
| // Try to make some kind of recovery. |
| skip_decl(); |
| } |
| Error = 1; |
| } |
| } |
| } |
| |
| /* A an extern C type declaration. Does nothing, but is ignored */ |
| |
| | EXTERN STRING LBRACE command RBRACE { } |
| |
| /* Officially, this directive doesn't exist yet */ |
| |
| | pragma { } |
| |
| /* %style directive. This applies to all current styles */ |
| |
| | STYLE stylelist { |
| } |
| |
| /* %localstyle directive. This applies only to the current style */ |
| |
| | LOCALSTYLE stylelist { |
| } |
| |
| /* %types directive. Used to register types with the type-checker */ |
| | TYPES LPAREN parms RPAREN SEMI { |
| Parm *p = $3; |
| while (p) { |
| SwigType *t = Gettype(p); |
| SwigType_remember(t); |
| p = Getnext(p); |
| } |
| Delete($3); |
| } |
| |
| /* Dcumentation disable/enable */ |
| |
| doc_enable : DOC_DISABLE { |
| } |
| /* %enabledoc directive */ |
| | DOC_ENABLE { |
| } |
| ; |
| |
| /* Note : This really needs to be re-done */ |
| |
| /* A typedef with pointers */ |
| typedef_decl : TYPEDEF type declaration { |
| init_language(); |
| /* Add a new typedef */ |
| Active_typedef = Copy($2); |
| add_pointers($2,$3.is_pointer); |
| SwigType_typedef($2, $3.id); |
| lang->add_typedef($2,$3.id); |
| cplus_register_type($3.id); |
| } typedeflist { }; |
| |
| /* A rudimentary typedef involving function pointers */ |
| |
| | TYPEDEF type LPAREN STAR pname RPAREN LPAREN parms RPAREN SEMI { |
| init_language(); |
| /* Typedef'd pointer */ |
| DOHList *l = typelist($8); |
| SwigType_add_function($2,l); |
| SwigType_add_pointer($2); |
| SwigType_typedef($2,$5); |
| lang->add_typedef($2,$5); |
| cplus_register_type($5); |
| Delete($2); |
| free($5); |
| Delete($8); |
| Delete(l); |
| } |
| |
| /* A typedef involving function pointers again */ |
| |
| | TYPEDEF type stars LPAREN STAR pname RPAREN LPAREN parms RPAREN SEMI { |
| init_language(); |
| add_pointers($2,$3); |
| DOHList *l = typelist($9); |
| SwigType_add_function($2,l); |
| SwigType_add_pointer($2); |
| SwigType_typedef($2,$6); |
| lang->add_typedef($2,$6); |
| cplus_register_type($6); |
| Delete($2); |
| free($6); |
| Delete($9); |
| Delete(l); |
| } |
| |
| /* A typedef involving arrays */ |
| |
| | TYPEDEF type declaration array { |
| init_language(); |
| Active_typedef = Copy($2); |
| // This datatype is going to be readonly |
| |
| add_pointers($2,$3.is_pointer); |
| SwigType_push($2,ArrayString); |
| SwigType_typedef($2,$3.id); |
| lang->add_typedef($2,$3.id); |
| cplus_register_type($3.id); |
| |
| } typedeflist { } |
| ; |
| |
| /* ------------------------------------------------------------------------ |
| Typedef list |
| |
| The following rules are used to manage typedef lists. Only a temporary |
| hack until the SWIG 2.0 parser gets online. |
| |
| Active_typedef contains the datatype of the last typedef (if applicable) |
| ------------------------------------------------------------------------ */ |
| |
| |
| typedeflist : COMMA declaration typedeflist { |
| if (Active_typedef) { |
| SwigType *t; |
| t = Copy(Active_typedef); |
| add_pointers(t,$2.is_pointer); |
| SwigType_typedef(t,$2.id); |
| lang->add_typedef(t,$2.id); |
| cplus_register_type($2.id); |
| Delete(t); |
| } |
| } |
| | COMMA declaration array { |
| SwigType *t; |
| t = Copy(Active_typedef); |
| add_pointers(t, $2.is_pointer); |
| SwigType_push(t,ArrayString); |
| SwigType_typedef(t,$2.id); |
| lang->add_typedef(t,$2.id); |
| cplus_register_type($2.id); |
| Delete(t); |
| Printf(stderr,"%s : Line %d. Warning. Array type %s will be read-only without a typemap.\n",input_file,line_number, $2.id); |
| } |
| | empty { } |
| ; |
| |
| pragma : PRAGMA LPAREN ID COMMA ID stylearg RPAREN { |
| if (!WrapExtern) |
| lang->pragma($3,$5,$6); |
| Printf(stderr,"%s : Line %d. Warning. '%%pragma(lang,opt=value)' syntax is obsolete.\n", |
| input_file,line_number); |
| Printf(stderr," Use '%%pragma(lang) opt=value' instead.\n"); |
| } |
| |
| | PRAGMA ID stylearg { |
| if (!WrapExtern) |
| swig_pragma($2,$3); |
| } |
| | PRAGMA LPAREN ID RPAREN ID stylearg { |
| if (!WrapExtern) |
| lang->pragma($3,$5,$6); |
| } |
| ; |
| |
| /* Allow lists of variables and functions to be built up */ |
| |
| stail : SEMI { } |
| | COMMA declaration array2 def_args { |
| init_language(); |
| temp_typeptr = Copy(Active_type); |
| add_pointers(temp_typeptr, $2.is_pointer); |
| if ($3 > 0) { |
| SwigType_push(temp_typeptr, ArrayString); |
| } |
| if ($2.is_reference) { |
| Printf(stderr,"%s : Line %d. Error. Linkage to C++ reference not allowed.\n", input_file, line_number); |
| FatalError(); |
| } else { |
| if (SwigType_isconst(temp_typeptr)) { |
| create_constant($2.id, temp_typeptr, $4.id); |
| } else { |
| create_variable(Active_extern,$2.id, temp_typeptr); |
| } |
| } |
| Delete(temp_typeptr); |
| } stail { } |
| | COMMA declaration LPAREN parms RPAREN cpp_const { |
| init_language(); |
| temp_typeptr = Copy(Active_type); |
| add_pointers(temp_typeptr, $2.is_pointer); |
| if ($2.is_reference) SwigType_add_reference(temp_typeptr); |
| create_function(Active_extern, $2.id, temp_typeptr, $4); |
| Delete(temp_typeptr); |
| Delete($4); |
| } stail { } |
| ; |
| |
| extern : EXTERN { $$ = 1; } |
| | empty {$$ = 0; } |
| | EXTERN STRING { |
| if (strcmp($2,"C") == 0) { |
| $$ = 2; |
| } else { |
| Printf(stderr,"%s : Line %d. Unrecognized extern type \"%s\" (ignored).\n", input_file, line_number, $2); |
| FatalError(); |
| } |
| } |
| ; |
| |
| /* End of a function declaration. Allows C++ "const" directive and inline code */ |
| |
| func_end : cpp_const LBRACE { skip_brace(); } |
| /* | LBRACE { skip_brace(); } */ |
| ; |
| |
| /* ------------------------------------------------------------------------------ |
| Function parameter lists |
| |
| ------------------------------------------------------------------------------ */ |
| |
| parms : parm ptail { |
| SwigType *pt = Gettype($1); |
| if (SwigType_type(pt) != T_VOID) { |
| Setnext($1,$2); |
| $$ = $1; |
| } else { |
| $$ = $2; |
| } |
| } |
| | empty { $$ = 0; } |
| ; |
| |
| ptail : COMMA parm ptail { |
| Setnext($2,$3); |
| $$ = $2; |
| } |
| | empty { $$ = 0; } |
| ; |
| |
| parm : parm_type { |
| $$ = $1; |
| } |
| |
| parm_type : type pname { |
| if (InArray) { |
| // Add array string to the type |
| SwigType_push($1, ArrayString); |
| } |
| $$ = NewParm($1,$2); |
| Setvalue($$,DefArg); |
| Delete($1); |
| free($2); |
| } |
| |
| | type stars pname { |
| $$ = NewParm($1,$3); |
| add_pointers(Gettype($$), $2); |
| Setvalue($$,DefArg); |
| if (InArray) { |
| // Add array string to the type |
| SwigType_push(Gettype($$), ArrayString); |
| } |
| Delete($1); |
| free($3); |
| } |
| |
| | type maybestars CONST pname { |
| $$ = NewParm($1,$4); |
| add_pointers(Gettype($$), $2); |
| SwigType_add_qualifier($$,(char*)"const"); |
| Setvalue($$,DefArg); |
| Delete($1); |
| free($4); |
| } |
| |
| | type maybestars AND pname { |
| $$ = NewParm($1,$4); |
| SwigType *pt = Gettype($$); |
| add_pointers(Gettype($$), $2); |
| SwigType_add_reference(pt); |
| Setvalue($$,DefArg); |
| if (!CPlusPlus) { |
| Printf(stderr,"%s : Line %d. Warning. Use of C++ Reference detected. Use the -c++ option.\n", input_file, line_number); |
| } |
| Delete($1); |
| free($4); |
| } |
| |
| | type LPAREN stars pname RPAREN LPAREN parms RPAREN { |
| $$ = NewParm($1,$4); |
| SwigType *pt = Gettype($$); |
| DOHList *l = typelist($7); |
| SwigType_add_function(pt,l); |
| add_pointers(pt,$3); |
| Setname($$,$4); |
| Delete($1); |
| free($4); |
| Delete($7); |
| Delete(l); |
| } |
| | PERIOD PERIOD PERIOD { |
| Printf(stderr,"%s : Line %d. Variable length arguments not supported (ignored).\n", input_file, line_number); |
| $$ = NewParm(NewSwigType(T_INT),(char *) "varargs"); |
| FatalError(); |
| } |
| ; |
| |
| pname : ID def_args { |
| $$ = $1; |
| InArray = 0; |
| if ($2.type == T_CHAR) |
| DefArg = Swig_copy_string(Char(ConstChar)); |
| else |
| DefArg = Swig_copy_string($2.id); |
| if ($2.id) free($2.id); |
| } |
| | ID array { |
| $$ = $1; |
| InArray = $2; |
| DefArg = 0; |
| } |
| | array { |
| $$ = (char *) malloc(1); |
| $$[0] = 0; |
| InArray = $1; |
| DefArg = 0; |
| } |
| | empty { $$ = (char *) malloc(1); |
| $$[0] = 0; |
| InArray = 0; |
| DefArg = 0; |
| } |
| ; |
| |
| def_args : EQUAL definetype { $$ = $2; } |
| | EQUAL AND ID { |
| $$.id = (char *) malloc(strlen($3)+2); |
| $$.id[0] = '&'; |
| strcpy(&$$.id[1], $3); |
| $$.type = T_USER; |
| } |
| | EQUAL LBRACE { |
| skip_brace(); |
| $$.id = 0; $$.type = T_INT; |
| } |
| | COLON NUM_INT { |
| } |
| | empty {$$.id = 0; $$.type = T_INT;} |
| ; |
| |
| /* Declaration must be an identifier, possibly preceded by a * for pointer types */ |
| |
| declaration : ID { $$.id = $1; |
| $$.is_pointer = 0; |
| $$.is_reference = 0; |
| } |
| | stars ID { |
| $$.id = $2; |
| $$.is_pointer = $1; |
| $$.is_reference = 0; |
| } |
| | AND ID { |
| $$.id = $2; |
| $$.is_pointer = 0; |
| $$.is_reference = 1; |
| if (!CPlusPlus) { |
| Printf(stderr,"%s : Line %d. Warning. Use of C++ Reference detected. Use the -c++ option.\n", input_file, line_number); |
| } |
| } |
| ; |
| |
| stars : STAR empty { $$ = 1; } |
| | STAR stars { $$ = $2 + 1;} |
| ; |
| |
| maybestars : empty { $$ = 0; } |
| | stars { $$ = $1; } |
| ; |
| |
| array : LBRACKET RBRACKET array2 { |
| $$ = $3 + 1; |
| SwigType_add_array(ArrayString,(char*)""); |
| } |
| | LBRACKET expr RBRACKET array2 { |
| $$ = $4 + 1; |
| SwigType_add_array(ArrayString,$2.id); |
| } |
| ; |
| array2 : array { |
| $$ = $1; |
| } |
| | empty { |
| $$ = 0; |
| Clear(ArrayString); |
| } |
| ; |
| |
| /* Data type must be a built in type or an identifier for user-defined types |
| This type can be preceded by a modifier. */ |
| |
| type : TYPE_INT { |
| $$ = $1; |
| } |
| | TYPE_SHORT opt_int { |
| $$ = $1; |
| } |
| | TYPE_LONG opt_int { |
| $$ = $1; |
| } |
| | TYPE_LONG TYPE_LONG opt_int { |
| $$ = NewString("long long"); |
| } |
| | TYPE_CHAR { |
| $$ = $1; |
| } |
| | TYPE_BOOL { |
| $$ = $1; |
| } |
| | TYPE_FLOAT { |
| $$ = $1; |
| } |
| | TYPE_DOUBLE { |
| $$ = $1; |
| } |
| | TYPE_VOID { |
| $$ = $1; |
| } |
| | TYPE_SIGNED opt_signed { |
| if ($2) $$ = $2; |
| else $$ = $1; |
| } |
| | TYPE_UNSIGNED opt_unsigned { |
| if ($2) $$ = $2; |
| else $$ = $1; |
| } |
| | TYPE_TYPEDEF objc_protolist { |
| $$ = $1; |
| $$ = NewStringf("%s%s",$1,$2); |
| Delete($1); |
| } |
| | ID objc_protolist { |
| $$ = NewStringf("%s%s",$1,$2); |
| free($1); |
| } |
| | CONST type { |
| $$ = $2; |
| SwigType_add_qualifier($$,(char*)"const"); |
| } |
| | cpptype ID { |
| $$ = NewStringf("%s %s",$1,$2); |
| } |
| | ID DCOLON ID { |
| $$ = NewStringf("%s::%s", $1,$3); |
| } |
| /* This declaration causes a shift-reduce conflict. Unresolved for now */ |
| |
| |
| | DCOLON ID { |
| $$ = NewString($2); |
| } |
| | ENUM ID { |
| $$ = NewStringf("enum %s", $2); |
| } |
| | TYPE_RAW { |
| $$ = $1; |
| } |
| ; |
| |
| /* type specification without ID symbol. Used in some cases to prevent shift-reduce conflicts */ |
| |
| strict_type : TYPE_INT { |
| $$ = $1; |
| } |
| | TYPE_SHORT opt_int { |
| $$ = $1; |
| } |
| | TYPE_LONG opt_int { |
| $$ = $1; |
| } |
| | TYPE_LONG TYPE_LONG opt_int { |
| $$ = NewString("long long"); |
| } |
| | TYPE_CHAR { |
| $$ = $1; |
| } |
| | TYPE_BOOL { |
| $$ = $1; |
| } |
| | TYPE_FLOAT { |
| $$ = $1; |
| } |
| | TYPE_DOUBLE { |
| $$ = $1; |
| } |
| | TYPE_VOID { |
| $$ = $1; |
| } |
| | TYPE_SIGNED opt_signed { |
| if ($2) $$ = $2; |
| else $$ = $1; |
| } |
| | TYPE_UNSIGNED opt_unsigned { |
| if ($2) $$ = $2; |
| else $$ = $1; |
| } |
| | TYPE_TYPEDEF objc_protolist { |
| $$ = NewStringf("%s%s", $1,$2); |
| } |
| | CONST type { |
| $$ = $2; |
| SwigType_add_qualifier($$,(char*)"const"); |
| } |
| | cpptype ID { |
| $$ = NewStringf("%s %s", $1, $2); |
| } |
| | TYPE_RAW { |
| $$ = $1; |
| } |
| ; |
| |
| /* Optional signed types */ |
| |
| opt_signed : empty { |
| $$ = 0; |
| } |
| | TYPE_INT { |
| $$ = $1; |
| } |
| | TYPE_SHORT opt_int { |
| $$ = $1; |
| } |
| | TYPE_LONG opt_int { |
| $$ = $1; |
| } |
| | TYPE_LONG TYPE_LONG opt_int { |
| $$ = NewString("long long"); |
| } |
| | TYPE_CHAR { |
| $$ = NewString("signed char"); |
| } |
| ; |
| |
| /* Optional unsigned types */ |
| |
| opt_unsigned : empty { |
| $$ = 0; |
| } |
| | TYPE_INT { |
| $$ = NewString("unsigned int"); |
| } |
| | TYPE_SHORT opt_int { |
| $$ = NewString("unsigned short"); |
| } |
| | TYPE_LONG opt_int { |
| $$ = NewString("unsigned long"); |
| } |
| | TYPE_LONG TYPE_LONG opt_int { |
| $$ = NewString("unsigned long long"); |
| } |
| | TYPE_CHAR { |
| $$ = NewString("unsigned char"); |
| } |
| ; |
| |
| opt_int : TYPE_INT { } |
| | empty { } |
| ; |
| |
| definetype : { scanner_check_typedef(); } expr { |
| $$ = $2; |
| scanner_ignore_typedef(); |
| if (ConstChar) Delete(ConstChar); |
| ConstChar = 0; |
| } |
| | STRING { |
| $$.id = $1; |
| $$.type = T_CHAR; |
| if (ConstChar) Delete(ConstChar); |
| ConstChar = NewStringf("\"%(escape)s\"",$1); |
| } |
| | CHARCONST { |
| $$.id = $1; |
| $$.type = T_CHAR; |
| if (ConstChar) Delete(ConstChar); |
| ConstChar = NewStringf("'%(escape)s'", $1); |
| } |
| ; |
| |
| |
| /* Initialization function links */ |
| |
| initlist : initlist COMMA ID { |
| $$ = $1; |
| $$.names[$$.count] = Swig_copy_string($3); |
| $$.count++; |
| $$.names[$$.count] = (char *) 0; |
| } |
| | empty { |
| $$.names = (char **) malloc(NI_NAMES*sizeof(char*)); |
| $$.count = 0; |
| for (i = 0; i < NI_NAMES; i++) |
| $$.names[i] = (char *) 0; |
| } |
| ; |
| |
| /* Some stuff for handling enums */ |
| |
| ename : ID { $$ = $1; } |
| | empty { $$ = (char *) 0;} |
| ; |
| |
| /* SWIG enum list. |
| */ |
| |
| enumlist : enumlist COMMA edecl {} |
| | edecl {} |
| ; |
| |
| |
| edecl : ID { |
| temp_typeptr = NewSwigType(T_INT); |
| create_constant($1, temp_typeptr, $1); |
| Delete(temp_typeptr); |
| } |
| | ID EQUAL { scanner_check_typedef();} etype { |
| temp_typeptr = NewSwigType($4.type); |
| // Use enum name instead of value |
| // OLD create_constant($1, temp_typeptr, $4.id); |
| if ($4.type == T_CHAR) |
| create_constant($1,temp_typeptr, $4.id); |
| else |
| create_constant($1, temp_typeptr, $1); |
| Delete(temp_typeptr); |
| scanner_ignore_typedef(); |
| } |
| | empty { } |
| ; |
| |
| etype : expr { |
| $$ = $1; |
| if (($$.type != T_INT) && ($$.type != T_UINT) && |
| ($$.type != T_LONG) && ($$.type != T_ULONG) && |
| ($$.type != T_SHORT) && ($$.type != T_USHORT) && |
| ($$.type != T_SCHAR) && ($$.type != T_UCHAR)) { |
| Printf(stderr,"%s : Lind %d. Type error. Expecting an int\n", |
| input_file, line_number); |
| FatalError(); |
| } |
| |
| } |
| | CHARCONST { |
| $$.id = $1; |
| $$.type = T_INT; |
| } |
| ; |
| |
| /* Arithmetic expressions. Used for constants and other cool stuff. |
| Really, we're not doing anything except string concatenation, but |
| this does allow us to parse many constant declarations. |
| */ |
| |
| expr : NUM_INT { |
| $$.id = $1; |
| $$.type = T_INT; |
| } |
| | NUM_FLOAT { |
| $$.id = $1; |
| $$.type = T_DOUBLE; |
| } |
| | NUM_UNSIGNED { |
| $$.id = $1; |
| $$.type = T_UINT; |
| } |
| | NUM_LONG { |
| $$.id = $1; |
| $$.type = T_LONG; |
| } |
| | NUM_ULONG { |
| $$.id = $1; |
| $$.type = T_ULONG; |
| } |
| | SIZEOF LPAREN type RPAREN { |
| $$.id = (char *) malloc(Len($3)+9); |
| sprintf($$.id,"sizeof(%s)", Char($3)); |
| $$.type = T_INT; |
| } |
| | LPAREN strict_type RPAREN expr %prec UMINUS { |
| $$.id = (char *) malloc(strlen($4.id)+Len($2)+3); |
| sprintf($$.id,"(%s)%s",Char($2),$4.id); |
| $$.type = SwigType_type($2); |
| } |
| | ID { |
| $$.id = $1; |
| $$.type = T_INT; |
| } |
| | ID DCOLON ID { |
| $$.id = (char *) malloc(strlen($1)+strlen($3)+3); |
| sprintf($$.id,"%s::%s",$1,$3); |
| $$.type = T_INT; |
| free($1); |
| free($3); |
| } |
| | expr PLUS expr { |
| E_BINARY($$.id,$1.id,$3.id,"+"); |
| $$.type = promote($1.type,$3.type); |
| free($1.id); |
| free($3.id); |
| } |
| | expr MINUS expr { |
| E_BINARY($$.id,$1.id,$3.id,"-"); |
| $$.type = promote($1.type,$3.type); |
| free($1.id); |
| free($3.id); |
| } |
| | expr STAR expr { |
| E_BINARY($$.id,$1.id,$3.id,"*"); |
| $$.type = promote($1.type,$3.type); |
| free($1.id); |
| free($3.id); |
| |
| } |
| | expr SLASH expr { |
| E_BINARY($$.id,$1.id,$3.id,"/"); |
| $$.type = promote($1.type,$3.type); |
| free($1.id); |
| free($3.id); |
| |
| } |
| | expr AND expr { |
| E_BINARY($$.id,$1.id,$3.id,"&"); |
| $$.type = promote($1.type,$3.type); |
| if (($1.type == T_DOUBLE) || ($3.type == T_DOUBLE)) { |
| Printf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); |
| FatalError(); |
| } |
| free($1.id); |
| free($3.id); |
| |
| } |
| | expr OR expr { |
| E_BINARY($$.id,$1.id,$3.id,"|"); |
| $$.type = promote($1.type,$3.type); |
| if (($1.type == T_DOUBLE) || ($3.type == T_DOUBLE)) { |
| Printf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); |
| FatalError(); |
| } |
| $$.type = T_INT; |
| free($1.id); |
| free($3.id); |
| |
| } |
| | expr XOR expr { |
| E_BINARY($$.id,$1.id,$3.id,"^"); |
| $$.type = promote($1.type,$3.type); |
| if (($1.type == T_DOUBLE) || ($3.type == T_DOUBLE)) { |
| Printf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); |
| FatalError(); |
| } |
| $$.type = T_INT; |
| free($1.id); |
| free($3.id); |
| |
| } |
| | expr LSHIFT expr { |
| E_BINARY($$.id,$1.id,$3.id,"<<"); |
| $$.type = promote($1.type,$3.type); |
| if (($1.type == T_DOUBLE) || ($3.type == T_DOUBLE)) { |
| Printf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); |
| FatalError(); |
| } |
| $$.type = T_INT; |
| free($1.id); |
| free($3.id); |
| |
| } |
| | expr RSHIFT expr { |
| E_BINARY($$.id,$1.id,$3.id,">>"); |
| $$.type = promote($1.type,$3.type); |
| if (($1.type == T_DOUBLE) || ($3.type == T_DOUBLE)) { |
| Printf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); |
| FatalError(); |
| } |
| $$.type = T_INT; |
| free($1.id); |
| free($3.id); |
| |
| } |
| | MINUS expr %prec UMINUS { |
| $$.id = (char *) malloc(strlen($2.id)+2); |
| sprintf($$.id,"-%s",$2.id); |
| $$.type = $2.type; |
| free($2.id); |
| |
| } |
| | NOT expr { |
| $$.id = (char *) malloc(strlen($2.id)+2); |
| sprintf($$.id,"~%s",$2.id); |
| if ($2.type == T_DOUBLE) { |
| Printf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); |
| FatalError(); |
| } |
| $$.type = $2.type; |
| free($2.id); |
| } |
| | LPAREN expr RPAREN { |
| $$.id = (char *) malloc(strlen($2.id)+3); |
| sprintf($$.id,"(%s)", $2.id); |
| $$.type = $2.type; |
| free($2.id); |
| } |
| ; |
| /****************************************************************/ |
| /* C++ Support */ |
| /****************************************************************/ |
| |
| cpp : cpp_class { } |
| | cpp_other {} |
| ; |
| |
| cpp_class : |
| |
| /* A class/struct/union definition */ |
| extern cpptype ID inherit LBRACE { |
| char *iname; |
| init_language(); |
| SwigType_new_scope(); |
| |
| sprintf(temp_name,"CPP_CLASS:%s\n",$3); |
| if (add_symbol(temp_name)) { |
| Printf(stderr,"%s : Line %d. Error. %s %s is multiply defined.\n", input_file, line_number, $2, $3); |
| FatalError(); |
| } |
| if ((!CPlusPlus) && (strcmp($2,"class") == 0)) |
| Printf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); |
| |
| iname = make_name($3); |
| if (iname == $3) |
| cplus_open_class($3, 0, $2); |
| else |
| cplus_open_class($3, iname, $2); |
| if (strcmp($2,"class") == 0) |
| cplus_mode = CPLUS_PRIVATE; |
| else |
| cplus_mode = CPLUS_PUBLIC; |
| scanner_clear_start(); |
| nested_list = 0; |
| // Merge in scope from base classes |
| cplus_inherit_scope($4.count,$4.names); |
| } cpp_members RBRACE { |
| if ($4.names) { |
| if (strcmp($2,"union") != 0) |
| cplus_inherit($4.count, $4.names); |
| else { |
| Printf(stderr,"%s : Line %d. Inheritance not allowed for unions.\n",input_file, line_number); |
| FatalError(); |
| } |
| } |
| // Clean up the inheritance list |
| if ($4.names) { |
| int j; |
| for (j = 0; j < $4.count; j++) { |
| if ($4.names[j]) free($4.names[j]); |
| } |
| free($4.names); |
| } |
| |
| // Dumped nested declarations (if applicable) |
| dump_nested($3); |
| |
| // Save and collapse current scope |
| SwigType_set_scope_name($3); |
| cplus_register_scope(SwigType_pop_scope()); |
| |
| cplus_class_close((char *) 0); |
| cplus_mode = CPLUS_PUBLIC; |
| } |
| |
| /* Class with a typedef */ |
| |
| | TYPEDEF cpptype ID inherit LBRACE { |
| char *iname; |
| init_language(); |
| SwigType_new_scope(); |
| |
| sprintf(temp_name,"CPP_CLASS:%s\n",$3); |
| if (add_symbol(temp_name)) { |
| Printf(stderr,"%s : Line %d. Error. %s %s is multiply defined.\n", input_file, line_number, $2, $3); |
| FatalError(); |
| } |
| if ((!CPlusPlus) && (strcmp($2,"class") == 0)) |
| Printf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); |
| |
| iname = make_name($3); |
| if ($3 == iname) |
| cplus_open_class($3, 0, $2); |
| else |
| cplus_open_class($3, iname, $2); |
| if (strcmp($2,"class") == 0) |
| cplus_mode = CPLUS_PRIVATE; |
| else |
| cplus_mode = CPLUS_PUBLIC; |
| scanner_clear_start(); |
| nested_list = 0; |
| |
| // Merge in scope from base classes |
| cplus_inherit_scope($4.count,$4.names); |
| |
| } cpp_members RBRACE declaration { |
| if ($4.names) { |
| if (strcmp($2,"union") != 0) |
| cplus_inherit($4.count, $4.names); |
| else { |
| Printf(stderr,"%s : Line %d. Inheritance not allowed for unions.\n",input_file, line_number); |
| FatalError(); |
| } |
| } |
| // Create a datatype for correctly processing the typedef |
| Active_typedef = NewStringf("%s %s", $2, $3); |
| // Clean up the inheritance list |
| if ($4.names) { |
| int j; |
| for (j = 0; j < $4.count; j++) { |
| if ($4.names[j]) free($4.names[j]); |
| } |
| free($4.names); |
| } |
| |
| if ($9.is_pointer > 0) { |
| Printf(stderr,"%s : Line %d. typedef struct { } *id not supported properly. Winging it...\n", input_file, line_number); |
| |
| } |
| // Create dump nested class code |
| if ($9.is_pointer > 0) { |
| dump_nested($3); |
| } else { |
| dump_nested($9.id); |
| } |
| |
| // Collapse any datatypes created in the the class |
| |
| SwigType_set_scope_name($3); |
| cplus_register_scope(SwigType_pop_scope()); |
| if ($9.is_pointer > 0) { |
| cplus_class_close($3); |
| } else { |
| cplus_class_close($9.id); |
| } |
| // Create a typedef in global scope |
| if ($9.is_pointer == 0) { |
| SwigType_typedef(Active_typedef,$9.id); |
| lang->add_typedef(Active_typedef,$9.id); |
| } else { |
| SwigType *t = Copy(Active_typedef); |
| add_pointers(t,$9.is_pointer); |
| SwigType_typedef(t,$9.id); |
| lang->add_typedef(t,$9.id); |
| cplus_register_type($9.id); |
| Delete(t); |
| } |
| cplus_mode = CPLUS_PUBLIC; |
| } typedeflist { }; |
| |
| /* An unnamed struct with a typedef */ |
| |
| | TYPEDEF cpptype LBRACE { |
| char *iname; |
| init_language(); |
| SwigType_new_scope(); |
| if ((!CPlusPlus) && (strcmp($2,"class") == 0)) |
| Printf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); |
| |
| iname = make_name((char*)""); |
| if (strlen(iname)) |
| cplus_open_class((char *)"", iname, $2); |
| else |
| cplus_open_class((char *) "",0,$2); |
| if (strcmp($2,"class") == 0) |
| cplus_mode = CPLUS_PRIVATE; |
| else |
| cplus_mode = CPLUS_PUBLIC; |
| scanner_clear_start(); |
| nested_list = 0; |
| } cpp_members RBRACE declaration { |
| if ($7.is_pointer > 0) { |
| Printf(stderr,"%s : Line %d. typedef %s {} *%s not supported correctly. Will be ignored.\n", input_file, line_number, $2, $7.id); |
| cplus_abort(); |
| } else { |
| sprintf(temp_name,"CPP_CLASS:%s\n",$7.id); |
| if (add_symbol(temp_name)) { |
| Printf(stderr,"%s : Line %d. Error. %s %s is multiply defined.\n", input_file, line_number, $2, $7.id); |
| FatalError(); |
| } |
| } |
| // Create a datatype for correctly processing the typedef |
| Active_typedef = NewString($7.id); |
| |
| // Dump nested classes |
| if ($7.is_pointer == 0) |
| dump_nested($7.id); |
| |
| // Go back to previous scope |
| |
| cplus_register_scope(SwigType_pop_scope()); |
| if ($7.is_pointer == 0) |
| cplus_class_close($7.id); |
| cplus_mode = CPLUS_PUBLIC; |
| } typedeflist { } |
| ; |
| |
| cpp_other :/* A dummy class name */ |
| |
| extern cpptype ID SEMI { |
| char *iname; |
| init_language(); |
| iname = make_name($3); |
| lang->cpp_class_decl($3,iname,$2); |
| } |
| |
| /* A static C++ member function (declared out of scope) */ |
| |
| | extern type declaration DCOLON ID LPAREN parms RPAREN SEMI { |
| init_language(); |
| if (!CPlusPlus) |
| Printf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); |
| |
| add_pointers($2,$3.is_pointer); |
| if ($3.is_reference) SwigType_add_reference($2); |
| // Fix up the function name |
| sprintf(temp_name,"%s::%s",$3.id,$5); |
| if (!Rename_true) { |
| Rename_true = 1; |
| sprintf(yy_rename,"%s_%s",$3.id,$5); |
| } |
| create_function($1, temp_name, $2, $7); |
| Delete($2); |
| Delete($7); |
| } |
| |
| /* A static C++ member data */ |
| | extern type declaration DCOLON ID SEMI { |
| init_language(); |
| if (!CPlusPlus) |
| Printf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); |
| |
| add_pointers($2,$3.is_pointer); |
| // Fix up the function name |
| sprintf(temp_name,"%s::%s",$3.id,$5); |
| if (!Rename_true) { |
| Rename_true = 1; |
| sprintf(yy_rename,"%s_%s",$3.id,$5); |
| } |
| create_variable($1,temp_name, $2); |
| Delete($2); |
| } |
| |
| /* Operator overloading catch */ |
| |
| | extern type declaration DCOLON OPERATOR { |
| Printf(stderr,"%s : Line %d. Operator overloading not supported (ignored).\n", input_file, line_number); |
| skip_decl(); |
| Delete($2); |
| } |
| |
| |
| /* Template catch */ |
| | TEMPLATE { |
| Printf(stderr,"%s : Line %d. Templates not currently supported (ignored).\n", |
| input_file, line_number); |
| skip_decl(); |
| } |
| |
| /* %addmethods directive used outside of a class definition */ |
| |
| | ADDMETHODS ID LBRACE { |
| cplus_mode = CPLUS_PUBLIC; |
| cplus_set_class($2); |
| scanner_clear_start(); |
| AddMethods = 1; |
| } added_members RBRACE { |
| cplus_unset_class(); |
| AddMethods = 0; |
| } |
| ; |
| |
| added_members : cpp_member cpp_members { } |
| | objc_method objc_methods { } |
| | empty { } |
| ; |
| |
| cpp_members : cpp_member cpp_members {} |
| | ADDMETHODS LBRACE { |
| AddMethods = 1; |
| } cpp_members RBRACE { |
| AddMethods = 0; |
| } cpp_members { } |
| | error { |
| skip_decl(); |
| { |
| static int last_error_line = -1; |
| if (last_error_line != line_number) { |
| Printf(stderr,"%s : Line %d. Syntax error in input.\n", input_file, line_number); |
| FatalError(); |
| last_error_line = line_number; |
| } |
| } |
| } cpp_members { } |
| | empty { } |
| ; |
| |
| cpp_member : type declaration LPAREN parms RPAREN cpp_end { |
| char *iname; |
| init_language(); |
| if (cplus_mode == CPLUS_PUBLIC) { |
| add_pointers($1,$2.is_pointer); |
| if ($2.is_reference) SwigType_add_reference($1); |
| iname = make_name($2.id); |
| if (iname == $2.id) iname = 0; |
| cplus_member_func($2.id, iname, $1,$4,0); |
| } |
| scanner_clear_start(); |
| Delete($1); |
| Delete($4); |
| } |
| |
| /* Virtual member function */ |
| |
| | VIRTUAL type declaration LPAREN parms RPAREN cpp_vend { |
| char *iname; |
| init_language(); |
| if (cplus_mode == CPLUS_PUBLIC) { |
| add_pointers($2,$3.is_pointer); |
| if ($3.is_reference) SwigType_add_reference($2); |
| iname = make_name($3.id); |
| if (iname == $3.id) iname = 0; |
| cplus_member_func($3.id,iname,$2,$5,$7 ? PURE_VIRTUAL : PLAIN_VIRTUAL); |
| } |
| scanner_clear_start(); |
| Delete($2); |
| Delete($5); |
| } |
| |
| /* Possibly a constructor */ |
| | ID LPAREN parms RPAREN ctor_end { |
| char *iname; |
| init_language(); |
| if (cplus_mode == CPLUS_PUBLIC) { |
| iname = make_name($1); |
| if (iname == $1) iname = 0; |
| cplus_constructor($1,iname, $3); |
| } |
| scanner_clear_start(); |
| Delete($3); |
| } |
| |
| /* A destructor (hopefully) */ |
| |
| | NOT ID LPAREN parms RPAREN cpp_end { |
| char *iname; |
| init_language(); |
| if (cplus_mode == CPLUS_PUBLIC) { |
| iname = make_name($2); |
| if (iname == $2) iname = 0; |
| cplus_destructor($2,iname); |
| } |
| scanner_clear_start(); |
| Delete($4); |
| } |
| |
| /* A virtual destructor */ |
| |
| | VIRTUAL NOT ID LPAREN RPAREN cpp_end { |
| char *iname; |
| init_language(); |
| if (cplus_mode == CPLUS_PUBLIC) { |
| iname = make_name($3); |
| if (iname == $3) iname = 0; |
| cplus_destructor($3,iname); |
| } |
| scanner_clear_start(); |
| } |
| |
| /* Member data */ |
| |
| | type declaration def_args { |
| char *iname; |
| init_language(); |
| if (cplus_mode == CPLUS_PUBLIC) { |
| if (Active_type) Delete(Active_type); |
| Active_type = Copy($1); |
| add_pointers($1,$2.is_pointer); |
| if ($2.is_reference) SwigType_add_reference($1); |
| if (SwigType_isconst($1)) { |
| iname = make_name($2.id); |
| if (iname == $2.id) iname = 0; |
| my_cplus_declare_const($2.id,iname, $1, $3.id); |
| } else { |
| iname = make_name($2.id); |
| if (iname == $2.id) iname = 0; |
| cplus_variable($2.id,iname,$1); |
| } |
| } |
| scanner_clear_start(); |
| Delete($1); |
| } cpp_tail { } |
| |
| | type declaration array def_args { |
| char *iname; |
| init_language(); |
| if (cplus_mode == CPLUS_PUBLIC) { |
| if (Active_type) Delete(Active_type); |
| Active_type = Copy($1); |
| add_pointers($1, $2.is_pointer); |
| if ($2.is_reference) SwigType_add_reference($1); |
| SwigType_push($1,ArrayString); |
| iname = make_name($2.id); |
| if (iname == $2.id) iname = 0; |
| cplus_variable($2.id,iname,$1); |
| } |
| scanner_clear_start(); |
| Delete($1); |
| } |
| |
| |
| /* Static Member data */ |
| |
| | STATIC type declaration { |
| char *iname; |
| init_language(); |
| if (cplus_mode == CPLUS_PUBLIC) { |
| add_pointers($2,$3.is_pointer); |
| iname = make_name($3.id); |
| if (iname == $3.id) iname = 0; |
| cplus_static_var($3.id,iname,$2); |
| if (Active_type) Delete(Active_type); |
| Active_type = Copy($2); |
| } |
| scanner_clear_start(); |
| Delete($2); |
| } cpp_tail { } |
| |
| /* Static member function */ |
| |
| | STATIC type declaration LPAREN parms RPAREN cpp_end { |
| char *iname; |
| add_pointers($2,$3.is_pointer); |
| if ($3.is_reference) SwigType_add_reference($2); |
| if (cplus_mode == CPLUS_PUBLIC) { |
| iname = make_name($3.id); |
| if (iname == $3.id) iname = 0; |
| cplus_static_func($3.id, iname, $2, $5); |
| } |
| scanner_clear_start(); |
| Delete($2); |
| Delete($5); |
| } |
| /* Turn on public: mode */ |
| |
| | PUBLIC COLON { |
| cplus_mode = CPLUS_PUBLIC; |
| scanner_clear_start(); |
| } |
| |
| /* Turn on private: mode */ |
| |
| | PRIVATE COLON { |
| cplus_mode = CPLUS_PRIVATE; |
| scanner_clear_start(); |
| } |
| |
| /* Turn on protected mode */ |
| |
| | PROTECTED COLON { |
| cplus_mode = CPLUS_PROTECTED; |
| scanner_clear_start(); |
| } |
| |
| /* This is the new style rename */ |
| |
| | NAME LPAREN ID RPAREN { |
| strcpy(yy_rename,$3); |
| Rename_true = 1; |
| } |
| |
| /* New mode */ |
| | NEW { |
| NewObject = 1; |
| } cpp_member { |
| NewObject = 0; |
| } |
| |
| /* C++ Enum */ |
| | ENUM ename LBRACE {scanner_clear_start();} cpp_enumlist RBRACE SEMI { |
| |
| // if ename was supplied. Install it as a new integer datatype. |
| init_language(); |
| if (cplus_mode == CPLUS_PUBLIC) { |
| if ($2) { |
| cplus_register_type($2); |
| if (temp_type) Delete(temp_type); |
| /* temp_type = NewSwigType(T_INT); */ |
| temp_type = NewStringf("enum %s",$2); |
| SwigType_typedef(temp_type,$2); |
| lang->add_typedef(temp_type,$2); |
| } |
| } |
| } |
| | READONLY { |
| Status = Status | STAT_READONLY; |
| scanner_clear_start(); |
| } |
| | READWRITE { |
| Status = Status & ~(STAT_READONLY); |
| scanner_clear_start(); |
| } |
| /* A friend : Illegal */ |
| | FRIEND { |
| Printf(stderr,"%s : Line %d. Friends are not allowed--members only! (ignored)\n", input_file, line_number); |
| skip_decl(); |
| scanner_clear_start(); |
| } |
| |
| /* An operator: Illegal */ |
| | type type_extra OPERATOR { |
| Printf(stderr,"%s : Line %d. Operator overloading not supported (ignored).\n", input_file, line_number); |
| skip_decl(); |
| scanner_clear_start(); |
| } |
| |
| /* A typedef inside a class */ |
| | typedef_decl { } |
| |
| /* Pragma directive */ |
| |
| | cpp_pragma { |
| scanner_clear_start(); |
| } |
| |
| |
| cpp_pragma : PRAGMA ID stylearg { |
| if (!WrapExtern) { } |
| } |
| | PRAGMA LPAREN ID RPAREN ID stylearg { |
| if (!WrapExtern) |
| cplus_add_pragma($3,$5,$6); |
| } |
| ; |
| |
| |
| |
| /* ---------------------------------------------------------------------- |
| Nested structure. This is a big ugly "hack". If we encounter |
| a nested structure, we're going to grab the text of its definition and |
| feed it back into the scanner. In the meantime, we need to grab |
| variable declaration information and generate the associated wrapper |
| code later. Yikes! |
| |
| This really only works in a limited sense. Since we use the |
| code attached to the nested class to generate both C/C++ code, |
| it can't have any SWIG directives in it. It also needs to be parsable |
| by SWIG or this whole thing is going to puke. |
| ---------------------------------------------------------------------- */ |
| |
| /* A struct sname { } id; declaration */ |
| |
| | cpptype ID LBRACE { start_line = line_number; skip_brace(); |
| } nested_decl SEMI { |
| |
| if (cplus_mode == CPLUS_PUBLIC) { |
| cplus_register_type($2); |
| if ($5.id) { |
| if (strcmp($1,"class") == 0) { |
| Printf(stderr,"%s : Line %d. Warning. Nested classes not currently supported (ignored).\n", input_file, line_number); |
| /* Generate some code for a new class */ |
| } else { |
| Nested *n = (Nested *) malloc(sizeof(Nested)); |
| n->code = NewString(""); |
| Printv(n->code, "typedef ", $1, " ", |
| Char(CCode), " $classname_", $5.id, ";\n", 0); |
| n->name = Swig_copy_string($5.id); |
| n->line = start_line; |
| n->type = NewString(""); |
| add_pointers(n->type, $5.is_pointer); |
| if ($5.is_reference) SwigType_add_reference(n->type); |
| n->next = 0; |
| add_nested(n); |
| } |
| } |
| } |
| } |
| /* An unnamed structure definition */ |
| | cpptype LBRACE { start_line = line_number; skip_brace(); |
| } declaration SEMI { |
| if (cplus_mode == CPLUS_PUBLIC) { |
| if (strcmp($1,"class") == 0) { |
| Printf(stderr,"%s : Line %d. Warning. Nested classes not currently supported (ignored)\n", input_file, line_number); |
| /* Generate some code for a new class */ |
| } else { |
| /* Generate some code for a new class */ |
| |
| Nested *n = (Nested *) malloc(sizeof(Nested)); |
| n->code = NewString(""); |
| Printv(n->code, "typedef ", $1, " " , |
| Char(CCode), " $classname_", $4.id, ";\n",0); |
| n->name = Swig_copy_string($4.id); |
| n->line = start_line; |
| n->type = NewString(""); |
| add_pointers(n->type, $4.is_pointer); |
| if ($4.is_reference) SwigType_add_reference(n->type); |
| n->next = 0; |
| add_nested(n); |
| |
| } |
| } |
| } |
| /* An empty class declaration */ |
| | cpptype ID SEMI { |
| if (cplus_mode == CPLUS_PUBLIC) { |
| cplus_register_type($2); |
| } |
| } |
| |
| /* Other miscellaneous errors */ |
| | type stars LPAREN { |
| skip_decl(); |
| Printf(stderr,"%s : Line %d. Function pointers not currently supported (ignored).\n", input_file, line_number); |
| |
| } |
| | strict_type LPAREN STAR { |
| skip_decl(); |
| Printf(stderr,"%s : Line %d. Function pointers not currently supported (ignored).\n", input_file, line_number); |
| |
| } |
| | ID LPAREN STAR { |
| skip_decl(); |
| Printf(stderr,"%s : Line %d. Function pointers not currently supported (ignored).\n", input_file, line_number); |
| |
| } |
| | doc_enable { } |
| | SEMI { } |
| ; |
| |
| nested_decl : declaration { $$ = $1;} |
| | empty { $$.id = 0; } |
| ; |
| |
| type_extra : stars {} |
| | AND {} |
| | empty {} |
| ; |
| |
| cpp_tail : SEMI { } |
| | COMMA declaration def_args { |
| init_language(); |
| if (cplus_mode == CPLUS_PUBLIC) { |
| temp_typeptr = Copy(Active_type); |
| add_pointers(temp_typeptr, $2.is_pointer); |
| cplus_variable($2.id,(char *) 0,temp_typeptr); |
| Delete(temp_typeptr); |
| } |
| scanner_clear_start(); |
| } cpp_tail { } |
| | COMMA declaration array def_args { |
| init_language(); |
| if (cplus_mode == CPLUS_PUBLIC) { |
| temp_typeptr = Copy(Active_type); |
| add_pointers(temp_typeptr, $2.is_pointer); |
| cplus_variable($2.id,(char *) 0,temp_typeptr); |
| Delete(temp_typeptr); |
| } |
| scanner_clear_start(); |
| } cpp_tail { } |
| ; |
| |
| cpp_end : cpp_const SEMI { |
| Clear(CCode); |
| } |
| | cpp_const LBRACE { skip_brace(); } |
| ; |
| |
| cpp_vend : cpp_const SEMI { Clear(CCode); $$ = 0; } |
| | cpp_const EQUAL definetype SEMI { Clear(CCode); $$ = 1; } |
| | cpp_const LBRACE { skip_brace(); $$ = 0; } |
| ; |
| |
| cpp_enumlist : cpp_enumlist COMMA cpp_edecl {} |
| | cpp_edecl {} |
| ; |
| |
| cpp_edecl : ID { |
| if (cplus_mode == CPLUS_PUBLIC) { |
| temp_typeptr = NewSwigType(T_INT); |
| my_cplus_declare_const($1, (char *) 0, temp_typeptr, (char *) 0); |
| Delete(temp_typeptr); |
| scanner_clear_start(); |
| } |
| } |
| | ID EQUAL etype { |
| if (cplus_mode == CPLUS_PUBLIC) { |
| temp_typeptr = NewSwigType(T_INT); |
| my_cplus_declare_const($1,(char *) 0, temp_typeptr,(char *) 0); |
| // OLD : Bug with value my_cplus_declare_const($1,(char *) 0, temp_typeptr,$3.id); |
| Delete(temp_typeptr); |
| scanner_clear_start(); |
| } |
| } |
| | NAME LPAREN ID RPAREN ID { |
| if (cplus_mode == CPLUS_PUBLIC) { |
| temp_typeptr = NewSwigType(T_INT); |
| my_cplus_declare_const($5, $3, temp_typeptr, (char *) 0); |
| Delete(temp_typeptr); |
| scanner_clear_start(); |
| } |
| } |
| | NAME LPAREN ID RPAREN ID EQUAL etype { |
| if (cplus_mode == CPLUS_PUBLIC) { |
| temp_typeptr = NewSwigType(T_INT); |
| my_cplus_declare_const($5,$3, temp_typeptr, (char *) 0); |
| Delete(temp_typeptr); |
| scanner_clear_start(); |
| } |
| } |
| | empty { } |
| ; |
| |
| inherit : COLON base_list { |
| $$ = $2; |
| } |
| | empty { |
| $$.names = (char **) 0; |
| $$.count = 0; |
| } |
| ; |
| |
| base_list : base_specifier { |
| int i; |
| $$.names = (char **) malloc(NI_NAMES*sizeof(char *)); |
| $$.count = 0; |
| for (i = 0; i < NI_NAMES; i++){ |
| $$.names[i] = (char *) 0; |
| } |
| if ($1) { |
| $$.names[$$.count] = Swig_copy_string($1); |
| $$.count++; |
| } |
| } |
| |
| | base_list COMMA base_specifier { |
| $$ = $1; |
| if ($3) { |
| $$.names[$$.count] = Swig_copy_string($3); |
| $$.count++; |
| } |
| } |
| ; |
| |
| base_specifier : ID { |
| Printf(stderr,"%s : Line %d. No access specifier given for base class %s (ignored).\n", |
| input_file,line_number,$1); |
| $$ = (char *) 0; |
| } |
| | VIRTUAL ID { |
| Printf(stderr,"%s : Line %d. No access specifier given for base class %s (ignored).\n", |
| input_file,line_number,$2); |
| $$ = (char *) 0; |
| } |
| | VIRTUAL access_specifier ID { |
| if (strcmp($2,"public") == 0) { |
| $$ = $3; |
| } else { |
| Printf(stderr,"%s : Line %d. %s inheritance not supported (ignored).\n", |
| input_file,line_number,$2); |
| $$ = (char *) 0; |
| } |
| } |
| | access_specifier ID { |
| if (strcmp($1,"public") == 0) { |
| $$ = $2; |
| } else { |
| Printf(stderr,"%s : Line %d. %s inheritance not supported (ignored).\n", |
| input_file,line_number,$1); |
| $$ = (char *) 0; |
| } |
| } |
| | access_specifier VIRTUAL ID { |
| if (strcmp($1,"public") == 0) { |
| $$ = $3; |
| } else { |
| Printf(stderr,"%s : Line %d. %s inheritance not supported (ignored).\n", |
| input_file,line_number,$1); |
| $$ = (char *) 0; |
| } |
| } |
| ; |
| |
| access_specifier : PUBLIC { $$ = (char*)"public"; } |
| | PRIVATE { $$ = (char*)"private"; } |
| | PROTECTED { $$ = (char*)"protected"; } |
| ; |
| |
| |
| cpptype : CLASS { $$ = (char*)"class"; } |
| | STRUCT { $$ = (char*)"struct"; } |
| | UNION {$$ = (char*)"union"; } |
| ; |
| |
| cpp_const : CONST {} |
| | THROW LPAREN parms RPAREN { Delete($3);} |
| | CONST THROW LPAREN parms RPAREN { Delete($4);} |
| | empty {} |
| ; |
| |
| /* Constructor initializer */ |
| |
| ctor_end : cpp_const ctor_initializer SEMI { |
| Clear(CCode); |
| } |
| | cpp_const ctor_initializer LBRACE { skip_brace(); } |
| ; |
| |
| ctor_initializer : COLON mem_initializer_list {} |
| | empty {} |
| ; |
| |
| mem_initializer_list : mem_initializer { } |
| | mem_initializer_list COMMA mem_initializer { } |
| ; |
| |
| mem_initializer : ID LPAREN expr_list RPAREN { } |
| | ID LPAREN RPAREN { } |
| ; |
| |
| expr_list : expr { } |
| | expr_list COMMA expr { } |
| ; |
| |
| |
| /**************************************************************/ |
| /* Objective-C parsing */ |
| /**************************************************************/ |
| |
| objective_c : OC_INTERFACE ID objc_inherit { |
| ObjCClass = 1; |
| init_language(); |
| cplus_mode = CPLUS_PROTECTED; |
| sprintf(temp_name,"CPP_CLASS:%s\n",$2); |
| if (add_symbol(temp_name)) { |
| Printf(stderr,"%s : Line %d. @interface %s is multiple defined.\n", |
| input_file,line_number,$2); |
| FatalError(); |
| } |
| scanner_clear_start(); |
| cplus_open_class($2, (char *) 0, (char*)""); // Open up a new C++ class |
| } LBRACE objc_data RBRACE objc_methods OC_END { |
| if ($3) { |
| char *inames[1]; |
| inames[0] = $3; |
| cplus_inherit(1,inames); |
| } |
| cplus_class_close($2); |
| cplus_mode = CPLUS_PUBLIC; |
| ObjCClass = 0; |
| free($2); |
| free($3); |
| } |
| /* An obj-c category declaration */ |
| | OC_INTERFACE ID LPAREN ID RPAREN objc_protolist { |
| ObjCClass = 1; |
| init_language(); |
| cplus_mode = CPLUS_PROTECTED; |
| cplus_set_class($2); |
| scanner_clear_start(); |
| } objc_methods OC_END { |
| cplus_unset_class(); |
| } |
| | OC_IMPLEMENT { skip_to_end(); } |
| | OC_PROTOCOL { skip_to_end(); } |
| | OC_CLASS ID initlist SEMI { |
| char *iname = make_name($2); |
| init_language(); |
| lang->cpp_class_decl($2,iname,(char*)""); |
| for (int i = 0; i <$3.count; i++) { |
| if ($3.names[i]) { |
| iname = make_name($3.names[i]); |
| lang->cpp_class_decl($3.names[i],iname,(char*)""); |
| free($3.names[i]); |
| } |
| } |
| free($3.names); |
| } |
| ; |
| |
| objc_inherit : COLON ID objc_protolist { $$ = $2;} |
| | objc_protolist empty { $$ = 0; } |
| ; |
| |
| |
| objc_protolist : LESSTHAN { skip_template(); |
| /* CCode.strip(); // Strip whitespace |
| CCode.replace("<","< "); |
| CCode.replace(">"," >"); */ |
| $$ = Char(CCode); |
| } |
| | empty { |
| $$ = (char*)""; |
| } |
| ; |
| |
| objc_data : objc_vars objc_data { } |
| | OC_PUBLIC { |
| cplus_mode = CPLUS_PUBLIC; |
| } objc_data { } |
| | OC_PRIVATE { |
| cplus_mode = CPLUS_PRIVATE; |
| } objc_data { } |
| | OC_PROTECTED { |
| cplus_mode = CPLUS_PROTECTED; |
| } objc_data { } |
| | error { |
| if (!Error) { |
| skip_decl(); |
| { |
| static int last_error_line = -1; |
| if (last_error_line != line_number) { |
| Printf(stderr,"%s : Line %d. Syntax error in input.\n", input_file, line_number); |
| FatalError(); |
| last_error_line = line_number; |
| } |
| Error = 1; |
| } |
| } |
| } objc_data { } |
| | empty { } |
| ; |
| |
| objc_vars : objc_var objc_vartail SEMI { |
| |
| } |
| ; |
| |
| /* An objective-C member variable */ |
| |
| objc_var : type declaration { |
| if (cplus_mode == CPLUS_PUBLIC) { |
| int oldstatus = Status; |
| char *iname; |
| if (Active_type) Delete(Active_type); |
| Active_type = Copy($1); |
| add_pointers($1,$2.is_pointer); |
| if ($2.is_reference) SwigType_add_reference($1); |
| iname = make_name($2.id); |
| if (iname == $2.id) iname = 0; |
| cplus_variable($2.id,iname,$1); |
| Status = oldstatus; |
| } |
| scanner_clear_start(); |
| Delete($1); |
| } |
| | type declaration array { |
| if (cplus_mode == CPLUS_PUBLIC) { |
| int oldstatus = Status; |
| char *iname; |
| if (Active_type) Delete(Active_type); |
| Active_type = Copy($1); |
| add_pointers($1,$2.is_pointer); |
| if ($2.is_reference) SwigType_add_reference($1); |
| SwigType_push($1,ArrayString); |
| iname = make_name($2.id); |
| if (iname == $2.id) iname = 0; |
| cplus_variable($2.id,iname,$1); |
| Status = oldstatus; |
| } |
| scanner_clear_start(); |
| Delete($1); |
| } |
| | NAME LPAREN ID RPAREN { |
| strcpy(yy_rename,$3); |
| Rename_true = 1; |
| } objc_var { }; |
| |
| objc_vartail : COMMA declaration objc_vartail { |
| if (cplus_mode == CPLUS_PUBLIC) { |
| int oldstatus = Status; |
| char *iname; |
| SwigType *t = Copy(Active_type); |
| add_pointers(t,$2.is_pointer); |
| if ($2.is_reference) SwigType_add_reference(t); |
| iname = make_name($2.id); |
| if (iname == $2.id) iname = 0; |
| cplus_variable($2.id,iname,t); |
| Status = oldstatus; |
| Delete(t); |
| } |
| scanner_clear_start(); |
| } |
| | COMMA declaration array objc_vartail { |
| char *iname; |
| if (cplus_mode == CPLUS_PUBLIC) { |
| int oldstatus = Status; |
| SwigType *t = Copy(Active_type); |
| add_pointers(t,$2.is_pointer); |
| if ($2.is_reference) SwigType_add_reference(t); |
| SwigType_push(t,ArrayString); |
| iname = make_name($2.id); |
| if (iname == $2.id) iname = 0; |
| cplus_variable($2.id,iname,t); |
| Status = oldstatus; |
| Delete(t); |
| } |
| scanner_clear_start(); |
| } |
| | empty { } |
| ; |
| |
| objc_methods : objc_method objc_methods { }; |
| | ADDMETHODS LBRACE { |
| AddMethods = 1; |
| } objc_methods RBRACE { |
| AddMethods = 0; |
| } |
| | NAME LPAREN ID RPAREN { |
| strcpy(yy_rename,$3); |
| Rename_true = 1; |
| } objc_methods { } |
| | error { |
| skip_decl(); |
| if (!Error) { |
| { |
| static int last_error_line = -1; |
| if (last_error_line != line_number) { |
| Printf(stderr,"%s : Line %d. Syntax error in input.\n", input_file, line_number); |
| FatalError(); |
| last_error_line = line_number; |
| } |
| Error = 1; |
| } |
| } |
| } objc_methods { } |
| | empty { } |
| ; |
| |
| objc_method : MINUS objc_ret_type ID objc_args objc_end { |
| char *iname; |
| // An objective-C instance function |
| // This is like a C++ member function |
| |
| if (strcmp($3,objc_destruct) == 0) { |
| // This is an objective C destructor |
| cplus_destructor($3,(char *) 0); |
| } else { |
| iname = make_name($3); |
| if (iname == $3) iname = 0; |
| cplus_member_func($3,iname,$2,$4,0); |
| scanner_clear_start(); |
| Delete($2); |
| free($3); |
| Delete($4); |
| } |
| } |
| | PLUS objc_ret_type ID objc_args objc_end { |
| char *iname; |
| // An objective-C class function |
| // This is like a c++ static member function |
| if (strcmp($3,objc_construct) == 0) { |
| // This is an objective C constructor |
| cplus_constructor($3,0,$4); |
| } else { |
| iname = make_name($3); |
| if (iname == $3) iname = 0; |
| cplus_static_func($3,iname,$2,$4); |
| } |
| scanner_clear_start(); |
| Delete($2); |
| free($3); |
| Delete($4); |
| } |
| ; |
| |
| objc_end : SEMI { Clear(CCode); } |
| | LBRACE { skip_brace(); } |
| ; |
| |
| objc_ret_type : LPAREN type RPAREN { |
| $$ = $2; |
| } |
| | LPAREN type stars RPAREN { |
| $$ = $2; |
| add_pointers($$,$3); |
| } |
| | empty { /* Empty type means "id" type */ |
| $$ = NewString("id"); |
| } |
| ; |
| |
| objc_arg_type : LPAREN parm RPAREN { |
| $$ = Copy(Gettype($2)); |
| Delete($2); |
| } |
| | empty { |
| $$ = NewString("id"); |
| } |
| ; |
| |
| objc_args : objc_args objc_separator objc_arg_type ID { |
| Parm *p= NewParm($3,$4); |
| /* p->objc_separator = $2; */ |
| $$ = $1; |
| if (!$$) { |
| $$ = p; |
| } else { |
| Parm *np, *pp; |
| np = $$; |
| while(np) { |
| pp = np; |
| np = Getnext(np); |
| } |
| Setnext(pp,p); |
| } |
| } |
| | empty { |
| $$ = 0; |
| } |
| ; |
| |
| objc_separator : COLON { $$ = Swig_copy_string((char*)":"); } |
| | ID COLON { $$ = (char *) malloc(strlen($1)+2); |
| strcpy($$,$1); |
| strcat($$,":"); |
| free($1); |
| } |
| ; |
| |
| /* Miscellaneous stuff */ |
| |
| /* Documentation style list */ |
| |
| stylelist : ID stylearg styletail { |
| $$ = $3; |
| $$.names[$$.count] = Swig_copy_string($1); |
| $$.values[$$.count] = Swig_copy_string($2); |
| $$.count++; |
| } |
| ; |
| |
| |
| styletail : styletail COMMA ID stylearg { |
| $$ = $1; |
| $$.names[$$.count] = Swig_copy_string($3); |
| $$.values[$$.count] = Swig_copy_string($4); |
| $$.count++; |
| } |
| | empty { |
| $$.names = (char **) malloc(NI_NAMES*sizeof(char *)); |
| $$.values = (char **) malloc(NI_NAMES*sizeof(char *)); |
| $$.count = 0; |
| } |
| ; |
| |
| stylearg : EQUAL NUM_INT { |
| $$ = $2; |
| } |
| | EQUAL STRING { |
| $$ = $2; |
| } |
| | empty { |
| $$ = 0; |
| } |
| ; |
| |
| |
| /* -------------------------------------------------------------- |
| * Type-map parameters |
| * -------------------------------------------------------------- */ |
| |
| tm_method : ID { |
| $$ = $1; |
| } |
| | CONST { |
| $$ = Swig_copy_string((char*)"const"); |
| } |
| ; |
| |
| tm_list : typemap_parm tm_tail { |
| $$ = $1; |
| $$->next = $2; |
| } |
| ; |
| |
| tm_tail : COMMA typemap_parm tm_tail { |
| $$ = $2; |
| $$->next = $3; |
| } |
| | empty { $$ = 0;} |
| ; |
| |
| typemap_parm : type typemap_name { |
| if (InArray) { |
| SwigType_push($1,ArrayString); |
| } |
| $$ = NewTMParm(); |
| $$->p = NewParm($1,$2); |
| $$->args = tm_parm; |
| Delete($1); |
| free($2); |
| } |
| |
| | type stars typemap_name { |
| $$ = NewTMParm(); |
| $$->p = NewParm($1,$3); |
| SwigType *pt = Gettype($$->p); |
| add_pointers(pt,$2); |
| if (InArray) { |
| SwigType_push(pt,ArrayString); |
| } |
| $$->args = tm_parm; |
| Delete($1); |
| free($3); |
| } |
| |
| | type maybestars AND typemap_name { |
| $$ = NewTMParm(); |
| $$->p = NewParm($1,$4); |
| SwigType *pt = Gettype($$->p); |
| add_pointers(pt,$2); |
| SwigType_add_reference(pt); |
| if (!CPlusPlus) { |
| Printf(stderr,"%s : Line %d. Warning. Use of C++ Reference detected. Use the -c++ option.\n", input_file, line_number); |
| } |
| $$->args = tm_parm; |
| Delete($1); |
| free($4); |
| } |
| | type LPAREN stars typemap_name RPAREN LPAREN parms RPAREN { |
| Printf(stderr,"%s : Line %d. Error. Function pointer not allowed (remap with typedef).\n", input_file, line_number); |
| FatalError(); |
| $$ = NewTMParm(); |
| $$->p = NewParm($1,$4); |
| SwigType *pt = Gettype($$->p); |
| DOHList *l = typelist($7); |
| SwigType_add_function(pt,l); |
| add_pointers(pt,$3); |
| $$->args = tm_parm; |
| Delete($1); |
| free($4); |
| Delete($7); |
| } |
| ; |
| |
| typemap_name : ID typemap_args { |
| $$ = $1; |
| InArray = 0; |
| } |
| | ID array { |
| ArrayBackup = Copy(ArrayString); |
| } typemap_args { |
| $$ = $1; |
| InArray = $2; |
| Clear(ArrayString); |
| Append(ArrayString,ArrayBackup); |
| Delete(ArrayBackup); |
| } |
| | array { |
| ArrayBackup = Copy(ArrayString); |
| } typemap_args { |
| $$ = (char *) malloc(1); |
| $$[0] = 0; |
| InArray = $1; |
| Clear(ArrayString); |
| Append(ArrayString,ArrayBackup); |
| Delete(ArrayBackup); |
| } |
| | typemap_args { $$ = (char *) malloc(1); |
| $$[0] = 0; |
| InArray = 0; |
| } |
| ; |
| |
| typemap_args : LPAREN parms RPAREN { |
| tm_parm = $2; |
| } |
| | empty { |
| tm_parm = 0; |
| } |
| ; |
| |
| |
| /* Parsing of expressions, but only for throw away code */ |
| |
| /* Might need someday |
| dummyexpr : NUM_INT { } |
| | NUM_FLOAT { } |
| | NUM_UNSIGNED { } |
| | NUM_LONG { } |
| | NUM_ULONG { } |
| | SIZEOF LPAREN type RPAREN { } |
| | ID { } |
| | dummyexpr PLUS dummyexpr { } |
| | dummyexpr MINUS dummyexpr { } |
| | dummyexpr STAR dummyexpr { } |
| | dummyexpr SLASH dummyexpr { } |
| | dummyexpr AND dummyexpr { } |
| | dummyexpr OR dummyexpr { } |
| | dummyexpr XOR dummyexpr { } |
| | dummyexpr LSHIFT dummyexpr { } |
| | dummyexpr RSHIFT dummyexpr { } |
| | MINUS dummyexpr %prec UMINUS { } |
| | NOT dummyexpr { } |
| | LPAREN dummyexpr RPAREN { } |
| ; |
| |
| */ |
| |
| |
| empty : ; |
| |
| %% |
| |
| void error_recover() { |
| int c; |
| c = yylex(); |
| while ((c > 0) && (c != SEMI)) |
| c = yylex(); |
| } |
| |
| /* Called by the parser (yyparse) when an error is found.*/ |
| void yyerror (char *) { |
| // Printf(stderr,"%s : Line %d. Syntax error.\n", input_file, line_number); |
| // error_recover(); |
| } |
| |
| |
| |
| |
| |