Lexer daha anlaşılır hale getirildi
This commit is contained in:
parent
8adeabaff1
commit
0f33740a07
654
core/Lexer.cpp
654
core/Lexer.cpp
|
|
@ -20,372 +20,406 @@ public:
|
|||
int size = 0;
|
||||
int offset = 0;
|
||||
std::vector<int> offsetMap;
|
||||
void beginPosition()
|
||||
{
|
||||
this->offsetMap.push_back(this->getLastPosition());
|
||||
}
|
||||
int getLastPosition()
|
||||
{
|
||||
if(this->offsetMap.size() == 0)
|
||||
{
|
||||
return this->offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->offsetMap[this->offsetMap.size() - 1];
|
||||
}
|
||||
}
|
||||
void acceptPosition()
|
||||
{
|
||||
int T = this->offsetMap[this->offsetMap.size() - 1];
|
||||
this->setLastPosition(T);
|
||||
}
|
||||
void setLastPosition(int n)
|
||||
{
|
||||
if(this->offsetMap.size() == 0)
|
||||
{
|
||||
this->offset = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->offsetMap[this->offsetMap.size() - 1] = n;
|
||||
}
|
||||
}
|
||||
bool isEnd()
|
||||
{
|
||||
bool result = this->size <= this->getOffset();
|
||||
return result;
|
||||
}
|
||||
void rejectPosition()
|
||||
{
|
||||
this->offsetMap.pop_back();
|
||||
}
|
||||
int * positionRange()
|
||||
{
|
||||
int len = this->offsetMap.size();
|
||||
if(len == 0)
|
||||
{
|
||||
return new int[2]{0, this->offset};
|
||||
}
|
||||
else if(len == 1)
|
||||
{
|
||||
return new int[2]{
|
||||
this->offset,
|
||||
this->offsetMap[len - 1]
|
||||
};
|
||||
}else{
|
||||
return new int[2]{
|
||||
this->offsetMap[len - 2],
|
||||
this->offsetMap[len - 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
std::string getPositionRange()
|
||||
{
|
||||
int *A = this->positionRange();
|
||||
std::string mem;
|
||||
void beginPosition();
|
||||
int getLastPosition();
|
||||
void acceptPosition();
|
||||
void setLastPosition(int);
|
||||
bool isEnd();
|
||||
void rejectPosition();
|
||||
int * positionRange();
|
||||
std::string getPositionRange();
|
||||
bool include(std::string,bool);
|
||||
int getOffset();
|
||||
int setOffset(int);
|
||||
char getchar(int);
|
||||
char getchar();
|
||||
void nextChar();
|
||||
void toChar(int);
|
||||
void setText(std::string);
|
||||
void skipWhiteSpace();
|
||||
bool isNumeric();
|
||||
INumber readNumeric();
|
||||
};
|
||||
|
||||
for (int i = A[0]; i < A[1];i++)
|
||||
{
|
||||
mem.push_back(this->input.at(i));
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
void Lexer::beginPosition()
|
||||
{
|
||||
this->offsetMap.push_back(this->getLastPosition());
|
||||
}
|
||||
|
||||
bool include(std::string word,bool accept = true)
|
||||
|
||||
int Lexer::getLastPosition()
|
||||
{
|
||||
if(this->offsetMap.size() == 0)
|
||||
{
|
||||
this->beginPosition();
|
||||
for (int i = 0; i < word.size(); i++)
|
||||
return this->offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->offsetMap[this->offsetMap.size() - 1];
|
||||
}
|
||||
}
|
||||
void Lexer::acceptPosition()
|
||||
{
|
||||
int T = this->offsetMap[this->offsetMap.size() - 1];
|
||||
this->setLastPosition(T);
|
||||
}
|
||||
void Lexer::setLastPosition(int n)
|
||||
{
|
||||
if(this->offsetMap.size() == 0)
|
||||
{
|
||||
this->offset = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->offsetMap[this->offsetMap.size() - 1] = n;
|
||||
}
|
||||
}
|
||||
bool Lexer::isEnd()
|
||||
{
|
||||
bool result = this->size <= this->getOffset();
|
||||
return result;
|
||||
}
|
||||
void Lexer::rejectPosition()
|
||||
{
|
||||
this->offsetMap.pop_back();
|
||||
}
|
||||
int * Lexer::positionRange()
|
||||
{
|
||||
int len = this->offsetMap.size();
|
||||
if(len == 0)
|
||||
{
|
||||
return new int[2]{0, this->offset};
|
||||
}
|
||||
else if(len == 1)
|
||||
{
|
||||
return new int[2]{
|
||||
this->offset,
|
||||
this->offsetMap[len - 1]
|
||||
};
|
||||
}else{
|
||||
return new int[2]{
|
||||
this->offsetMap[len - 2],
|
||||
this->offsetMap[len - 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
std::string Lexer::getPositionRange()
|
||||
{
|
||||
int *A = this->positionRange();
|
||||
std::string mem;
|
||||
|
||||
for (int i = A[0]; i < A[1];i++)
|
||||
{
|
||||
mem.push_back(this->input.at(i));
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
|
||||
bool Lexer::include(std::string word,bool accept = true)
|
||||
{
|
||||
this->beginPosition();
|
||||
for (int i = 0; i < word.size(); i++)
|
||||
{
|
||||
if(this->isEnd())
|
||||
{
|
||||
if(this->isEnd())
|
||||
{
|
||||
if(word.size() == i)
|
||||
{
|
||||
break;
|
||||
}else{
|
||||
this->rejectPosition();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(word.at(i) != this->getchar())
|
||||
if(word.size() == i)
|
||||
{
|
||||
break;
|
||||
}else{
|
||||
this->rejectPosition();
|
||||
return false;
|
||||
}
|
||||
this->nextChar();
|
||||
}
|
||||
if(accept)
|
||||
{
|
||||
this->acceptPosition();
|
||||
}
|
||||
else
|
||||
if(word.at(i) != this->getchar())
|
||||
{
|
||||
this->rejectPosition();
|
||||
};
|
||||
return true;
|
||||
}
|
||||
int getOffset()
|
||||
{
|
||||
return this->getLastPosition();
|
||||
}
|
||||
int setOffset(int n)
|
||||
{
|
||||
this->setLastPosition(n);
|
||||
return this->getLastPosition();
|
||||
}
|
||||
char getchar(int additionalOffset = 0)
|
||||
{
|
||||
int target = this->getOffset() + additionalOffset;
|
||||
if(this->size - 1 < target)
|
||||
{
|
||||
std::cerr << "Hata yanlış erişim\n";
|
||||
return '\0';
|
||||
}else{
|
||||
return this->input.at(target);
|
||||
return false;
|
||||
}
|
||||
this->nextChar();
|
||||
}
|
||||
void nextChar()
|
||||
if(accept)
|
||||
{
|
||||
if(this->isEnd() == true)
|
||||
{
|
||||
return;
|
||||
};
|
||||
this->setOffset(this->getOffset() + 1);
|
||||
this->acceptPosition();
|
||||
}
|
||||
void toChar(int n)
|
||||
else
|
||||
{
|
||||
if(this->isEnd() == true)
|
||||
{
|
||||
return;
|
||||
};
|
||||
this->setOffset(this->getOffset() + n);
|
||||
}
|
||||
void setText(std::string input) {
|
||||
this->input = input;
|
||||
this->size = input.length();
|
||||
}
|
||||
void skipWhiteSpace()
|
||||
this->rejectPosition();
|
||||
};
|
||||
return true;
|
||||
}
|
||||
int Lexer::getOffset()
|
||||
{
|
||||
return this->getLastPosition();
|
||||
}
|
||||
int Lexer::setOffset(int n)
|
||||
{
|
||||
this->setLastPosition(n);
|
||||
return this->getLastPosition();
|
||||
}
|
||||
char Lexer::getchar(int additionalOffset)
|
||||
{
|
||||
int target = this->getOffset() + additionalOffset;
|
||||
if(this->size - 1 < target)
|
||||
{
|
||||
while(this->isEnd() == false)
|
||||
std::cerr << "Hata yanlış erişim\n";
|
||||
return '\0';
|
||||
}else{
|
||||
return this->input.at(target);
|
||||
}
|
||||
}
|
||||
char Lexer::getchar()
|
||||
{
|
||||
int target = this->getOffset();
|
||||
if(this->size - 1 < target)
|
||||
{
|
||||
std::cerr << "Hata yanlış erişim\n";
|
||||
return '\0';
|
||||
}else{
|
||||
return this->input.at(target);
|
||||
}
|
||||
}
|
||||
void Lexer::nextChar()
|
||||
{
|
||||
if(this->isEnd() == true)
|
||||
{
|
||||
return;
|
||||
};
|
||||
this->setOffset(this->getOffset() + 1);
|
||||
}
|
||||
void Lexer::toChar(int n)
|
||||
{
|
||||
if(this->isEnd() == true)
|
||||
{
|
||||
return;
|
||||
};
|
||||
this->setOffset(this->getOffset() + n);
|
||||
}
|
||||
void Lexer::setText(std::string input) {
|
||||
this->input = input;
|
||||
this->size = input.length();
|
||||
}
|
||||
void Lexer::skipWhiteSpace()
|
||||
{
|
||||
while(this->isEnd() == false)
|
||||
{
|
||||
switch(this->getchar())
|
||||
{
|
||||
switch(this->getchar())
|
||||
{
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\b':
|
||||
case '\t':
|
||||
case ' ':{
|
||||
this->nextChar();
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
return;
|
||||
}
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\b':
|
||||
case '\t':
|
||||
case ' ':{
|
||||
this->nextChar();
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isNumeric()
|
||||
bool Lexer::isNumeric()
|
||||
{
|
||||
char c = this->getchar();
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':{
|
||||
return true;
|
||||
}
|
||||
default:{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INumber Lexer::readNumeric()
|
||||
{
|
||||
INumber numberToken;
|
||||
numberToken.start = this->getLastPosition();
|
||||
if(this->getchar() == '-')
|
||||
{
|
||||
this->nextChar();
|
||||
numberToken.positive = false;
|
||||
}else if(this->getchar() == '+'){
|
||||
this->nextChar();
|
||||
numberToken.positive = true;
|
||||
}else{
|
||||
numberToken.positive = true;
|
||||
}
|
||||
|
||||
bool nextDot = false;
|
||||
if(this->getchar() == '0')
|
||||
{
|
||||
numberToken.token.push_back('0');
|
||||
this->nextChar();
|
||||
char c = this->getchar();
|
||||
switch(c)
|
||||
{
|
||||
case 'x':{
|
||||
numberToken.token.push_back(c);
|
||||
numberToken.base = 16;
|
||||
break;
|
||||
}
|
||||
case 'b':{
|
||||
numberToken.token.push_back(c);
|
||||
numberToken.base = 2;
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
if(c != '.')
|
||||
{
|
||||
numberToken.token.push_back(c);
|
||||
numberToken.base = 8;
|
||||
}else{
|
||||
numberToken.token.push_back(c);
|
||||
numberToken.base = 10;
|
||||
nextDot = true;
|
||||
numberToken.isFloat = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->nextChar();
|
||||
}else{
|
||||
numberToken.base = 10;
|
||||
}
|
||||
|
||||
|
||||
while(this->isEnd() == false)
|
||||
{
|
||||
char c = this->getchar();
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '1':{
|
||||
numberToken.token.push_back(c);
|
||||
break;
|
||||
}
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '7':{
|
||||
if(numberToken.base >= 8)
|
||||
{
|
||||
numberToken.token.push_back(c);
|
||||
break;
|
||||
}else{
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
}
|
||||
case '8':
|
||||
case '9':{
|
||||
return true;
|
||||
}
|
||||
default:{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INumber readNumeric(){
|
||||
INumber numberToken;
|
||||
numberToken.start = this->getLastPosition();
|
||||
if(this->getchar() == '-')
|
||||
{
|
||||
this->nextChar();
|
||||
numberToken.positive = false;
|
||||
}else if(this->getchar() == '+'){
|
||||
this->nextChar();
|
||||
numberToken.positive = true;
|
||||
}else{
|
||||
numberToken.positive = true;
|
||||
}
|
||||
|
||||
bool nextDot = false;
|
||||
if(this->getchar() == '0')
|
||||
{
|
||||
numberToken.token.push_back('0');
|
||||
this->nextChar();
|
||||
char c = this->getchar();
|
||||
switch(c)
|
||||
{
|
||||
case 'x':{
|
||||
if(numberToken.base >= 10)
|
||||
{
|
||||
numberToken.token.push_back(c);
|
||||
numberToken.base = 16;
|
||||
break;
|
||||
}else{
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
case 'b':{
|
||||
}
|
||||
case 'a': case 'A':
|
||||
case 'b': case 'B':
|
||||
case 'c': case 'C':
|
||||
case 'd': case 'D':
|
||||
case 'f': case 'F':{
|
||||
if(numberToken.base >= 16)
|
||||
{
|
||||
numberToken.token.push_back(c);
|
||||
numberToken.base = 2;
|
||||
break;
|
||||
}else{
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
default:{
|
||||
if(c != '.')
|
||||
}
|
||||
case '.':{
|
||||
if(nextDot == false)
|
||||
{
|
||||
if(numberToken.token.size() == 0)
|
||||
{
|
||||
numberToken.token.push_back(c);
|
||||
numberToken.base = 8;
|
||||
numberToken.token.push_back('0');
|
||||
numberToken.token.push_back('.');
|
||||
}else{
|
||||
numberToken.token.push_back(c);
|
||||
numberToken.base = 10;
|
||||
nextDot = true;
|
||||
numberToken.isFloat = true;
|
||||
numberToken.token.push_back('.');
|
||||
}
|
||||
nextDot = true;
|
||||
numberToken.isFloat = true;
|
||||
break;
|
||||
}else{
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
}
|
||||
this->nextChar();
|
||||
}else{
|
||||
numberToken.base = 10;
|
||||
}
|
||||
|
||||
|
||||
while(this->isEnd() == false)
|
||||
{
|
||||
char c = this->getchar();
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':{
|
||||
case 'e':case 'E':{
|
||||
if(numberToken.base == 16)
|
||||
{
|
||||
numberToken.token.push_back(c);
|
||||
break;
|
||||
}
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':{
|
||||
if(numberToken.base >= 8)
|
||||
if(numberToken.base == 10)
|
||||
{
|
||||
numberToken.hasEpsilon = true;
|
||||
numberToken.token.push_back(c);
|
||||
this->nextChar();
|
||||
c = this->getchar();
|
||||
|
||||
if(c == '+' || c == '-')
|
||||
{
|
||||
numberToken.token.push_back(c);
|
||||
break;
|
||||
}else{
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
}
|
||||
case '8':
|
||||
case '9':{
|
||||
if(numberToken.base >= 10)
|
||||
{
|
||||
numberToken.token.push_back(c);
|
||||
break;
|
||||
}else{
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
}
|
||||
case 'a': case 'A':
|
||||
case 'b': case 'B':
|
||||
case 'c': case 'C':
|
||||
case 'd': case 'D':
|
||||
case 'f': case 'F':{
|
||||
if(numberToken.base >= 16)
|
||||
{
|
||||
numberToken.token.push_back(c);
|
||||
break;
|
||||
}else{
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
}
|
||||
case '.':{
|
||||
if(nextDot == false)
|
||||
{
|
||||
if(numberToken.token.size() == 0)
|
||||
{
|
||||
numberToken.token.push_back('0');
|
||||
numberToken.token.push_back('.');
|
||||
}else{
|
||||
numberToken.token.push_back('.');
|
||||
}
|
||||
nextDot = true;
|
||||
numberToken.isFloat = true;
|
||||
break;
|
||||
}else{
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
}
|
||||
case 'e':case 'E':{
|
||||
if(numberToken.base == 16)
|
||||
{
|
||||
numberToken.token.push_back(c);
|
||||
break;
|
||||
}
|
||||
if(numberToken.base == 10)
|
||||
{
|
||||
numberToken.hasEpsilon = true;
|
||||
numberToken.token.push_back(c);
|
||||
this->nextChar();
|
||||
c = this->getchar();
|
||||
|
||||
if(c == '+' || c == '-')
|
||||
{
|
||||
numberToken.token.push_back(c);
|
||||
this->nextChar();
|
||||
}
|
||||
|
||||
while(this->isEnd() == false)
|
||||
{
|
||||
char c = this->getchar();
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':{
|
||||
numberToken.token.push_back(c);
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
}
|
||||
this->nextChar();
|
||||
}
|
||||
break;
|
||||
}
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
default:{
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
|
||||
while(this->isEnd() == false)
|
||||
{
|
||||
char c = this->getchar();
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':{
|
||||
numberToken.token.push_back(c);
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
}
|
||||
this->nextChar();
|
||||
}
|
||||
break;
|
||||
}
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
default:{
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
}
|
||||
this->nextChar();
|
||||
}
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
this->nextChar();
|
||||
}
|
||||
numberToken.end = this->getLastPosition();
|
||||
return numberToken;
|
||||
};
|
||||
#endif
|
||||
Loading…
Reference in New Issue