Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
бАКАЛАВР_РАБОТА.docx
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
2.13 Mб
Скачать

Файл lexer.Cpp

#include "lexer.h"

inline bool lexer::Lexer::readch()

{

return in.get(peek);

}

inline bool lexer::Lexer::readch(char c)

{

if(!readch()) return false;// END

if(peek != c) return false;

peek = ' ';

return true;

}

inline void lexer::Lexer::error(Type_error type )

{

static logger::Logger & diag=logger::Logger::getLogger();

string prefix_msg="lexer error - "+getLine()+": ";

switch(type){

case INVAL_NE: diag.log(prefix_msg+"undefined symbol "+"\'!\'"); break;

case UNDEF_SYM: diag.log(prefix_msg+"undefined symbol "+"\'"+peek+"\'");readch(); break;

case DECIM_POINT: diag.log(prefix_msg+"expected digit after decimal separator");break;

case EXPON: diag.log(prefix_msg+"expected digit after exponent");break;

case INVAL_SUFF: diag.log(prefix_msg + "invalid suffix on constant");skipAlpha();break;

}

}

void lexer::Lexer::skipAlpha()

{

while( readch() && isalpha(peek) );

}

std::string lexer::Lexer::getLine() const

{

char buff[10];

sprintf_s(buff,"%d",line);

return string(buff);

}

inline void lexer::Lexer::warning(const string &info)

{

logger::Logger::getLogger().log("lexer warning - "+getLine()+": "+info);

}

lexer::shared_ptr<lexer::Token> lexer::Lexer::scan()

{

for( ; ; readch() ){

if(in.eof()) {

return shared_ptr<Token>(new Token(Token::END));

}

if( peek == ' '||peek == '\t') continue;

else if( peek == '\n') line = line+1;

else break;

}

switch(peek){

case '/' :

if(readch('/')){ // skip comments

for( ; ; readch() ){

if(in.eof()) {

return shared_ptr<Token>(new Token(Token::END));

}

if( peek == '\n'){

break;

}

}

return scan();

} else return shared_ptr<Token>(new Token(Token::Tag('/')));

case '!' :

if(readch('=')) return shared_ptr<Token>(new Token(Token::NE));

else {

error(INVAL_NE); // invalid NotEqual;

return scan();

}

case '=' :

if( readch('=')) return shared_ptr<Token>(new Token(Token::EQ));

else return shared_ptr<Token>(new Token(Token::Tag('=')));

case '<' :

if(readch())

switch(peek){

case '=': peek=' '; return shared_ptr<Token>(new Token(Token::LE));

case '>': peek=' '; return shared_ptr<Token>(new Token(Token::NE));

default:

;

}

return shared_ptr<Token>(new Token(Token::Tag('<')));

case '>' :

if( readch('=')) return shared_ptr<Token>(new Token(Token::GE));

else return shared_ptr<Token>(new Token(Token::Tag('>')));

case '*' :

case '+' :

case '-' :

case '(' :

case ')' :

case '[' :

case ']' :

case ',' :

case ';' :

case '\'': // symbol '

case '~' :

char temp; temp=peek;

peek = ' ';

return shared_ptr<Token>(new Token(Token::Tag(temp)));

default:

if(isdigit(peek)) {

bool flag_float=0;

std::string str_number;

// before decimal point

do {

str_number.push_back(peek);

} while (readch() && isdigit(peek));

// after decimal point

if(peek == '.') {

str_number.push_back(peek);

if(readch() && isdigit(peek)){

++flag_float;

do {

str_number.push_back(peek);

} while (readch() && isdigit(peek));

} else{

//error

error(DECIM_POINT);

// restore

str_number.push_back('0');

}

}

// after symbol of order

if(peek == 'E' || peek == 'e') {

str_number.push_back(peek);

if( readch() && (peek == '+' || peek == '-') ) {str_number.push_back(peek);readch();}

if(isdigit(peek)){

++flag_float;

do {

str_number.push_back(peek);

} while (readch() && isdigit(peek));

} else{

//error

error(EXPON);

// restore

str_number.push_back('0');

}

}

if(isalpha(peek)) error(INVAL_SUFF); // error

Token *num;

// for strtod(l)

errno=0;

double t=0.;

if( flag_float ) {num= new FloatLiteral( t=strtod(str_number.c_str(),0) );}

else num= new IntLiteral( int(strtol(str_number.c_str(),0,10)) );

if(errno){

if(flag_float)

if(t==0.0) warning("underflow float constant");

else warning("overflow float constant");

else

warning("overflow integer consant");

}

return shared_ptr<Token>(num);

}

if(isalpha(peek) || peek == '_') {

string str_ident;

do {

str_ident.push_back(peek);

} while( readch() && ( isalnum(peek) || peek == '_'));

hashmap::const_iterator i = words.find(str_ident);

if( i != words.end() )

return i->second;

shared_ptr<Word> w(new Word(Token::ID, str_ident));

words.insert(std::make_pair(str_ident,w));

return w;

}

error(UNDEF_SYM); return scan();

}

}