Logo Search packages:      
Sourcecode: sam2p version File versions

int MiniPS::Tokenizer::yylex (  ) 

Reads and returns next token. Token types are named for their first character: '1': integertype: 31 bits signed (-1073741824 .. 1073741823) is guaranteed. VALUED '.': realtype (NOT implemented), double guaranteed. VALUED 'E': Ename (name without a slash). VALUED '/': Sname (name beginning with a slash). VALUED '(': stringtype (also with `<hexadecimal>') VALUED '[': beginning-of-array (also with `{') ']': end-of-array (also with '}') '<': beginning-of-dict (`<<') '>': end-of-dict (`>>') -1: EOF

Definition at line 89 of file minips.cpp.

References Error::sev(), tv, and GenBuffer::Readable::vi_getcc().

                           {
  int c=0; /* dummy initialization */
  bool hi;
  unsigned hv;
  slen_t nest, len;
  signed long l;
  double d;
  Real::metric_t metric;
  char saved;
  
  if (ungot==EOFF) return EOFF;
  if (ungot!=NO_UNGOT) { c=ungot; ungot=NO_UNGOT; goto again; }
 again_getcc:
  c=in.vi_getcc();
 again:
  switch (c) {
   case -1: eof:
    return ungot=EOFF;
   case '\n': case '\r': case '\t': case ' ': case '\f': case '\0':
    goto again_getcc;
   case '%': /* one-line comment */
    while ((c=in.vi_getcc())!='\n' && c!='\r' && c!=-1) ;
    if (c==-1) goto eof;
    goto again_getcc;
   case '{': case '[':
    return '[';
   case '}': case ']':
    return ']';
   case ')': goto err;
   case '>':
    if (in.vi_getcc()!='>') goto err;
    return '>';
   case '<':
    if ((c=in.vi_getcc())==-1) { uf_hex: Error::sev(Error::EERROR) << "miniPS: unfinished hexstr" << (Error*)0; }
    if (c=='<') return '<';
    if (c=='~') Error::sev(Error::EERROR) << "miniPS: a85str unsupported" << (Error*)0;
    tv.bb=&b; b.clear();
    hi=true;
    while (c!='>') {
      if ((hv=b.hexc2n(c))!=16) {
        if (hi) { b << (char)(hv<<4); hi=false; }
           else { b.end_()[-1]|=hv; hi=true; }
      } else if (!is_ps_white(c)) Error::sev(Error::EERROR) << "miniPS: syntax error in hexstr" << (Error*)0;
      if ((c=in.vi_getcc())==-1) goto uf_hex;
    }
    /* This is correct even if an odd number of hex digits have arrived */
    return '(';
   case '(':
    tv.bb=&b; b.clear();
    nest=1;
    while ((c=in.vi_getcc())!=-1) { redo:
      if (c==')' && --nest==0) return '(';
      if (c!='\\') { if (c=='(') nest++; b << (char)c; continue; }
      /* read a backslash */
      switch (c=in.vi_getcc()) {
       case -1: goto uf_str;
       case 'n': b << '\n'; break;
       case 'r': b << '\r'; break;
       case 't': b << '\t'; break;
       case 'b': b << '\010'; break; /* \b and \a conflict between -ansi and -traditional */
       case 'f': b << '\f'; break;
       default:
        if (c<'0' || c>'7') { b << (char)c; break; }
        hv=c-'0'; /* read at most 3 octal chars */
        if ((c=in.vi_getcc())==-1) goto uf_str;
        if (c<'0' || c>'7') { b << (char)hv; goto redo; }
        hv=8*hv+(c-'0');
        if ((c=in.vi_getcc())==-1) goto uf_str;
        if (c<'0' || c>'7') { b << (char)hv; goto redo; }
        b << (char)(8*hv+(c-'0'));
      } /* SWITCH */
    } /* WHILE */    
    uf_str: Error::sev(Error::EERROR) << "miniPS: unfinished str" << (Error*)0;
   case '/':
    /* fall-through, b will begin with '/' */
   default: /* /nametype, /integertype or /realtype */
    tv.bb=&b; b.clear();
    b.clear(); b << (char)c;
    while ((c=in.vi_getcc())!=-1 && is_ps_name(c)) b << (char)c;
    ungot=c==-1?EOFF:c;
    if (b[0]=='/') return '/';
    b.term0();
    /* Dat: we don't support base-n number such as `16#100' == 256 in PostScript */
    if (!toInteger(b, l)) { tv.i=l; return '1'; }
    /* Dat: call toInteger _before_ toReal */
    // if (!toReal(b, tv.d)) { fprintf(stderr,"%f;\n", tv.d); }
    /* assert(tv.bb!=NULLP); */
    len=b.getLength();
    if (!toReal(b, d)) { /* tv.bb is also valid */
      tv.r=new Real(d, b(), len);
      return '.';
    } 
    if (len>2 && (metric=Real::str2metric(b()+len-2))!=Real::ME_COUNT) {
      saved=b[len-2];
      b[len-2]='\0';
      if (!toReal(b, d)) {
        tv.r=new Real(d, b(), len-2);
        tv.r->setMetric(metric);
        return ':'; /* Real with metric */
      }
      b[len-2]=saved;
    }
    return 'E'; /* /nametype */
  }
 err:
  Error::sev(Error::EERROR) << "miniPS: syntax error" << (Error*)0;
  goto again_getcc; /* notreached */
}


Generated by  Doxygen 1.6.0   Back to index