функция eval() для Arduino?

Я планирую сделать следующее:

void setup(){
  String term = "12 + (2 * 5)";
  int result = eval(term); // функция eval (от Python)
  Serial.println(результат); // ожидание 22
}

Однако функция eval отсутствует. Есть ли альтернативы?

, 👍4

Обсуждение

Думаю, есть больше к этому вопросу, как "Строковый термин = 12 + (2 * 5);" можно оценить во время компиляции., @Mikael Patel


3 ответа


1

Нет, альтернативы нет. Вам нужно разобрать строку и выполнить операции самостоятельно.

Лично я предпочитаю использовать RPN, так как его намного проще анализировать. Тогда ваша строка может быть переписана следующим образом:

2,5,*,12,+

Включите токен и посмотрите , является ли это числом (нажмите на стек) или оператором (всплывающие операнды из стека, выполните операцию, нажмите результат в стеке).

,

Вот оболочка, которая работает соответственно. Сочетание синтаксиса Forth и Postscript; https://github.com/mikaelpatel/Arduino-Shell, @Mikael Patel


0

Я погуглил, и новости не очень хорошие. В C/C++нет готовой функции, которая делала бы это. Существует множество ссылок на алгоритмы, которые вы могли бы реализовать. Но хватит ли у вас памяти, чтобы сделать это на Arduino?

Итак, рассматривая проблему с другой точки зрения, почему бы вам не запустить python на Arduino? Существует версия под названием pymite, которая работает на мега.

,

5

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
                ↑
Я не понял этой части.
,