Back to index

tetex-bin  3.0
Public Member Functions | Private Member Functions | Private Attributes
Lexer Class Reference

#include <Lexer.h>

Collaboration diagram for Lexer:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 Lexer (XRef *xref, Stream *str)
 Lexer (XRef *xref, Object *obj)
 ~Lexer ()
ObjectgetObj (Object *obj)
void skipToNextLine ()
void skipChar ()
StreamgetStream ()
int getPos ()
void setPos (Guint pos, int dir=0)

Private Member Functions

int getChar ()
int lookChar ()

Private Attributes

Arraystreams
int strPtr
Object curStr
GBool freeArray
char tokBuf [tokBufSize]

Detailed Description

Definition at line 29 of file Lexer.h.


Constructor & Destructor Documentation

Lexer::Lexer ( XRef xref,
Stream str 
)

Definition at line 49 of file Lexer.cc.

                                    {
  Object obj;

  curStr.initStream(str);
  streams = new Array(xref);
  streams->add(curStr.copy(&obj));
  strPtr = 0;
  freeArray = gTrue;
  curStr.streamReset();
}

Here is the call graph for this function:

Lexer::Lexer ( XRef xref,
Object obj 
)

Definition at line 60 of file Lexer.cc.

                                    {
  Object obj2;

  if (obj->isStream()) {
    streams = new Array(xref);
    freeArray = gTrue;
    streams->add(obj->copy(&obj2));
  } else {
    streams = obj->getArray();
    freeArray = gFalse;
  }
  strPtr = 0;
  if (streams->getLength() > 0) {
    streams->get(strPtr, &curStr);
    curStr.streamReset();
  }
}

Here is the call graph for this function:

Definition at line 78 of file Lexer.cc.

              {
  if (!curStr.isNone()) {
    curStr.streamClose();
    curStr.free();
  }
  if (freeArray) {
    delete streams;
  }
}

Here is the call graph for this function:


Member Function Documentation

int Lexer::getChar ( ) [private]

