?? soapcpp2.y
字號:
/* soapcpp2.y Yacc/Bison grammarThe contents of this file are subject to the Mozilla Public License Version 1.1(the "License"); you may not use this file except in compliance with theLicense. You may obtain a copy of the License athttp://www.cs.fsu.edu/~engelen/gsoapcompilerlicense.htmlSoftware distributed under the License is distributed on an "AS IS" basis,WITHOUT WARRANTY OF ANY KIND, either express or implied. See the Licensefor the specific language governing rights and limitations under the License.The Original Code is ''gSOAP compiler'' consisting of:error2.c, error2.h, init2.c, soapcpp2.c, soapcpp2.h, soapcpp2.l, soapcpp2.y, symbol2.c.The Initial Developer of the Original Code is Robert A. van Engelen.Copyright (C) 2000-2002 Robert A. van Engelen. All Rights Reserved.*/%{#include "soapcpp2.h"#ifdef WIN32extern int soapcpp2lex();#endif#define MAXNEST 8 /* max. nesting depth of scopes */struct Scope{ Table *table; Entry *entry; Node node; LONG64 val; int offset; Bool grow; /* true if offset grows with declarations */ Bool mask; /* true if enum is mask */} stack[MAXNEST], /* stack of tables and offsets */ *sp; /* current scope stack pointer */Table *classtable = (Table*)0, *uniontable = (Table*)0, *enumtable = (Table*)0, *typetable = (Table*)0, *booltable = (Table*)0;Symbol *namespaceid = NULL;int transient = 0;int custom_header = 1;int custom_fault = 1;/* function prototypes for support routine section */static Entry *undefined(Symbol*);static Tnode *mgtype(Tnode*, Tnode*);static Node op(const char*, Node, Node), iop(const char*, Node, Node), relop(const char*, Node, Node);static void mkscope(Table*, int), enterscope(Table*, int), exitscope();static int integer(Tnode*), real(Tnode*), numeric(Tnode*), pointer(Tnode*);static void add_header(Table*), add_fault(Table*), add_response(Entry*, Entry*);extern char *c_storage(Storage), *c_type(Tnode*);/* temporaries used in semantic rules */int i;char *s, *s1, *s2;Symbol *sym;Entry *p, *q;Tnode *t;Node tmp, c;%}%union{ Symbol *sym; LONG64 i; double r; char c; char *s; Tnode *typ; Storage sto; Node rec; Entry *e;}/* pragmas */%token <s> PRAGMA/* keywords */%token <sym> AUTO DOUBLE INT STRUCT%token <sym> BREAK ELSE LONG SWITCH%token <sym> CASE ENUM REGISTER TYPEDEF%token <sym> CHAR EXTERN RETURN UNION%token <sym> CONST FLOAT SHORT UNSIGNED%token <sym> CONTINUE FOR SIGNED VOID%token <sym> DEFAULT GOTO SIZEOF VOLATILE%token <sym> DO IF STATIC WHILE%token <sym> CLASS PRIVATE PROTECTED PUBLIC%token <sym> VIRTUAL INLINE OPERATOR LLONG%token <sym> BOOL CFALSE CTRUE WCHAR%token <sym> TIME USING NAMESPACE ULLONG%token <sym> MUSTUNDERSTAND SIZE/* */%token NONE/* identifiers (TYPE = typedef identifier) */%token <sym> ID TYPE/* constants */%token <i> LNG%token <r> DBL%token <c> CHR%token <s> STR/* types and related */%type <typ> type%type <sto> store virtual constobj abstract%type <e> fname class super%type <sym> name/* expressions and statements */%type <rec> expr cexp oexp obex aexp abex rexp lexp pexp init spec tspec ptrs array texp qexp occurs/* terminals */%left ','%right '=' PA NA TA DA MA AA XA OA LA RA /* += -= *= /= %= &= ^= |= <<= >>= */%right '?'%right ':'%left OR /* || */%left AN /* && */%left '|'%left '^'%left '&'%left EQ NE /* == != */%left '<' LE '>' GE /* <= >= */%left LS RS /* << >> */%left '+' '-'%left '*' '/' '%'%left AR /* -> */%token PP NN /* ++ -- */%%/******************************************************************************\ Program syntax\******************************************************************************/prog : s1 exts { add_header(sp->table); add_fault(sp->table); compile(sp->table); freetable(classtable); freetable(uniontable); freetable(enumtable); freetable(typetable); freetable(booltable); } ;s1 : /* empty */ { classtable = mktable((Table*)0); uniontable = mktable((Table*)0); enumtable = mktable((Table*)0); typetable = mktable((Table*)0); booltable = mktable((Table*)0); p = enter(booltable, lookup("false")); p->info.typ = mkint(); p->info.val.i = 0; p = enter(booltable, lookup("true")); p->info.typ = mkint(); p->info.val.i = 1; mkscope(mktable(mktable((Table*)0)), 0); } ;exts : NAMESPACE ID '{' exts1 '}' /* for future use */ { namespaceid = $2; } | exts1 { namespaceid = NULL; }exts1 : /* empty */ | exts1 ext ;ext : dclrs ';' /* declaration */ | pragma | error ';' { synerror("input before ; skipped"); while (sp > stack) { freetable(sp->table); exitscope(); } yyerrok; } | '[' { transient++; } | ']' { transient--; if (transient < 0) { semwarn("Too many ']'"); transient = 0; } } ;pragma : PRAGMA { if (i = atoi($1+1) > 0) yylineno = i; /* doesn't work, why??? */ else { sprintf(errbuf, "ignoring pragma `%s'", $1); semwarn(errbuf); } } ;/******************************************************************************\ Declarations\******************************************************************************/decls : /* empty */ | dclrs ';' decls { } | PRIVATE ':' decls { } | PROTECTED ':' decls { } | PUBLIC ':' decls { } | '[' t1 decls ']' t2 decls { } ;t1 : /* empty */ { transient++; } ;t2 : /* empty */ { transient--; if (transient < 0) { semwarn("Too many ']'"); transient = 0; } } ;dclrs : spec fdclr func { } | spec dclr { } | spec { } | dclrs ',' fdclr func { } | dclrs ',' dclr { } | constr func { } | destr func { } ;dclr : ptrs ID array occurs init { if ($3.sto & Stypedef) { p = enter(typetable, $2); p->info.typ = mksymtype($3.typ, $2); if ($3.sto & Sextern) p->info.typ->transient = -1; p->info.sto = $3.sto; $2->token = TYPE; } else { p = enter(sp->table, $2); p->info.typ = $3.typ; p->info.sto = $3.sto; if ($5.hasval) { p->info.hasval = True; switch ($3.typ->type) { case Tchar: case Tuchar: case Tshort: case Tushort: case Tint: case Tuint: case Tlong: case Tulong: case Tenum: case Ttime: if ($5.typ->type == Tint || $5.typ->type == Tchar) sp->val = p->info.val.i = $5.val.i; else semerror("type error in initialization constant"); break; case Tfloat: case Tdouble: if ($5.typ->type == Tfloat || $5.typ->type == Tdouble) p->info.val.r = $5.val.r; else semerror("type error in initialization constant"); break; default: if ($5.typ->type == Tpointer && ((Tnode*)$5.typ->ref)->type == Tchar) p->info.val.s = $5.val.s; else semerror("Initialization constant type error"); break; } } else p->info.val.i = sp->val; p->info.minOccurs = $4.minOccurs; p->info.maxOccurs = $4.maxOccurs; if (sp->mask) sp->val <<= 1; else sp->val++; p->info.offset = sp->offset; if ($3.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; } ;fdclr : ptrs name { if ($1.sto & Stypedef) { p = enter(typetable, $2); p->info.typ = mksymtype($1.typ, $2); p->info.sto = $1.sto; $2->token = TYPE; } else { p = enter(sp->table, $2); p->info.typ = $1.typ; p->info.sto = $1.sto; p->info.hasval = False; p->info.offset = sp->offset; /* if ($1.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; } ;name : ID { $$ = $1; } | OPERATOR '=' { $$ = lookup("operator="); } | OPERATOR PA { $$ = lookup("operator+="); } | OPERATOR NA { $$ = lookup("operator-="); } | OPERATOR TA { $$ = lookup("operator*="); } | OPERATOR DA { $$ = lookup("operator/="); } | OPERATOR MA { $$ = lookup("operator%="); } | OPERATOR AA { $$ = lookup("operator&="); } | OPERATOR XA { $$ = lookup("operator^="); } | OPERATOR OA { $$ = lookup("operator|="); } | OPERATOR LA { $$ = lookup("operator<<="); } | OPERATOR RA { $$ = lookup("operator>>="); } | OPERATOR OR { $$ = lookup("operator||"); } | OPERATOR AN { $$ = lookup("operator&&"); } | OPERATOR '|' { $$ = lookup("operator|"); } | OPERATOR '^' { $$ = lookup("operator^"); } | 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'['']'{ $$ = 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)) == (Entry*)0) semerror("illegal 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)) == (Entry*)0) semerror("illegal 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 '(' s2 fargso ')' constobj abstract { if ($1->level == GLOBAL) { if (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); } 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) { $1->info.typ = mkfun(sp->entry); if (!is_transient(sp->entry->info.typ) && !is_response(sp->entry->info.typ)) add_response($1, sp->entry); } 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); } unlinklast(sp->table); if ((p = entry(classtable, $1->sym)) != (Entry*) 0) if ((Table*) p->info.typ->ref != (Table*) 0) { sprintf(errbuf, "remote method name clash: struct/class `%s' already defined (reference from 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 |= $6 | $7; } exitscope(); } ;fname : { $$ = sp->entry; } ;fargso : /* empty */ { } | fargs { } ;fargs : farg { } | farg ',' fargs { } ;farg : spec dclr { } ;/******************************************************************************\ Type specification\******************************************************************************//* texp : type expression (subset of C) */texp : tspec ptrs array { $$ = $3; } ;spec : /*empty */ { $$.typ = mkint();
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -