📄 parser.y
字号:
struct: TK_STRUCT TK_NAME { if (notSkipping()) { classDef *cd; cd = newClass(currentSpec,class_iface,text2scopedName($2)); pushScope(cd); sectionFlags = SECT_IS_PUBLIC; } } optflags '{' classbody '}' ';' { if (notSkipping()) { finishClass(currentSpec, currentModule, currentScope(), &$4); popScope(); } } ;classtmpl: template class { if (currentSpec->genc) yyerror("Class templates not allowed in a C module"); if (notSkipping()) { classTmplDef *tcd; /* * Make sure there is room for the extra class * name argument. */ if ($1.nrArgs == MAX_NR_ARGS) yyerror("Internal error - increase the value of MAX_NR_ARGS"); tcd = sipMalloc(sizeof (classTmplDef)); tcd->sig = $1; tcd->cd = $2; tcd->next = currentSpec->classtemplates; currentSpec->classtemplates = tcd; } } ;template: TK_TEMPLATE '<' cpptypelist '>' { $$ = $3; } ;class: TK_CLASS scopedname { if (currentSpec -> genc) yyerror("Class definition not allowed in a C module"); if (notSkipping()) { classDef *cd; cd = newClass(currentSpec, class_iface, scopeScopedName($2)); pushScope(cd); sectionFlags = SECT_IS_PRIVATE; } } superclasses optflags optclassbody ';' { if (notSkipping()) { classDef *cd = currentScope(); /* * See if the class was defined or just * declared. */ if ($6) { if ($2->next != NULL) yyerror("A scoped name cannot be given in a class definition"); } else if (cd->supers != NULL) yyerror("Class has super-classes but no definition"); else setIsOpaque(cd); finishClass(currentSpec, currentModule, cd, &$5); popScope(); /* * Check that external classes have only been * declared at the global scope. */ if (isExternal(cd) && currentScope() != NULL) yyerror("External classes can only be declared in the global scope"); $$ = cd; } } ;superclasses: | ':' superlist ;superlist: superclass | superlist ',' superclass ;superclass: scopedname { if (notSkipping()) { classDef *cd, *super; cd = currentScope(); super = findClass(currentSpec,class_iface,$1); appendToClassList(&cd -> supers,super); addToUsedList(&cd->iff->used, super->iff); } } ;optclassbody: { $$ = FALSE; } | '{' classbody '}' { $$ = TRUE; } ;classbody: classline | classbody classline ;classline: ifstart | ifend | namespace | struct | class | exception | typedef | enum | typecode { if (notSkipping()) appendCodeBlock(¤tScope() -> cppcode,$1); } | typehdrcode { if (notSkipping()) appendCodeBlock(¤tScope() -> hdrcode,$1); } | travcode { if (currentScope()->travcode != NULL) yyerror("%GCTraverseCode already given for class"); if (notSkipping()) currentScope()->travcode = $1; } | clearcode { if (currentScope()->clearcode != NULL) yyerror("%GCClearCode already given for class"); if (notSkipping()) currentScope()->clearcode = $1; } | readbufcode { if (currentScope()->readbufcode != NULL) yyerror("%BIGetReadBufferCode already given for class"); if (notSkipping()) currentScope()->readbufcode = $1; } | writebufcode { if (currentScope()->writebufcode != NULL) yyerror("%BIGetWriteBufferCode already given for class"); if (notSkipping()) currentScope()->writebufcode = $1; } | segcountcode { if (currentScope()->segcountcode != NULL) yyerror("%BIGetSegCountCode already given for class"); if (notSkipping()) currentScope()->segcountcode = $1; } | charbufcode { if (currentScope()->charbufcode != NULL) yyerror("%BIGetCharBufferCode already given for class"); if (notSkipping()) currentScope()->charbufcode = $1; } | ctor | dtor | varmember | TK_TOSUBCLASS codeblock { if (notSkipping()) { classDef *cd = currentScope(); if (cd -> convtosubcode != NULL) yyerror("Class has more than one %ConvertToSubClassCode directive"); cd -> convtosubcode = $2; } } | TK_TOTYPE codeblock { if (notSkipping()) { classDef *cd = currentScope(); if (cd -> convtocode != NULL) yyerror("Class has more than one %ConvertToTypeCode directive"); cd -> convtocode = $2; } } | TK_PUBLIC optslot ':' { if (currentSpec -> genc) yyerror("public section not allowed in a C module"); if (notSkipping()) sectionFlags = SECT_IS_PUBLIC | $2; } | TK_PROTECTED optslot ':' { if (currentSpec -> genc) yyerror("protected section not allowed in a C module"); if (notSkipping()) sectionFlags = SECT_IS_PROT | $2; } | TK_PRIVATE optslot ':' { if (currentSpec -> genc) yyerror("private section not allowed in a C module"); if (notSkipping()) sectionFlags = SECT_IS_PRIVATE | $2; } | TK_SIGNALS ':' { if (currentSpec -> genc) yyerror("signals section not allowed in a C module"); if (notSkipping()) sectionFlags = SECT_IS_SIGNAL; } ;optslot: { $$ = 0; } | TK_SLOTS { $$ = SECT_IS_SLOT; } ;dtor: optvirtual '~' TK_NAME '(' ')' optexceptions optflags ';' methodcode virtualcatchercode { /* Note that we allow non-virtual dtors in C modules. */ if (notSkipping()) { classDef *cd = currentScope(); if (strcmp(classBaseName(cd),$3) != 0) yyerror("Destructor doesn't have the same name as its class"); if (isDtor(cd)) yyerror("Destructor has already been defined"); if (currentSpec -> genc && $9 == NULL) yyerror("Destructor in C modules must include %MethodCode"); cd -> dealloccode = $9; cd -> dtorcode = $10; cd -> dtorexceptions = $6; cd -> classflags |= sectionFlags; /* * The class has a shadow if we have a virtual * dtor or some dtor code. */ if ($1 || $10 != NULL) { if (currentSpec -> genc) yyerror("Virtual destructor or %VirtualCatcherCode not allowed in a C module"); setHasShadow(cd); } if (getReleaseGIL(&$7)) setIsReleaseGILDtor(cd); } } ;ctor: TK_EXPLICIT {currentCtorIsExplicit = TRUE;} simplector | simplector ;simplector: TK_NAME '(' arglist ')' optexceptions optflags optctorsig ';' methodcode { /* Note that we allow ctors in C modules. */ if (notSkipping()) { if (currentSpec -> genc) { if ($9 == NULL && $3.nrArgs != 0) yyerror("Constructors with arguments in C modules must include %MethodCode"); if (currentCtorIsExplicit) yyerror("Explicit constructors not allowed in a C module"); } if ((sectionFlags & (SECT_IS_PUBLIC | SECT_IS_PROT | SECT_IS_PRIVATE)) == 0) yyerror("Constructor must be in the public, private or protected sections"); newCtor($1,sectionFlags,&$3,&$6,$9,$5,$7,currentCtorIsExplicit); } free($1); currentCtorIsExplicit = FALSE; } ;optctorsig: { $$ = NULL; } | '[' '(' arglist ')' ']' { $$ = sipMalloc(sizeof (signatureDef)); *$$ = $3; } ;optsig: { $$ = NULL; } | '[' cpptype '(' arglist ')' ']' { $$ = sipMalloc(sizeof (signatureDef)); *$$ = $4; $$ -> result = $2; } ;optvirtual: { $$ = FALSE; } | TK_VIRTUAL { $$ = TRUE; } ;function: cpptype TK_NAME '(' arglist ')' optconst optexceptions optabstract optflags optsig ';' methodcode virtualcatchercode { if (notSkipping()) { if (sectionFlags != 0 && (sectionFlags & (SECT_IS_PUBLIC | SECT_IS_PROT | SECT_IS_PRIVATE | SECT_IS_SLOT | SECT_IS_SIGNAL)) == 0) yyerror("Class function must be in the public, private, protected, slot or signal sections"); $4.result = $1; newFunction(currentSpec,currentModule, sectionFlags,currentIsStatic, currentOverIsVirt, $2,&$4,$6,$8,&$9,$12,$13,$7,$10); } currentIsStatic = FALSE; currentOverIsVirt = FALSE; } | cpptype TK_OPERATOR operatorname '(' arglist ')' optconst optexceptions optabstract optflags optsig ';' methodcode virtualcatchercode { if (notSkipping()) { classDef *cd = currentScope(); /* Handle the unary '+' and '-' operators. */ if ((cd != NULL && $5.nrArgs == 0) || (cd == NULL && $5.nrArgs == 1)) { if (strcmp($3, "__add__") == 0) $3 = "__pos__"; else if (strcmp($3, "__sub__") == 0) $3 = "__neg__"; } $5.result = $1; newFunction(currentSpec,currentModule, sectionFlags,currentIsStatic, currentOverIsVirt, $3,&$5,$7,$9,&$10,$13,$14,$8,$11); } currentIsStatic = FALSE; currentOverIsVirt = FALSE; } | TK_OPERATOR cpptype '(' arglist ')' optconst optexceptions optabstract optflags optsig ';' methodcode virtualcatchercode { classDef *scope = currentScope(); if (scope == NULL || $4.nrArgs != 0) yyerror("Operator casts must be specified in a class and have no arguments"); if (notSkipping()) { const char *sname; switch ($2.atype) { case defined_type: sname = NULL; break; case bool_type: case cbool_type: case short_type: case ushort_type: case int_type: case cint_type: case uint_type: sname = "__int__"; break; case long_type: case ulong_type: case longlong_type: case ulonglong_type: sname = "__long__"; break; case float_type: case cfloat_type: case double_type: case cdouble_type: sname = "__float__"; break; default: yyerror("Unsupported operator cast"); } if (sname != NULL) { $4.result = $2; newFunction(currentSpec, currentModule, sectionFlags, currentIsStatic, currentOverIsVirt, sname, &$4, $6, $8, &$9, $12, $13, $7, $10); } else { argList *al; /* Check it doesn't already exist. */ for (al = scope->casts; al != NULL; al = al->next) if (sameScopedName($2.u.snd, al->arg.u.snd)) yyerror("This operator cast has already been specified in this class"); al = sipMalloc(sizeof (argList)); al->arg = $2; al->next = scope->casts; scope->casts = al; } } currentIsStatic = FALSE; currentOverIsVirt = FALSE; } ;operatorname: '+' {$$ = "__add__";} | '-' {$$ = "__sub__";} | '*' {$$ = "__mul__";} | '/' {$$ = "__div__";} | '%' {$$ = "__mod__";} | '&' {$$ = "__and__";} | '|' {$$ = "__or__";} | '^' {$$ = "__xor__";} | '<' '<' {$$ = "__lshift__";} | '>' '>' {$$ = "__rshift__";} | '+' '=' {$$ = "__iadd__";} | '-' '=' {$$ = "__isub__";} | '*' '=' {$$ = "__imul__";} | '/' '=' {$$ = "__idiv__";} | '%' '=' {$$ = "__imod__";} | '&' '=' {$$ = "__iand__";} | '|' '=' {$$ = "__ior__";} | '^' '=' {$$ = "__ixor__";} | '<' '<' '=' {$$ = "__ilshift__";} | '>' '>' '=' {$$ = "__irshift__";} | '~' {$$ = "__invert__";} | '(' ')' {$$ = "__call__";} | '[' ']' {$$ = "__getitem__";} | '<' {$$ = "__lt__";} | '<' '=' {$$ = "__le__";} | '=' '=' {$$ = "__eq__";} | '!' '=' {$$ = "__ne__";} | '>' {$$ = "__gt__";} | '>' '=' {$$ = "__ge__";} ;optconst: { $$ = FALSE; } | TK_CONST { $$ = TRUE; } ;optabstract: { $$ = 0; } | '=' TK_NUMBER { if ($2 != 0) yyerror("Abstract virtual function '= 0' expected"); $$ = TRUE; } ;optflags: { $$.nrFlags = 0; } | '/' flaglist '/' { $$ = $2; } ;flaglist: flag { $$.flags[0] = $1; $$.nrFlags = 1; } | flaglist ',' flag { /* Check there is room. */ if ($1.nrFlags == MAX_NR_FLAGS) yyerror("Too many optional flags"); $$ = $1; $$.flags[$$.nrFlags++] = $3; } ;flag: TK_NAME { $$.ftype = bool_flag; $$.fname = $1; } | TK_NAME '=' flagvalue { $$ = $3; $$.fname = $1; } ;flagvalue: TK_NAME { $$.ftype = name_flag; $$.fvalue.sval = $1; } | TK_STRING { $$.ftype = string_flag; $$.fvalue.sval = $1; } | TK_NUMBER { $$.ftype = integer_flag; $$.fvalue.ival = $1; } ;methodcode: { $$ = NULL; } | TK_METHODCODE codeblock { $$ = $2; } ;virtualcatchercode: { $$ = NULL; } | TK_VIRTUALCATCHERCODE codeblock { $$ = $2; } ;arglist: rawarglist { int a, nrrxcon, nrrxdis, nrslotcon, nrslotdis, nrarray, nrarraysize; nrrxcon = nrrxdis = nrslotcon = nrslotdis = nrarray = nrarraysize = 0; for (a = 0; a < $1.nrArgs; ++a) { argDef *ad = &$1.args[a]; switch (ad -> atype) { case rxcon_type: ++nrrxcon; break; case rxdis_type: ++nrrxdis; break; case slotcon_type: ++nrslotcon; break; case slotdis_type: ++nrslotdis; break; } if (isArray(ad)) ++nrarray; if (isArraySize(ad)) ++nrarraysize; } if (nrrxcon != nrslotcon || nrrxcon > 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -