📄 soapcpp2_yacc.y
字号:
| OPERATOR '&' { $$ = lookup("operator&"); } | OPERATOR EQ { $$ = lookup("operator=="); } | OPERATOR NE { $$ = lookup("operator!="); } | OPERATOR '<' { $$ = lookup("operator<"); } | OPERATOR LE { $$ = lookup("operator<="); } | OPERATOR '>' { $$ = lookup("operator>"); } | OPERATOR GE { $$ = lookup("operator>="); } | OPERATOR LS { $$ = lookup("operator<<"); } | OPERATOR RS { $$ = lookup("operator>>"); } | OPERATOR '+' { $$ = lookup("operator+"); } | OPERATOR '-' { $$ = lookup("operator-"); } | OPERATOR '*' { $$ = lookup("operator*"); } | OPERATOR '/' { $$ = lookup("operator/"); } | OPERATOR '%' { $$ = lookup("operator%"); } | OPERATOR PP { $$ = lookup("operator++"); } | OPERATOR NN { $$ = lookup("operator--"); } | OPERATOR AR { $$ = lookup("operator->"); } | OPERATOR'['']'{ $$ = lookup("operator[]"); } | OPERATOR'('')'{ $$ = lookup("operator()"); } | OPERATOR texp { s1 = c_storage($2.sto); s2 = c_type($2.typ); s = (char*)emalloc(strlen(s1) + strlen(s2) + 10); strcpy(s, "operator "); strcat(s, s1); strcat(s, s2); $$ = lookup(s); if (!$$) $$ = install(s, ID); } ;constr : TYPE { if (!(p = entry(classtable, $1))) semerror("invalid constructor"); sp->entry = enter(sp->table, $1); sp->entry->info.typ = mknone(); sp->entry->info.sto = Snone; sp->entry->info.offset = sp->offset; sp->node.typ = mkvoid(); sp->node.sto = Snone; } ;destr : virtual '~' TYPE { if (!(p = entry(classtable, $3))) semerror("invalid destructor"); s = (char*)emalloc(strlen($3->name) + 2); strcpy(s, "~"); strcat(s, $3->name); sym = lookup(s); if (!sym) sym = install(s, ID); sp->entry = enter(sp->table, sym); sp->entry->info.typ = mknone(); sp->entry->info.sto = $1; sp->entry->info.offset = sp->offset; sp->node.typ = mkvoid(); sp->node.sto = Snone; } ;func : fname '(' s6 fargso ')' constobj abstract { if ($1->level == GLOBAL) { if (!($1->info.sto & Sextern) && sp->entry && sp->entry->info.typ->type == Tpointer && ((Tnode*)sp->entry->info.typ->ref)->type == Tchar) { sprintf(errbuf, "last output parameter of remote method function prototype '%s' is a pointer to a char which will only return one byte: use char** instead to return a string", $1->sym->name); semwarn(errbuf); } if ($1->info.sto & Sextern) $1->info.typ = mkmethod($1->info.typ, sp->table); else if (sp->entry && (sp->entry->info.typ->type == Tpointer || sp->entry->info.typ->type == Treference || sp->entry->info.typ->type == Tarray || is_transient(sp->entry->info.typ))) { if ($1->info.typ->type == Tint) { sp->entry->info.sto = (Storage)((int)sp->entry->info.sto | (int)Sreturn); $1->info.typ = mkfun(sp->entry); $1->info.typ->id = $1->sym; if (!is_transient(sp->entry->info.typ)) { if (!is_response(sp->entry->info.typ)) { if (!is_XML(sp->entry->info.typ)) add_response($1, sp->entry); } else add_result(sp->entry->info.typ); } } else { sprintf(errbuf, "return type of remote method function prototype '%s' must be integer", $1->sym->name); semerror(errbuf); } } else { sprintf(errbuf, "last output parameter of remote method function prototype '%s' is a return parameter and must be a pointer or reference", $1->sym->name); semerror(errbuf); } if (!($1->info.sto & Sextern)) { unlinklast(sp->table); if ((p = entry(classtable, $1->sym))) { if (p->info.typ->ref) { sprintf(errbuf, "remote method name clash: struct/class '%s' already declared at line %d", $1->sym->name, p->lineno); semerror(errbuf); } else { p->info.typ->ref = sp->table; p->info.typ->width = sp->offset; } } else { p = enter(classtable, $1->sym); p->info.typ = mkstruct(sp->table, sp->offset); p->info.typ->id = $1->sym; } } } else if ($1->level == INTERNAL) { $1->info.typ = mkmethod($1->info.typ, sp->table); $1->info.sto = (Storage)((int)$1->info.sto | (int)$6 | (int)$7); transient &= ~1; } exitscope(); } ;fname : { $$ = sp->entry; } ;fargso : /* empty */ { } | fargs { } ;fargs : farg { } | farg ',' fargs{ } ;farg : tspec ptrs arg arrayck occurs init { if ($4.sto & Stypedef) semwarn("typedef in function argument"); p = enter(sp->table, $3); p->info.typ = $4.typ; p->info.sto = $4.sto; if ($5.minOccurs < 0) { if (($4.sto & Sattribute) || $4.typ->type == Tpointer) p->info.minOccurs = 0; else p->info.minOccurs = 1; } else p->info.minOccurs = $5.minOccurs; p->info.maxOccurs = $5.maxOccurs; if ($6.hasval) { p->info.hasval = True; switch ($4.typ->type) { case Tchar: case Tuchar: case Tshort: case Tushort: case Tint: case Tuint: case Tlong: case Tulong: case Tenum: case Ttime: if ($6.typ->type == Tint || $6.typ->type == Tchar || $6.typ->type == Tenum) sp->val = p->info.val.i = $6.val.i; else { semerror("type error in initialization constant"); p->info.hasval = False; } break; case Tfloat: case Tdouble: case Tldouble: if ($6.typ->type == Tfloat || $6.typ->type == Tdouble || $6.typ->type == Tldouble) p->info.val.r = $6.val.r; else if ($6.typ->type == Tint) p->info.val.r = (double)$6.val.i; else { semerror("type error in initialization constant"); p->info.hasval = False; } break; default: if ($4.typ->type == Tpointer && ((Tnode*)$4.typ->ref)->type == Tchar && $6.typ->type == Tpointer && ((Tnode*)$6.typ->ref)->type == Tchar) p->info.val.s = $6.val.s; else if ($4.typ->type == Tpointer && ((Tnode*)$4.typ->ref)->id == lookup("std::string")) p->info.val.s = $6.val.s; else if ($4.typ->id == lookup("std::string")) p->info.val.s = $6.val.s; else if ($4.typ->type == Tpointer && $6.typ->type == Tint && $6.val.i == 0) p->info.val.i = 0; else { semerror("type error in initialization constant"); p->info.hasval = False; } break; } } p->info.offset = sp->offset; if ($4.sto & Sextern) p->level = GLOBAL; else if (sp->grow) sp->offset += p->info.typ->width; else if (p->info.typ->width > sp->offset) sp->offset = p->info.typ->width; sp->entry = p; } ;arg : /* empty */ { if (sp->table->level != PARAM) $$ = gensymidx("param", (int)++sp->val); else if (eflag) $$ = gensymidx("_param", (int)++sp->val); else $$ = gensym("_param"); } | ID { if (vflag != 1 && *$1->name == '_' && sp->table->level == GLOBAL) { sprintf(errbuf, "SOAP 1.2 does not support anonymous parameters '%s'", $1->name); semwarn(errbuf); } $$ = $1; } ;/******************************************************************************\ Type specification\******************************************************************************//* texp : type expression (subset of C) */texp : tspec ptrs array { $$ = $3; } | tspec ptrs ID array { $$ = $4; } ;spec : /*empty */ { $$.typ = mkint(); $$.sto = Snone; sp->node = $$; } | store spec { $$.typ = $2.typ; $$.sto = (Storage)((int)$1 | (int)$2.sto); if (($$.sto & Sattribute) && !is_primitive_or_string($2.typ) && !is_stdstr($2.typ) && !is_binary($2.typ) && !is_external($2.typ)) { semwarn("invalid attribute type"); $$.sto &= ~Sattribute; } sp->node = $$; if ($1 & Sextern) transient = 0; } | type spec { if ($1->type == Tint) switch ($2.typ->type) { case Tchar: $$.typ = $2.typ; break; case Tshort: $$.typ = $2.typ; break; case Tint: $$.typ = $1; break; case Tlong: $$.typ = $2.typ; break; case Tllong: $$.typ = $2.typ; break; default: semwarn("illegal use of 'signed'"); $$.typ = $2.typ; } else if ($1->type == Tuint) switch ($2.typ->type) { case Tchar: $$.typ = mkuchar(); break; case Tshort: $$.typ = mkushort(); break; case Tint: $$.typ = $1; break; case Tlong: $$.typ = mkulong(); break; case Tllong: $$.typ = mkullong(); break; default: semwarn("illegal use of 'unsigned'"); $$.typ = $2.typ; } else if ($1->type == Tlong) switch ($2.typ->type) { case Tint: $$.typ = $1; break; case Tlong: $$.typ = mkllong(); break; case Tuint: $$.typ = mkulong(); break; case Tulong: $$.typ = mkullong(); break; case Tdouble: $$.typ = mkldouble(); break; default: semwarn("illegal use of 'long'"); $$.typ = $2.typ; } else if ($1->type == Tulong) switch ($2.typ->type) { case Tint: $$.typ = $1; break; case Tlong: $$.typ = mkullong(); break; case Tuint: $$.typ = $1; break; case Tulong: $$.typ = mkullong(); break; default: semwarn("illegal use of 'long'"); $$.typ = $2.typ; } else if ($2.typ->type == Tint) $$.typ = $1; else semwarn("invalid type (missing ';'?)"); $$.sto = $2.sto; sp->node = $$; } ;tspec : store { $$.typ = mkint(); $$.sto = $1; sp->node = $$; if ($1 & Sextern) transient = 0; } | type { $$.typ = $1; $$.sto = Snone; sp->node = $$; } | store tspec { $$.typ = $2.typ; $$.sto = (Storage)((int)$1 | (int)$2.sto); if (($$.sto & Sattribute) && !is_primitive_or_string($2.typ) && !is_stdstr($2.typ) && !is_binary($2.typ) && !is_external($2.typ)) { semwarn("invalid attribute type"); $$.sto &= ~Sattribute; } sp->node = $$; if ($1 & Sextern) transient = 0; } | type tspec { if ($1->type == Tint) switch ($2.typ->type) { case Tchar: $$.typ = $2.typ; break; case Tshort: $$.typ = $2.typ; break; case Tint: $$.typ = $1; break; case Tlong: $$.typ = $2.typ; break; case Tllong: $$.typ = $2.typ; break; default: semwarn("illegal use of 'signed'"); $$.typ = $2.typ; } else if ($1->type == Tuint) switch ($2.typ->type) { case Tchar: $$.typ = mkuchar(); break; case Tshort: $$.typ = mkushort(); break; case Tint: $$.typ = $1; break; case Tlong: $$.typ = mkulong(); break; case Tllong: $$.typ = mkullong(); break; default: semwarn("illegal use of 'unsigned'"); $$.typ = $2.typ; } else if ($1->type == Tlong) switch ($2.typ->type) { case Tint: $$.typ = $1; break; case Tlong: $$.typ = mkllong(); break; case Tuint: $$.typ = mkulong(); break; case Tulong: $$.typ = mkullong(); break; case Tdouble: $$.typ = mkldouble(); break; default: semwarn("illegal use of 'long'"); $$.typ = $2.typ; } else if ($1->type == Tulong) switch ($2.typ->type) { case Tint: $$.typ = $1; break; case Tlong: $$.typ = mkullong(); break; case Tuint: $$.typ = $1; break; case Tulong: $$.typ = mkullong(); break; default: semwarn("illegal use of 'long'"); $$.typ = $2.typ; } else if ($2.typ->type == Tint) $$.typ = $1; else semwarn("invalid type"); $$.sto = $2.sto; sp->node = $$; } ;type : VOID { $$ = mkvoid(); } | BOOL { $$ = mkbool(); } | CHAR { $$ = mkchar(); } | WCHAR { $$ = mkwchart(); } | SHORT { $$ = mkshort(); } | INT { $$ = mkint(); } | LONG { $$ = mklong(); } | LLONG { $$ = mkllong(); } | ULLONG { $$ = mkullong(); } | SIZE { $$ = mkulong(); } | FLOAT { $$ = mkfloat(); } | DOUBLE { $$ = mkdouble(); } | SIGNED { $$ = mkint(); } | UNSIGNED { $$ = mkuint(); } | TIME { $$ = mktimet(); } | TEMPLATE '<' tname id '>' CLASS id { if (!(p = entry(templatetable, $7))) { p = enter(templatetable, $7); p->info.typ = mktemplate(NULL, $7); $7->token = TYPE; } $$ = p->info.typ; } | CLASS '{' s2 decls '}' { sym = gensym("_Struct"); sprintf(errbuf, "anonymous class will be named '%s'", sym->name); semwarn(errbuf); if ((p = entry(classtable, sym))) { if (p->info.typ->ref || p->info.typ->type != Tclass) { sprintf(errbuf, "class '%s' already declared at line %d", sym->name, p->lineno); semerror(errbuf); } } else { p = enter(classtable, sym); p->info.typ = mkclass((Table*)0, 0); } sym->token = TYPE; sp->table->sym = sym; p->info.typ->ref = sp->table; p->info.typ->width = sp->offset; p->info.typ->id = sym; $$ = p->info.typ; exitscope(); } | class '{' s2 decls '}' { p = reenter(classtable, $1->sym); sp->table->sym = p->sym; p->info.typ->ref = sp->table; p->info.typ->width = sp->offset; p->info.typ->id = p->sym; if (p->info.typ->base) sp->table->prev = (Table*)entry(classtable, p->info.typ->base)->info.typ->ref; $$ = p->info.typ; exitscope(); } | class ':' base '{' s2 decls '}' { p = reenter(classtable, $1->sym); sp->table->sym = p->sym; if (!$3) semerror("invalid base class"); else { sp->table->prev = (Table*)$3->info.typ->ref; if (!sp->table->prev && !$3->info.typ->transient) { sprintf(errbuf, "class '%s' has incomplete type", $3->sym->name); semerror(errbuf); } p->info.typ->base = $3->info.typ->id; } p->info.typ->ref = sp->table; p->info.typ->width = sp->offset; p->info.typ->id = p->sym; $$ = p->info.typ; exitscope(); } | class { $1->info.typ->id = $1->sym; $$ = $1->info.typ; } | class ':' base { if (!$3) semerror("invalid base class"); else { if (!$3->info.typ->ref && !$3->info.typ->transient) { sprintf(errbuf, "class '%s' has incomplete type", $3->sym->name); semerror(errbuf); } $1->info.typ->base = $3->info.typ->id; } $1->info.typ->id = $1->sym; $$ = $1->info.typ; } | STRUCT '{' s2 decls '}' { sym = gensym("_Struct"); sprintf(errbuf, "anonymous struct will be named '%s'", sym->name); semwarn(errbuf); if ((p = entry(classtable, sym))) { if (p->info.typ->ref || p->info.typ->type != Tstruct) { sprintf(errbuf, "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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -