Własny język programowania - proste Hello World

0

Witam,
pytanie z ciekawości. Jak się tworzy język programowania? Co trzeba wykorzystać do stworzenia prostego języka, które obsługiwałby coś w rodzaju funkcji print('Hello World');? Wie ktoś coś na ten temat? Prosiłbym o jasne wytłumaczenie. Pozdrawiam.

1

http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools
http://kompilatory.agh.edu.pl/

Masz całą masę narzędzi -> flex, bison yacc, ANTlr które pozwalają na generacje parsera na bazie gramatyki i zbudowanie dość szybko prostego interpretera / kompilatora.

1

Prędzej http://kompilatory.agh.edu.pl/pages/tk-laboratorium/bison.html skoro on chce hello worlda ;)

0

Rekomendacja pierwsza: wspaniala książka przez Jacka Crenshaw "Niech napiszemy kompilatora" (compilers.iecc.com/crenshaw/tutorfinal.pdf) Pan nawet nie wie, że to jest tak latwo.
Rekomendacja druga: http://stackoverflow.com/questions/1669/learning-to-write-a-compiler Gdy to nie pomoże, już nic nie pomoże.

2

Ty chcesz stworzyc jezyk, ktory umozliwialby hello worlda, czy pisac cos co jest turing-complete? Bo do tego pierwszego wystarczy niewielka ilosc umiejetnosci i troche pomyslunku i mozna napisac prosty interpreter.

#include <vector>
#include <map>
#include <stack>
#include <functional>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
using namespace std::placeholders;

class Interpreter {
  map<string, string> data;
  stack<string> stack;
  map<string, function<int(vector<string>)>> instructions;

public:
  Interpreter() {
    instructions["dd"] = bind(&Interpreter::dd, this, _1);
    instructions["push"] = bind(&Interpreter::push, this, _1);
    instructions["pop"] = bind(&Interpreter::pop, this, _1);
    instructions["print"] = bind(&Interpreter::print, this, _1);
    instructions["exit"] = bind(&Interpreter::exit, this, _1);
  }

  int run(vector<vector<string>> code) {
    for(vector<string> line : code) {
      if(line.size() == 0) {
        continue;
      }

      if(instructions.count(line[0]) == 0) {
        return -1;
      }

      auto fun = instructions[line[0]];
      int rv = fun(vector<string>(line.begin() + 1, line.end()));
      if(rv != 0) {
        return -1;
      }
    }

    return 0;
  }

  int dd(vector<string> args) {
    if(args.size() != 2) {
      return -1;
    }

    data[args[0]] = args[1];
    return 0;
  }

  int push(vector<string> args) {
    if(args.size() != 1 || data.count(args[0]) == 0) {
      return -1;
    }

    stack.push(data[args[0]]);
    return 0;
  }

  int pop(vector<string> args) {
    if(args.size() != 0 || stack.size() == 0) {
      return -1;
    }

    stack.pop();
    return 0;
  }

  int print(vector<string> args) {
    if(args.size() != 0 || stack.size() == 0) {
      return -1;
    }
    
    
    puts(stack.top().c_str());
    return 0;
  }

  int exit(vector<string> args) {
    if(args.size() != 1) {
      return -1;
    }

    return stoi(args[0]);
  }
};

int main() {
  string tmp;
  vector<vector<string>> code;
  while(getline(cin, tmp)) {
    vector<string> tmp_v;
    istringstream iss(tmp);
    do {
      string sub;
      iss >> sub;
      if(!sub.empty()) tmp_v.push_back(sub);
    } while(iss);
    code.push_back(tmp_v);
  }

  Interpreter i;
  return i.run(code);
}

Dla takiego sobie jezyka:

dd hello Hello_World

push hello
print
pop

exit 0

Ofc. mozesz zrobic swoja skladnie, ale cos w stylu assemblera jest najprosciej pokazac. Tip: scanf() ma calkiem duze mozliwosci wyciagania danych ;P

1 użytkowników online, w tym zalogowanych: 0, gości: 1