функция eval() для Arduino?
Я планирую сделать следующее:
void setup(){
String term = "12 + (2 * 5)";
int result = eval(term); // функция eval (от Python)
Serial.println(результат); // ожидание 22
}
Однако функция eval отсутствует. Есть ли альтернативы?
@loucket, 👍4
Обсуждение3 ответа
Нет, альтернативы нет. Вам нужно разобрать строку и выполнить операции самостоятельно.
Лично я предпочитаю использовать RPN, так как его намного проще анализировать. Тогда ваша строка может быть переписана следующим образом:
2,5,*,12,+
Включите токен и посмотрите , является ли это числом (нажмите на стек) или оператором (всплывающие операнды из стека, выполните операцию, нажмите результат в стеке).
Вот оболочка, которая работает соответственно. Сочетание синтаксиса Forth и Postscript; https://github.com/mikaelpatel/Arduino-Shell, @Mikael Patel
Я погуглил, и новости не очень хорошие. В C/C++нет готовой функции, которая делала бы это. Существует множество ссылок на алгоритмы, которые вы могли бы реализовать. Но хватит ли у вас памяти, чтобы сделать это на Arduino?
Итак, рассматривая проблему с другой точки зрения, почему бы вам не запустить python на Arduino? Существует версия под названием pymite, которая работает на мега.
TinyExpr делает то, что вы хотите, и даже больше.
TinyExpr-это очень небольшой рекурсивный парсер спуска и вычислительный механизм для математических выражений. Это удобно, когда вы хотите добавить возможность вычисления математических выражений во время выполнения, не добавляя к своему проекту кучу хлама.
В дополнение к стандартным математическим операторам и приоритету TinyExpr также поддерживает стандартные математические функции C и привязку переменных во время выполнения.
Ваш пример
Вам просто нужно сохранить tinyexpr.h
и tinyexpr.c
рядом с вашим скетчем.
#include "tinyexpr.h"
void setup() {
Serial.begin(115200);
}
void loop() {
char term[] = "12 + (2 * 5)";
Serial.println(term);
int error;
double result = te_interp(term, &error);
if (error){
Serial.println("Problem with expression.");
} else {
Serial.printf(" = %.10g\n", result);
}
delay(1000);
}
Он выводит:
12 + (2 * 5)
= 22
Поскольку term
известен во время компиляции, этот пример не очень полезен, и он просто выводит 22
в бесконечном цикле.
Базовая интерактивная консоль
Если вы используете ввод из последовательного
порта , вы можете написать очень простую интерактивную консоль. Для краткости была использована строка, но этот пример можно было бы переписать с помощью cstrings:
#include "tinyexpr.h"
void setup() {
Serial.begin(115200);
}
void loop() {
if (Serial.available() > 0) {
String expression = Serial.readStringUntil('\n');
Serial.print("> ");
Serial.println(expression);
int error;
double result = te_interp(expression.c_str(), &error);
if (error) {
Serial.print(" ");
for (int i = 0; i < error; i++) {
Serial.print(" ");
}
Serial.println("↑");
Serial.println("I didn't understand this part.");
} else {
Serial.printf(" = %.10g\n", result);
}
}
delay(50);
}
TinyExpr знает порядок операций и понимает многие другие математические выражения:
> 12 + 2 * 5
= 22
> 3^5
= 243
> exp(7)
= 1096.633158
> (1 + sqrt(5)) / 2
= 1.618033989
> 1 + 2 * 3 + 4 * 5
= 27
> sin(pi/2)
= 1
> sin(pi/3)
= 0.8660254038
Если где - то есть синтаксическая ошибка, error
сообщает вам положение первой встреченной ошибки:
> 3 +
↑
Я не понял этой части.
> sin() * 5
↑
Я не понял этой части.
> 3 / (4 + 5 * 7
↑
Я не понял этой части.
- Как разделить входящую строку?
- Как вывести несколько переменных в строке?
- форматирование строк в Arduino для вывода
- Очень простая операция Arduino Uno Serial.readString()
- DateTime в строку
- Как преобразовать строку в массив байтов
- Как отправить строку на мастер с помощью i2c
- Создание форматированной строки (включая числа с плавающей запятой) в Arduino-совместимом C++
Думаю, есть больше к этому вопросу, как "Строковый термин = 12 + (2 * 5);" можно оценить во время компиляции., @Mikael Patel