Create a Natural Language Calculator
This example builds a simple calculator that takes numbers in natural language and supports several infix operators of different relative precedence.
Use the built-in token form "SemanticNumber" and four more custom tokens.
tokens = {GrammarToken["SemanticNumber"], GrammarToken["Summand"],
GrammarToken["Multiplicand"], GrammarToken["Addition"],
GrammarToken["Multiplication"]};
A summand can be a full addition expression (to implement associativity), a full multiplication expression, or a number. A multiplicand can be a full multiplication expression (again to implement associativity) or a number, but not an addition expression, which assigns higher precedence to multiplication.
defs1 = {"Summand" ->
s : (GrammarToken["Addition"] | GrammarToken["Multiplication"] |
GrammarToken["SemanticNumber"]) :> s,
"Multiplicand" ->
m : (GrammarToken["Multiplication"] |
GrammarToken["SemanticNumber"]) :> m};
Associate the "Addition" token to sums and rests, and the "Multiplication" token to products and divisions. Rests and divisions are not commutative, and therefore you need to keep the order of terms by using FixedOrder.
defs2 = {
"Addition" ->
FixedOrder[a : GrammarToken["Summand"], "+",
b : GrammarToken["Summand"]] :> a + b,
"Addition" ->
FixedOrder[a : GrammarToken["Summand"], "-",
b : GrammarToken["Summand"]] :> a - b,
"Multiplication" ->
FixedOrder[a : GrammarToken["Multiplicand"], "*",
b : GrammarToken["Multiplicand"]] :> a*b,
"Multiplication" ->
FixedOrder[a : GrammarToken["Multiplicand"], "/",
b : GrammarToken["Multiplicand"]] :> a/b};
Deploy the GrammarRules object to the Wolfram Cloud.
calc = CloudDeploy[GrammarRules[tokens, Join[defs1, defs2]]];
Evaluate some arithmetic inputs containing natural language.
GrammarApply[calc, "one + one"]
GrammarApply[calc, "one + two + three"]
GrammarApply[calc, "five + seventeen * ten"]
GrammarApply[calc, "one hundred - one hundredth"]
GrammarApply[calc, "zero + one/forty-five"]
GrammarApply[calc, "one/forty-five - one"]