Zoadian před 10 roky
rodič
revize
5fe2a255c1
4 změnil soubory, kde provedl 262 přidání a 2 odebrání
  1. 4 2
      ccsim.pro
  2. 17 0
      mainwindow.cpp
  3. 160 0
      parse.cpp
  4. 81 0
      parse.h

+ 4 - 2
ccsim.pro

@@ -18,14 +18,16 @@ SOURCES += main.cpp\
     debugwidget.cpp \
     program.cpp \
     simulator.cpp \
-    instruction.cpp
+    instruction.cpp \
+    parse.cpp
 
 HEADERS  += mainwindow.h \
     simulator.h \
     playfield.h \
     debugwidget.h \
     program.h \
-    instruction.h
+    instruction.h \
+    parse.h
 
 FORMS    += mainwindow.ui \
     debugwidget.ui

+ 17 - 0
mainwindow.cpp

@@ -3,6 +3,9 @@
 
 #include "playfield.h"
 
+#include <QFile>
+#include <QTextStream>
+#include "parse.h"
 
 MainWindow::MainWindow(QWidget *parent)
     : QMainWindow(parent)
@@ -12,6 +15,20 @@ MainWindow::MainWindow(QWidget *parent)
     lblCycles = new QLabel(ui->statusBar);
     ui->statusBar->addWidget(lblCycles);
 
+
+    QFile file("C:/test.ccp");
+    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+        return;
+
+    QTextStream in(&file);
+
+    QString code = in.readAll();
+
+    auto tokens = lex(code);
+
+    QVector<ParseError> errors;
+    auto instrbanks = parse(code, tokens, errors);
+
 //    setMinimumSize(simulator.size * 40, simulator.size * 40);
 
     simulator.loadProgram(Qt::red, 10, 10);

+ 160 - 0
parse.cpp

@@ -0,0 +1,160 @@
+#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;
+
+    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
+            while(i < tokens.size() && tokens[i].tokenType != TokenTypeEOL) {
+                ++i;
+            }
+            ++i;
+            continue;
+        }
+        else {
+            QString word = code.mid(tokens[i].begin, tokens[i].end - tokens[i].begin).toUpper();
+
+            if(word.compare("CREATE", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "MOVE", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "DIE", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "TRANS", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "RTRANS", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "TURN", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "JUMP", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "AJUMP", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "BJUMP", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "TURN", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "SCAN", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "FARSCAN", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "SET", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "ADD", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "SUB", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "MUL", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "DIV", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "MOD", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "MIN", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "MAX", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "RANDOM", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "IF", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "IFN", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "IFG", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "IFL", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "IFGE", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "IFLE", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "INIT", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "BREAK", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "RESUME", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "SLEEP", Qt::CaseInsensitive)) {
+            }
+            else if(word.compare( "QUIT", Qt::CaseInsensitive)) {
+            }
+            else {
+                errors += ParseError(tokens[i].line, tokens[i].column, QObject::tr("is not a valid Instruction"));
+            }
+            ++i;
+        }
+    }
+}

+ 81 - 0
parse.h

@@ -0,0 +1,81 @@
+#ifndef PARSE_H
+#define PARSE_H
+
+#include <QString>
+#include <QVector>
+using namespace std;
+
+#include "instruction.h"
+
+enum TokenType {
+    TokenTypeError,
+    TokenTypeEOL,
+    TokenTypeComma,
+    TokenTypeHash,
+    TokenTypePercent,
+    TokenTypeDollar,
+    TokenTypeNumber,
+    TokenTypeWord,
+};
+
+struct Token {
+    size_t line = 0;
+    size_t column = 0;
+    TokenType tokenType = TokenTypeError;
+    size_t begin = 0;
+    size_t end = 0;
+
+    Token()
+        : line(0)
+        , column(0)
+        , tokenType(TokenTypeError)
+        , begin(0)
+        , end(0)
+    {}
+
+    Token(const Token& tok)
+        : line(tok.line)
+        , column(tok.column)
+        , tokenType(tok.tokenType)
+        , begin(tok.begin)
+        , end(tok.end)
+    {}
+
+    Token(size_t line, size_t column, TokenType tokenType, size_t begin, size_t end)
+        : line(line)
+        , column(column)
+        , tokenType(tokenType)
+        , begin(begin)
+        , end(end)
+    {}
+};
+
+QVector<Token> lex(const QString& code);
+
+struct ParseError {
+    size_t line = 0;
+    size_t column = 0;
+    QString text;
+
+    ParseError()
+        : line(0)
+        , column(0)
+        , text("")
+    {}
+
+    ParseError(const ParseError& par)
+        : line(par.line)
+        , column(par.column)
+        , text(par.text)
+    {}
+
+    ParseError(size_t line, size_t column, const QString& text)
+        : line(line)
+        , column(column)
+        , text(text)
+    {}
+};
+
+QVector<QVector<Instruction>> parse(const QString& code, const QVector<Token>& tokens, QVector<ParseError>& errors);
+
+#endif // PARSE_H