Можно ли преобразовать строку, структурированную точно так же, как условный оператор, в оператор, который можно прочитать и обработать? - PullRequest
3 голосов
/ 21 апреля 2019

Мне и нескольким другим было поручено создать Генератор таблиц правды для нашего первого года проекта.У нас есть большая часть проделанной работы, за исключением нескольких вещей, наиболее важной из которых является функция, которая фактически преобразует утверждения (например, p V q) в логические значения истинности.

Можно ли преобразовать строковый оператор с правильным синтаксисом аргумента c ++, например, "(p ||! Q)" (p и q - предварительно определенные переменные с соответствующими значениями), непосредственно в условие?

Мы рассмотрели маршрут многих условных операторов на основе того, что мы можем найти с помощью анализа строк и обработки переменных на основе результатов, но мне было интересно, существует ли гораздо более эффективный способ на самом деле это кодировать.Код разработан так, чтобы принимать практически любые входные данные для оператора таблицы истинности, преобразовывать его в правильный синтаксис c ++ и разделять оператор на компоненты.Тем не менее, есть немало вариантов, которые нужно учитывать, если бы мы делали это, находя определенные элементы и оперируя ими с помощью операторов if-then или switch.Если есть более эффективный маршрут, я открыт для предложений и приветствую любую критику нашего процесса.

В качестве наглядной демонстрации мы подумали об этом:

bool p=1, q=0;
string test= "(!p || q)"; // would supposedly return 0 if analyzed as a conditional statement

cout << endl << "Truth Table Generator Test" << endl;
cout << "p = " << p << endl << "q = " << q << endl;
cout << test << " = " << truthVal(test) // Used to signify the conversion from string to condition

Предположительновывод:


Truth Table Generator Test
p = 1
q = 0
(!p || q) = 0

Ответы [ 2 ]

2 голосов
/ 21 апреля 2019

Невозможно сделать в C ++ при вызове так:

cout << test << " = " << truthVal(test) 

Однако, слегка переставив, становится возможным:

bool p=1, q=0;
char test[]= "(!p || q)"; // would supposedly return 0 if analyzed as a conditional statement

cout << endl << "Truth Table Generator Test" << endl;
cout << "p = " << p << endl << "q = " << q << endl;
cout << test << " = " << truthVal(test, 'p', p, 'q', q)

Причина, по которой это возможно, заключается в том, что2 критических изменения.test теперь является постоянным массивом символов.Как таковой он может быть проанализирован с помощью шаблона метапрограммирования.Обратите внимание, что разные массивы test могут создавать уникальные экземпляры функций.Это делается, например, в библиотеке Boost's printf.Поскольку шаблонное метапрограммирование завершено по Тьюрингу, может быть реализован интерпретатор, который будет проверять p и q или любое дополнительное количество переменных во время выполнения.Вам также нужно определить соглашение, чтобы связать переменные, переданные с переменными в массиве char.Я сделал это здесь, указав имя переменной в виде символа, но это можно сделать другими способами.Вы даже можете проверить тип переданных переменных.Но вы не можете получить доступ к переменным, которые не передаются в вызове функции.По сути, вы реализуете интерпретатор времени компиляции.

Однако метапрограммирование шаблона является важной задачей.Но выполнимо.

2 голосов
/ 21 апреля 2019

Нет. C ++ во время выполнения имеет нулевой доступ к именам переменных времени компиляции, за исключением некоторого искажения символов в некоторых компиляторах.

Даже у «constexpr runtime» нет доступа к нему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...