📄 soapcpp2_yacc.y
字号:
} | aexp { $$ = $1; } ;obex : oexp { $$ = $1; } ;/* aexp : and-expression */aexp : abex AN rexp { $$.hasval = False; $$.typ = mkint(); } | rexp { $$ = $1; } ;abex : aexp { $$ = $1; } ;/* rexp : relational expression */rexp : rexp '|' rexp { $$ = iop("|", $1, $3); } | rexp '^' rexp { $$ = iop("^", $1, $3); } | rexp '&' rexp { $$ = iop("&", $1, $3); } | rexp EQ rexp { $$ = relop("==", $1, $3); } | rexp NE rexp { $$ = relop("!=", $1, $3); } | rexp '<' rexp { $$ = relop("<", $1, $3); } | rexp LE rexp { $$ = relop("<=", $1, $3); } | rexp '>' rexp { $$ = relop(">", $1, $3); } | rexp GE rexp { $$ = relop(">=", $1, $3); } | rexp LS rexp { $$ = iop("<<", $1, $3); } | rexp RS rexp { $$ = iop(">>", $1, $3); } | rexp '+' rexp { $$ = op("+", $1, $3); } | rexp '-' rexp { $$ = op("-", $1, $3); } | rexp '*' rexp { $$ = op("*", $1, $3); } | rexp '/' rexp { $$ = op("/", $1, $3); } | rexp '%' rexp { $$ = iop("%", $1, $3); } | lexp { $$ = $1; } ;/* lexp : lvalue kind of expression with optional prefix contructs */lexp : '!' lexp { if ($2.hasval) $$.val.i = !$2.val.i; $$.typ = $2.typ; $$.hasval = $2.hasval; } | '~' lexp { if ($2.hasval) $$.val.i = ~$2.val.i; $$.typ = $2.typ; $$.hasval = $2.hasval; } | '-' lexp { if ($2.hasval) { if (integer($2.typ)) $$.val.i = -$2.val.i; else if (real($2.typ)) $$.val.r = -$2.val.r; else typerror("string?"); } $$.typ = $2.typ; $$.hasval = $2.hasval; } | '+' lexp { $$ = $2; } | '*' lexp { if ($2.typ->type == Tpointer) { $$.typ = (Tnode*) $2.typ->ref; } else typerror("dereference of non-pointer type"); $$.sto = Snone; $$.hasval = False; } | '&' lexp { $$.typ = mkpointer($2.typ); $$.sto = Snone; $$.hasval = False; } | SIZEOF '(' texp ')' { $$.hasval = True; $$.typ = mkint(); $$.val.i = $3.typ->width; } | pexp { $$ = $1; } ;/* pexp : primitive expression with optional postfix constructs */pexp : '(' expr ')' { $$ = $2; } | ID { if ((p = enumentry($1)) == (Entry*) 0) p = undefined($1); else $$.hasval = True; $$.typ = p->info.typ; $$.val = p->info.val; } | LNG { $$.typ = mkint(); $$.hasval = True; $$.val.i = $1; } | null { $$.typ = mkint(); $$.hasval = True; $$.val.i = 0; } | DBL { $$.typ = mkfloat(); $$.hasval = True; $$.val.r = $1; } | CHR { $$.typ = mkchar(); $$.hasval = True; $$.val.i = $1; } | STR { $$.typ = mkstring(); $$.hasval = True; $$.val.s = $1; } | CFALSE { $$.typ = mkbool(); $$.hasval = True; $$.val.i = 0; } | CTRUE { $$.typ = mkbool(); $$.hasval = True; $$.val.i = 1; } ;%%/* * ??? */intyywrap(){ return 1;}/******************************************************************************\ Support routines\******************************************************************************/static Nodeop(const char *op, Node p, Node q){ Node r; Tnode *typ; r.typ = p.typ; r.sto = Snone; if (p.hasval && q.hasval) { if (integer(p.typ) && integer(q.typ)) switch (op[0]) { case '|': r.val.i = p.val.i | q.val.i; break; case '^': r.val.i = p.val.i ^ q.val.i; break; case '&': r.val.i = p.val.i & q.val.i; break; case '<': r.val.i = p.val.i << q.val.i; break; case '>': r.val.i = p.val.i >> q.val.i; break; case '+': r.val.i = p.val.i + q.val.i; break; case '-': r.val.i = p.val.i - q.val.i; break; case '*': r.val.i = p.val.i * q.val.i; break; case '/': r.val.i = p.val.i / q.val.i; break; case '%': r.val.i = p.val.i % q.val.i; break; default: typerror(op); } else if (real(p.typ) && real(q.typ)) switch (op[0]) { case '+': r.val.r = p.val.r + q.val.r; break; case '-': r.val.r = p.val.r - q.val.r; break; case '*': r.val.r = p.val.r * q.val.r; break; case '/': r.val.r = p.val.r / q.val.r; break; default: typerror(op); } else semerror("illegal constant operation"); r.hasval = True; } else { typ = mgtype(p.typ, q.typ); r.hasval = False; } return r;}static Nodeiop(const char *iop, Node p, Node q){ if (integer(p.typ) && integer(q.typ)) return op(iop, p, q); typerror("integer operands only"); return p;}static Noderelop(const char *op, Node p, Node q){ Node r; Tnode *typ; r.typ = mkint(); r.sto = Snone; r.hasval = False; if (p.typ->type != Tpointer || p.typ != q.typ) typ = mgtype(p.typ, q.typ); return r;}/******************************************************************************\ Scope management\******************************************************************************//*mkscope - initialize scope stack with a new table and offset*/static voidmkscope(Table *table, int offset){ sp = stack-1; enterscope(table, offset);}/*enterscope - enter a new scope by pushing a new table and offset on the stack*/static voidenterscope(Table *table, int offset){ if (++sp == stack+MAXNEST) execerror("maximum scope depth exceeded"); sp->table = table; sp->val = 0; sp->offset = offset; sp->grow = True; /* by default, offset grows */ sp->mask = False;}/*exitscope - exit a scope by popping the table and offset from the stack*/static voidexitscope(){ check(sp-- != stack, "exitscope() has no matching enterscope()");}/******************************************************************************\ Undefined symbol\******************************************************************************/static Entry*undefined(Symbol *sym){ Entry *p; sprintf(errbuf, "undefined identifier '%s'", sym->name); semwarn(errbuf); p = enter(sp->table, sym); p->level = GLOBAL; p->info.typ = mkint(); p->info.sto = Sextern; p->info.hasval = False; return p;}/*mgtype - return most general type among two numerical types*/Tnode*mgtype(Tnode *typ1, Tnode *typ2){ if (numeric(typ1) && numeric(typ2)) { if (typ1->type < typ2->type) return typ2; } else typerror("non-numeric type"); return typ1;}/******************************************************************************\ Type checks\******************************************************************************/static intinteger(Tnode *typ){ switch (typ->type) { case Tchar: case Tshort: case Tint: case Tlong: return True; default: break; } return False;}static intreal(Tnode *typ){ switch (typ->type) { case Tfloat: case Tdouble: case Tldouble: return True; default: break; } return False;}static intnumeric(Tnode *typ){ return integer(typ) || real(typ);}static voidadd_fault(Table *gt){ Table *t; Entry *p1, *p2, *p3, *p4; Symbol *s1, *s2, *s3, *s4; imported = NULL; s1 = lookup("SOAP_ENV__Code"); p1 = entry(classtable, s1); if (!p1 || !p1->info.typ->ref) { t = mktable((Table*)0); if (!p1) { p1 = enter(classtable, s1); p1->info.typ = mkstruct(t, 3*4); p1->info.typ->id = s1; } else p1->info.typ->ref = t; p2 = enter(t, lookup("SOAP_ENV__Value")); p2->info.typ = qname; p2->info.minOccurs = 0; p2 = enter(t, lookup("SOAP_ENV__Subcode")); p2->info.typ = mkpointer(p1->info.typ); p2->info.minOccurs = 0; } s2 = lookup("SOAP_ENV__Detail"); p2 = entry(classtable, s2); if (!p2 || !p2->info.typ->ref) { t = mktable((Table*)0); if (!p2) { p2 = enter(classtable, s2); p2->info.typ = mkstruct(t, 3*4); p2->info.typ->id = s2; } else p2->info.typ->ref = t; p3 = enter(t, lookup("__type")); p3->info.typ = mkint(); p3->info.minOccurs = 0; p3 = enter(t, lookup("fault")); p3->info.typ = mkpointer(mkvoid()); p3->info.minOccurs = 0; p3 = enter(t, lookup("__any")); p3->info.typ = xml; p3->info.minOccurs = 0; custom_fault = 0; } s4 = lookup("SOAP_ENV__Reason"); p4 = entry(classtable, s4); if (!p4 || !p4->info.typ->ref) { t = mktable((Table*)0); if (!p4) { p4 = enter(classtable, s4); p4->info.typ = mkstruct(t, 4); p4->info.typ->id = s4; } else p4->info.typ->ref = t; p3 = enter(t, lookup("SOAP_ENV__Text")); p3->info.typ = mkstring(); p3->info.minOccurs = 0; } s3 = lookup("SOAP_ENV__Fault"); p3 = entry(classtable, s3); if (!p3 || !p3->info.typ->ref) { t = mktable(NULL); if (!p3) p3 = enter(classtable, s3); p3->info.typ = mkstruct(t, 9*4); p3->info.typ->id = s3; p3 = enter(t, lookup("faultcode")); p3->info.typ = qname; p3->info.minOccurs = 0; p3 = enter(t, lookup("faultstring")); p3->info.typ = mkstring(); p3->info.minOccurs = 0; p3 = enter(t, lookup("faultactor")); p3->info.typ = mkstring(); p3->info.minOccurs = 0; p3 = enter(t, lookup("detail")); p3->info.typ = mkpointer(p2->info.typ); p3->info.minOccurs = 0; p3 = enter(t, s1); p3->info.typ = mkpointer(p1->info.typ); p3->info.minOccurs = 0; p3 = enter(t, s4); p3->info.typ = mkpointer(p4->info.typ); p3->info.minOccurs = 0; p3 = enter(t, lookup("SOAP_ENV__Node")); p3->info.typ = mkstring(); p3->info.minOccurs = 0; p3 = enter(t, lookup("SOAP_ENV__Role")); p3->info.typ = mkstring(); p3->info.minOccurs = 0; p3 = enter(t, lookup("SOAP_ENV__Detail")); p3->info.typ = mkpointer(p2->info.typ); p3->info.minOccurs = 0; }}static voidadd_XML(){ Symbol *s = lookup("_XML"); p = enter(typetable, s); xml = p->info.typ = mksymtype(mkstring(), s); p->info.sto = Stypedef;}static voidadd_qname(){ Symbol *s = lookup("_QName"); p = enter(typetable, s); qname = p->info.typ = mksymtype(mkstring(), s); p->info.sto = Stypedef;}static voidadd_header(Table *gt){ Table *t; Entry *p; Symbol *s = lookup("SOAP_ENV__Header"); imported = NULL; p = entry(classtable, s); if (!p || !p->info.typ->ref) { t = mktable((Table*)0); if (!p) p = enter(classtable, s); p->info.typ = mkstruct(t, 0); p->info.typ->id = s; custom_header = 0; }}static voidadd_response(Entry *fun, Entry *ret){ Table *t; Entry *p, *q; Symbol *s; size_t n = strlen(fun->sym->name); char *r = (char*)emalloc(n+9); strcpy(r, fun->sym->name); strcat(r, "Response"); if (!(s = lookup(r))) s = install(r, ID); free(r); t = mktable((Table*)0); q = enter(t, ret->sym); q->info = ret->info; if (q->info.typ->type == Treference) q->info.typ = (Tnode*)q->info.typ->ref; p = enter(classtable, s); p->info.typ = mkstruct(t, 4); p->info.typ->id = s; fun->info.typ->response = p;}static voidadd_result(Tnode *typ){ Entry *p; if (!typ->ref || !((Tnode*)typ->ref)->ref) { semwarn("response struct/class must be declared before used in function prototype"); return; } for (p = ((Table*)((Tnode*)typ->ref)->ref)->list; p; p = p->next) if (p->info.sto & Sreturn) return; for (p = ((Table*)((Tnode*)typ->ref)->ref)->list; p; p = p->next) { if (p->info.typ->type != Tfun && !(p->info.sto & Sattribute) && !is_transient(p->info.typ) && !(p->info.sto & (Sprivate|Sprotected))) p->info.sto = (Storage)((int)p->info.sto | (int)Sreturn); return; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -