📄 parser.y
字号:
yyerror("%Platforms has already been defined for this module"); } '{' platformlist '}' { qualDef *qd; int nrneeded; /* * Check that exactly one platform in the set was * requested. */ nrneeded = 0; for (qd = currentModule -> qualifiers; qd != NULL; qd = qd -> next) if (qd -> qtype == platform_qualifier && isNeeded(qd)) ++nrneeded; if (nrneeded > 1) yyerror("No more than one of these %Platforms must be specified with the -t flag"); } ;platformlist: platform | platformlist platform ;platform: TK_NAME { newQualifier(currentModule,-1,-1,$1,platform_qualifier); } ;feature: TK_FEATURE TK_NAME { newQualifier(currentModule,-1,-1,$2,feature_qualifier); } ;timeline: TK_TIMELINE { currentTimelineOrder = 0; } '{' qualifierlist '}' { qualDef *qd; int nrneeded; /* * Check that exactly one time slot in the set was * requested. */ nrneeded = 0; for (qd = currentModule -> qualifiers; qd != NULL; qd = qd -> next) if (qd -> qtype == time_qualifier && isNeeded(qd)) ++nrneeded; if (nrneeded > 1) yyerror("At most one of this %Timeline must be specified with the -t flag"); currentModule -> nrtimelines++; } ;qualifierlist: qualifiername | qualifierlist qualifiername ;qualifiername: TK_NAME { newQualifier(currentModule,currentModule -> nrtimelines,currentTimelineOrder++,$1,time_qualifier); } ;ifstart: TK_IF '(' qualifiers ')' { int skipNext; if (skipStackPtr >= MAX_NESTED_IF) yyerror("Internal error: increase the value of MAX_NESTED_IF"); /* Nested %Ifs are implicit logical ands. */ if (skipStackPtr > 0) $3 = ($3 && skipStack[skipStackPtr - 1]); skipStack[skipStackPtr++] = $3; } ;oredqualifiers: TK_NAME { $$ = platOrFeature($1,FALSE); } | '!' TK_NAME { $$ = platOrFeature($2,TRUE); } | oredqualifiers TK_LOGICAL_OR TK_NAME { $$ = (platOrFeature($3,FALSE) || $1); } | oredqualifiers TK_LOGICAL_OR '!' TK_NAME { $$ = (platOrFeature($4,TRUE) || $1); } ;qualifiers: oredqualifiers | optname '-' optname { $$ = timePeriod($1,$3); } ;ifend: TK_END { if (skipStackPtr-- <= 0) yyerror("Too many %End directives"); } ;license: TK_LICENSE optflags { optFlag *of; if ($2.nrFlags == 0) yyerror("%License details not specified"); if ((of = findOptFlag(&$2,"Type",string_flag)) == NULL) yyerror("%License type not specified"); currentModule -> license = sipMalloc(sizeof (licenseDef)); currentModule -> license -> type = of -> fvalue.sval; currentModule -> license -> licensee = ((of = findOptFlag(&$2,"Licensee",string_flag)) != NULL) ? of -> fvalue.sval : NULL; currentModule -> license -> timestamp = ((of = findOptFlag(&$2,"Timestamp",string_flag)) != NULL) ? of -> fvalue.sval : NULL; currentModule -> license -> sig = ((of = findOptFlag(&$2,"Signature",string_flag)) != NULL) ? of -> fvalue.sval : NULL; } ;module: modlang modname optnumber { /* Check the module hasn't already been defined. */ moduleDef *mod; for (mod = currentSpec -> modules; mod != NULL; mod = mod -> next) if (mod->fullname != NULL && strcmp(mod->fullname, $2) == 0) yyerror("Module is already defined"); currentModule->fullname = $2; if ((currentModule->name = strrchr($2, '.')) != NULL) currentModule->name++; else currentModule->name = $2; currentModule -> version = $3; if (currentSpec -> genc < 0) currentSpec -> genc = $1; else if (currentSpec -> genc != $1) yyerror("Cannot mix C and C++ modules"); } ;modlang: TK_MODULE { $$ = FALSE; } | TK_CMODULE { $$ = TRUE; } ;modname: TK_NAME | TK_PATHNAME { /* * The grammar design is a bit broken and this is the * easiest way to allow periods in module names. */ char *cp; for (cp = $1; *cp != '\0'; ++cp) if (*cp != '.' && *cp != '_' && !isalnum(*cp)) yyerror("Invalid character in module name"); $$ = $1; } ;optnumber: { $$ = -1; } | TK_NUMBER ;include: TK_INCLUDE TK_PATHNAME { parseFile(NULL,$2,NULL,FALSE); } ;optinclude: TK_OPTINCLUDE TK_PATHNAME { parseFile(NULL,$2,NULL,TRUE); } ;import: TK_IMPORT TK_PATHNAME { newImport($2); } ;optaccesscode: { $$ = NULL; } | TK_ACCESSCODE codeblock { $$ = $2; } ;optgetcode: { $$ = NULL; } | TK_GETCODE codeblock { $$ = $2; } ;optsetcode: { $$ = NULL; } | TK_SETCODE codeblock { $$ = $2; } ;copying: TK_COPYING codeblock { if (inMainModule()) appendCodeBlock(¤tSpec -> copying,$2); } ;modhdrcode: TK_MODHEADERCODE codeblock { $$ = $2; } ;typehdrcode: TK_TYPEHEADERCODE codeblock { $$ = $2; } ;opttypehdrcode: { $$ = NULL; } | typehdrcode ;travcode: TK_TRAVERSECODE codeblock { $$ = $2; } ;clearcode: TK_CLEARCODE codeblock { $$ = $2; } ;readbufcode: TK_READBUFFERCODE codeblock { $$ = $2; } ;writebufcode: TK_WRITEBUFFERCODE codeblock { $$ = $2; } ;segcountcode: TK_SEGCOUNTCODE codeblock { $$ = $2; } ;charbufcode: TK_CHARBUFFERCODE codeblock { $$ = $2; } ;modcode: TK_MODCODE codeblock { $$ = $2; } ;typecode: TK_TYPECODE codeblock { $$ = $2; } ;preinitcode: TK_PREINITCODE codeblock { if (notSkipping() && inMainModule()) appendCodeBlock(¤tSpec -> preinitcode,$2); } ;postinitcode: TK_POSTINITCODE codeblock { if (notSkipping() && inMainModule()) appendCodeBlock(¤tSpec -> postinitcode,$2); } ;prepycode: TK_PREPYCODE codeblock { /* * This is a no-op and is retained for compatibility * until the last use of it (by SIP v3) can be removed * from PyQt. */ } ;doc: TK_DOC codeblock { if (inMainModule()) appendCodeBlock(¤tSpec -> docs,$2); } ;exporteddoc: TK_EXPORTEDDOC codeblock { appendCodeBlock(¤tSpec -> docs,$2); } ;makefile: TK_MAKEFILE TK_PATHNAME optfilename codeblock { if (inMainModule()) yywarning("%Makefile is ignored, please use the -b flag instead"); } ;codeblock: codelines TK_END ;codelines: TK_CODELINE | codelines TK_CODELINE { $$ = $1; append(&$$->frag, $2->frag); free($2->frag); free($2->filename); free($2); } ;enum: TK_ENUM optname optflags { if (notSkipping()) { if (sectionFlags != 0 && (sectionFlags & ~(SECT_IS_PUBLIC | SECT_IS_PROT)) != 0) yyerror("Class enums must be in the public or protected sections"); currentEnum = newEnum(currentSpec,currentModule,$2,&$3,sectionFlags); } } '{' optenumbody '}' ';' ;optfilename: { $$ = NULL; } | TK_PATHNAME { $$ = $1; } ;optname: { $$ = NULL; } | TK_NAME { $$ = $1; } ;optenumbody: | enumbody ;enumbody: enumline | enumbody enumline ;enumline: ifstart | ifend | TK_NAME optenumassign optflags optcomma { if (notSkipping()) { /* * Note that we don't use the assigned value. * This is a hangover from when enums where * generated in Python. We can remove it when * we have got around to updating all the .sip * files. */ enumMemberDef *emd; emd = sipMalloc(sizeof (enumMemberDef)); emd -> pyname = cacheName(currentSpec, getPythonName(&$3, $1)); emd -> cname = $1; emd -> ed = currentEnum; checkAttributes(currentSpec,emd -> ed -> ecd,emd -> pyname -> text,FALSE); emd -> next = currentEnum -> members; currentEnum -> members = emd; if (inMainModule()) setIsUsedName(emd -> pyname); } } ;optcomma: | ',' ;optenumassign: | '=' value ;optassign: { $$ = NULL; } | '=' expr { $$ = $2; } ;expr: value | expr binop value { valueDef *vd; if ($1 -> vtype == string_value || $3 -> vtype == string_value) yyerror("Invalid binary operator for string"); /* Find the last value in the existing expression. */ for (vd = $1; vd -> next != NULL; vd = vd -> next) ; vd -> vbinop = $2; vd -> next = $3; $$ = $1; } ;binop: '-' { $$ = '-'; } | '+' { $$ = '+'; } | '*' { $$ = '*'; } | '/' { $$ = '/'; } | '&' { $$ = '&'; } | '|' { $$ = '|'; } ;optunop: { $$ = '\0'; } | '!' { $$ = '!'; } | '~' { $$ = '~'; } | '-' { $$ = '-'; } | '+' { $$ = '+'; } ;value: optunop simplevalue { if ($1 != '\0' && $2.vtype == string_value) yyerror("Invalid unary operator for string"); /* * Convert the value to a simple expression on the * heap. */ $$ = sipMalloc(sizeof (valueDef)); *$$ = $2; $$ -> vunop = $1; $$ -> vbinop = '\0'; $$ -> next = NULL; } ;scopedname: scopepart | scopedname TK_SCOPE scopepart { if (currentSpec -> genc) yyerror("Scoped names are not allowed in a C module"); appendScopedName(&$1,$3); } ;scopepart: TK_NAME { $$ = text2scopePart($1); } ;simplevalue: scopedname { /* * We let the C++ compiler decide if the value is a * valid one - no point in building a full C++ parser * here. */ $$.vtype = scoped_value; $$.u.vscp = $1; } | basetype '(' exprlist ')' { fcallDef *fcd; fcd = sipMalloc(sizeof (fcallDef)); *fcd = $3; fcd -> type = $1; $$.vtype = fcall_value; $$.u.fcd = fcd; } | TK_REAL { $$.vtype = real_value; $$.u.vreal = $1; } | TK_NUMBER { $$.vtype = numeric_value; $$.u.vnum = $1; } | TK_TRUE { $$.vtype = numeric_value; $$.u.vnum = 1; } | TK_FALSE { $$.vtype = numeric_value; $$.u.vnum = 0; } | TK_NULL { $$.vtype = numeric_value; $$.u.vnum = 0; } | TK_STRING { $$.vtype = string_value; $$.u.vstr = $1; } | TK_QCHAR { $$.vtype = qchar_value; $$.u.vqchar = $1; } ;exprlist: { /* No values. */ $$.nrArgs = 0; } | expr { /* The single or first expression. */ $$.args[0] = $1; $$.nrArgs = 1; } | exprlist ',' expr { /* Check that it wasn't ...(,expression...). */ if ($$.nrArgs == 0) yyerror("First argument to function call is missing"); /* Check there is room. */ if ($1.nrArgs == MAX_NR_ARGS) yyerror("Too many arguments to function call"); $$ = $1; $$.args[$$.nrArgs] = $3; $$.nrArgs++; } ;typedef: TK_TYPEDEF cpptype TK_NAME ';' { if (notSkipping()) newTypedef(currentSpec,currentModule,$3,&$2); } | TK_TYPEDEF cpptype '(' deref TK_NAME ')' '(' cpptypelist ')' ';' { if (notSkipping()) { argDef ftype; signatureDef *sig; /* Create the full signature on the heap. */ sig = sipMalloc(sizeof (signatureDef)); *sig = $8; sig -> result = $2; /* Create the full type. */ ftype.atype = function_type; ftype.argflags = 0; ftype.nrderefs = $4; ftype.defval = NULL; ftype.u.sa = sig; newTypedef(currentSpec,currentModule,$5,&ftype); } } ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -