Ejemplo n.º 1
0
SglExprLex::ScanResult SglExprLex::searchResult2scanResult(Tables::SearchResult sr)
{
  ScanResult tokens[maxOverloadSymbols];
  ScanResult tmp;
  SymType stype;

  tokens[0].type = UNKNOWNTOKEN;
  tokens[0].symbol = 0;
  if (sr.count > maxOverloadSymbols)
    sr.count = 0;
  for (int i = -1; ++i < sr.count; ++sr.pt)
  {
    tmp.symbol = sr.pt.value();
    stype = tmp.symbol? tmp.symbol->type() : unassigned;
    switch(stype)
    {
      case tagSym:
        tmp.type = baseTag(tmp.symbol);
        break;
      case operatorSym:
        tmp.type = opToken(tmp.symbol);
        break;
      default:
        tmp.type = symbolType(stype);
    }
    // sort overloaded symbols (insertion sort)
    int j = i;
    for (; --j >= 0 && tokenOrder(tokens[j].type) < tokenOrder(tmp.type);)
      tokens[j+1] = tokens[j];
    tokens[j+1] = tmp;
  }
  for (int i = sr.count; --i > 0;)
    pending.enqueue(tokens[i]);
  if (sr.count == 1)
  {
    switch (stype)
    {
      case operatorSym:
        if (!tmp.symbol->asOp()->isUnary())
        {
          // append a NOPREFIX token for not overloaded binary operators
          tmp.type = NOPREFIX;
          tmp.symbol = 0;
          pending.enqueue(tmp);
        }
        break;
      case tagSym:
        if (tmp.symbol->asTag()->complement())
        {
          // split a complement tag into a base token and a complement token
          pending.enqueue(tmp);
          tokens[0].type = CMPLTAG;
        }
        break;
      default: ;
    }
  }
  return tokens[0];
}
Ejemplo n.º 2
0
// parses the next token
// returns false if done
void opScanner::ScanTokens(const inputtype& Input) {
    // if we've reached the end of the Input stream,
    // add an EOF token and return false

    int size = Input.Size();
    int current = 0;

    // TODO: the input list of chars is really a bad idea
    //		Input should be a vector, and we should not alter it,
    //		instead we should iterate over it (maybe w/ an iterator we pass
    //		around.

    while (current != size) {
        // scan for the next token
        // (with the correct precedence)
        if (current != size && Newline(Input, current))
            ;
        else if (current != size && CComment(Input, current))
            ;
        else if (current != size && Comment(Input, current))
            ;
        else if (current != size && String(Input, current))
            ;
        else if (current != size && WhiteSpace(Input, current))
            ;
        else if (current != size && Operator(Input, current))
            ;
        else if (current != size && Hexadecimals(Input, current))
            ;
        else if (current != size && Number(Input, current))
            ;
        else if (current != size && GetId(Input, current))
            ;
        else if (current != size) {
            opToken newToken(T_ANYCHAR, Input[current], CurrentLine);

            Tokens.PushBack(newToken);
            ++current;
        }
    }

    Tokens.PushBack(opToken(T_EOF, "", CurrentLine));
}
Ejemplo n.º 3
0
// TODO: should we replace this with @/spacer?
// do concatenation expansion
void OPMacroNode::ExpandConcatenation(opNode* cloned) {
    iterator i = cloned->GetBegin();
    iterator end = cloned->GetEnd();

    // check for concatenation at ends
    if (i != end) {
        opNode* errored = NULL;
        if (i->GetId() == T_CONCATENATION)
            errored = *i;
        else if (cloned->GetLast()->GetId() == T_CONCATENATION)
            errored = *cloned->GetLast();

        if (errored) {
            opError::MessageError(
                errored,
                "## opmacro operator cannot concatenate block boundaries.");
        }
    }

    while (i != end) {
        opNode* current = *i;

        if (current->IsTerminal()) {
            if (current->GetId() != T_CONCATENATION) {
                ++i;
                continue;
            }

            iterator nexti = i;
            ++nexti;
            iterator previ = i;
            --previ;
            opNode* previous = *previ;
            opNode* next = *nexti;

            if (next->IsTerminal() && previous->IsTerminal()) {
                // make sure they aren't whitespace!
                if (previous->IsWhitespace() || next->IsWhitespace()) {
                    opError::MessageError(
                        current,
                        "## opmacro operator cannot concatenate whitespace.");
                }

                // all we have to do is
                // delete all 3
                // insert a node at previous's position (preserve line #!
                // set the value to our string
                // set the id to T_ID, or else do a lookup on it
                // thats all folks

                // now we need to grab the pasted string
                opString pastedstring =
                    previous->GetStringValue() + next->GetStringValue();
                int line = current->GetLine();
                FileNode* file = current->GetFile();

                iterator newi = nexti;
                ++newi;

                // delete all 3 nodes
                cloned->DeleteNode(previ);
                cloned->DeleteNode(i);
                cloned->DeleteNode(nexti);

                stacked<TerminalNode> newnode = NEWNODE(
                    TerminalNode(opToken(T_ID, pastedstring, line), file));

                cloned->InsertNode(newnode, newi);

                i = newi;
                continue;
            }
        } else
            ExpandConcatenation(current);

        ++i;
    }
}