Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Интерпретатор / _sources / MyLanguage / TokenParser
.cpp#include <istream>
#include <iostream>
#include <cstdio>
#include <cctype>
#include "TokenParser.hpp"
using namespace Parser_impl;
char* Parser_impl::tokenName[] =
{ "identifier",
"var", "int", "float", "void", "begin", "end", "if",
"then", "else", "while", "do", "write", "return", "read",
"wasError", "exit",
"=", "||", "&&", "+", "-", "*", "/", "%", "^", "!",
"==", "!=", "<", "<=", ">", ">=", "-", "+", ";", ",", "(", ")", "EOF"
};
TokenParser::MapStr2Token TokenParser::reservedWords;
void TokenParser::initReservedWords()
{
if (reservedWords.size() >0)
return;
reservedWords["var"] = T_VAR;
reservedWords["int"] = T_INT;
reservedWords["float"] = T_FLOAT;
reservedWords["void"] = T_VOID;
reservedWords["begin"] = T_BEGIN;
reservedWords["end"] = T_END;
reservedWords["if"] = T_IF;
reservedWords["then"] = T_THEN;
reservedWords["else"] = T_ELSE;
reservedWords["while"] = T_WHILE;
reservedWords["do"] = T_DO;
reservedWords["write"] = T_WRITE;
reservedWords["return"] = T_RETURN;
reservedWords["read"] = T_READ;
reservedWords["wasError"] = T_WASERROR;
reservedWords["exit"] = T_EXIT;
}
void TokenParser::makeDelimToken()
{
current.type = TYPE_DELIM;
switch (ch) {
case ';' :
current.value = T_SEMIC;
break;
case ',' :
current.value = T_COMMA;
break;
case '(' :
current.value = T_LBRACK;
break;
case ')' :
current.value = T_RBRACK;
break;
case EOF :
current.value = T_EOF;
break;
}
}
namespace {
void replaceAll(std::string& str, const char* find, const unsigned l1,
const char* replace)
{
using std::string;
string::size_type pos = str.find(find,0);
while (pos != string::npos) {
str.replace(pos, l1, replace);
pos = str.find(find,pos);
}
}
}
void TokenParser::makeOperationToken()
{
current.type = TYPE_OPER;
switch (ch) {
case '+' :
current.value = T_PLUS;
break;
case '-' :
current.value = T_MINUS;
break;
case '*' :
current.value = T_MUL;
break;
case '%' :
current.value = T_MOD;
break;
case '/' :
current.value = T_DIV;
break;
case '^' :
current.value = T_DEG;
break;
case '=' :
current.value = T_ASS;
break;
case '!' :
current.value = T_NOT;
break;
case '<' :
current.value = T_LSS;
break;
case '>' :
current.value = T_GRT;
break;
default :
std::cerr << "Wrong operation " << ch << "in TokenParser::makeOperationToken()!" << std::endl;
}
}
void TokenParser::getNextToken()
{
if (pushbacked) {
pushbacked = false;
return;
}
States state = ST_START;
while (state != ST_FINISH)
switch (state) {
case ST_START:
while (std::isspace(ch)) {
if (ch == '\n')
++lineNumber;
getNextChar();
}
if (std::isalpha(ch) || ch == '_') { // ID
clearBuffer();
addCharToBuffer();
getNextChar();
while( std::isalpha(ch) || ch == '_' || std::isdigit(ch) ){
addCharToBuffer();
getNextChar();
}
MapStr2Token::iterator pos = reservedWords.find(current.str);
if ( pos != reservedWords.end()){
current.type = TYPE_RES;
current.value = pos->second;
} else {
current.type = TYPE_ID;
}
state = ST_FINISH;
} else if (std::isdigit(ch) ){ // Number
clearBuffer();
do {
addCharToBuffer();
getNextChar();
} while (std::isdigit(ch));
current.isFloat = false;
if (ch == '.') {
current.isFloat = true;
addCharToBuffer();
getNextChar();
while (std::isdigit(ch)){
addCharToBuffer();
getNextChar();
}
}
current.type = TYPE_LIT;
current.value = std::atof(current.str.c_str());
state = ST_FINISH;
} else if (ch == '{') { // Comment
getNextChar();
state = ST_COM;
} else if (ch == '\"') { // String
clearBuffer();
getNextChar();
state = ST_STR;
} else if ( isOP() ) { // Operation: +, -, *, /, %, ^
makeOperationToken();
getNextChar();
state = ST_FINISH;
} else if ( ch == '|' ) { // Operation: ||
getNextChar();
if (ch != '|')
error(ch, '|');
current.type = TYPE_OPER;
current.value = T_OR;
getNextChar();
state = ST_FINISH;
} else if ( ch == '&' ) { // Operation: &&
getNextChar();
if (ch != '&')
error(ch, '&');
current.type = TYPE_OPER;
current.value = T_AND;
getNextChar();
state = ST_FINISH;
} else if ( isOP3() ) { // Operation: =, !, <, >, ==, !=, <=, >=
makeOperationToken();
getNextChar();
if (ch == '='){
switch (current.getLong()) {
case T_ASS:
current.value = T_EQ;
break;
case T_NOT:
current.value = T_NEQ;
break;
case T_LSS:
current.value = T_LSSEQ;
break;
case T_GRT:
current.value = T_GRTEQ;
break;
}
getNextChar();
}
state = ST_FINISH;
} else if ( isDelim() ) { // Delimiter: ;, ,, (, ), EOF
makeDelimToken();
getNextChar();
state = ST_FINISH;
} else {
error(ch);
}
break; // ST_FINISH
case ST_COM:
while (ch != '}'){
if (ch == EOF)
throw TokenParserException("Not closed comment!");
if (ch == '\n')
++lineNumber;
getNextChar();
}
getNextChar();
state = ST_START;
break; // ST_COM
case ST_STR:
while (ch != '\"'){
if (ch == EOF)
throw TokenParserException("Not closed string !");
addCharToBuffer();
getNextChar();
}
current.type = TYPE_LITSTR;
replaceAll(current.str, "\\n", 2, "\n");
replaceAll(current.str, "\\t", 2, "\t");
getNextChar();
state = ST_FINISH;
break; // ST_STR
case ST_FINISH:
break; // ST_FINISH
} // switch
} // TokenParser::getNextToken()
Соседние файлы в папке MyLanguage