Definition at line 88 of file Lexer.cc.

                   {
  int c;

  c = EOF;
  while (!curStr.isNone() && (c = curStr.streamGetChar()) == EOF) {
    curStr.streamClose();
    curStr.free();
    ++strPtr;
    if (strPtr < streams->getLength()) {
      streams->get(strPtr, &curStr);
      curStr.streamReset();
    }
  }
  return c;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Object * Lexer::getObj ( Object obj)

Definition at line 111 of file Lexer.cc.

                                 {
  char *p;
  int c, c2;
  GBool comment, neg, done;
  int numParen;
  int xi;
  double xf, scale;
  GString *s;
  int n, m;

  // skip whitespace and comments
  comment = gFalse;
  while (1) {
    if ((c = getChar()) == EOF) {
      return obj->initEOF();
    }
    if (comment) {
      if (c == '\r' || c == '\n')
       comment = gFalse;
    } else if (c == '%') {
      comment = gTrue;
    } else if (specialChars[c] != 1) {
      break;
    }
  }

  // start reading token
  switch (c) {

  // number
  case '0': case '1': case '2': case '3': case '4':
  case '5': case '6': case '7': case '8': case '9':
  case '-': case '.':
    neg = gFalse;
    xi = 0;
    if (c == '-') {
      neg = gTrue;
    } else if (c == '.') {
      goto doReal;
    } else {
      xi = c - '0';
    }
    while (1) {
      c = lookChar();
      if (isdigit(c)) {
       getChar();
       xi = xi * 10 + (c - '0');
      } else if (c == '.') {
       getChar();
       goto doReal;
      } else {
       break;
      }
    }
    if (neg)
      xi = -xi;
    obj->initInt(xi);
    break;
  doReal:
    xf = xi;
    scale = 0.1;
    while (1) {
      c = lookChar();
      if (!isdigit(c)) {
       break;
      }
      getChar();
      xf = xf + scale * (c - '0');
      scale *= 0.1;
    }
    if (neg)
      xf = -xf;
    obj->initReal(xf);
    break;

  // string
  case '(':
    p = tokBuf;
    n = 0;
    numParen = 1;
    done = gFalse;
    s = NULL;
    do {
      c2 = EOF;
      switch (c = getChar()) {

      case EOF:
#if 0
      // This breaks some PDF files, e.g., ones from Photoshop.
      case '\r':
      case '\n':
#endif
       error(getPos(), "Unterminated string");
       done = gTrue;
       break;

      case '(':
       ++numParen;
       c2 = c;
       break;

      case ')':
       if (--numParen == 0) {
         done = gTrue;
       } else {
         c2 = c;
       }
       break;

      case '\\':
       switch (c = getChar()) {
       case 'n':
         c2 = '\n';
         break;
       case 'r':
         c2 = '\r';
         break;
       case 't':
         c2 = '\t';
         break;
       case 'b':
         c2 = '\b';
         break;
       case 'f':
         c2 = '\f';
         break;
       case '\\':
       case '(':
       case ')':
         c2 = c;
         break;
       case '0': case '1': case '2': case '3':
       case '4': case '5': case '6': case '7':
         c2 = c - '0';
         c = lookChar();
         if (c >= '0' && c <= '7') {
           getChar();
           c2 = (c2 << 3) + (c - '0');
           c = lookChar();
           if (c >= '0' && c <= '7') {
             getChar();
             c2 = (c2 << 3) + (c - '0');
           }
         }
         break;
       case '\r':
         c = lookChar();
         if (c == '\n') {
           getChar();
         }
         break;
       case '\n':
         break;
       case EOF:
         error(getPos(), "Unterminated string");
         done = gTrue;
         break;
       default:
         c2 = c;
         break;
       }
       break;

      default:
       c2 = c;
       break;
      }

      if (c2 != EOF) {
       if (n == tokBufSize) {
         if (!s)
           s = new GString(tokBuf, tokBufSize);
         else
           s->append(tokBuf, tokBufSize);
         p = tokBuf;
         n = 0;
       }
       *p++ = (char)c2;
       ++n;
      }
    } while (!done);
    if (!s)
      s = new GString(tokBuf, n);
    else
      s->append(tokBuf, n);
    obj->initString(s);
    break;

  // name
  case '/':
    p = tokBuf;
    n = 0;
    while ((c = lookChar()) != EOF && !specialChars[c]) {
      getChar();
      if (c == '#') {
       c2 = lookChar();
       if (c2 >= '0' && c2 <= '9') {
         c = c2 - '0';
       } else if (c2 >= 'A' && c2 <= 'F') {
         c = c2 - 'A' + 10;
       } else if (c2 >= 'a' && c2 <= 'f') {
         c = c2 - 'a' + 10;
       } else {
         goto notEscChar;
       }
       getChar();
       c <<= 4;
       c2 = getChar();
       if (c2 >= '0' && c2 <= '9') {
         c += c2 - '0';
       } else if (c2 >= 'A' && c2 <= 'F') {
         c += c2 - 'A' + 10;
       } else if (c2 >= 'a' && c2 <= 'f') {
         c += c2 - 'a' + 10;
       } else {
         error(getPos(), "Illegal digit in hex char in name");
       }
      }
     notEscChar:
      if (++n == tokBufSize) {
       error(getPos(), "Name token too long");
       break;
      }
      *p++ = c;
    }
    *p = '\0';
    obj->initName(tokBuf);
    break;

  // array punctuation
  case '[':
  case ']':
    tokBuf[0] = c;
    tokBuf[1] = '\0';
    obj->initCmd(tokBuf);
    break;

  // hex string or dict punctuation
  case '<':
    c = lookChar();

    // dict punctuation
    if (c == '<') {
      getChar();
      tokBuf[0] = tokBuf[1] = '<';
      tokBuf[2] = '\0';
      obj->initCmd(tokBuf);

    // hex string
    } else {
      p = tokBuf;
      m = n = 0;
      c2 = 0;
      s = NULL;
      while (1) {
       c = getChar();
       if (c == '>') {
         break;
       } else if (c == EOF) {
         error(getPos(), "Unterminated hex string");
         break;
       } else if (specialChars[c] != 1) {
         c2 = c2 << 4;
         if (c >= '0' && c <= '9')
           c2 += c - '0';
         else if (c >= 'A' && c <= 'F')
           c2 += c - 'A' + 10;
         else if (c >= 'a' && c <= 'f')
           c2 += c - 'a' + 10;
         else
           error(getPos(), "Illegal character <%02x> in hex string", c);
         if (++m == 2) {
           if (n == tokBufSize) {
             if (!s)
              s = new GString(tokBuf, tokBufSize);
             else
              s->append(tokBuf, tokBufSize);
             p = tokBuf;
             n = 0;
           }
           *p++ = (char)c2;
           ++n;
           c2 = 0;
           m = 0;
         }
       }
      }
      if (!s)
       s = new GString(tokBuf, n);
      else
       s->append(tokBuf, n);
      if (m == 1)
       s->append((char)(c2 << 4));
      obj->initString(s);
    }
    break;

  // dict punctuation
  case '>':
    c = lookChar();
    if (c == '>') {
      getChar();
      tokBuf[0] = tokBuf[1] = '>';
      tokBuf[2] = '\0';
      obj->initCmd(tokBuf);
    } else {
      error(getPos(), "Illegal character '>'");
      obj->initError();
    }
    break;

  // error
  case ')':
  case '{':
  case '}':
    error(getPos(), "Illegal character '%c'", c);
    obj->initError();
    break;

  // command
  default:
    p = tokBuf;
    *p++ = c;
    n = 1;
    while ((c = lookChar()) != EOF && !specialChars[c]) {
      getChar();
      if (++n == tokBufSize) {
       error(getPos(), "Command token too long");
       break;
      }
      *p++ = c;
    }
    *p = '\0';
    if (tokBuf[0] == 't' && !strcmp(tokBuf, "true")) {
      obj->initBool(gTrue);
    } else if (tokBuf[0] == 'f' && !strcmp(tokBuf, "false")) {
      obj->initBool(gFalse);
    } else if (tokBuf[0] == 'n' && !strcmp(tokBuf, "null")) {
      obj->initNull();
    } else {
      obj->initCmd(tokBuf);
    }
    break;
  }

  return obj;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Lexer::getPos ( ) [inline]

Definition at line 58 of file Lexer.h.

    { return curStr.isNone() ? -1 : (int)curStr.streamGetPos(); }

Here is the call graph for this function:

Here is the caller graph for this function:

Stream* Lexer::getStream ( ) [inline]

Definition at line 53 of file Lexer.h.

    { return curStr.isNone() ? (Stream *)NULL : curStr.getStream(); }

Here is the call graph for this function:

Here is the caller graph for this function:

int Lexer::lookChar ( ) [private]

Definition at line 104 of file Lexer.cc.

                    {
  if (curStr.isNone()) {
    return EOF;
  }
  return curStr.streamLookChar();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Lexer::setPos ( Guint  pos,
int  dir = 0 
) [inline]

Definition at line 62 of file Lexer.h.

    { if (!curStr.isNone()) curStr.streamSetPos(pos, dir); }

Here is the call graph for this function:

Here is the caller graph for this function:

void Lexer::skipChar ( ) [inline]

Definition at line 50 of file Lexer.h.

{ getChar(); }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 459 of file Lexer.cc.

                           {
  int c;

  while (1) {
    c = getChar();
    if (c == EOF || c == '\n') {
      return;
    }
    if (c == '\r') {
      if ((c = lookChar()) == '\n') {
       getChar();
      }
      return;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Object Lexer::curStr [private]

Definition at line 72 of file Lexer.h.

Definition at line 73 of file Lexer.h.

Array* Lexer::streams [private]

Definition at line 70 of file Lexer.h.

int Lexer::strPtr [private]

Definition at line 71 of file Lexer.h.

char Lexer::tokBuf[tokBufSize] [private]

Definition at line 74 of file Lexer.h.


The documentation for this class was generated from the following files: