| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- #include "parse.h"
- #include <QObject>
- QVector<Token> lex(const QString& code) {
- QVector<Token> 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<QVector<Instruction>> parse(const QString& code, const QVector<Token>& tokens, QVector<ParseError>& 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();
- }
- }
- }
- }
|