Технически это решает проблему, как описано:
std::map< std::string, std::function<void()> > program_map;
void define_programs() {
program_map[ "io.print("Hello World!");\n" ] = []{
std::cout << "Hello World!\n";
};
program_map[ "io.print("Goodbye World!");\n" ] = []{
std::cout << "Goodbye World!\n";
};
};
int main() {
// load parser:
define_programs();
// read program from user:
std::string s;
std::cin >> s;
// compile and execute:
if (program_map.find(s) != program_map.end()) {
(*program_map.find(s))();
} else {
std::cout << "ERROR: unknown program.\n";
}
}
, но это вероятно, не решает проблему, которую вы хотите решить.
В целом, синтаксический анализ языка C или C++ - это большая работа. Вы можете упростить свою работу, упростив язык синтаксического анализа (синтаксис типа LISP довольно прост для анализа).
Если вы хотите разобрать язык на C/C++, я бы посоветовал вам узнать о грамматике и лексерах. Есть целые курсы обучения, которые заканчиваются написанием компилятора для языка, более простого, чем C/C++ - C++, в частности, очень трудно разобрать язык, и, как правило, вы не должны точно следовать его соглашениям.
Разработка грамматики и запись лексера (или обучение предварительно написанному лексеру) для вашей грамматики должны идти рука об руку.
Когда я проектирую языки игрушек, я обычно делаю их LISP такими, потому что LISP, как и языки, очень прост в работе. Таким образом, у вас есть инициализатор команды (
, команда, список аргументов (который может быть более поздним (
'd), и команда выполняется, когда вы достигаете соответствия )
.
Так эквивалент кода будет:
(io print "Hello World")
и теперь у меня есть команда io
(и экземпляры объектов будут виды «команд») с помощью метода печати (который он считывает из слота-) и аргументы к указанному методу «Hello World». Результатом этого, если бы я чувствовал себя функциональным, была бы программа, которая напечатала Hello World
- если нет, это будет делать это как побочный эффект и вернуть либо код ошибки, либо ничего.
Я бы написал среду вокруг нее, которая определяет некоторые команды (в том числе «сделать объект»), возможно, какой-то синтаксис цитирования (чтобы я мог определить lambdas) и т. Д. Я бы закончил с языком, который представляет собой плохо разработанную, субоптимальную, ограниченную реализацию небольшой части обычного lisp, которая является традиционной.
Только после того, как я смог бы сделать что-то вроде выше, я бы рассмотрел возможность написания парсера для более сложного анализа языка, такого как C/C++. И даже тогда я сначала переписал вышеупомянутый игрушечный язык в рамки lexing/parsing, а затем напишу свой язык на C/C++ в той же структуре.
Обычно вы начинаете с написания токенизатора (или нахождения подходящего) и грамматики, которая объединяет токены в AST или иначе «понимает» синтаксис, а затем оценивает этот синтаксис. – Useless
Я написал свой токенизатор, используя строковый вектор и строковые теги. Так что все, что я могу сделать, это использовать инструкции IF? – hCon
Нет, грамматика - это не просто утверждения 'if'. Вы можете использовать что-то вроде ANTLR напрямую или искать что-то вроде «анализатора грамматики C++». – Useless