📄 soapcpp2_yacc.y
字号:
} else { p = enter(classtable, sym); p->info.typ = mkstruct(sp->table, sp->offset); } p->info.typ->id = sym; $$ = p->info.typ; exitscope(); } | struct '{' s2 decls '}' { if ((p = entry(classtable, $1->sym)) && p->info.typ->ref) { sprintf(errbuf, "struct '%s' already declared at line %d", $1->sym->name, p->lineno); semerror(errbuf); } else { p = reenter(classtable, $1->sym); p->info.typ->ref = sp->table; p->info.typ->width = sp->offset; p->info.typ->id = p->sym; } $$ = p->info.typ; exitscope(); } | STRUCT ID { if ((p = entry(classtable, $2))) { if (p->info.typ->type == Tstruct) $$ = p->info.typ; else { sprintf(errbuf, "'struct %s' redeclaration (line %d)", $2->name, p->lineno); semerror(errbuf); $$ = mkint(); } } else { p = enter(classtable, $2); $$ = p->info.typ = mkstruct((Table*)0, 0); p->info.typ->id = $2; } } | STRUCT TYPE { if ((p = entry(classtable, $2))) { if (p->info.typ->type == Tstruct) $$ = p->info.typ; else { sprintf(errbuf, "'struct %s' redeclaration (line %d)", $2->name, p->lineno); semerror(errbuf); $$ = mkint(); } } else { p = enter(classtable, $2); $$ = p->info.typ = mkstruct((Table*)0, 0); p->info.typ->id = $2; } } | UNION '{' s3 decls '}' { sym = gensym("_Union"); sprintf(errbuf, "anonymous union will be named '%s'", sym->name); semwarn(errbuf); $$ = mkunion(sp->table, sp->offset); if ((p = entry(classtable, sym))) { if ((Table*) p->info.typ->ref) { sprintf(errbuf, "union or struct '%s' already declared at line %d", sym->name, p->lineno); semerror(errbuf); } else { p->info.typ->ref = sp->table; p->info.typ->width = sp->offset; } } else { p = enter(classtable, sym); p->info.typ = mkunion(sp->table, sp->offset); } p->info.typ->id = sym; $$ = p->info.typ; exitscope(); } | UNION id '{' s3 decls '}' { if ((p = entry(classtable, $2))) { if (p->info.typ->ref || p->info.typ->type != Tunion) { sprintf(errbuf, "union '%s' already declared at line %d", $2->name, p->lineno); semerror(errbuf); } else { p = reenter(classtable, $2); p->info.typ->ref = sp->table; p->info.typ->width = sp->offset; } } else { p = enter(classtable, $2); p->info.typ = mkunion(sp->table, sp->offset); } p->info.typ->id = $2; $$ = p->info.typ; exitscope(); } | UNION ID { if ((p = entry(classtable, $2))) { if (p->info.typ->type == Tunion) $$ = p->info.typ; else { sprintf(errbuf, "'union %s' redeclaration (line %d)", $2->name, p->lineno); semerror(errbuf); $$ = mkint(); } } else { p = enter(classtable, $2); $$ = p->info.typ = mkunion((Table*) 0, 0); p->info.typ->id = $2; } } | UNION TYPE { if ((p = entry(classtable, $2))) { if (p->info.typ->type == Tunion) $$ = p->info.typ; else { sprintf(errbuf, "'union %s' redeclaration (line %d)", $2->name, p->lineno); semerror(errbuf); $$ = mkint(); } } else { p = enter(classtable, $2); $$ = p->info.typ = mkunion((Table*) 0, 0); p->info.typ->id = $2; } } | ENUM '{' s2 dclrs s5 '}' { sym = gensym("_Enum"); sprintf(errbuf, "anonymous enum will be named '%s'", sym->name); semwarn(errbuf); if ((p = entry(enumtable, sym))) { if ((Table*) p->info.typ->ref) { sprintf(errbuf, "enum '%s' already declared at line %d", sym->name, p->lineno); semerror(errbuf); } else { p->info.typ->ref = sp->table; p->info.typ->width = 4; /* 4 = enum */ } } else { p = enter(enumtable, sym); p->info.typ = mkenum(sp->table); } p->info.typ->id = sym; $$ = p->info.typ; exitscope(); } | enum '{' s2 dclrs s5 '}' { if ((p = entry(enumtable, $1->sym))) { if ((Table*) p->info.typ->ref) { sprintf(errbuf, "enum '%s' already declared at line %d", $1->sym->name, p->lineno); semerror(errbuf); } else { p->info.typ->ref = sp->table; p->info.typ->width = 4; /* 4 = enum */ } } else { p = enter(enumtable, $1->sym); p->info.typ = mkenum(sp->table); } p->info.typ->id = $1->sym; $$ = p->info.typ; exitscope(); } | ENUM '*' id '{' s4 dclrs s5 '}' { if ((p = entry(enumtable, $3))) { if (p->info.typ->ref) { sprintf(errbuf, "enum '%s' already declared at line %d", $3->name, p->lineno); semerror(errbuf); } else { p->info.typ->ref = sp->table; p->info.typ->width = 8; /* 8 = mask */ } } else { p = enter(enumtable, $3); p->info.typ = mkmask(sp->table); } p->info.typ->id = $3; $$ = p->info.typ; exitscope(); } | ENUM ID { if ((p = entry(enumtable, $2))) $$ = p->info.typ; else { p = enter(enumtable, $2); $$ = p->info.typ = mkenum((Table*)0); p->info.typ->id = $2; } } | ENUM TYPE { if ((p = entry(enumtable, $2))) $$ = p->info.typ; else { p = enter(enumtable, $2); $$ = p->info.typ = mkenum((Table*)0); p->info.typ->id = $2; } } | TYPE { if ((p = entry(typetable, $1))) $$ = p->info.typ; else if ((p = entry(classtable, $1))) $$ = p->info.typ; else if ((p = entry(enumtable, $1))) $$ = p->info.typ; else if ($1 == lookup("std::string") || $1 == lookup("std::wstring")) { p = enter(classtable, $1); $$ = p->info.typ = mkclass((Table*)0, 0); p->info.typ->id = $1; p->info.typ->transient = -2; } else { sprintf(errbuf, "unknown type '%s'", $1->name); semerror(errbuf); $$ = mkint(); } } | TYPE '<' texp '>' { if ((p = entry(templatetable, $1))) $$ = mktemplate($3.typ, $1); else { sprintf(errbuf, "invalid template '%s'", $1->name); semerror(errbuf); $$ = mkint(); } } ;struct : STRUCT id { if ((p = entry(classtable, $2))) { if (p->info.typ->ref) { sprintf(errbuf, "struct '%s' already declared at line %d", $2->name, p->lineno); semerror(errbuf); } else p = reenter(classtable, $2); } else { p = enter(classtable, $2); p->info.typ = mkstruct((Table*)0, 0); } $$ = p; } ;class : CLASS id { if ((p = entry(classtable, $2))) { if (p->info.typ->ref) { sprintf(errbuf, "class '%s' already declared at line %d", $2->name, p->lineno); semerror(errbuf); } else p = reenter(classtable, $2); } else { p = enter(classtable, $2); p->info.typ = mkclass((Table*)0, 0); p->info.typ->id = p->sym; } $2->token = TYPE; $$ = p; } ;enum : ENUM id { if ((p = entry(enumtable, $2))) { if (p->info.typ->ref) { sprintf(errbuf, "enum '%s' already declared at line %d", $2->name, p->lineno); semerror(errbuf); } /* else p = reenter(classtable, $2); */ } else { p = enter(enumtable, $2); p->info.typ = mkenum(0); } $$ = p; } ;tname : CLASS { } | TYPENAME { } ;base : PROTECTED base{ $$ = $2; } | PRIVATE base { $$ = $2; } | PUBLIC base { $$ = $2; } | TYPE { $$ = entry(classtable, $1); if (!$$) { p = entry(typetable, $1); if (p && (p->info.typ->type == Tclass || p->info.typ->type == Tstruct)) $$ = p; } } | STRUCT ID { $$ = entry(classtable, $2); } ;s2 : /* empty */ { if (transient == -2) transient = 0; permission = 0; enterscope(mktable(NULL), 0); sp->entry = NULL; } ;s3 : /* empty */ { if (transient == -2) transient = 0; permission = 0; enterscope(mktable(NULL), 0); sp->entry = NULL; sp->grow = False; } ;s4 : /* empty */ { enterscope(mktable(NULL), 0); sp->entry = NULL; sp->mask = True; sp->val = 1; } ;s5 : /* empty */ { } | ',' { } ;s6 : /* empty */ { if (sp->table->level == INTERNAL) transient |= 1; permission = 0; enterscope(mktable(NULL), 0); sp->entry = NULL; sp->table->level = PARAM; } ;store : AUTO { $$ = Sauto; } | REGISTER { $$ = Sregister; } | STATIC { $$ = Sstatic; } | EXPLICIT { $$ = Sexplicit; } | EXTERN { $$ = Sextern; transient = 1; } | TYPEDEF { $$ = Stypedef; } | VIRTUAL { $$ = Svirtual; } | CONST { $$ = Sconst; } | FRIEND { $$ = Sfriend; } | INLINE { $$ = Sinline; } | MUSTUNDERSTAND{ $$ = SmustUnderstand; } | RETURN { $$ = Sreturn; } | '@' { $$ = Sattribute; if (eflag) semwarn("SOAP RPC encoding does not support XML attributes"); } | VOLATILE { $$ = Sextern; transient = -2; } ;constobj: /* empty */ { $$ = Snone; } | CONST { $$ = Sconstobj; } ;abstract: /* empty */ { $$ = Snone; } | '=' LNG { $$ = Sabstract; } ;virtual : /* empty */ { $$ = Snone; } | VIRTUAL { $$ = Svirtual; } ;ptrs : /* empty */ { $$ = tmp = sp->node; } | ptrs '*' { /* handle const pointers, such as const char* */ if (/*tmp.typ->type == Tchar &&*/ (tmp.sto & Sconst)) tmp.sto = (tmp.sto & ~Sconst) | Sconstptr; tmp.typ = mkpointer(tmp.typ); tmp.typ->transient = transient; $$ = tmp; } | ptrs '&' { tmp.typ = mkreference(tmp.typ); tmp.typ->transient = transient; $$ = tmp; } ;array : /* empty */ { $$ = tmp; /* tmp is inherited */ } | '[' cexp ']' array { if ($4.typ->type == Tchar) { sprintf(errbuf, "char["SOAP_LONG_FORMAT"] will be encoded as an array of "SOAP_LONG_FORMAT" bytes: use char* for strings", $2.val.i, $2.val.i); semwarn(errbuf); } if ($2.hasval && $2.typ->type == Tint && $2.val.i > 0 && $4.typ->width > 0) $$.typ = mkarray($4.typ, (int) $2.val.i * $4.typ->width); else { $$.typ = mkarray($4.typ, 0); semerror("undetermined array size"); } $$.sto = $4.sto; } | '[' ']' array { $$.typ = mkpointer($3.typ); /* zero size array = pointer */ $$.sto = $3.sto; } ;arrayck : array { if ($1.typ->type == Tstruct || $1.typ->type == Tclass) if (!$1.typ->ref && !$1.typ->transient && !($1.sto & Stypedef)) { sprintf(errbuf, "struct/class '%s' has incomplete type", $1.typ->id->name); semerror(errbuf); } $$ = $1; } ;init : /* empty */ { $$.hasval = False; } | '=' cexp { if ($2.hasval) { $$.typ = $2.typ; $$.hasval = True; $$.val = $2.val; } else { $$.hasval = False; semerror("initialization expression not constant"); } } ;occurs : patt { $$.minOccurs = -1; $$.maxOccurs = 1; $$.pattern = $1; } | patt cint { $$.minOccurs = (long)$2; $$.maxOccurs = 1; $$.pattern = $1; } | patt cint ':' { $$.minOccurs = (long)$2; $$.maxOccurs = 1; $$.pattern = $1; } | patt cint ':' cint { $$.minOccurs = (long)$2; $$.maxOccurs = (long)$4; $$.pattern = $1; } | patt ':' cint { $$.minOccurs = -1; $$.maxOccurs = (long)$3; $$.pattern = $1; } ;patt : /* empty */ { $$ = NULL; } | STR { $$ = $1; } ;cint : LNG { $$ = $1; } | '-' LNG { $$ = -$2; } ;/******************************************************************************\ Expressions\******************************************************************************/expr : expr ',' expr { $$ = $3; } | cexp { $$ = $1; } ;/* cexp : conditional expression */cexp : obex '?' qexp ':' cexp { $$.typ = $3.typ; $$.sto = Snone; $$.hasval = False; } | oexp ;/* qexp : true-branch of ? : conditional expression */qexp : expr { $$ = $1; } ;/* oexp : or-expression */oexp : obex OR aexp { $$.hasval = False; $$.typ = mkint();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -