# Userinput String to formula

**URL:** <https://discourse.processing.org/t/userinput-string-to-formula/29585>\
**Category:** Processing\
**Created:** [April 23, 2021, 6:23pm UTC](https://discourse.processing.org/t/userinput-string-to-formula/29585 "2021-04-23T18:23:54Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Flolo](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/flolo/32/13874_2.png) [@Flolo](https://discourse.processing.org/u/Flolo)\
**Post date:** [April 23, 2021, 6:23pm UTC](https://discourse.processing.org/t/userinput-string-to-formula/29585/1 "2021-04-23T18:23:55Z")

</div>

Hey I want to write a program where the user can enter a formula in a text field and that program then converts this string to the “correct” formula and then calculates it.

Here a example:

```auto
//This would appear in front of the text input: x = 
String userInput = "x*2";
float x;
void calculateX(String userInput){
    x = userInput;
   //the computer should then calculate x = x * 2
}

```

The problem is I dont know how I can turn a string in programm code…

I hope you know what I mean.  
Thank you in advance 🙂

---

<div class="post-metadata">

**Author:** ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)\
**Post date:** [April 23, 2021, 10:59pm UTC](https://discourse.processing.org/t/userinput-string-to-formula/29585/2 "2021-04-23T22:59:47Z")

</div>

Hi,

What you are trying to do is roughly what the parser is doing with your code : you give him a input string (your source code) and the parser split it into tokens that are then used to create an abstract syntax tree of your program.

You can refer to the Wikipedia article on the parsing process :

> **[Parsing | Overview of process](https://en.wikipedia.org/wiki/Parsing#Overview_of_process)**
>
> The following example demonstrates the common case of parsing a computer language with two levels of grammar: lexical and syntactic.
> The first stage is the token generation, or lexical analysis, by which the input character stream is split into meaningful symbols defined by a grammar of regular expressions. For example, a calculator program would look at an input such as "12 \* (3 + 4)^2" and split it into the tokens 12, \*, (, 3, +, 4, ), ^, 2, each of which is a meaningful symbol in the context ...

The steps are (simplified) :

- Lexical analysis (split the input string into tokens defined by regular expressions like name identifiers, key words, numbers, commas, line breaks…)

- Syntactic analysis → build the [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) of the program : it’s representing the program structure as a tree where the leaves are variables or values and the non-leaf nodes are operations or operators

> **[Abstract syntax tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree)**
>
> In computer science, an abstract syntax tree (AST), or just syntax tree, is a tree representation of the abstract syntactic structure of source code written in a programming language. Each node of the tree denotes a construct occurring in the source code.
> The syntax is "abstract" in the sense that it does not represent every detail appearing in the real syntax, but rather just the structural or content-related details. For instance, grouping parentheses are implicit in the tree structure, so the...

- The last step is the execution. In real programming languages, some machine code is usually generated by using the AST but in your case you might want to just evaluate the tree and return the result.

So this is not trivial, you need to make a program that takes a string as input, split the string into tokens (variables like `x` or `y`, function names like `cos`, `exp`, numbers `2`, `6.4` or `4e10` and operators `+`, `*`…) then construct the syntax tree with those tokens (taking into account [operator precedence](https://en.wikipedia.org/wiki/Order_of_operations), [associativity](https://en.wikipedia.org/wiki/Operator_associativity), parenthesis, function calls…)

For example the `4 + 3 * 5 / (8 - x)` expression gives the following AST :

 ![Capture d’écran de 2021-04-24 00-30-22](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/3e8f10bea431c037ba4f26f17fad1eb12325cd8e.png)

Note : the above expression is equivalent to `4 + ((3 * 5) / (8 - x))` with parenthesis (which enforce precedence)

In order to execute this expression, you need to construct the AST in your code. This is where object oriented programming comes handy because you every token is basically a node (whether it’s a variable, operator or number) and you can evaluate it :

For example any number evaluate (the result is) to itself : `4` → `4`  
A binary operator evaluate to the operator applied on the left and right member : `+(4, 5)` → `4 + 5` → `9`  
A variable is just a lookup in a lexical environment table with values associated to variable names: `{ x: 4 }`

So you have this abstract base class for each node :

```auto
abstract class ASTNode {
  float eval();
}

```

And the concrete implementations of the binary operator and value :

```auto
class ValueNode extends ASTNode {
  float value; // The actual value

  ValueNode(float value) {
    this.value = value;
  }
  
  // Must implement abstract method
  float eval() {
    return value; // Simply return the value
  }
}

// Usage : 

ASTNode number = new ValueNode(5);
println(number.eval()); // -> 5

```

```java
class BinOp extends ASTNode {
  String op; // The operator '+', '*', '/'...
  ASTNode left, right; // Note that we use the abstract class

  BinOp(String op, ASTNode left, ASTNode right) {
    this.op = op;
    this.left = left;
    this.right = right;
  }

  float eval() {
    // Getting the left and right values of the subtree
    float a = left.eval(): // Note that it's recursive
    float b = right.eval();

    // Switch on the operator...
    switch(op) {
      case "+":
        return a + b;
      case "-":
        return a - b;
      default:
        return -1; // error
    }
  }
}

// Usage
ASTNode add = new BinOp("+", new ValueNode(4), new ValueNode(2));
println(add.eval()); // -> 6

```

So this is roughly how it works but in a more advanced compiler architecture, you would use some design patterns like the Visitor.

> <https://softwareengineering.stackexchange.com/questions/283611/ast-processing-and-usefulness-of-visitor-pattern>

You can take a look at this tutorial for more information :

> **[Let’s Build A Simple Interpreter. Part 7: Abstract Syntax Trees](https://ruslanspivak.com/lsbasi-part7/)**
>
> As I promised you last time, today I will talk about one of the central data structures that we’ll use throughout the rest of the series, so buckle up and let’s go. Up until now, we had our interpreter and parser code mixed together and the...

> <https://stackoverflow.com/questions/28256/equation-expression-parser-with-precedence>

Also if you want to do this in Java there’s useful links on this thread 😋 :

> <https://stackoverflow.com/questions/3422673/how-to-evaluate-a-math-expression-given-in-string-form>

---

<div class="post-metadata">

**Author:** ![tony](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tony/32/949_2.png) [@tony](https://discourse.processing.org/u/tony)\
**Post date:** [April 24, 2021, 6:23am UTC](https://discourse.processing.org/t/userinput-string-to-formula/29585/3 "2021-04-24T06:23:41Z")

</div>

Great write up @josephh !

@Flolo what is this for?

---

<div class="post-metadata">

**Author:** ![Flolo](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/flolo/32/13874_2.png) [@Flolo](https://discourse.processing.org/u/Flolo)\
**Post date:** [April 24, 2021, 9:42am UTC](https://discourse.processing.org/t/userinput-string-to-formula/29585/4 "2021-04-24T09:42:48Z")

</div>

The code in functionF I want to change with the user input…  
I would recomment to run it in tweak mode…

Here is the code:

```auto
float minX = -10;
float maxX = 10;
float minY = -10;
float maxY = 10;

float cellSize;

float translateX;
float translateY;

void setup() {
  size(900, 900);

  translateX = 400;
  translateY = 400;

  cellSize = float(width) / (maxX);
  print(cellSize);
}
void draw() {
  translateX = 400;
  translateY = 400;

  translate(translateX, translateY);
  background(0);

  stroke(255);
  strokeWeight(20);
  point(0, 0);

  strokeWeight(5);
  line(-width/2-translateX, 0, width/2+translateX, 0);
  line(0, -height/2-translateY, 0, height/2+translateY);

  stroke(255);
  strokeWeight(2);
  noFill();
  beginShape();
  for (float x = minX; x < maxX-1; x += 0.01) {
    float y = functionF(x);

    vertex(x*cellSize, y*cellSize);
  }
  endShape();
}
float functionF(float x) {
  float y = 0.25*(x*x);

  return -y;
}

```

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [April 24, 2021, 11:23am UTC](https://discourse.processing.org/t/userinput-string-to-formula/29585/5 "2021-04-24T11:23:14Z")

</div>

If you are using Java mode then I suggest the Jasmine library which was designed to create expressions from strings and then evaluate them very quickly.

Jasmine can be installed in Processing from the Contributions manager and detailed information about using the library can be found [here](http://www.lagers.org.uk/jasmine/index.html).

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [April 24, 2021, 1:29pm UTC](https://discourse.processing.org/t/userinput-string-to-formula/29585/6 "2021-04-24T13:29:30Z")

</div>

A quick demo of Jasmine to calculate the area of circles with radii from 1 to 5 inclusive

```auto
import org.quark.jasmine.*;

String formula = "PI*r^2";

Expression expr = Compile.expression(formula, false);
for(int i = 1; i <= 5; i++){
  float area = expr.eval(i).answer().toFloat();
  println("Radius = " + i + " Area of circle = " + area);
}

```

Output is

```auto
Radius = 1 Area of circle = 3.1415927
Radius = 2 Area of circle = 12.566371
Radius = 3 Area of circle = 28.274334
Radius = 4 Area of circle = 50.265484
Radius = 5 Area of circle = 78.53982

```

---

<div class="post-metadata">

**Author:** ![micuat](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micuat/32/19407_2.png) [@micuat](https://discourse.processing.org/u/micuat)\
**Post date:** [April 24, 2021, 2:34pm UTC](https://discourse.processing.org/t/userinput-string-to-formula/29585/7 "2021-04-24T14:34:18Z")

</div>

a versatile option (but can go wrong) is to use builtin Nashorn JavaScript interpreter:

```auto
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptContext;
import javax.script.ScriptException;
import javax.script.Invocable;

private static ScriptEngineManager engineManager;
private static ScriptEngine nashorn;

void setup() {
  size(400, 400, P3D);

  String[] options = new String[] { "--language=es6" };
  jdk.nashorn.api.scripting.NashornScriptEngineFactory factory = new jdk.nashorn.api.scripting.NashornScriptEngineFactory();
  nashorn = (jdk.nashorn.api.scripting.NashornScriptEngine) factory.getScriptEngine(options);

  try {
    Object res = nashorn.eval("5 * 2.2");
    println(res);

    res = nashorn.eval("Math.sin(Math.PI / 4)");
    println(res);

    res = nashorn.eval("'hello'.length");
    println(res);
  }
  catch (Exception e) {
    e.printStackTrace();
  }
}

```

outputs

```auto
11.0
0.7071067811865475
5

```

---

<div class="post-metadata">

**Author:** ![Flolo](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/flolo/32/13874_2.png) [@Flolo](https://discourse.processing.org/u/Flolo)\
**Post date:** [April 24, 2021, 10:41pm UTC](https://discourse.processing.org/t/userinput-string-to-formula/29585/8 "2021-04-24T22:41:51Z")

</div>

Hey thanks for the help and the examples 🙂  
I appreciate it.
