/* check domains cardinality agreement */ static int checkDoms(Expr *x1, Expr *x2) { if ((x1->nvals != 1) && (x2->nvals != 1)) { if (x1->hdom != x2->hdom) { synerr(); fprintf(stderr, "host domains have different size (%d and %d)\n", x1->hdom, x2->hdom); return 0; } if (x1->e_idom != x2->e_idom) { synerr(); fprintf(stderr, "instance domains have different size (%d and %d)\n", x1->e_idom, x2->e_idom); return 0; } if (x1->tdom != x2->tdom) { synerr(); fprintf(stderr, "time domains have different size (%d and %d)\n", x1->tdom, x2->tdom); return 0; } } return 1; }
FUNCTION CODE getkey ( FAST struct SYNBLK *sb, /* in/out: symbol table */ TEXT key[TOKESIZ+1] /* out: parameter name */ ) { FAST CODE code; FAST CODE toktyp; /* token type */ TEXT dummy[TOKESIZ+1]; key[0] = EOS; code = SUCCESS; if ((toktyp = gettok(sb, key)) == S_WHITE) /* get token into key */ toktyp = gettok(sb, key); /* if white, get another */ if (toktyp == S_COMSEP) /* if comma separator */ code = S_NONE; else if (toktyp == EOS) if ((*sb).lstcg == S_COMSEP) /* if following comma */ { code = S_NONE; /* null value */ (*sb).lstcg = EOS; } else /* otherwise */ code = EOS; /* end of command stream */ else if (toktyp == FLAG_CHAR) /* start of flagged keyword? */ code = S_KEYWORD; else if (toktyp != S_ALPHA && toktyp != S_QALPHA) { (*sb).errchr = (*sb).curchr - 1;/* point to where error detected */ synerr(sb, "Invalid parameter name"); /* put EM in syntax block */ code = S_SYNERR; } else /* got a keyword (or positional value) */ { if ((toktyp = gettok(sb, dummy)) == S_WHITE) /* eat the "=" */ toktyp = gettok(sb, dummy); if (toktyp == '=') /* if trailing "=" was present */ { if (s_length(key) > F_Q_NAMESIZ) { (*sb).errchr = (*sb).curchr - 1; synerr(sb, "Parameter name too long"); code = S_SYNERR; } } else /* else no trailing blank, so... */ code = S_NONE; /* value without keyword */ } return(code); }
/* truth valued variable */ Expr * boolVar(Expr *x) { if (x->sem == SEM_CHAR) { synerr(); fprintf(stderr, "truth valued variable expected\n"); return NULL; } return x; }
/* numeric valued variable */ Expr * numVar(Expr *x) { if (x->sem == SEM_BOOLEAN || x->sem == SEM_CHAR) { synerr(); fprintf(stderr, "numeric valued variable expected\n"); return NULL; } return x; }
/********************************** * We put out an external definition. */ void out_extdef(symbol *s) { pstate.STflags |= PFLextdef; if (//config.flags2 & CFG2phgen || (config.flags2 & (CFG2phauto | CFG2phautoy) && !(pstate.STflags & (PFLhxwrote | PFLhxdone))) ) synerr(EM_data_in_pch,prettyident(s)); // data or code in precompiled header }
void ndinstal(char *name, Char *definition) { char *copy_string(); Char *copy_unsigned_string(); if ( addsym( copy_string( name ), (char *) copy_unsigned_string( definition ), 0, ndtbl, NAME_TABLE_HASH_SIZE ) ) synerr( _( "name defined twice" ) ); }
/* ANMTGRP: Parse a name or name token group, create attribute descriptors for its members, and add them to the attribute descriptor list. The parse either terminates or returns a good token, so no switch is needed. */ int anmtgrp(struct parse *pcb, /* PCB for name or name token grp. */ struct ad nt[], /* Buffer for creating name token list. */ int grplim, /* Maximum size of list (plus 1). */ UNS *adn, /* Ptr to number of names or tokens in grp. */ int adsz) /* Size of att def list. */ { UNCH adtype = (UNCH)(pcb==&pcbgrnt ? ANMTGRP:ANOTEGRP);/*Attribute type.*/ int essv = es; /* Entity stack level when grp started. */ *adn = 0; /* Group is empty to start. */ while (parse(pcb)!=GRPE && *adn<grplim) { switch (pcb->action) { case NAS_: /* Name or name token (depending on pcb). */ case NMT_: parsenm(lbuf, NAMECASE); nt[*adn+1].adname = savenm(lbuf); if (antvget((int)(adsz+*adn), nt[*adn+1].adname, (UNCH **)0)) mderr(98, ntoa((int)*adn+1), nt[*adn+1].adname+1); nt[++*adn].adtype = adtype; nt[*adn].addef = NULL; continue; case EE_: /* Entity ended (correctly or incorrectly). */ if (es<essv) {synerr(37, pcb); essv = es;} continue; case PIE_: /* PI entity reference (invalid). */ entpisw = 0; /* Reset PI entity indicator. */ synerr(59, pcb); continue; default: break; } break; } if (es!=essv) synerr(37, pcb); if (*adn==grplim) return -1; else return *adn; /* Return number of tokens. */ }
/* MDNOT: Process NOTATION declaration. */ VOID mdnot(UNCH *tbuf) /* Work area for tokenization[LITLEN+2]. */ { struct fpi fpicb; /* Formal public identifier structure. */ PDCB dcb; /* Ptr to notation entity in dcntab. */ UNCH estore = ESK; /* Entity storage class. */ mdname = key[KNOTATION]; /* Identify declaration for messages. */ subdcl = NULL; /* No subject as yet. */ parmno = 0; /* No parameters as yet. */ mdessv = es; /* Save es for checking entity nesting. */ /* PARAMETER 1: Notation name. */ pcbmd.newstate = 0; parsemd(lbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("1: name"); if (pcbmd.action!=NAS) {mderr(120, (UNCH *)0, (UNCH *)0); return;} subdcl = lbuf+1; /* Save notation name for error msgs. */ /* PARAMETER 2: External identifier keyword. */ pcbmd.newstate = 0; parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("2: extid"); if (pcbmd.action!=NAS) {mderr(29, (UNCH *)0, (UNCH *)0); return;} if (mdextid(tbuf, &fpicb, lbuf+1, &estore, (PNE)0)==0) return; /* PARAMETER 3: End of declaration. Token was parsed by MDEXTID. */ TRACEMD(emd); if (pcbmd.action!=EMD) mderr(126, (UNCH *)0, (UNCH *)0); if (es!=mdessv) synerr(37, &pcbmd); /* EXECUTE: Store notation name. */ if ((dcb = dcnfind(lbuf)) != 0 && dcb->defined) { mderr(56, lbuf+1, (UNCH *)0); return; } /* else */ dcb = dcndef(lbuf); dcb->defined = 1; dcb->sysid = fpicb.fpisysis ? savestr(fpicb.fpisysis) : 0; dcb->pubid = fpicb.fpipubis ? savestr(fpicb.fpipubis) : 0; ++ds.dcncnt; ds.dcntext += entlen; TRACEDCN(dcb); return; }
/* boolean merge expression */ Expr * boolMergeExpr(int op, Expr *arg) { /* error guard */ if (arg == NULL) return NULL; /* check argument semantics */ if (arg->sem != SEM_BOOLEAN) { synerr(); fprintf(stderr, "operator \"%s\" requires boolean valued argument\n", opStrings(op)); return NULL; } return mergeExpr(op, arg); }
/* MDDTDE: Process DOCTYPE declaration end. */ VOID mddtde(UNCH *tbuf) /* Work area for tokenization. */ { mdessv = es; /* Save es for checking entity nesting. */ propcb = &pcbpro; /* Restore normal prolog parse. */ indtdsw = 0; /* Prohibit "DTD only" parameters. */ mdname = key[KDOCTYPE]; /* Identify declaration for messages. */ subdcl = dtype+1; /* Subject of declaration for error msgs. */ parmno = 0; /* No parameters as yet. */ /* PARAMETER 4: End of declaration. */ pcbmd.newstate = 0; parsemd(tbuf, NAMECASE, &pcblitp, LITLEN); TRACEMD(emd); if (pcbmd.action!=EMD) mderr(126, (UNCH *)0, (UNCH *)0); if (es!=mdessv) synerr(37, &pcbmd); }
FUNCTION CODE chkend (FAST struct SYNBLK *sb) { FAST CODE code; /* return code */ CODE toktyp; /* token type */ TEXT dummy[TOKESIZ+1]; if ((toktyp = gettok(sb, dummy)) == S_WHITE) /* get token... */ toktyp = gettok(sb, dummy); /* if white, get another */ if (toktyp == EOS) code = SUCCESS; else { code = S_SYNERR; (*sb).errchr = (*sb).curchr - 1; synerr(sb, "Unexpected trailing characters"); } return(code); }
/* MDMS: Process marked section start. If already in special parse, bump the level counters and return without parsing the declaration. */ struct parse *mdms(UNCH *tbuf, /* Work area for tokenization [NAMELEN+2]. */ struct parse *pcb) /* Parse control block for this parse. */ { int key; /* Index of keyword in mslist. */ int ptype; /* Parameter token type. */ int pcbcode = 0; /* Parse code: 0=same; 2-4 per defines. */ if (++mslevel>TAGLVL) { --mslevel; sgmlerr(27, (struct parse *)0, ntoa(TAGLVL), (UNCH *)0); } /* If already in IGNORE mode, return without parsing parameters. */ if (msplevel) {++msplevel; return(pcb);} parmno = 0; /* No parameters as yet. */ mdessv = es; /* Save es for checking entity nesting. */ pcbmd.newstate = pcbmdtk; /* First separator is optional. */ /* PARAMETERS: TEMP, RCDATA, CDATA, IGNORE, INCLUDE, or MDS. */ while ((ptype = parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN))==NAS){ if ((key = mapsrch(mstab, tbuf+1))==0) { sgmlerr(64, (struct parse *)0, ntoa(parmno), tbuf+1); continue; } if (key==MSTEMP) continue; /* TEMP: for documentation. */ msplevel = 1; /* Special parse required. */ if (key>pcbcode) pcbcode = key; /* Update if higher priority. */ } if (ptype!=MDS) { NEWCC; /* Syntax error did REPEATCC. */ sgmlerr(97, (struct parse *)0, lex.m.dso, (UNCH *)0); REPEATCC; /* 1st char of marked section. */ } if (es!=mdessv) synerr(37, pcb); TRACEMS(1, pcbcode, mslevel, msplevel); if (pcbcode==MSIGNORE) pcb = &pcbmsi; else if (pcbcode) { pcb = pcbcode==MSCDATA ? &pcbmsc : (rcessv = es, &pcbmsrc); } return(pcb); /* Tell caller whether to change the parse. */ }
/* construct rule Expr */ Expr * ruleExpr(Expr *cond, Expr *act) { Expr *x; if (cond == NULL) return act; if (act == NULL) return cond; if (cond->nvals != 1) { synerr(); fprintf(stderr, "rule condition must have a single boolean value\n"); } perf->numrules++; x = newExpr(RULE, cond, act, -1, -1, -1, 1, SEM_BOOLEAN); newRingBfr(x); findEval(x); return x; }
FUNCTION static CODE de_ref ( FAST struct SYNBLK *sb, /* in/out: syntax blk -- cmd stream*/ FAST TEXT name[F_Q_NAMESIZ+1] /* out: deref'd var name string */ ) { TEXT token[TOKESIZ+1]; FAST CODE toke_type; TEXT *init_pos, *fld_pos; CODE code; name[0] = EOS; init_pos = SAVPOS; toke_type = gettok(sb, token); if (toke_type == S_WHITE) toke_type = gettok(sb, token); if (toke_type == '@') { fld_pos = SAVPOS; /* posit of begin of name field */ toke_type = gettok(sb, token); /* look for symbol */ if (toke_type == S_ALPHA || toke_type == S_QALPHA) { SETPOS(fld_pos); /* back up to get entire name fld*/ code = getfld(sb, token); if (code == SUCCESS || code == S_WHITE || code == S_COMSEP || code == EOS) { s_bcopy(token, name, F_Q_NAMESIZ); (*sb).lstcg = code; return (SUCCESS); } } (*sb).errchr = (*sb).curchr - 1; synerr(sb, "A variable name must follow '@'."); return (S_SYNERR); } SETPOS(init_pos); /* return to init pos */ return (FAIL); }
/* statement */ Symbol statement(char *name, Expr *x) { Symbol s; /* error guard */ if (x == NULL) return NULL; /* if name not given, make one up */ if (name == NULL) name = nameGen(); /* the parsed object is a rule (expression to evaluate) */ if (x->op != NOP) { if (symLookup(&rules, name)) { synerr(); fprintf(stderr, "rule \"%s\" multiply defined\n", name); freeExpr(x); return NULL; } else { if (errs == 0) { postExpr(x); s = symIntern(&rules, name); } else return NULL; } } /* the parsed object is a non-rule */ else { if ( (s = symLookup(&vars, name)) ) freeExpr(symValue(s)); else s = symIntern(&vars, name); } symValue(s) = x; return s; }
FUNCTION CODE getvrb ( FAST struct SYNBLK *sb, /* in/out: syntax block */ TEXT *verb /*out: verb */ ) { FAST CODE code; /* return code */ FAST CODE toktyp; /* token type */ code = SUCCESS; if ((toktyp = gettok(sb, verb)) == S_WHITE) /* get a token... */ toktyp = gettok(sb, verb); /* if white, get another */ if (toktyp != S_ALPHA && toktyp != S_QUOTED) { code = S_SYNERR; (*sb).errchr = (*sb).curchr - 1; synerr(sb, "Incorrectly formatted command name"); } strpqu(verb); /* remove quotes if present */ return(code); }
/* mode==0: consume spaces (excluding EOL) until a token is found, or EOF mode==1: as in 0, but EOLs are allowed before tokens return codes: 1 if a non-null token was found 0 on EOL and no token (including truncated quoted tokens) -1 on EOF and no token */ int read_token(int fd, int mode) { int result=0, t=0; int quote=0; if(c==buf+len) return -1; while(isspace(*c)) { if(*c=='\n') { if(!mode) return 0; line++; } c++; if(c==buf+len) { if(!fetch(fd)) return -1; } } while(!isspace(*c) || quote) { if(*c=='\n') { synerr(); t=0; goto out; } /* we want result=0 here */ if(*c=='"') { if(!quote) { quote=1; goto inc; } else { quote=0; result=1; goto inc; } } else { token[t++]=*c; if(t==TOKEN_LEN) diag(SS_PARSER|DIE|ERROR, "Token too long in config file at line %d\n",line); } inc: c++; if(c==buf+len) { if(!fetch(fd)) { result=-1; break; } } if(result) break; } out: token[t]=0; /* diag(SS_PARSER|DEBUG,"Line %d\ttoken: %s\n",line,token); */ if(t) result=1; return result; }
/** mapdoc - map a function to each document in a document list * * mapdoc calls the specified function for each document in * the passed document list. The document list is passed as * a handle to the folder, and the list of document id's. * The specified function is called with the folder handle * and the document id as arguments. * * This procedure just parses the given list into ranges; * a range may contain only one value, in which case * the low and high values will be the same. * Once the range has been determined, the work is farmed * out to the routine 'maprange' which does all of the * calling. * * Entry: name = ptr to string containing the list of docid's * fh = handle to folder containing documents * func = ptr to function to be called for each document * Return: none */ static VOID mapdoc(INT (*func)(Fhandle, Docid), Fhandle fh, PSTR list) { Docid low, high; INT flags; /* name is "all" */ if ( list == NULL ) { high = getfldlen(fh); maprange(MINDOCID, high, fh, func); return; } while ( *list != '\0' ) { flags = 0; /* get beginning of range */ if ( *list == '-' ) { low = MINDOCID; flags = 1; } else { if ( scan(&list, (PSHORT)&low) ) { synerr(); return; } } /* check for only one number */ switch(*list) { case ',': case '\0': /* only one number in range */ high = low; break; case '-': /* trailer in range */ list += 1; switch(*list) { case '\0': case ',': if ( flags ) { synerr(); return; } high = getfldlen(fh); break; default: if ( scan(&list, (PSHORT)&high) ) { synerr(); return; } } break; default: synerr(); return; } if ( *list == ',' ) list += 1; if ( low > high) synerr(); else maprange(low, high, fh, func); } }
char *template_mangle(symbol *s,param_t *arglist) { /* mangling ::= '$' template_name { type | expr } type ::= "T" mangled type expr ::= integer | string | address | float | double | long_double integer ::= "I" dimension string ::= "S" string address ::= "R" zname float ::= "F" hex_digits double ::= "D" hex_digits long_double ::= "L" hex_digits */ param_t *p; assert(s); symbol_debug(s); //assert(s->Sclass == SCtemplate); //printf("\ntemplate_mangle(s = '%s', arglist = %p)\n", s->Sident, arglist); //arglist->print_list(); MangleInuse m; mangle.znamei = 0; mangle.argi = 0; mangle.np = mangle.buf; mangle.buf[BUFIDMAX + 1] = 0x55; if (NEWTEMPMANGLE) STR("?$"); else CHAR('$'); // BUG: this is for templates nested inside class scopes. // Need to check if it creates names that are properly unmanglable. cpp_zname(s->Sident); if (s->Sscope) cpp_scope(s->Sscope); for (p = arglist; p; p = p->Pnext) { if (p->Ptype) { /* Argument is a type */ if (!NEWTEMPMANGLE) CHAR('T'); cpp_argument_list(p->Ptype, 1); } else if (p->Psym) { CHAR('V'); // this is a 'class' name, but it should be a 'template' name cpp_ecsu_name(p->Psym); } else { /* Argument is an expression */ elem *e = p->Pelem; tym_t ty = tybasic(e->ET->Tty); char *p; char a[2]; int ni; char c; L2: switch (e->Eoper) { case OPconst: switch (ty) { case TYfloat: ni = FLOATSIZE; c = 'F'; goto L1; case TYdouble_alias: case TYdouble: ni = DOUBLESIZE; c = 'D'; goto L1; case TYldouble: ni = LNGDBLSIZE; c = 'L'; goto L1; L1: if (NEWTEMPMANGLE) CHAR('$'); CHAR(c); p = (char *)&e->EV.Vdouble; while (ni--) { char c; #if __GNUC__ static char hex[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; #else static char hex[16] = "0123456789ABCDEF"; #endif c = *p++; CHAR(hex[c & 15]); CHAR(hex[(c >> 4) & 15]); } break; default: #ifdef DEBUG if (!tyintegral(ty) && !tymptr(ty)) elem_print(e); #endif assert(tyintegral(ty) || tymptr(ty)); if (NEWTEMPMANGLE) STR("$0"); else CHAR('I'); cpp_dimension(el_tolongt(e)); break; } break; case OPstring: if (NEWTEMPMANGLE) STR("$S"); else CHAR('S'); if (e->EV.ss.Voffset) synerr(EM_const_init); // constant initializer expected cpp_string(e->EV.ss.Vstring,e->EV.ss.Vstrlen); break; case OPrelconst: if (e->EV.sp.Voffset) synerr(EM_const_init); // constant initializer expected s = e->EV.sp.Vsym; if (NEWTEMPMANGLE) { STR("$1"); cpp_decorated_name(s); } else { CHAR('R'); cpp_zname(s->Sident); } break; case OPvar: if (e->EV.sp.Vsym->Sflags & SFLvalue && tybasic(e->ET->Tty) != TYstruct) { e = e->EV.sp.Vsym->Svalue; goto L2; } else if (e->EV.sp.Vsym->Sclass == SCconst /*&& pstate.STintemplate*/) { CHAR('V'); // pretend to be a class name cpp_zname(e->EV.sp.Vsym->Sident); break; } default: #if SCPP #ifdef DEBUG if (!errcnt) elem_print(e); #endif synerr(EM_const_init); // constant initializer expected assert(errcnt); #endif break; } } } *mangle.np = 0; //printf("template_mangle() = '%s'\n", mangle.buf); assert(strlen(mangle.buf) <= BUFIDMAX); assert(mangle.buf[BUFIDMAX + 1] == 0x55); return mangle.buf; }
char *cpp_operator2(token_t *to, int *pcastoverload) { int i; char *s; token_t *tn; int oper; *pcastoverload = 0; if (!to || !to->TKnext) return NULL; for (i = 0; i < arraysize(oparray); i++) { //printf("[%d] %d, %d\n", i, oparray[i].tokn, tok.TKval); if (oparray[i].tokn == to->TKval) goto L1; } //printf("cpp_operator2(): castoverload\n"); *pcastoverload = 1; return NULL; L1: tn = to->TKnext; s = oparray[i].string; oper = oparray[i].oper; switch (oper) { case OPcall: if (tn->TKval != TKrpar) synerr(EM_rpar); // ')' expected break; case OPbrack: if (tn->TKval != TKrbra) synerr(EM_rbra); // ']' expected break; case OPnew: if (tn->TKval != TKlbra) break; oper = OPanew; // operator new[] s = cpp_name_anew; goto L3; case OPdelete: if (tn->TKval != TKlbra) break; oper = OPadelete; // operator delete[] s = cpp_name_adelete; L3: if (tn->TKval != TKrbra) synerr(EM_rbra); // ']' expected if (!(config.flags4 & CFG4anew)) { cpperr(EM_enable_anew); // throw -Aa to support this config.flags4 |= CFG4anew; } break; } Lret: return s; }
char *cpp_operator(int *poper,type **pt) { int i; type *typ_spec; char *s; *pt = NULL; stoken(); /* skip over operator keyword */ for (i = 0; i < arraysize(oparray); i++) { if (oparray[i].tokn == tok.TKval) goto L1; } /* Look for type conversion */ if (type_specifier(&typ_spec)) { type *t; t = ptr_operator(typ_spec); // parse ptr-operator fixdeclar(t); type_free(typ_spec); *pt = t; return cpp_typetostring(t,"?B"); } cpperr(EM_not_overloadable); // that token cannot be overloaded s = "_"; goto L2; L1: s = oparray[i].string; *poper = oparray[i].oper; switch (*poper) { case OPcall: if (stoken() != TKrpar) synerr(EM_rpar); /* ')' expected */ break; case OPbrack: if (stoken() != TKrbra) synerr(EM_rbra); /* ']' expected */ break; case OPnew: if (stoken() != TKlbra) goto Lret; *poper = OPanew; // operator new[] s = cpp_name_anew; goto L3; case OPdelete: if (stoken() != TKlbra) goto Lret; *poper = OPadelete; // operator delete[] s = cpp_name_adelete; L3: if (stoken() != TKrbra) synerr(EM_rbra); // ']' expected if (!(config.flags4 & CFG4anew)) { cpperr(EM_enable_anew); // throw -Aa to support this config.flags4 |= CFG4anew; } break; } L2: stoken(); Lret: return s; }
int yylex(void) { int toktype; static int beglin = false; if ( eofseen ) toktype = EOF; else toktype = flexscan(); if ( toktype == EOF || toktype == 0 ) { eofseen = 1; if ( sectnum == 1 ) { synerr( "premature EOF" ); sectnum = 2; toktype = SECTEND; } else if ( sectnum == 2 ) { sectnum = 3; toktype = 0; } else toktype = 0; } if ( trace ) { if ( beglin ) { fprintf( stderr, "%d\t", num_rules + 1 ); beglin = 0; } switch ( toktype ) { case '<': case '>': case '^': case '$': case '"': case '[': case ']': case '{': case '}': case '|': case '(': case ')': case '-': case '/': case '\\': case '?': case '.': case '*': case '+': case ',': (void) putc( toktype, stderr ); break; case '\n': (void) putc( '\n', stderr ); if ( sectnum == 2 ) beglin = 1; break; case SCDECL: fputs( "%s", stderr ); break; case XSCDECL: fputs( "%x", stderr ); break; case WHITESPACE: (void) putc( ' ', stderr ); break; case SECTEND: fputs( "%%\n", stderr ); /* we set beglin to be true so we'll start * writing out numbers as we echo rules. flexscan() has * already assigned sectnum */ if ( sectnum == 2 ) beglin = 1; break; case NAME: fprintf( stderr, "'%s'", nmstr ); break; case CHAR: switch ( yylval ) { case '<': case '>': case '^': case '$': case '"': case '[': case ']': case '{': case '}': case '|': case '(': case ')': case '-': case '/': case '\\': case '?': case '.': case '*': case '+': case ',': fprintf( stderr, "\\%c", yylval ); break; default: if ( ! isascii( yylval ) || ! isprint( yylval ) ) fprintf( stderr, "\\%.3o", yylval ); else (void) putc( yylval, stderr ); break; } break; case NUMBER: fprintf( stderr, "%d", yylval ); break; case PREVCCL: fprintf( stderr, "[%d]", yylval ); break; case EOF_OP: fprintf( stderr, "<<EOF>>" ); break; case 0: fprintf( stderr, "End Marker" ); break; default: fprintf( stderr, "*Something Weird* - tok: %d val: %d\n", toktype, yylval ); break; } } return ( toktype ); }
targ_size_t type_size(type *t) { targ_size_t s; unsigned long u; tym_t tyb; type_debug(t); tyb = tybasic(t->Tty); #ifdef DEBUG if (tyb >= TYMAX) /*type_print(t),*/ dbg_printf("tyb = x%lx\n",tyb); #endif assert(tyb < TYMAX); s = tysize[tyb]; if (s == (targ_size_t) -1) { switch (tyb) { // in case program plays games with function pointers case TYffunc: case TYfpfunc: #if TX86 case TYnfunc: /* in case program plays games with function pointers */ case TYhfunc: case TYnpfunc: case TYnsfunc: case TYfsfunc: case TYf16func: case TYifunc: case TYjfunc: #endif #if SCPP if (ANSI) synerr(EM_unknown_size,"function"); /* size of function is not known */ #endif s = 1; break; case TYarray: if (t->Tflags & TFsizeunknown) { #if SCPP synerr(EM_unknown_size,"array"); /* size of array is unknown */ #endif t->Tflags &= ~TFsizeunknown; } if (t->Tflags & TFvla) { s = tysize[pointertype]; break; } s = type_size(t->Tnext); u = t->Tdim * (unsigned long) s; #if TX86 && SCPP type_chksize(u); #endif s = u; break; case TYstruct: t = t->Ttag->Stype; /* find main instance */ /* (for const struct X) */ if (t->Tflags & TFsizeunknown) { #if SCPP template_instantiate_forward(t->Ttag); if (t->Tflags & TFsizeunknown) synerr(EM_unknown_size,t->Tty & TYstruct ? prettyident(t->Ttag) : "struct"); t->Tflags &= ~TFsizeunknown; #endif } assert(t->Ttag); s = t->Ttag->Sstruct->Sstructsize; break; #if SCPP case TYenum: if (t->Ttag->Senum->SEflags & SENforward) synerr(EM_unknown_size, prettyident(t->Ttag)); s = type_size(t->Tnext); break; #endif case TYvoid: #if SCPP && TARGET_WINDOS // GNUC allows it, so we will, too synerr(EM_void_novalue); // voids have no value #endif s = 1; break; #if SCPP case TYref: case TYmemptr: case TYvtshape: s = tysize(tym_conv(t)); break; case TYident: synerr(EM_unknown_size, t->Tident); s = 1; break; #endif #if MARS case TYref: s = tysize(TYnptr); break; #endif default: #ifdef DEBUG WRTYxx(t->Tty); #endif assert(0); } } return s; }
/* MDELEM: Process ELEMENT declaration. */ VOID mdelem(UNCH *tbuf) /* Work area for tokenization (tbuf). */ { UNCH *ranksuff = lbuf; /* Rank suffix. */ UNS dctype = 0; /* Declared content type (from dctab). */ UNCH fmin = 0; /* Minimization bit flags. */ int i; /* Loop counter. */ UNS u; /* Temporary variable. */ struct etd **mexgrp, **pexgrp; /* Ptr to model exceptions array. */ struct thdr *cmod, *cmodsv; /* Ptr to content model. */ UNCH *etdgi; /* GI of current etd (when going through group).*/ int minomitted = 0; /* Tag minimization parameters omitted. */ mdname = key[KELEMENT]; /* Identify declaration for messages. */ subdcl = NULL; /* No subject as yet. */ parmno = 0; /* No parameters as yet. */ mdessv = es; /* Save es level for entity nesting check. */ ranksuff[0] = 0; mexgrp = pexgrp = 0; /* PARAMETER 1: Element name or a group of them. */ parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("1: element name or grp"); switch (pcbmd.action) { case NAS: nmgrp[0] = etddef(tbuf); nmgrp[1] = 0; break; case GRPS: parsegrp(nmgrp, &pcbgrnm, tbuf); break; default: mderr(121, (UNCH *)0, (UNCH *)0); return; } /* Save first GI for trace and error messages. */ if (nmgrp[0]) subdcl = nmgrp[0]->etdgi+1; /* PARAMETER 1A: Rank suffix (optional). */ parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("1A: rank suffix"); switch (pcbmd.action) { case NUM: ustrcpy(ranksuff, tbuf); parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); default: break; } /* PARAMETER 2A: Start-tag minimization. */ TRACEMD("2A: start min"); switch (pcbmd.action) { case CDR: break; case NAS: if (!ustrcmp(tbuf+1, key[KO])) { if (OMITTAG==YES) SET(fmin, SMO); break; } /* fall through */ default: if (OMITTAG==NO) {minomitted=1; break;} mderr(129, tbuf+1, (UNCH *)0); return; } /* Must omit omitted end-tag minimization, if omitted start-tag minimization was omitted (because OMITTAG == NO). */ if (!minomitted) { /* PARAMETER 2B: End-tag minimization. */ parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("2B: end min"); switch (pcbmd.action) { case NAS: if (ustrcmp(tbuf+1, key[KO])) {mderr(129, tbuf+1, (UNCH *)0); return;} if (OMITTAG==YES) SET(fmin, EMO); break; case CDR: SET(fmin, EMM); break; default: mderr(129, tbuf+1, (UNCH *)0); return; } /* PARAMETER 3: Declared content. */ parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); } TRACEMD("3: declared content"); switch (pcbmd.action) { case NAS: dctype = mapsrch(dctab, tbuf+1); if (!dctype) {mderr(24, tbuf+1, (UNCH *)0); return;} /* Eliminate incompatibilities among parameters. */ if (GET(fmin, SMO) && GET(dctype, MNONE+MCDATA+MRCDATA)) { mderr(58, (UNCH *)0, (UNCH *)0); RESET(fmin, SMO); } if (GET(dctype, MNONE) && BITON(fmin, EMM)) { mderr(87, (UNCH *)0, (UNCH *)0); SET(fmin, EMO); } /* If valid, process like a content model. */ case GRPS: cmodsv = parsemod((int)(pcbmd.action==GRPS ? 0 : dctype)); if (cmodsv==0) return; u = (dctype ? 1 : cmodsv->tu.tnum+2) * THSZ; cmod = (struct thdr *)rmalloc(u); memcpy((UNIV)cmod , (UNIV)cmodsv, u ); ds.modcnt += cmod->tu.tnum; TRACEMOD(cmod); break; default: mderr(130, (UNCH *)0, (UNCH *)0); return; } /* PARAMETERS 3A, 3B: Exceptions or end. */ parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); if (BITOFF(cmod->ttype, MCDATA+MRCDATA+MNONE)) { /* PARAMETER 3A: Minus exceptions. */ TRACEMD("3A: -grp"); switch (pcbmd.action) { case MGRP: /* We cheat and use nnmgrp for this. */ mexgrp = copygrp((PETD *)nnmgrp, u = parsegrp((PETD *)nnmgrp, &pcbgrnm, tbuf)); ++ds.pmexgcnt; ds.pmexcnt += u-1; TRACEGRP(mexgrp); parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); default: break; } /* PARAMETER 3B: Plus exceptions. */ TRACEMD("3B: +grp"); switch (pcbmd.action) { case PGRP: pexgrp = copygrp((PETD *)nnmgrp, u = parsegrp((PETD *)nnmgrp, &pcbgrnm, tbuf)); ++ds.pmexgcnt; ds.pmexcnt += u-1; TRACEGRP(pexgrp); parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); default: break; } } /* PARAMETER 4: End of declaration. */ TRACEMD(emd); if (pcbmd.action!=EMD) mderr(126, (UNCH *)0, (UNCH *)0); if (es!=mdessv) synerr(37, &pcbmd); /* EXECUTE: Store the definition for each element name specified. */ TRACEGRP(nmgrp); for (i = -1; nmgrp[++i];) { etdgi = nmgrp[i]->etdgi; if (*ranksuff) { if ((tbuf[0] = *etdgi + ustrlen(ranksuff)) - 2 > NAMELEN) { mderr(131, etdgi+1, ranksuff); continue; } memcpy(tbuf+1, etdgi+1, *etdgi-1); ustrcpy(tbuf+*etdgi-1, ranksuff); etdcan(etdgi); nmgrp[i] = etddef(tbuf); } if (nmgrp[i]->etdmod) {mderr(56, etdgi+1, (UNCH *)0); continue;} etdset(nmgrp[i], fmin+ETDDCL, cmod, mexgrp, pexgrp, nmgrp[i]->etdsrm); ++ds.etdcnt; if (nmgrp[i]->adl) etdadl(nmgrp[i]); /* Check ETD conflicts. */ TRACEETD(nmgrp[i]); } }
/* MDDTDS: Process start of DOCTYPE declaration (through MSO). */ VOID mddtds(UNCH *tbuf) /* Work area for tokenization[LITLEN+2]. */ { struct fpi fpicb; /* Formal public identifier structure. */ union etext etx; /* Ptr to entity text. */ UNCH estore = ESD; /* Entity storage class. */ int emdsw = 0; /* 1=end of declaration found; 0=not yet. */ mdname = key[KDOCTYPE]; /* Identify declaration for messages. */ subdcl = NULL; /* No subject as yet. */ parmno = 0; /* No parameters as yet. */ mdessv = es; /* Save es for checking entity nesting. */ dtdrefsw = 0; /* No external DTD entity as yet. */ /* PARAMETER 1: Document type name. */ pcbmd.newstate = 0; parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("1: doc type name"); if (pcbmd.action!=NAS) {mderr(120, (UNCH *)0, (UNCH *)0); return;} dtype = savenm(tbuf); subdcl = dtype+1; /* Subject of declaration for error msgs. */ /* PARAMETER 2: External identifier keyword or MDS. */ pcbmd.newstate = 0; parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("2: extid or MDS"); switch (pcbmd.action) { case NAS: if (mdextid(tbuf, &fpicb, dtype+1, &estore, (PNE)0)==0) return; if ((etx.x = entgen(&fpicb))==0){ mderr(146, dtype+1, (UNCH *)0); exit(100); // added by john bradley } else dtdrefsw = 1; /* Signal external DTD entity. */ break; case MDS: goto execute; default: mderr(128, (UNCH *)0, (UNCH *)0); return; } /* PARAMETER 3: MDS or end of declaration. */ TRACEMD("3: MDS or EMD"); switch (pcbmd.action) { default: /* Treat as end of declaration. */ mderr(126, (UNCH *)0, (UNCH *)0); case EMD: emdsw = 1; case MDS: break; } /* EXECUTE: Store entity definition if an external ID was specified. */ execute: if (es!=mdessv) synerr(37, &pcbmd); propcb = &pcbmds; /* Prepare to parse doc type definition (MDS). */ if (dtdrefsw) { /* TO DO: If concurrent DTD's supported, free existing etext for all but first DTD (or reuse it). */ entdef(indtdent, estore, &etx); ++ds.ecbcnt; ds.ecbtext += entlen; if (emdsw) { REPEATCC; /* Push back the MDC. */ *FPOS = lex.d.msc; /* Simulate end of DTD subset. */ REPEATCC; /* Back up to read MSC next. */ delmscsw = 1; /* Insert MSC after referenced DTD. */ } } indtdsw = 1; /* Allow "DTD only" parameters. */ return; }
int yylex() { int toktype; static int beglin = false; if ( eofseen ) toktype = EOF; else toktype = flexscan(); if ( toktype == EOF ) { eofseen = 1; if ( sectnum == 1 ) { synerr( "unexpected EOF" ); sectnum = 2; toktype = SECTEND; } else if ( sectnum == 2 ) { sectnum = 3; toktype = SECTEND; } else toktype = 0; } if ( trace ) { if ( beglin ) { fprintf( stderr, "%d\t", accnum + 1 ); beglin = 0; } switch ( toktype ) { case '<': case '>': case '^': case '$': case '"': case '[': case ']': case '{': case '}': case '|': case '(': case ')': case '-': case '/': case '\\': case '?': case '.': case '*': case '+': case ',': (void) putc( toktype, stderr ); break; case '\n': (void) putc( '\n', stderr ); if ( sectnum == 2 ) beglin = 1; break; case SCDECL: fputs( "%s", stderr ); break; case XSCDECL: fputs( "%x", stderr ); break; case WHITESPACE: (void) putc( ' ', stderr ); break; case SECTEND: fputs( "%%\n", stderr ); /* we set beglin to be true so we'll start * writing out numbers as we echo rules. flexscan() has * already assigned sectnum */ if ( sectnum == 2 ) beglin = 1; break; case NAME: fprintf( stderr, "'%s'", nmstr ); break; case CHAR: switch ( yylval ) { case '<': case '>': case '^': case '$': case '"': case '[': case ']': case '{': case '}': case '|': case '(': case ')': case '-': case '/': case '\\': case '?': case '.': case '*': case '+': case ',': fprintf( stderr, "\\%c", yylval ); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: fprintf( stderr, "^%c", 'A' + yylval - 1 ); break; case 127: (void) putc( '^', stderr ); (void) putc( '@', stderr ); break; default: (void) putc( yylval, stderr ); break; } break; case NUMBER: fprintf( stderr, "%d", yylval ); break; case PREVCCL: fprintf( stderr, "[%d]", yylval ); break; case 0: fprintf( stderr, "End Marker" ); break; default: fprintf( stderr, "*Something Weird* - tok: %d val: %d\n", toktype, yylval ); break; } } return ( toktype ); }
/* MDADL: Process ATTLIST declaration. */ VOID mdadl(UNCH *tbuf) /* Work area for tokenization (tbuf). */ { int i; /* Loop counter; temporary variable. */ int adlim; /* Number of unused ad slots in al. */ struct ad *alperm = 0; /* Attribute definition list. */ int stored = 0; mdname = key[KATTLIST]; /* Identify declaration for messages. */ subdcl = 0; /* No subject as yet. */ parmno = 0; /* No parameters as yet. */ mdessv = es; /* Save es level for entity nesting check. */ reqadn = noteadn = 0; /* No required attributes yet. */ idadn = conradn = 0; /* No special atts yet.*/ AN(al) = 0; /* Number of attributes defined. */ ADN(al) = 0; /* Number of ad's in al (atts + name vals).*/ /* PARAMETER 1: Element name or a group of them. */ parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("1: element name or group"); switch (pcbmd.action) { case NAS: nmgrp[0] = etddef(tbuf); nmgrp[1] = 0; break; case GRPS: parsegrp(nmgrp, &pcbgrnm, tbuf); break; case RNS: /* Reserved name started. */ if (ustrcmp(tbuf+1, key[KNOTATION])) { mderr(118, tbuf+1, key[KNOTATION]); return; } mdnadl(tbuf); return; default: mderr(121, (UNCH *)0, (UNCH *)0); return; } /* Save first GI for error msgs. */ if (nmgrp[0]) subdcl = nmgrp[0]->etdgi+1; /* PARAMETER 2: Attribute definition list. */ parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("2: attribute list"); if (pcbmd.action!=NAS) { mderr(120, (UNCH *)0, (UNCH *)0); return; } while (pcbmd.action==NAS) { al[ADN(al)+1].adname = savenm(tbuf); if ((adlim = ATTCNT-((int)++ADN(al)))<0) { mderr(111, (UNCH *)0, (UNCH *)0); adlfree(al, 1); return; } ++AN(al); if (mdattdef(adlim, 0)) { adlfree(al, 1); return; } parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); } if (AN(al)>0) { /* Save list only if 1 or more good atts. */ if (reqadn) SET(ADLF(al), ADLREQ); /* Element must have start-tag. */ if (noteadn) SET(ADLF(al), ADLNOTE); /* Element cannot be EMPTY. */ if (conradn) SET(ADLF(al), ADLCONR); /* Element cannot be EMPTY. */ alperm = (struct ad *)rmalloc((1+ADN(al))*ADSZ); memcpy((UNIV)alperm, (UNIV)al, (1+ADN(al))*ADSZ ); ds.attcnt += AN(al); /* Number of attributes defined. */ ds.attgcnt += ADN(al) - AN(al); /* Number of att grp members. */ TRACEADL(alperm); } /* Clear attribute list for next declaration. */ MEMZERO((UNIV)al, (1+ADN(al))*ADSZ); /* PARAMETER 3: End of declaration. */ /* Next pcb.action was set during attribute definition loop. */ TRACEMD(emd); if (pcbmd.action!=EMD) {mderr(126, (UNCH *)0, (UNCH *)0); return;} if (es!=mdessv) synerr(37, &pcbmd); /* EXECUTE: Store the definition for each element name specified. */ TRACEGRP(nmgrp); for (i = 0; nmgrp[i]; i++) { if (nmgrp[i]->adl) { /* Error if an ADL exists. */ mderr(112, (UNCH *)0, (UNCH *)0); continue; } nmgrp[i]->adl = alperm; /* If virgin, store the adl ptr. */ stored = 1; if (alperm && nmgrp[i]->etdmod) etdadl(nmgrp[i]); /* Check for conflicts with ETD. */ } if (!stored && alperm) { adlfree(alperm, 1); frem((UNIV)alperm); } }
/* scanner main function */ int yylex(void) { int c, d; /* current character */ int esc = 0; /* for escape processing */ static int ahead = 0; /* lookahead token */ int behind = 0; /* lookbehind token */ LexEntry1 *lt1; /* scans through lexbuf1 */ LexEntry2 *lt2; /* scans through lexbuf2 */ char *p, *q; int i; char nbuf[LEX_MAX+1]; /* for getting macro name */ /* token from previous invocation */ if (ahead) { c = ahead; ahead = 0; #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> TOKEN (ahead) \'%c\'\n", c); #endif return c; } /* scan token from input */ c = nextc(); while (c != EOF) { /* skip blanks */ while (isspace(c)) c = nextc(); /* scan C style comment */ if (c == '/') { if ((d = nextc()) != '*') prevc(d); else { c = nextc(); while (c != EOF) { d = nextc(); if ((c == '*') && (d == '/')) { c = nextc(); break; } c = d; } continue; } } /* scan C++ style comment */ if (c == '/') { if ((d = nextc()) != '/') prevc(d); else { do c = nextc(); while (( c != '\n') && (c != EOF)); continue; } } /* scan alphanumeric */ if (isalpha(c) || (c == '\'') || (c == '%')) { d = c; if (d == '\'') c = nextc(); i = 0; do { if (c == '$') { /* macro embedded in identifier */ int sts; if (!get_ident(nbuf)) return EOF; sts = varDeref(nbuf); if (sts == DEREF_ERROR) { /* error reporting in varDeref() */ lexSync(); return EOF; } else if (sts != DEREF_STRING) { synerr(); fprintf(stderr, "macro $%s not string valued as expected\n", nbuf); lexSync(); return EOF; } c = nextc(); } else { if (c == '\\') c = nextc(); token[i++] = c; c = nextc(); } } while ((isalpha(c) || isdigit(c) || c == '.' || c == '_' || c == '\\' || c == '$' || (d == '\'' && c != d)) && (i < LEX_MAX)); token[i] = '\0'; if (d == '\'') c = nextc(); /* * recognize keywords associated with units of space, time * and count, see unitab[] */ if (d != '\'') { lt2 = &unitab[0]; if (i > 0 && token[i-1] == 's') i--; do { if (strlen(lt2->key) == i && strncmp(token, lt2->key, i) == 0) { /* if looking ahead after '/', return UNIT_SLASH */ if (behind == '/') { prevs(&token[0]); prevc(c); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \"/\"\n"); #endif return UNIT_SLASH; } prevc(c); yylval.u = noUnits; switch (lt2->token) { case SPACE_UNIT: yylval.u.dimSpace = 1; yylval.u.scaleSpace = lt2->scale; break; case TIME_UNIT: yylval.u.dimTime = 1; yylval.u.scaleTime = lt2->scale; break; case EVENT_UNIT: yylval.u.dimCount = 1; yylval.u.scaleCount = lt2->scale; break; } #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> UNITS \"%s\"\n", pmUnitsStr(&yylval.u)); #endif return lt2->token; } lt2++; } while (lt2->key); } /* if looking ahead, return previous token */ if (behind) { prevs(&token[0]); prevc(c); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> TOKEN (behind) \'%c\'\n", behind); #endif return behind; } prevc(c); /* recognize aggregation and quantification */ if (d != '\'') { if ((p = strchr(token, '_')) != NULL) { *p = '\0'; lt1 = &quantab[0]; do { if (strcmp(&token[0], lt1->key) == 0) { c = lt1->token; q = p + 1; lt1 = &domtab[0]; do { if (strcmp(q, lt1->key) == 0) { ahead = lt1->token; #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \"%s\'\n", token); #endif return c; } lt1++; } while (lt1->key); break; } lt1++; } while (lt1->key); *p = '_'; } /* recognize other reserved word */ lt1 = &optab[0]; do { if (strcmp(&token[0], lt1->key) == 0) { #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> RESERVED-WORD \"%s\"\n", token); #endif return lt1->token; } lt1++; } while (lt1->key); } /* recognize identifier */ yylval.s = (char *) alloc(strlen(&token[0]) + 1); strcpy(yylval.s, &token[0]); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> IDENT \"%s\"\n", token); #endif return IDENT; } /* if looking ahead, return preceding token */ if (behind) { prevc(c); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> TOKEN (behind) \'%c\'\n", behind); #endif return behind; } /* special case for .[0-9]... number without leading [0-9] */ if (c == '.') { c = nextc(); if (isdigit(c)) { /* note prevc() implements a FIFO, not a stack! */ prevc('.'); /* push back period */ prevc(c); /* push back digit */ c = '0'; /* start with fake leading zero */ } else prevc(c); /* not a digit after period, push back */ } /* scan NUMBER */ if (isdigit(c)) { int flote = 0; i = 0; do { token[i++] = c; c = nextc(); if ((flote == 0) && (c == '.') && (i < LEX_MAX)) { c = nextc(); if (c == '.') prevc(c); /* INTERVAL token */ else { flote = 1; token[i++] = '.'; } } if ((flote <= 1) && (i < LEX_MAX) && ((c == 'e') || (c == 'E'))) { flote = 2; token[i++] = c; c = nextc(); } if ((flote <= 2) && (c == '-') && (i < LEX_MAX)) { flote = 3; token[i++] = c; c = nextc(); } } while (isdigit(c) && (i < LEX_MAX)); prevc(c); token[i] = '\0'; yylval.d = strtod(&token[0], NULL); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> NUMBER %g\n", yylval.d); #endif return NUMBER; } /* scan string */ if (c == '"') { yylval.s = NULL; i = 0; c = nextc(); while ((c != '"') && (c != EOF) && (i < LEX_MAX)) { /* escape character */ if (c == '\\') { esc = 1; c = nextc(); switch (c) { case 'n': c = '\n'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; case 'b': c = '\b'; break; case 'r': c = '\r'; break; case 'f': c = '\f'; break; case 'a': c = '\a'; break; } } else esc = 0; /* macro embedded in string */ if (c == '$' && !esc) { int sts; if (!get_ident(nbuf)) return EOF; sts = varDeref(nbuf); if (sts == DEREF_ERROR) { /* error reporting in varDeref() */ lexSync(); return EOF; } else if (sts != DEREF_STRING) { synerr(); fprintf(stderr, "macro $%s not string valued as expected\n", nbuf); lexSync(); return EOF; } c = nextc(); } /* add character to string */ yylval.s = (char *) ralloc(yylval.s, i+2); yylval.s[i++] = c; c = nextc(); } if (i == 0) { /* special case for null string */ yylval.s = (char *) ralloc(yylval.s, 1); } yylval.s[i++] = '\0'; #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> STRING \"%s\"\n", yylval.s); #endif return STRING; } /* scan operator */ switch (c) { case ';': case '}': do d = nextc(); while (isspace(d)); if (d == '.') { while (lin) unwind(); } else prevc(d); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> END-OF-RULE\n"); #endif return EOF; case '$': if (!get_ident(nbuf)) return EOF; switch (varDeref(nbuf)) { case DEREF_ERROR: lexSync(); return EOF; case DEREF_STRING: c = nextc(); continue; case DEREF_BOOL: #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> (boolean) macro $%s\n", nbuf); #endif return VAR; case DEREF_NUMBER: #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> (numeric) macro $%s\n", nbuf); #endif return VAR; } /*NOTREACHED*/ break; case '/': behind = c; c = nextc(); continue; case '-': if ((d = nextc()) == '>') { #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \"->\"\n"); #endif return ARROW; } prevc(d); break; case '=': if ((d = nextc()) == '=') { #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \"==\"\n"); #endif return EQ_REL; } prevc(d); break; case '!': if ((d = nextc()) == '=') { #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \"!=\"\n"); #endif return NEQ_REL; } prevc(d); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \"!\"\n"); #endif return NOT; case '<': if ((d = nextc()) == '=') { #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \"<=\"\n"); #endif return LEQ_REL; } prevc(d); break; case '>': if ((d = nextc()) == '=') { #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \">=\"\n"); #endif return GEQ_REL; } prevc(d); break; case '&': if ((d = nextc()) == '&') { #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \"&&\"\n"); #endif return AND; } prevc(d); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \"&\"\n"); #endif return SEQ; case '|': if ((d = nextc()) == '|') { #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \"||\"\n"); #endif return OR; } prevc(d); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \"|\"\n"); #endif return ALT; case '.': if ((d = nextc()) == '.') { #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> OPERATOR \"..\"\n"); #endif return INTERVAL; } prevc(d); break; } #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) { if (c == EOF) fprintf(stderr, "yylex() -> EOF\n"); else fprintf(stderr, "yylex() -> TOKEN \'%c\' (0x%x)\n", c, c & 0xff); } #endif return c; } #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "yylex() -> EOF\n"); #endif return EOF; }
int yylex() { int toktype; static int beglin = false; extern char *yytext; if ( eofseen ) toktype = EOF; else toktype = flexscan(); if ( toktype == EOF || toktype == 0 ) { eofseen = 1; if ( sectnum == 1 ) { synerr( _( "premature EOF" ) ); sectnum = 2; toktype = SECTEND; } else toktype = 0; } if ( trace ) { if ( beglin ) { fprintf( stderr, "%d\t", num_rules + 1 ); beglin = 0; } switch ( toktype ) { case '<': case '>': case '^': case '$': case '"': case '[': case ']': case '{': case '}': case '|': case '(': case ')': case '-': case '/': case '\\': case '?': case '.': case '*': case '+': case ',': (void) putc( toktype, stderr ); break; case '\n': (void) putc( '\n', stderr ); if ( sectnum == 2 ) beglin = 1; break; case SCDECL: fputs( "%s", stderr ); break; case XSCDECL: fputs( "%x", stderr ); break; case SECTEND: fputs( "%%\n", stderr ); /* We set beglin to be true so we'll start * writing out numbers as we echo rules. * flexscan() has already assigned sectnum. */ if ( sectnum == 2 ) beglin = 1; break; case NAME: fprintf( stderr, "'%s'", nmstr ); break; case CHAR: switch ( yylval ) { case '<': case '>': case '^': case '$': case '"': case '[': case ']': case '{': case '}': case '|': case '(': case ')': case '-': case '/': case '\\': case '?': case '.': case '*': case '+': case ',': fprintf( stderr, "\\%c", yylval ); break; default: if ( ! isascii( yylval ) || ! isprint( yylval ) ) fprintf( stderr, "\\%.3o", (unsigned int) yylval ); else (void) putc( yylval, stderr ); break; } break; case NUMBER: fprintf( stderr, "%d", yylval ); break; case PREVCCL: fprintf( stderr, "[%d]", yylval ); break; case EOF_OP: fprintf( stderr, "<<EOF>>" ); break; case OPTION_OP: fprintf( stderr, "%s ", yytext ); break; case OPT_OUTFILE: case OPT_PREFIX: case CCE_ALNUM: case CCE_ALPHA: case CCE_BLANK: case CCE_CNTRL: case CCE_DIGIT: case CCE_GRAPH: case CCE_LOWER: case CCE_PRINT: case CCE_PUNCT: case CCE_SPACE: case CCE_UPPER: case CCE_XDIGIT: fprintf( stderr, "%s", yytext ); break; case 0: fprintf( stderr, _( "End Marker\n" ) ); break; default: fprintf( stderr, _( "*Something Weird* - tok: %d val: %d\n" ), toktype, yylval ); break; } } return toktype; }
/* MDNADL: Process ATTLIST declaration for notation. TO DO: Pass deftab and dvtab as parameters so that prohibited types can be handled by leaving them out of the tables. */ VOID mdnadl(UNCH *tbuf) /* Work area for tokenization (tbuf). */ { int i; /* Loop counter; temporary variable. */ int adlim; /* Number of unused ad slots in al. */ struct ad *alperm = 0; /* Attribute definition list. */ int stored = 0; /* PARAMETER 1: Notation name or a group of them. */ parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("1: notation name or group"); switch (pcbmd.action) { case NAS: nnmgrp[0] = dcndef(tbuf); nnmgrp[1] = 0; break; case GRPS: parsngrp(nnmgrp, &pcbgrnm, tbuf); break; default: mderr(121, (UNCH *)0, (UNCH *)0); return; } subdcl = nnmgrp[0]->ename+1; /* Save first name for error msgs. */ /* PARAMETER 2: Attribute definition list. */ parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("2: attribute list"); if (pcbmd.action!=NAS) { mderr(120, (UNCH *)0, (UNCH *)0); return; } while (pcbmd.action==NAS) { al[ADN(al)+1].adname = savenm(tbuf); if ((adlim = ATTCNT-((int)ADN(al)++))<0) { mderr(111, (UNCH *)0, (UNCH *)0); adlfree(al, 1); return; } ++AN(al); if (mdattdef(adlim, 1)) { adlfree(al, 1); return; } parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); } if (AN(al)>0) { /* Save list only if 1 or more good atts. */ alperm = (struct ad *)rmalloc((1+ADN(al))*ADSZ); memcpy((UNIV)alperm, (UNIV)al, (1+ADN(al))*ADSZ ); ds.attcnt += AN(al); /* Number of attributes defined. */ ds.attgcnt += ADN(al) - AN(al); /* Number of att grp members. */ TRACEADL(alperm); } /* Clear attribute list for next declaration. */ MEMZERO((UNIV)al, (1+ADN(al))*ADSZ); /* PARAMETER 3: End of declaration. */ /* Next pcb.action was set during attribute definition loop. */ TRACEMD(emd); if (pcbmd.action!=EMD) {mderr(126, (UNCH *)0, (UNCH *)0); return;} if (es!=mdessv) synerr(37, &pcbmd); /* EXECUTE: Store the definition for each notation name specified. */ TRACENGR(nnmgrp); for (i = 0; nnmgrp[i]; i++) { if (nnmgrp[i]->adl) { /* Error if an ADL exists. */ mderr(112, (UNCH *)0, (UNCH *)0); continue; } nnmgrp[i]->adl = alperm; /* If virgin, store the adl ptr. */ if (nnmgrp[i]->entsw) fixdatt(nnmgrp[i]); stored = 1; TRACEDCN(nnmgrp[i]); } if (!stored && alperm) { adlfree(alperm, 1); frem((UNIV)alperm); } }