Arithmetic evaluation: Difference between revisions

m
syntax highlighting fixup automation
m (syntax highlighting fixup automation)
Line 25:
=={{header|11l}}==
[[wp:Pratt parser|Pratt parser]]
<langsyntaxhighlight lang=11l>T Symbol
String id
Int lbp
Line 140:
L(expr_str) [‘-2 / 2 + 4 + 3 * 2’,
‘2 * (3 + (4 * 5 + (6 * 7) * 8) - 9) * 10’]
print(expr_str‘ = ’parse(expr_str).eval())</langsyntaxhighlight>
{{out}}
<pre>
Line 154:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - A68RS has not implemented forward declarations}}
<langsyntaxhighlight lang=algol68>INT base=10;
MODE FIXED = LONG REAL; # numbers in the format 9,999.999 #
 
Line 295:
index error:
printf(("Stack over flow"))
)</langsyntaxhighlight>
{{out}}
<pre>
Line 303:
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
<langsyntaxhighlight lang=AutoHotkey>/*
hand coded recursive descent parser
expr : term ( ( PLUS | MINUS ) term )* ;
Line 452:
}
 
#include calclex.ahk</langsyntaxhighlight>
calclex.ahk<langsyntaxhighlight lang=AutoHotkey>tokenize(string, lexer)
{
stringo := string ; store original string
Line 519:
string := "pos= " token.pos "`nvalue= " token.value "`ntype= " token.type
return string
}</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang=bbcbasic> Expr$ = "1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10"
PRINT "Input = " Expr$
AST$ = FNast(Expr$)
Line 580:
ENDIF
UNTIL FALSE
= num$</langsyntaxhighlight>
{{out}}
<pre>
Line 595:
 
{{libheader|Boost.Spirit|1.8.4}}
<langsyntaxhighlight lang=cpp> #include <boost/spirit.hpp>
#include <boost/spirit/tree/ast.hpp>
#include <string>
Line 710:
}
}
};</langsyntaxhighlight>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang=Clojure>(def precedence '{* 0, / 0
+ 1, - 1})
 
Line 765:
 
user> (evaluate "1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1")
60</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
Line 783:
This implementation can read integers, and produce integral and rational values.
 
<langsyntaxhighlight lang=lisp>(defun tokenize-stream (stream)
(labels ((whitespace-p (char)
(find char #(#\space #\newline #\return #\tab)))
Line 868:
(loop for token = (tokenize-stream in)
until (null token)
collect token)))))))</langsyntaxhighlight>
Examples
Line 912:
=={{header|D}}==
After the AST tree is constructed, a visitor pattern is used to display the AST structure and calculate the expression value.
<langsyntaxhighlight lang=d>import std.stdio, std.string, std.ascii, std.conv, std.array,
std.exception, std.traits;
 
Line 1,132:
immutable exp = (args.length > 1) ? args[1 .. $].join(' ') : exp0;
new AST().parse(exp).CalcVis; // Should be 60.
}</langsyntaxhighlight>
{{out}}
<pre> ........................................................+.
Line 1,154:
=={{header|Dyalect}}==
 
<langsyntaxhighlight lang=dyalect>type Expr = Bin(op, Expr left, Expr right) or Literal(Float val)
with Lookup
 
Line 1,271:
print( eval("(1+33.23)*7") )
print( eval("1+33.23*7") )</langsyntaxhighlight>
 
{{out}}
Line 1,282:
While the task requirements specify not evaluating using the language's built-in eval, they don't say that you have to write your own ''parser''...
 
<langsyntaxhighlight lang=e>def eParser := <elang:syntax.makeEParser>
def LiteralExpr := <elang:evm.makeLiteralExpr>.asType()
def arithEvaluate(expr :String) {
Line 1,299:
return evalAST(ast)
}</langsyntaxhighlight>
 
Parentheses are handled by the parser.
 
<langsyntaxhighlight lang=e>? arithEvaluate("1 + 2")
# value: 3
 
Line 1,310:
 
? arithEvaluate("(1 + 2 / 2) * (5 + 5)")
# value: 20.0</langsyntaxhighlight>
 
=={{header|Elena}}==
ELENA 5.0 :
<langsyntaxhighlight lang=elena>import system'routines;
import extensions;
import extensions'text;
Line 1,654:
text.clear()
}
}</langsyntaxhighlight>
 
=={{header|Emacs Lisp}}==
<langsyntaxhighlight lang=lisp>#!/usr/bin/env emacs --script
;; -*- mode: emacs-lisp; lexical-binding: t -*-
;;> ./arithmetic-evaluation '(1 + 2) * 3'
Line 1,750:
(terpri)))
(setq command-line-args-left nil)
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,772:
 
=={{header|ERRE}}==
<langsyntaxhighlight lang=ERRE>
PROGRAM EVAL
 
Line 2,006:
IF NERR>0 THEN PRINT("Internal Error #";NERR) ELSE PRINT("Value is ";DB#) END IF
END PROGRAM
</syntaxhighlight>
</lang>
This solution is based on a stack: as a plus there is a power (^) operator. Unary operator "-" is accepted. Program shows the stack after every operation and you must press a key to go on (this feature can be avoided by removing the final REPEAT..UNTIL loop at the end of "DISEGNA_STACK" procedure).
 
Line 2,013:
 
<code>AbstractSyntaxTree.fs</code>:
<langsyntaxhighlight lang=fsharp>module AbstractSyntaxTree
type Expression =
Line 2,020:
| Minus of Expression * Expression
| Times of Expression * Expression
| Divide of Expression * Expression</langsyntaxhighlight>
 
<code>Lexer.fsl</code>:
<langsyntaxhighlight lang=fsharp>{
module Lexer
 
Line 2,046:
| newline { lexbuf.EndPos <- lexbuf.EndPos.NextLine; token lexbuf }
| eof { EOF }
| _ { failwithf "unrecognized input: '%s'" <| lexeme lexbuf }</langsyntaxhighlight>
 
<code>Parser.fsy</code>:
<langsyntaxhighlight lang=fsharp>%{
open AbstractSyntaxTree
%}
Line 2,074:
| Expr TIMES Expr { Times ($1, $3) }
| Expr DIVIDE Expr { Divide ($1, $3) }
| LPAREN Expr RPAREN { $2 } </langsyntaxhighlight>
 
<code>Program.fs</code>:
<langsyntaxhighlight lang=fsharp>open AbstractSyntaxTree
open Lexer
open Parser
Line 2,097:
|> parse
|> eval
|> printfn "%d"</langsyntaxhighlight>
 
=={{header|Factor}}==
<langsyntaxhighlight lang=factor>USING: accessors kernel locals math math.parser peg.ebnf ;
IN: rosetta.arith
 
Line 2,141:
 
: evaluate ( string -- result )
expr-ast eval-ast ;</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang=FreeBASIC>
'Arithmetic evaluation
'
Line 2,340:
if sym <> done_sym then error_msg("unexpected input")
loop
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,355:
=={{header|Groovy}}==
Solution:
<langsyntaxhighlight lang=groovy>enum Op {
ADD('+', 2),
SUBTRACT('-', 2),
Line 2,498:
}
return elements[0] instanceof List ? parse(elements[0]) : elements[0]
}</langsyntaxhighlight>
 
Test:
<langsyntaxhighlight lang=groovy>def testParse = {
def ex = parse(it)
print """
Line 2,536:
try { testParse('1++') } catch (e) { println e }
try { testParse('*1') } catch (e) { println e }
try { testParse('/ 1 /') } catch (e) { println e }</langsyntaxhighlight>
 
{{out}}
Line 2,605:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang=haskell>{-# LANGUAGE FlexibleContexts #-}
 
import Text.Parsec
Line 2,651:
 
main :: IO ()
main = print $ solution "(1+3)*7"</langsyntaxhighlight>
{{Out}}
<pre>28</pre>
Line 2,667:
* Notice that the code looks remarkably like a typical grammar, rather than being an opaque cryptic solution
* Does not rely on any library to silently solve 1/2 the problem; in fact, this code would probably suit being put into a library almost verbatim
<langsyntaxhighlight lang=Icon>procedure main() #: simple arithmetical parser / evaluator
write("Usage: Input expression = Abstract Syntax Tree = Value, ^Z to end.")
repeat {
Line 2,767:
procedure exponent()
suspend tab(any('eE')) || =("+" | "-" | "") || digits() | ""
end</langsyntaxhighlight>
 
{{out|Sample Output}}
Line 2,799:
The implementation here uses a shift/reduce parser to build a tree structure for evaluation (a tree structure which J happens to support for evaluation):
 
<langsyntaxhighlight lang=j>parse=:parse_parser_
eval=:monad define
'gerund structure'=:y
Line 2,864:
coerase tmp
r
)</langsyntaxhighlight>
example use:
<langsyntaxhighlight lang=j> eval parse '1+2*3/(4-5+6)'
2.2</langsyntaxhighlight>
 
You can also display the syntax tree, for example:
<langsyntaxhighlight lang=j> parse '2*3/(4-5)'
┌─────────────────────────────────────────────────────┬───────────────────┐
│┌───┬───────┬───┬───────┬───┬─┬───────┬───┬───────┬─┐│┌───────┬─┬───────┐│
Line 2,879:
││ │└─────┘│ │└─────┘│ │ │└─────┘│ │└─────┘│ ││ │
│└───┴───────┴───┴───────┴───┴─┴───────┴───┴───────┴─┘│ │
└─────────────────────────────────────────────────────┴───────────────────┘</langsyntaxhighlight>
 
At the top level, the first box is a list of terminals, and the second box represents their parsed structure within the source sentence, with numbers indexing the respective terminals. Within the list of terminals - each terminal is contained with a box. Operators are strings inside of boxes (the leading $ "operator" in this example is not really an operator - it's just a placeholder that was used to help in the parsing). Punctuation is simply the punctuation string (left or right parenthesis - these are also not really operators and are just placeholders which were used during parsing). Numeric values are a box inside of a box where the inner box carries two further boxes. The first indicates syntactic data type ('0' for arrays - here that means numbers) and the second carries the value.
Line 2,887:
Uses the [[Arithmetic/Rational/Java|BigRational class]] to handle arbitrary-precision numbers (rational numbers since basic arithmetic will result in rational values).
 
<langsyntaxhighlight lang=java>import java.util.Stack;
 
public class ArithmeticEvaluation {
Line 3,051:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 3,066:
Spaces are removed, expressions like <code>5--1</code> are treated as <code>5 - -1</code>
 
<langsyntaxhighlight lang=javascript>function evalArithmeticExp(s) {
s = s.replace(/\s/g,'').replace(/^\+/,'');
var rePara = /\([^\(\)]*\)/;
Line 3,120:
}
}
}</langsyntaxhighlight>
 
 
Line 3,136:
 
=== PEG operations ===
<langsyntaxhighlight lang=jq>def star(E): (E | star(E)) // .;
def plus(E): E | (plus(E) // . );
def optional(E): E // .;
def amp(E): . as $in | E | $in;
def neg(E): select( [E] == [] );</langsyntaxhighlight>
 
 
=== Helper functions ===
<langsyntaxhighlight lang=jq>def literal($s):
select(.remainder | startswith($s))
| .result += [$s]
Line 3,165:
def parseNumber($re):
consume($re)
| .result = .result + [.match|tonumber] ;</langsyntaxhighlight>
 
=== PEG Grammar ===
The PEG grammar for arithmetic expressions follows the one given at the Raku entry.<langsyntaxhighlight lang=jq>def Expr:
 
def ws: consume(" *");
Line 3,180:
Product | ws | star( (literal("+") // literal("-")) | Product);
 
Sum;</langsyntaxhighlight>
 
=== Evaluation ===
<langsyntaxhighlight lang=jq># Left-to-right evaluation
def eval:
if type == "array" then
Line 3,204:
{remainder: String}
| Expr.result
| eval;</langsyntaxhighlight>
 
=== Example ===
Line 3,214:
From Javascript entry.
 
<langsyntaxhighlight lang=javascript>/* Arithmetic evaluation, in Jsish */
function evalArithmeticExp(s) {
s = s.replace(/\s/g,'').replace(/^\+/,'');
Line 3,290:
evalArithmeticExp('2*-3--4+-0.25') ==> -2.25
=!EXPECTEND!=
*/</langsyntaxhighlight>
 
{{out}}
Line 3,303:
=={{header|Julia}}==
Julia's homoiconic nature and strong metaprogramming facilities make AST/Expression parsing and creation as accessible and programmatic as other language features
<langsyntaxhighlight lang=julia>julia> expr="2 * (3 -1) + 2 * 5"
"2 * (3 -1) + 2 * 5"
 
Line 3,343:
 
julia> eval(parse("2 * (3 + ((5) / (7 - 11)))"))
3.5</langsyntaxhighlight>
 
=={{header|Kotlin}}==
{{trans|JavaScript}}
<langsyntaxhighlight lang=scala>// version 1.2.10
 
/* if string is empty, returns zero */
Line 3,432:
"1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1"
).forEach { println("$it = ${evalArithmeticExp(it)}") }
}</langsyntaxhighlight>
 
