This repository has been archived on 2024-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
SNOL/source/lexer.d

153 lines
3.7 KiB
D
Raw Permalink Normal View History

2022-07-25 22:07:11 +02:00
module lexer;
import std.stdio;
import core.stdc.ctype;
import std.string;
enum TOKEN_TYPE
{
OPERATOR,
INTEGER,
FLOAT,
VARIABLE,
PROCEDURE,
UNKNOWN,
END_OF_TEXT
}
struct Token
{
TOKEN_TYPE type;
string data;
}
const string OPERATORS = "=+-*/%";
struct Lexer
{
long position = 0;
private string textToTokenize;
this(string textToTokenize)
{
this.textToTokenize = textToTokenize;
}
Token getNextToken()
{
if (position >= textToTokenize.length)
return Token(TOKEN_TYPE.END_OF_TEXT, null);
string dataStr;
char lastChar = textToTokenize[position];
while (isspace(lastChar))
{
position++;
if (position >= textToTokenize.length)
return Token(TOKEN_TYPE.END_OF_TEXT, null);
lastChar = textToTokenize[position];
}
if (isalpha(lastChar))
{
dataStr ~= lastChar;
lastChar = textToTokenize[++position];
while (isalnum(lastChar))
{
dataStr ~= lastChar;
position++;
if (position >= textToTokenize.length)
break;
else
lastChar = textToTokenize[position];
}
if (dataStr == "BEG")
return Token(TOKEN_TYPE.PROCEDURE, dataStr);
else if (dataStr == "PRINT")
{
return Token(TOKEN_TYPE.PROCEDURE, dataStr);
}
else if (dataStr == "EXIT" && lastChar == '!')
{
position++;
return Token(TOKEN_TYPE.PROCEDURE, dataStr);
}
else
{
return Token(TOKEN_TYPE.VARIABLE, dataStr);
}
}
if (indexOf(OPERATORS, lastChar) > -1)
{
dataStr ~= lastChar;
position++;
return Token(TOKEN_TYPE.OPERATOR, dataStr);
}
if (isdigit(lastChar))
{
dataStr ~= lastChar;
position++;
if (position >= textToTokenize.length)
return Token(TOKEN_TYPE.INTEGER, dataStr);
lastChar = textToTokenize[position];
while (isdigit(lastChar))
{
dataStr ~= lastChar;
position++;
if (position >= textToTokenize.length)
return Token(TOKEN_TYPE.INTEGER, dataStr);
lastChar = textToTokenize[position];
}
if (lastChar == '.')
{
dataStr ~= lastChar;
position++;
if (position >= textToTokenize.length)
{
position--;
return Token(TOKEN_TYPE.INTEGER, dataStr);
}
lastChar = textToTokenize[position];
while (isdigit(lastChar))
{
dataStr ~= lastChar;
position++;
if (position >= textToTokenize.length)
return Token(TOKEN_TYPE.FLOAT, dataStr);
lastChar = textToTokenize[position];
}
if(dataStr[$-1] == '.')
{
position--;
return Token(TOKEN_TYPE.INTEGER, dataStr[0..$-1]);
}
return Token(TOKEN_TYPE.FLOAT, dataStr);
}
else
{
return Token(TOKEN_TYPE.INTEGER, dataStr);
}
}
dataStr ~= lastChar;
position++;
return Token(TOKEN_TYPE.UNKNOWN, dataStr);
}
}