Ejemplo n.º 1
0
 void ParseSymbols()
 {
     StartToken();
     
     switch (Previous())
     {
         case '/':
             if (Current() == '/')
             {
                 ParseLineComment();
                 break;
             }
             else if (Current() == '*')
             {
                 ParseBlockComment();
                 break;
             }
             
             // Yes. No break. This is deliberate.
             
         default:
         {
             String4 tinySource = {};
             tinySource.Append(Previous());
             lastSourceToken.tokenType = TokenType::Reserved;
             lastSourceToken.tokenIndex = FindOperator(tinySource);
             
             for (int i = index; i < length && IsSymbol(source[i]); ++i)
             {
                 tinySource.Append(source[i]);
                 auto tokenIndex = FindOperator(tinySource);
                 
                 if (tokenIndex != -1)
                 {
                     lastSourceToken.tokenIndex = tokenIndex;
                     lastSourceToken.length = i - index + 2;
                 }
             }
             
             int offset = lastSourceToken.length - 1;
             index += offset;
             position.column += offset;
             
             break;
         }
     }
 }
char* Preprocessor::ParseLexem( char* start, char* end, Lexem& out )
{
    if( start == end )
        return start;
    char current_char = *start;

    if( IsTrivial( current_char ) )
    {
        out.Value += current_char;
        out.Type = TrivialTypes[Trivials.find_first_of( current_char )];
        return ++start;
    }

    if( IsIdentifierStart( current_char ) )
        return ParseIdentifier( start, end, out );

    if( current_char == '#' )
    {
        out.Value = "#";
        ++start;
        if( *start == '#' )
        {
            out.Value = "##";
            out.Type = Lexem::IGNORE;
            return ( ++start );
        }
        while( start != end && ( *start == ' ' || *start == '\t' ) )
            ++start;
        if( start != end && IsIdentifierStart( *start ) )
            start = ParseIdentifier( start, end, out );
        out.Type = Lexem::PREPROCESSOR;
        return start;
    }

    if( IsNumber( current_char ) )
        return ParseNumber( start, end, out );
    if( current_char == '\"' )
        return ParseStringLiteral( start, end, '\"', out );
    if( current_char == '\'' )
        return ParseStringLiteral( start, end, '\'', out );  // Todo: set optional ParseCharacterLiteral?
    if( current_char == '/' )
    {
        // Need to see if it's a comment.
        ++start;
        if( start == end )
            return start;
        if( *start == '*' )
            return ParseBlockComment( start, end, out );
        if( *start == '/' )
            return ParseLineComment( start, end, out );
        // Not a comment - let default code catch it as MISC
        --start;
    }
    if( current_char == '\\' )
    {
        out.Type = Lexem::BACKSLASH;
        return ++start;
    }

    out.Value = std::string( 1, current_char );
    out.Type = Lexem::IGNORE;
    return ++start;
}