{{out}}
Line 3,449:
 
=={{header|Liberty BASIC}}==
<syntaxhighlight lang=lb>
<lang lb>
'[RC] Arithmetic evaluation.bas
'Buld the tree (with linked nodes, in array 'cause LB has no pointers)
Line 3,685:
addOpNode = newNode
end function
</syntaxhighlight>
</lang>
 
{{out}}
Line 3,703:
=={{header|Lua}}==
 
<langsyntaxhighlight lang=lua>require"lpeg"
 
P, R, C, S, V = lpeg.P, lpeg.R, lpeg.C, lpeg.S, lpeg.V
Line 3,742:
end
 
print(eval{expression:match(io.read())})</langsyntaxhighlight>
 
=={{header|M2000 Interpreter}}==
Line 3,748:
All visible variables can be used, and all known functions, internal and user (if they are visible at that point). Global variables and functions are always visible.
 
<langsyntaxhighlight lang=M2000 Interpreter>
y=100
Module CheckEval {
Line 3,761:
}
Call CheckEval
</syntaxhighlight>
</lang>
 
From BBC BASIC. In M2000 we can't call a user function which isn't a child function, so here we make all functions as members of same group, so now they call each other. A function as a member in a group can use other members, using a dot or This and a dot, so .Ast$() is same as This.Ast$().
 
<langsyntaxhighlight lang=M2000 Interpreter>
Module CheckAst {
Group Eval {
Line 3,819:
}
CheckAst
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight lang=Mathematica>(*parsing:*)
parse[string_] :=
Module[{e},
Line 3,855:
evaluate[{"*", a_, b_}] := evaluate[a]*evaluate[b];
evaluate[{"/", a_, b_}] := evaluate[a]/evaluate[b];
evaluate[string_String] := evaluate[parse[string]]</langsyntaxhighlight>
 
Example use:
<langsyntaxhighlight lang=Mathematica>parse["-1+2(3+4*-5/6)"]
evaluate["-1+2(3+4*-5/6)"]</langsyntaxhighlight>
 
{{out}}
Line 3,866:
 
=={{header|MiniScript}}==
<langsyntaxhighlight lang=MiniScript>Expr = {}
Expr.eval = 0
 
Line 3,928:
print ast.eval
end while
</syntaxhighlight>
</lang>
{{out}}
<pre>Enter expression: 200*42
Line 3,947:
This implementation uses a Pratt parser.
 
<langsyntaxhighlight lang=nim>import strutils
import os
 
Line 4,097:
 
# In the end, we print out the result.
echo ==ast</langsyntaxhighlight>
 
=={{header|OCaml}}==
 
<langsyntaxhighlight lang=ocaml>type expression =
| Const of float
| Sum of expression * expression (* e1 + e2 *)
Line 4,139:
let parse_expression = parser [< e = parse_expr; _ = Stream.empty >] -> e
 
let read_expression s = parse_expression(lexer(Stream.of_string s))</langsyntaxhighlight>
 
Using the function <code>read_expression</code> in an interactive loop:
 
<langsyntaxhighlight lang=ocaml>let () =
while true do
print_string "Expression: ";
Line 4,151:
let res = eval expr in
Printf.printf " = %g\n%!" res;
done</langsyntaxhighlight>
 
Compile with:
Line 4,157:
 
=={{header|ooRexx}}==
<langsyntaxhighlight lang=ooRexx>
expressions = .array~of("2+3", "2+3/4", "2*3-4", "2*(3+4)+5/6", "2 * (3 + (4 * 5 + (6 * 7) * 8) - 9) * 10", "2*-3--4+-.25")
loop input over expressions
Line 4,393:
raise syntax 98.900 array("Invalid expression")
return expression
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 4,410:
The <code>Do</code> procedure automatically threads the input state through a sequence of procedure calls.
 
<langsyntaxhighlight lang=oz>declare
 
fun {Expr X0 ?X}
Line 4,497:
{Inspector.configure widgetShowStrings true}
{Inspect AST}
{Inspect {Eval AST}}</langsyntaxhighlight>
 
To improve performance, the number of choice points should be limited, for example by reading numbers deterministically instead.
Line 4,506:
 
=={{header|Perl}}==
<langsyntaxhighlight lang=perl>sub ev
# Evaluates an arithmetic expression like "(1+3)*7" and returns
# its value.
Line 4,566:
my ($op, @operands) = @$ast;
$_ = ev_ast($_) foreach @operands;
return $ops{$op}->(@operands);}}</langsyntaxhighlight>
 
=={{header|Phix}}==
Line 4,573:
plus this as asked for has an AST, whereas Phix uses cross-linked flat IL.
See also [[Arithmetic_evaluation/Phix]] for a translation of the D entry.
<!--<langsyntaxhighlight lang=Phix>(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Arithmetic_evaluation.exw</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Line 4,793:
<span style="color: #0000FF;">?</span><span style="color: #000000;">evaluate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">opstack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
I added a flag (for this task) to store the ast nodes as op_p_p, p_op_p, or p_p_op, whichever you prefer.
{{out}}
Line 4,867:
 
=={{header|Picat}}==
<langsyntaxhighlight lang=Picat>main =>
print("Enter an expression: "),
Str = read_line(),
Line 4,873:
Res is Exp,
printf("Result = %w\n", Res).
</syntaxhighlight>
</lang>
 
=={{header|PicoLisp}}==
Line 4,879:
(numbers and transient symbols). From that, a recursive descendent parser can
build an expression tree, resulting in directly executable Lisp code.
<langsyntaxhighlight lang=PicoLisp>(de ast (Str)
(let *L (str Str "")
(aggregate) ) )
Line 4,901:
((= "+" X) (term))
((= "-" X) (list '- (term)))
((= "(" X) (prog1 (aggregate) (pop '*L)))) ) )</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang=PicoLisp>: (ast "1+2+3*-4/(1+2)")
-> (+ (+ 1 2) (/ (* 3 (- 4)) (+ 1 2)))
 
: (ast "(1+2+3)*-4/(1+2)")
-> (/ (* (+ (+ 1 2) 3) (- 4)) (+ 1 2))</langsyntaxhighlight>
 
=={{header|Pop11}}==
 
<langsyntaxhighlight lang=pop11>/* Scanner routines */
/* Uncomment the following to parse data from standard input
 
Line 5,059:
 
;;; Test it
arith_eval(do_expr()) =></langsyntaxhighlight>
 
=={{header|Prolog}}==
{{works with|SWI Prolog 8.1.19}}
<langsyntaxhighlight lang=prolog>% Lexer
numeric(X) :- 48 =< X, X =< 57.
not_numeric(X) :- 48 > X ; X > 57.
Line 5,113:
% Example use
% calculator("(3+50)*7-9", X).</langsyntaxhighlight>
 
=={{header|Python}}==
Line 5,119:
<br>A subsequent example uses Pythons' ast module to generate the abstract syntax tree.
 
<langsyntaxhighlight lang=python>import operator
 
class AstNode(object):
Line 5,234:
expr = raw_input("Expression:")
astTree = Lex( expr, Yaccer())
print expr, '=',astTree.eval()</langsyntaxhighlight>
 
===ast standard library module===
Python comes with its own [http://docs.python.org/3.1/library/ast.html#module-ast ast] module as part of its standard libraries. The module compiles Python source into an AST tree that can in turn be compiled to bytecode then executed.
<langsyntaxhighlight lang=python>>>> import ast
>>>
>>> expr="2 * (3 -1) + 2 * 5"
Line 5,261:
>>> code_object = compile(node, filename='<string>', mode='eval')
>>> eval(code_object)
16</langsyntaxhighlight>
 
=={{header|Racket}}==
 
<langsyntaxhighlight lang=racket>#lang racket
 
(require parser-tools/yacc
Line 5,300:
(displayln (parse (λ () (lex i)))))
 
(calc "(1 + 2 * 3) - (1+2)*-3")</langsyntaxhighlight>
 
=={{header|Raku}}==
Line 5,306:
{{Works with|rakudo|2018.03}}
 
<langsyntaxhighlight lang=perl6>sub ev (Str $s --> Numeric) {
 
grammar expr {
Line 5,349:
say ev '1 + 2 - 3 * 4 / 5'; # 0.6
say ev '1 + 5*3.4 - .5 -4 / -2 * (3+4) -6'; # 25.5
say ev '((11+15)*15)* 2 + (3) * -4 *1'; # 768</langsyntaxhighlight>
 
=={{header|REXX}}==
Line 5,366:
:::* &nbsp; 12.3D+44 &nbsp; &nbsp; &nbsp; ("double" precision)
:::* &nbsp; 12.3Q+44 &nbsp; &nbsp; &nbsp; ("extended" or "quad" precision)
<langsyntaxhighlight lang=rexx>/*REXX program evaluates an infix─type arithmetic expression and displays the result.*/
nchars = '0123456789.eEdDqQ' /*possible parts of a number, sans ± */
e='***error***'; $=" "; doubleOps= '&|*/'; z= /*handy─dandy variables.*/
Line 5,481:
return substr(x, Nj, 1) /* [↑] ignore any blanks in expression*/
end /*Nj*/
return $ /*reached end-of-tokens, return $. */</langsyntaxhighlight>
To view a version of the above REXX program, see this version which has much more whitespace: &nbsp; ──► &nbsp; [[Arithmetic_evaluation/REXX]]. <br>
<br>
Line 5,492:
=={{header|Ruby}}==
Function to convert infix arithmetic expression to binary tree. The resulting tree knows how to print and evaluate itself. Assumes expression is well-formed (matched parens, all operators have 2 operands). Algorithm: http://www.seas.gwu.edu/~csci131/fall96/exp_to_tree.html
<langsyntaxhighlight lang=ruby>$op_priority = {"+" => 0, "-" => 0, "*" => 1, "/" => 1}
 
class TreeNode
Line 5,591:
node_stack.last
end</langsyntaxhighlight>
Testing:
<langsyntaxhighlight lang=ruby>exp = "1 + 2 - 3 * (4 / 6)"
puts("Original: " + exp)
 
Line 5,600:
puts("Infix: " + tree.to_s(:infix))
puts("Postfix: " + tree.to_s(:postfix))
puts("Result: " + tree.eval.to_s)</langsyntaxhighlight>
{{out}}
<pre>Original: 1 + 2 - 3 * (4 / 6)
Line 5,609:
 
=={{header|Rust}}==
<langsyntaxhighlight lang=rust>//! Simple calculator parser and evaluator
 
 
Line 5,782:
}
 
</syntaxhighlight>
</lang>
 
=={{header|Scala}}==
Line 5,788:
is practically non-existent, to avoid obscuring the code.
 
<langsyntaxhighlight lang=scala>
package org.rosetta.arithmetic_evaluator.scala
 
Line 5,835:
}
}
</syntaxhighlight>
</lang>
 
Example:
Line 5,864:
The parse function uses a recursive-descent parser to follow the precedence rules.
 
<langsyntaxhighlight lang=scheme>
(import (scheme base)
(scheme char)
Line 5,960:
(newline))
'("1 + 2" "20+4*5" "1/2+5*(6-3)" "(1+3)/4-1" "(1 - 5) * 2 / (20 + 1)"))
</syntaxhighlight>
</lang>
 
{{out}}
Line 5,974:
=={{header|Sidef}}==
{{trans|JavaScript}}
<langsyntaxhighlight lang=ruby>func evalArithmeticExp(s) {
 
func evalExp(s) {
Line 6,029:
 
return Number(evalExp(s))
}</langsyntaxhighlight>
 
Testing the function:
<langsyntaxhighlight lang=ruby>for expr,res in [
['2+3' => 5],
['-4-3' => -7],
Line 6,044:
assert_eq(num, res)
"%-45s == %10g\n".printf(expr, num)
}</langsyntaxhighlight>
 
=={{header|Standard ML}}==
This implementation uses a [https://en.wikipedia.org/wiki/Recursive_descent_parser recursive descent parser]. It first lexes the input. The parser builds a Abstract Syntax Tree (AST) and the evaluator evaluates it. The parser uses sub categories.
The parsing is a little bit tricky because the grammar is left recursive.
<langsyntaxhighlight lang=sml>(* AST *)
datatype expression =
Con of int (* constant *)
Line 6,117:
case parseE (lex (explode str)) of
(exp, nil) => eval exp
| _ => raise Error "not parseable stuff at the end"</langsyntaxhighlight>
 
=={{header|Tailspin}}==
<langsyntaxhighlight lang=tailspin>
def ops: ['+','-','*','/'];
 
Line 6,147:
'$ast -> evaluateArithmetic;
' -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 6,155:
 
If we don't need to get the AST, we could just evaluate right away:
<langsyntaxhighlight lang=tailspin>
composer calculator
(<WS>?) <addition|multiplication|term> (<WS>?)
Line 6,173:
'
' -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
<pre>16</pre>
Line 6,182:
in a form that it can be immediately eval-led,
using Tcl's prefix operators.
<langsyntaxhighlight lang=Tcl>namespace import tcl::mathop::*
 
proc ast str {
Line 6,225:
} \n] {
puts "$test ..... [eval $test] ..... [eval [eval $test]]"
}</langsyntaxhighlight>
{{out}}
<pre>
Line 6,241:
Use TXR text pattern matching to parse expression to a Lisp AST, then evaluate with <code>eval</code>:
 
<langsyntaxhighlight lang=txr>@(next :args)
@(define space)@/ */@(end)
@(define mulop (nod))@\
Line 6,293:
erroneous suffix "@bad"
@ (end)
@(end)</langsyntaxhighlight>
 
Run:
Line 6,307:
=={{header|Ursala}}==
with no error checking other than removal of spaces
<langsyntaxhighlight lang=Ursala>#import std
#import nat
#import flo
Line 6,324:
traverse = *^ ~&v?\%ep ^H\~&vhthPX '+-*/'-$<plus,minus,times,div>@dh
 
evaluate = traverse+ parse+ lex</langsyntaxhighlight>
 
test program:
<langsyntaxhighlight lang=Ursala>#cast %eL
 
test = evaluate*t
Line 6,343:
5-3*2
(1+1)*(2+3)
(2-4)/(3+5*(8-1))]-</langsyntaxhighlight>
{{out}}
<pre>
Line 6,363:
{{trans|Kotlin}}
{{libheader|Wren-pattern}}
<langsyntaxhighlight lang=ecmascript>import "/pattern" for Pattern
 
/* if string is empty, returns zero */
Line 6,452:
"1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10",
"1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1"
].each { |s| System.print("%(s) = %(evalArithmeticExp.call(s))") }</langsyntaxhighlight>
 
{{out}}
Line 6,470:
=={{header|zkl}}==
In zkl, the compiler stack is part of the language and is written in zkl so ...
<langsyntaxhighlight lang=zkl>Compiler.Parser.parseText("(1+3)*7").dump();
Compiler.Parser.parseText("1+3*7").dump();</langsyntaxhighlight>
The ASTs look like
{{out}}
Line 6,493:
</pre>
Evaluating them is just moving up the stack:
<langsyntaxhighlight lang=zkl>Compiler.Compiler.compileText("(1+3)*7").__constructor(); vm.regX;
Compiler.Compiler.compileText("1+3*7").__constructor(); vm.regX;</langsyntaxhighlight>
{{out}}
<pre>
Line 6,502:
 
=={{header|ZX Spectrum Basic}}==
<langsyntaxhighlight lang=zxbasic>10 PRINT "Use integer numbers and signs"'"+ - * / ( )"''
20 LET s$="": REM last symbol
30 LET pc=0: REM parenthesis counter
Line 6,533:
300 PRINT FLASH 1;"Invalid symbol ";c$;" detected in pos ";n: BEEP 1,-25
310 STOP
</syntaxhighlight>
</lang>
10,327

edits