#include "parse.h" #include QVector lex(const QString& code) { QVector tokens; size_t i = 0; size_t lineCounter = 0; size_t columnCounter = 0; while(i < code.size()) { if(code[i] == '\n') { tokens.push_back({lineCounter, columnCounter, TokenTypeEOL, i, i + 1}); ++lineCounter; columnCounter = 0; ++i; } else if(code[i] == ',') { tokens.push_back({lineCounter, columnCounter, TokenTypeComma, i, i + 1}); ++i; } else if(code[i] == '#') { tokens.push_back({lineCounter, columnCounter, TokenTypeHash, i, i + 1}); ++i; } else if(code[i] == '%') { tokens.push_back({lineCounter, columnCounter, TokenTypePercent, i, i + 1}); ++i; } else if(code[i] == '$') { tokens.push_back({lineCounter, columnCounter, TokenTypeDollar, i, i + 1}); ++i; } else if(code[i] == '/' && (i+1) < code.size() && code[i+1] == '/') { size_t s = i + 2; while(s < code.size() && code[s] != '\n') { ++s; } i = s; } else if(code[i].isSpace()) { ++i; } else if(code[i].isDigit()) { size_t s = i + 1; while(s < code.size() && code[s].isDigit()){ ++s; } tokens.push_back({lineCounter, columnCounter, TokenTypeNumber, i, s}); i = s; } else if(code[i].isLetter()) { size_t s = i + 1; while(s < code.size() && code[s].isLetter()){ ++s; } tokens.push_back({lineCounter, columnCounter, TokenTypeWord, i, s}); i = s; } else { tokens.push_back({lineCounter, columnCounter, TokenTypeError, i, i + 1}); ++i; } ++columnCounter; } return tokens; } QVector> parse(const QString& code, const QVector& tokens, QVector& errors) { size_t i = 0; auto skipToEol = [&tokens, &i](){ while(i < tokens.size() && tokens[i].tokenType != TokenTypeEOL) { ++i; } ++i; }; while(i < tokens.size()) { if(tokens[i].tokenType != TokenTypeWord) { errors += ParseError(tokens[i].line, tokens[i].column, QObject::tr("is not a valid Instruction")); //lets fast forward to next line skipToEol(); continue; } else { auto getTokenText = [&](size_t k){ return code.mid(tokens[k].begin, tokens[k].end - tokens[k].begin).toUpper(); }; QString word = getTokenText(i); if(word.compare("CREATE", Qt::CaseInsensitive)) { } else if(word.compare("MOVE", Qt::CaseInsensitive)) { } else if(word.compare("DIE", Qt::CaseInsensitive)) { if(i + 1 >= tokens.size() || tokens[i + 1].tokenType != TokenTypeEOL) { errors += ParseError(tokens[i - 1].line, tokens[i - 1].column, QObject::tr("error")); } skipToEol(); } else if(word.compare("TRANS", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("RTRANS", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("TURN", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("JUMP", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("AJUMP", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("BJUMP", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("TURN", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("SCAN", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("FARSCAN", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("SET", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("ADD", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("SUB", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("MUL", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("DIV", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("MOD", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("MIN", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("MAX", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("RANDOM", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("IF", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("IFN", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("IFG", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("IFL", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("IFGE", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("IFLE", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("INIT", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("BREAK", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("RESUME", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("SLEEP", Qt::CaseInsensitive)) { skipToEol(); } else if(word.compare("QUIT", Qt::CaseInsensitive)) { skipToEol(); } else { errors += ParseError(tokens[i].line, tokens[i].column, QObject::tr("is not a valid Instruction")); skipToEol(); } } } }