/** Returns true if the character is a valid token separator at the end of a number type token */
static bool GetIsNumberSeparator(char c)
{
    return c == 0 || isspace(c) || GetIsSymbol(c);
}
void HLSLTokenizer::Next(const bool EOLSkipping)
{
    m_bufferPrevious = m_buffer;

    while( SkipWhitespace(EOLSkipping) || SkipComment(&m_buffer, EOLSkipping) || ScanLineDirective() || SkipPragmaDirective() )
    {
    }

    if (m_error)
    {
        m_token = HLSLToken_EndOfStream;
        return;
    }

    if (!EOLSkipping && m_buffer[0] == '\n')
    {
        m_token = HLSLToken_EndOfLine;
        return;
    }

    m_tokenLineNumber = m_lineNumber;

    if (m_buffer >= m_bufferEnd || *m_buffer == '\0')
    {
        m_token = HLSLToken_EndOfStream;
        return;
    }

    const char* start = m_buffer;

    // +=, -=, *=, /=, ==, <=, >=
    if (m_buffer[0] == '+' && m_buffer[1] == '=')
    {
        m_token = HLSLToken_PlusEqual;
        m_buffer += 2;
        return;
    }
    else if (m_buffer[0] == '-' && m_buffer[1] == '=')
    {
        m_token = HLSLToken_MinusEqual;
        m_buffer += 2;
        return;
    }
    else if (m_buffer[0] == '*' && m_buffer[1] == '=')
    {
        m_token = HLSLToken_TimesEqual;
        m_buffer += 2;
        return;
    }
    else if (m_buffer[0] == '/' && m_buffer[1] == '=')
    {
        m_token = HLSLToken_DivideEqual;
        m_buffer += 2;
        return;
    }
    else if (m_buffer[0] == '=' && m_buffer[1] == '=')
    {
        m_token = HLSLToken_EqualEqual;
        m_buffer += 2;
        return;
    }
    else if (m_buffer[0] == '!' && m_buffer[1] == '=')
    {
        m_token = HLSLToken_NotEqual;
        m_buffer += 2;
        return;
    }
    else if (m_buffer[0] == '<' && m_buffer[1] == '=')
    {
        m_token = HLSLToken_LessEqual;
        m_buffer += 2;
        return;
    }
    else if (m_buffer[0] == '>' && m_buffer[1] == '=')
    {
        m_token = HLSLToken_GreaterEqual;
        m_buffer += 2;
        return;
    }
    else if (m_buffer[0] == '&' && m_buffer[1] == '&')
    {
        m_token = HLSLToken_AndAnd;
        m_buffer += 2;
        return;
    }
    else if (m_buffer[0] == '|' && m_buffer[1] == '|')
    {
        m_token = HLSLToken_BarBar;
        m_buffer += 2;
        return;
    }

    // ++, --
    if ((m_buffer[0] == '-' || m_buffer[0] == '+') && (m_buffer[1] == m_buffer[0]))
    {
        m_token = (m_buffer[0] == '+') ? HLSLToken_PlusPlus : HLSLToken_MinusMinus;
        m_buffer += 2;
        return;
    }

    // Check for the start of a number.
    if (ScanNumber())
    {
        return;
    }
    
    if (GetIsSymbol(m_buffer[0]))
    {
        m_token = static_cast<unsigned char>(m_buffer[0]);
        ++m_buffer;
        return;
    }

    // Must be an identifier or a reserved word.
    while (m_buffer < m_bufferEnd && m_buffer[0] != 0 && !GetIsSymbol(m_buffer[0]) && !isspace(m_buffer[0]))
    {
        ++m_buffer;
    }

    size_t length = m_buffer - start;
    memcpy(m_identifier, start, length);
    m_identifier[length] = 0;
    
    const int numReservedWords = sizeof(_reservedWords) / sizeof(const char*);
    for (int i = 0; i < numReservedWords; ++i)
    {
        if (strcmp(_reservedWords[i], m_identifier) == 0)
        {
            m_token = 256 + i;
            return;
        }
    }

    m_token = HLSLToken_Identifier;

}
Beispiel #3
0
void AccuInheritAtTreeSymbs (Environment globEnv) {
/* on entry:
       The internal representations of all single accumulating computations
       have been associated to the properties AccuLhs, AccuExecList, 
       AccuDepList of the computation key.
       The other Accu-properties are set.
       The inheritance relations in the computation scopes are established.
       The attribute types are determined.
   on exit:
       Each TREE symbol X has collected the accumulated computations from
       any CLASS Symbol it inherits from, stored in its properties AccuLhs, 
       AccuExecList, AccuDepList of X's computation key.
*/
  Binding symBind = DefinitionsOf (globEnv);

#ifdef ACCUTEST
  printf ("AccuInheritAtTreeSymbs begin\n");
#endif

  while (symBind != NoBinding) {
    DefTableKey symKey = KeyOf (symBind);
    if (GetIsNonterm (symKey, 0) && GetIsTreeSym (symKey, 0)) {
       Environment attrenv = GetAttrScope (symKey, NoEnv);
       Binding attr;
       Environment symLowScope = GetLowerScope (symKey, NoEnv);
       Environment symUpScope = GetUpperScope (symKey, NoEnv);
 
      /* search all attributes of this symbol for accumulating ones: */
         attr = DefinitionsOf (attrenv);
         while (attr != NoBinding) {
          if (InheritAttrAccu (attr)) {
             int attrId = IdnOf (attr);
             int attrCl = GetAttrClass (KeyOf (attr), NoClass);
             Environment symScope = 
                (attrCl == SYNTClass ? symLowScope : symUpScope);
             Binding inhComp, classSym;
             Binding symComp = BindingInEnv (symScope, attrId);
#ifdef ACCUTEST
  printf ("    accu attribute %s.%s\n",
     StringTable (GetNameSym (symKey, 0)),
     StringTable (attrId));
#endif
             if (symComp == NoBinding) {
                /* no symbol computation, no inherited computation 
                   create a symbol computation */
                symComp = 
                   MakeAnAccuBinding (symScope, attr, symKey, 
                                      GetCoord (symKey, ZeroCoord));
                ResetAccuLhs (KeyOf (symComp), 
                              newAttrAccSymb (symKey, KeyOf (attr), 0, 
                                              GetCoord (symKey, ZeroCoord)));
                break; /* no further action for this attr */
             } else if (EnvOf (symComp) == symScope) {
                inhComp = OverridesBinding (symComp);
                if (inhComp == NoBinding) 
                    /* a symbol computation, no inherited computation */
                    break; /* no action for this attr */
                /* else a symbol computation, an inherited computation */
             } else {
                /* no symbol computation, only inherited computations */
                /* create a symbol computation: */
                inhComp = symComp;
                symComp = 
                   MakeAnAccuBinding (symScope, attr, symKey, 
                                      GetCoord (symKey, ZeroCoord));
                ResetInheritedFrom (KeyOf (symComp), inhComp);
                ResetAccuLhs (KeyOf (symComp), 
                              newAttrAccSymb (symKey, KeyOf (attr), 0, 
                                              GetCoord (symKey, ZeroCoord)));
             }
             /* There are inherited computations to be accumulated on symComp: 
                We step through all symbols and search in their 
                computation scopes inhCompScope which 
                     Inheritsfrom (symScope, inhCompScope), 
                whether it has a computation to be accumulated on symComp.
             */
#ifdef ACCUTEST
  printf ("    there are inherited computations for %s.%s\n",
     StringTable (GetNameSym (symKey, 0)),
     StringTable (attrId));
#endif
             classSym = DefinitionsOf (globEnv);
             while (classSym != NoBinding) {
               DefTableKey k = KeyOf (classSym);
               if (k != symKey && GetIsSymbol (k, 0)) {
                  Environment inhCompScope =
                    (attrCl == SYNTClass ? 
                     GetLowerScope (k, NoEnv) : GetUpperScope (k, NoEnv));
                  if (Inheritsfrom (symScope, inhCompScope)) {
                     /* inheritance relation holds */
#ifdef ACCUTEST
  printf ("    inherits from class %s\n", StringTable (GetNameSym (k, 0)));
#endif
                     Binding attrComp = DefinitionsOf (inhCompScope);
                     while (attrComp != NoBinding) {
                       if (IdnOf (attrComp) == attrId) {
                           if (!GetIsAccu (KeyOf (attrComp), 0)) {
                             message (ERROR, 
                               CatStrInd ("Is inherited by an accumulating computation: ",
                                          attrId), 0, 
                               GetCoord (KeyOf(attrComp), ZeroCoord));
                               break;
                          } else if (GetIsTreeSym (k, 0)) {
                             message (ERROR, 
                               CatStrInd ("Can not inherit from a TREE symbol: ",
                                 attrId), 0, GetCoord (KeyOf(attrComp), ZeroCoord));
                             break;
                         } /* IsClass */
                         /* this computation is to be accumulated to symComp */

                         AccumulateAnInhComp (symComp, attrComp);

                         /* there is only one such computation in a scope: */
                         break;
                       }/* attr comps of this class symb */
                       attrComp = NextDefinition (attrComp);
                     }/* end search for a computation in a super scope */
                  }/* a super scope */
               }/* a symbol */
               classSym = NextDefinition (classSym);
             }/* a global definition */
          } /* accu attr */
          attr = NextDefinition (attr);
       }/* attributes */
    }/* IsTreeSym */
    symBind = NextDefinition (symBind);
  }/* definitions */
#ifdef ACCUTEST
  printf ("AccuInheritAtTreeSymbs end\n");
#endif
}/* AccuInheritAtTreeSymbs */