📄 parser.y
字号:
yyerror("SIP_RXOBJ_CON and SIP_SLOT_CON must both be given and at most once"); if (nrrxdis != nrslotdis || nrrxdis > 1) yyerror("SIP_RXOBJ_DIS and SIP_SLOT_DIS must both be given and at most once"); if (nrarray != nrarraysize || nrarray > 1) yyerror("/Array/ and /ArraySize/ must both be given and at most once"); $$ = $1; } ;rawarglist: { /* No arguments. */ $$.nrArgs = 0; } | argvalue { /* The single or first argument. */ $$.args[0] = $1; $$.nrArgs = 1; } | rawarglist ',' argvalue { /* Check that it wasn't ...(,arg...). */ if ($1.nrArgs == 0) yyerror("First argument of the list is missing"); /* Check there is nothing after an ellipsis. */ if ($1.args[$1.nrArgs - 1].atype == ellipsis_type) yyerror("An ellipsis must be at the end of the argument list"); /* * If this argument has no default value, then the * previous one mustn't either. */ if ($3.defval == NULL && $1.args[$1.nrArgs - 1].defval != NULL) yyerror("Compulsory argument given after optional argument"); /* Check there is room. */ if ($1.nrArgs == MAX_NR_ARGS) yyerror("Internal error - increase the value of MAX_NR_ARGS"); $$ = $1; $$.args[$$.nrArgs] = $3; $$.nrArgs++; } ;argvalue: TK_SIPSIGNAL optname optassign { $$.atype = signal_type; $$.argflags = 0; $$.nrderefs = 0; $$.name = $2; $$.defval = $3; currentSpec -> sigslots = TRUE; } | TK_SIPSLOT optname optassign { $$.atype = slot_type; $$.argflags = 0; $$.nrderefs = 0; $$.name = $2; $$.defval = $3; currentSpec -> sigslots = TRUE; } | TK_SIPANYSLOT optname optassign { $$.atype = anyslot_type; $$.argflags = 0; $$.nrderefs = 0; $$.name = $2; $$.defval = $3; currentSpec -> sigslots = TRUE; } | TK_SIPRXCON optname { $$.atype = rxcon_type; $$.argflags = 0; $$.nrderefs = 0; $$.name = $2; currentSpec -> sigslots = TRUE; } | TK_SIPRXDIS optname { $$.atype = rxdis_type; $$.argflags = 0; $$.nrderefs = 0; $$.name = $2; currentSpec -> sigslots = TRUE; } | TK_SIPSLOTCON '(' arglist ')' optname { $$.atype = slotcon_type; $$.argflags = 0; $$.nrderefs = 0; $$.name = $5; $3.result.atype = void_type; $3.result.argflags = 0; $3.result.nrderefs = 0; $$.u.sa = sipMalloc(sizeof (signatureDef)); *$$.u.sa = $3; currentSpec -> sigslots = TRUE; } | TK_SIPSLOTDIS '(' arglist ')' optname { $$.atype = slotdis_type; $$.argflags = 0; $$.nrderefs = 0; $$.name = $5; $3.result.atype = void_type; $3.result.argflags = 0; $3.result.nrderefs = 0; $$.u.sa = sipMalloc(sizeof (signatureDef)); *$$.u.sa = $3; currentSpec -> sigslots = TRUE; } | TK_QOBJECT optname { $$.atype = qobject_type; $$.argflags = 0; $$.nrderefs = 0; $$.name = $2; } | argtype optassign { $$ = $1; $$.defval = $2; } ;varmember: TK_STATIC {currentIsStatic = TRUE;} varmem | varmem ;varmem: member | variable ;member: TK_VIRTUAL {currentOverIsVirt = TRUE;} function | function ;variable: cpptype TK_NAME optflags ';' optaccesscode optgetcode optsetcode { if (notSkipping()) { /* Check the section. */ if (sectionFlags != 0) { if ((sectionFlags & SECT_IS_PUBLIC) == 0) yyerror("Class variables must be in the public section"); if (!currentIsStatic && $5 != NULL) yyerror("%AccessCode cannot be specified for non-static class variables"); } if (currentIsStatic && currentSpec -> genc) yyerror("Cannot have static members in a C structure"); if ($6 != NULL || $7 != NULL) { if ($5 != NULL) yyerror("Cannot mix %AccessCode and %GetCode or %SetCode"); if (currentScope() == NULL) yyerror("Cannot specify %GetCode or %SetCode for global variables"); } newVar(currentSpec,currentModule,$2,currentIsStatic,&$1,&$3,$5,$6,$7); } currentIsStatic = FALSE; } ;cpptype: TK_CONST basetype deref optref { $$ = $2; $$.nrderefs = $3; $$.argflags = ARG_IS_CONST | $4; $$.name = NULL; } | basetype deref optref { $$ = $1; $$.nrderefs = $2; $$.argflags = $3; $$.name = NULL; } ;argtype: cpptype optname optflags { $$ = $1; $$.name = $2; if (findOptFlag(&$3,"AllowNone",bool_flag) != NULL) $$.argflags |= ARG_ALLOW_NONE; if (findOptFlag(&$3,"GetWrapper",bool_flag) != NULL) $$.argflags |= ARG_GET_WRAPPER; if (findOptFlag(&$3,"Array",bool_flag) != NULL) $$.argflags |= ARG_ARRAY; if (findOptFlag(&$3,"ArraySize",bool_flag) != NULL) $$.argflags |= ARG_ARRAY_SIZE; if (findOptFlag(&$3,"Transfer",bool_flag) != NULL) $$.argflags |= ARG_XFERRED; if (findOptFlag(&$3,"TransferThis",bool_flag) != NULL) $$.argflags |= ARG_THIS_XFERRED; if (findOptFlag(&$3,"TransferBack",bool_flag) != NULL) $$.argflags |= ARG_XFERRED_BACK; if (findOptFlag(&$3,"In",bool_flag) != NULL) $$.argflags |= ARG_IN; if (findOptFlag(&$3,"Out",bool_flag) != NULL) $$.argflags |= ARG_OUT; if (findOptFlag(&$3,"Constrained",bool_flag) != NULL) { $$.argflags |= ARG_CONSTRAINED; switch ($$.atype) { case bool_type: $$.atype = cbool_type; break; case int_type: $$.atype = cint_type; break; case float_type: $$.atype = cfloat_type; break; case double_type: $$.atype = cdouble_type; break; } } } ;optref: { $$ = 0; } | '&' { if (currentSpec -> genc) yyerror("References not allowed in a C module"); $$ = ARG_IS_REF; } ;deref: { $$ = 0; } | deref '*' { $$ = $1 + 1; } ;basetype: scopedname { $$.atype = defined_type; $$.u.snd = $1; } | scopedname '<' cpptypelist '>' { templateDef *td; td = sipMalloc(sizeof(templateDef)); td -> fqname = $1; td -> types = $3; $$.atype = template_type; $$.u.td = td; } | TK_STRUCT scopedname { /* In a C module all structures must be defined. */ if (currentSpec -> genc) { $$.atype = defined_type; $$.u.snd = $2; } else { $$.atype = struct_type; $$.u.sname = $2; } } | TK_UNSIGNED TK_SHORT { $$.atype = ushort_type; } | TK_SHORT { $$.atype = short_type; } | TK_UNSIGNED { $$.atype = uint_type; } | TK_UNSIGNED TK_INT { $$.atype = uint_type; } | TK_INT { $$.atype = int_type; } | TK_LONG { $$.atype = long_type; } | TK_UNSIGNED TK_LONG { $$.atype = ulong_type; } | TK_LONG TK_LONG { $$.atype = longlong_type; } | TK_UNSIGNED TK_LONG TK_LONG { $$.atype = ulonglong_type; } | TK_FLOAT { $$.atype = float_type; } | TK_DOUBLE { $$.atype = double_type; } | TK_BOOL { $$.atype = bool_type; } | TK_SIGNED TK_CHAR { $$.atype = sstring_type; } | TK_UNSIGNED TK_CHAR { $$.atype = ustring_type; } | TK_CHAR { $$.atype = string_type; } | TK_VOID { $$.atype = void_type; } | TK_PYOBJECT { $$.atype = pyobject_type; } | TK_PYTUPLE { $$.atype = pytuple_type; } | TK_PYLIST { $$.atype = pylist_type; } | TK_PYDICT { $$.atype = pydict_type; } | TK_PYCALLABLE { $$.atype = pycallable_type; } | TK_PYSLICE { $$.atype = pyslice_type; } | TK_PYTYPE { $$.atype = pytype_type; } | TK_ELLIPSIS { $$.atype = ellipsis_type; } ;cpptypelist: cpptype { /* The single or first type. */ $$.args[0] = $1; $$.nrArgs = 1; } | cpptypelist ',' cpptype { /* Check there is nothing after an ellipsis. */ if ($1.args[$1.nrArgs - 1].atype == ellipsis_type) yyerror("An ellipsis must be at the end of the argument list"); /* Check there is room. */ if ($1.nrArgs == MAX_NR_ARGS) yyerror("Internal error - increase the value of MAX_NR_ARGS"); $$ = $1; $$.args[$$.nrArgs] = $3; $$.nrArgs++; } ;optexceptions: { $$ = NULL; } | TK_THROW '(' exceptionlist ')' { if (currentSpec->genc) yyerror("Exceptions not allowed in a C module"); if (notSkipping() && inMainModule()) { int e; ifaceFileList **ifl; /* * Make sure the exceptions' header files are * included. We unconditionally mark them to * be included in the current scope's header * file to save us the effort of checking if * they are being used with a protected method, * a virtual or a signal. */ ifl = (currentScope() != NULL) ? ¤tScope()->iff->used : ¤tSpec->used; for (e = 0; e < $3->nrArgs; ++e) addToUsedList(ifl, $3->args[e]->iff); } $$ = $3; } ;exceptionlist: { /* Empty list so use a blank. */ $$ = sipMalloc(sizeof (throwArgs)); $$ -> nrArgs = 0; } | scopedname { /* The only or first exception. */ $$ = sipMalloc(sizeof (throwArgs)); $$ -> nrArgs = 1; $$ -> args[0] = findException(currentSpec, $1, FALSE); } | exceptionlist ',' scopedname { /* Check that it wasn't ...(,arg...). */ if ($1 -> nrArgs == 0) yyerror("First exception of throw specifier is missing"); /* Check there is room. */ if ($1 -> nrArgs == MAX_NR_ARGS) yyerror("Internal error - increase the value of MAX_NR_ARGS"); $$ = $1; $$ -> args[$$ -> nrArgs++] = findException(currentSpec, $3, FALSE); } ;%%/* * Parse the specification. */void parse(sipSpec *spec,FILE *fp,char *filename,stringList *tsl, stringList *xfl){ classTmplDef *tcd; /* Initialise the spec. */ spec -> modules = NULL; spec -> allimports = NULL; spec -> namecache = NULL; spec -> ifacefiles = NULL; spec -> classes = NULL; spec -> classtemplates = NULL; spec -> proxies = NULL; spec -> exceptions = NULL; spec -> mappedtypes = NULL; spec -> mappedtypetemplates = NULL; spec -> qobjclass = -1; spec -> enums = NULL; spec -> vars = NULL; spec -> othfuncs = NULL; spec -> overs = NULL; spec -> typedefs = NULL; spec -> copying = NULL; spec -> hdrcode = NULL; spec -> cppcode = NULL; spec -> docs = NULL; spec -> preinitcode = NULL; spec -> postinitcode = NULL; spec -> used = NULL; spec -> sigslots = FALSE; spec -> genc = -1; spec -> emitters = TRUE; currentSpec = spec; neededQualifiers = tsl; excludedQualifiers = xfl; currentModule = NULL; currentMappedType = NULL; currentOverIsVirt = FALSE; currentCtorIsExplicit = FALSE; currentIsStatic = FALSE; previousFile = NULL; skipStackPtr = 0; currentScopeIdx = 0; sectionFlags = 0; newModule(fp,filename); spec -> module = currentModule; yyparse(); handleEOF(); handleEOM(); /* * Go through each template class and remove it from the list of * classes. */ for (tcd = spec->classtemplates; tcd != NULL; tcd = tcd->next) { classDef **cdp; for (cdp = &spec->classes; *cdp != NULL; cdp = &(*cdp)->next) if (*cdp == tcd->cd) { ifaceFileDef **ifdp; /* Remove the interface file as well. */ for (ifdp = &spec->ifacefiles; *ifdp != NULL; ifdp = &(*ifdp)->next) if (*ifdp == tcd->cd->iff) { *ifdp = (*ifdp)->next; break; } *cdp = (*cdp)->next; break; } }}/* * Tell the parser that a complete file has now been read. */void parserEOF(char *name,parserContext *pc){ previousFile = sipStrdup(name); newContext = *pc;}/* * Append a class definition to a class list if it doesn't already appear. * Append is needed specifically for the list of super-classes because the * order is important to Python. */void appendToClassList(classList **clp,classDef *cd){ classList *new; /* Find the end of the list. */ while (*clp != NULL) { if ((*clp) -> cd == cd) return; clp = &(*clp) -> next; } new = sipMalloc(sizeof (classList)); new -> cd = cd; new -> next = NULL; *clp = new;}/* * Create a new module for the current specification and make it current. */static void newModule(FILE *fp,char *filename){ moduleDef *newmod; parseFile(fp,filename,currentModule,FALSE); newmod = sipMalloc(sizeof (moduleDef)); newmod -> fullname = NULL; newmod -> name = NULL; newmod -> version = -1; newmod -> modflags = 0; newmod -> modulenr = -1; newmod -> file = filename; newmod -> qualifiers = NULL; newmod -> root.cd = NULL; newmod -> root.child = NULL; newmod -> nrtimelines = 0; newmod -> nrclasses = 0; newmod -> nrexceptions = 0; newmod -> nrmappedtypes = 0; newmod -> nrenums = 0; newmod -> nrtypedefs = 0; newmod -> nrvirthandlers = 0; newmod -> virthandlers = NULL; newmod -> license = NULL; newmod -> imports = NULL; newmod -> next = currentSpec -> modules; currentModule = currentSpec->modules = newmod;}/* * Switch to parsing a new file. */static void parseFile(FILE *fp,char *name,moduleDef *prevmod,int optional){ parserContext pc; pc.ifdepth = skipStackPtr; pc.prevmod = prevmod;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -