📄 lexer.cpp
字号:
}
// If it's an escape sequence, switch to the escape state and don't add the
// backslash to the lexeme
else if ( cCurrChar == '\\' )
{
iAddCurrChar = FALSE;
iCurrLexState = LEX_STATE_STRING_ESCAPE;
}
// Anything else gets added to the string
break;
// Escape sequence
case LEX_STATE_STRING_ESCAPE:
// Immediately switch back to the string state, now that the character's
// been added
iCurrLexState = LEX_STATE_STRING;
break;
// String closing quote
case LEX_STATE_STRING_CLOSE_QUOTE:
// Finish the string lexeme
iAddCurrChar = FALSE;
iLexemeDone = TRUE;
break;
}
// Add the next character to the lexeme and increment the index
if ( iAddCurrChar )
{
g_CurrLexerState.pstrCurrLexeme [ iNextLexemeCharIndex ] = cCurrChar;
++ iNextLexemeCharIndex;
}
// If the lexeme is complete, exit the loop
if ( iLexemeDone )
break;
}
// Complete the lexeme string
g_CurrLexerState.pstrCurrLexeme [ iNextLexemeCharIndex ] = '\0';
// Retract the lexeme end index by one
-- g_CurrLexerState.iCurrLexemeEnd;
// Determine the token type
Token TokenType;
switch ( iCurrLexState )
{
// Unknown
case LEX_STATE_UNKNOWN:
TokenType = TOKEN_TYPE_INVALID;
break;
// Integer
case LEX_STATE_INT:
TokenType = TOKEN_TYPE_INT;
break;
// Float
case LEX_STATE_FLOAT:
TokenType = TOKEN_TYPE_FLOAT;
break;
// Identifier/Reserved Word
case LEX_STATE_IDENT:
// Set the token type to identifier in case none of the reserved words match
TokenType = TOKEN_TYPE_IDENT;
// ---- Determine if the "identifier" is actually a reserved word
// var/var []
if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "var" ) == 0 )
TokenType = TOKEN_TYPE_RSRVD_VAR;
// true
if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "true" ) == 0 )
TokenType = TOKEN_TYPE_RSRVD_TRUE;
// false
if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "false" ) == 0 )
TokenType = TOKEN_TYPE_RSRVD_FALSE;
// if
if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "if" ) == 0 )
TokenType = TOKEN_TYPE_RSRVD_IF;
// else
if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "else" ) == 0 )
TokenType = TOKEN_TYPE_RSRVD_ELSE;
// break
if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "break" ) == 0 )
TokenType = TOKEN_TYPE_RSRVD_BREAK;
// continue
if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "continue" ) == 0 )
TokenType = TOKEN_TYPE_RSRVD_CONTINUE;
// for
if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "for" ) == 0 )
TokenType = TOKEN_TYPE_RSRVD_FOR;
// while
if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "while" ) == 0 )
TokenType = TOKEN_TYPE_RSRVD_WHILE;
// func
if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "func" ) == 0 )
TokenType = TOKEN_TYPE_RSRVD_FUNC;
// return
if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "return" ) == 0 )
TokenType = TOKEN_TYPE_RSRVD_RETURN;
// host
if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "host" ) == 0 )
TokenType = TOKEN_TYPE_RSRVD_HOST;
break;
// Delimiter
case LEX_STATE_DELIM:
// Determine which delimiter was found
switch ( g_CurrLexerState.pstrCurrLexeme [ 0 ] )
{
case ',':
TokenType = TOKEN_TYPE_DELIM_COMMA;
break;
case '(':
TokenType = TOKEN_TYPE_DELIM_OPEN_PAREN;
break;
case ')':
TokenType = TOKEN_TYPE_DELIM_CLOSE_PAREN;
break;
case '[':
TokenType = TOKEN_TYPE_DELIM_OPEN_BRACE;
break;
case ']':
TokenType = TOKEN_TYPE_DELIM_CLOSE_BRACE;
break;
case '{':
TokenType = TOKEN_TYPE_DELIM_OPEN_CURLY_BRACE;
break;
case '}':
TokenType = TOKEN_TYPE_DELIM_CLOSE_CURLY_BRACE;
break;
case ';':
TokenType = TOKEN_TYPE_DELIM_SEMICOLON;
break;
}
break;
// Operators
case LEX_STATE_OP:
TokenType = TOKEN_TYPE_OP;
break;
// Strings
case LEX_STATE_STRING_CLOSE_QUOTE:
TokenType = TOKEN_TYPE_STRING;
break;
// All that's left is whitespace, which means the end of the stream
default:
TokenType = TOKEN_TYPE_END_OF_STREAM;
}
// Return the token type and set the global copy
g_CurrLexerState.CurrToken = TokenType;
return TokenType;
}
/******************************************************************************************
*
* RewindTokenStream ()
*
* Moves the lexer back one token.
*/
void RewindTokenStream ()
{
CopyLexerState ( g_CurrLexerState, g_PrevLexerState );
}
/******************************************************************************************
*
* GetCurrToken ()
*
* Returns the current token.
*/
Token GetCurrToken ()
{
return g_CurrLexerState.CurrToken;
}
/******************************************************************************************
*
* GetCurrLexeme ()
*
* Returns a pointer to the current lexeme.
*/
char * GetCurrLexeme ()
{
return g_CurrLexerState.pstrCurrLexeme;
}
/******************************************************************************************
*
* CopyCurrLexeme ()
*
* Makes a physical copy of the current lexeme into the specified string buffer.
*/
void CopyCurrLexeme ( char * pstrBuffer )
{
strcpy ( pstrBuffer, g_CurrLexerState.pstrCurrLexeme );
}
/******************************************************************************************
*
* GetCurrOp ()
*
* Returns the current operator.
*/
int GetCurrOp ()
{
return g_CurrLexerState.iCurrOp;
}
/******************************************************************************************
*
* GetLookAheadChar ()
*
* Returns the first character of the next token.
*/
char GetLookAheadChar ()
{
// Save the current lexer state
LexerState PrevLexerState;
CopyLexerState ( PrevLexerState, g_CurrLexerState );
// Skip any whitespace that may exist and return the first non-whitespace character
char cCurrChar;
while ( TRUE )
{
cCurrChar = GetNextChar ();
if ( ! IsCharWhitespace ( cCurrChar ) )
break;
}
// Restore the lexer state
CopyLexerState ( g_CurrLexerState, PrevLexerState );
// Return the look-ahead character
return cCurrChar;
}
/******************************************************************************************
*
* GetCurrSourceLine ()
*
* Returns a pointer to the current source line string.
*/
char * GetCurrSourceLine ()
{
if ( g_CurrLexerState.pCurrLine )
return ( char * ) g_CurrLexerState.pCurrLine->pData;
else
return NULL;
}
/******************************************************************************************
*
* GetCurrSourceLineIndex ()
*
* Returns the current source line number.
*/
int GetCurrSourceLineIndex ()
{
return g_CurrLexerState.iCurrLineIndex;
}
/******************************************************************************************
*
* GetLexemeStartIndex ()
*
* Returns the pointer to the start of the current lexeme
*/
int GetLexemeStartIndex ()
{
return g_CurrLexerState.iCurrLexemeStart;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -