Arithmetic evaluation: Difference between revisions
m
syntax highlighting fixup automation
m (→{{header|J}}) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 25:
=={{header|11l}}==
[[wp:Pratt parser|Pratt parser]]
<
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())</
{{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}}
<
MODE FIXED = LONG REAL; # numbers in the format 9,999.999 #
Line 295:
index error:
printf(("Stack over flow"))
)</
{{out}}
<pre>
Line 303:
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
<
hand coded recursive descent parser
expr : term ( ( PLUS | MINUS ) term )* ;
Line 452:
}
#include calclex.ahk</
calclex.ahk<
{
stringo := string ; store original string
Line 519:
string := "pos= " token.pos "`nvalue= " token.value "`ntype= " token.type
return string
}</
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
PRINT "Input = " Expr$
AST$ = FNast(Expr$)
Line 580:
ENDIF
UNTIL FALSE
= num$</
{{out}}
<pre>
Line 595:
{{libheader|Boost.Spirit|1.8.4}}
<
#include <boost/spirit/tree/ast.hpp>
#include <string>
Line 710:
}
}
};</
=={{header|Clojure}}==
<
+ 1, - 1})
Line 765:
user> (evaluate "1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1")
60</
=={{header|Common Lisp}}==
Line 783:
This implementation can read integers, and produce integral and rational values.
<
(labels ((whitespace-p (char)
(find char #(#\space #\newline #\return #\tab)))
Line 868:
(loop for token = (tokenize-stream in)
until (null token)
collect token)))))))</
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.
<
std.exception, std.traits;
Line 1,132:
immutable exp = (args.length > 1) ? args[1 .. $].join(' ') : exp0;
new AST().parse(exp).CalcVis; // Should be 60.
}</
{{out}}
<pre> ........................................................+.
Line 1,154:
=={{header|Dyalect}}==
<
with Lookup
Line 1,271:
print( eval("(1+33.23)*7") )
print( eval("1+33.23*7") )</
{{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''...
<
def LiteralExpr := <elang:evm.makeLiteralExpr>.asType()
def arithEvaluate(expr :String) {
Line 1,299:
return evalAST(ast)
}</
Parentheses are handled by the parser.
<
# value: 3
Line 1,310:
? arithEvaluate("(1 + 2 / 2) * (5 + 5)")
# value: 20.0</
=={{header|Elena}}==
ELENA 5.0 :
<
import extensions;
import extensions'text;
Line 1,654:
text.clear()
}
}</
=={{header|Emacs Lisp}}==
<
;; -*- mode: emacs-lisp; lexical-binding: t -*-
;;> ./arithmetic-evaluation '(1 + 2) * 3'
Line 1,750:
(terpri)))
(setq command-line-args-left nil)
</syntaxhighlight>
{{out}}
Line 1,772:
=={{header|ERRE}}==
<
PROGRAM EVAL
Line 2,006:
IF NERR>0 THEN PRINT("Internal Error #";NERR) ELSE PRINT("Value is ";DB#) END IF
END PROGRAM
</syntaxhighlight>
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>:
<
type Expression =
Line 2,020:
| Minus of Expression * Expression
| Times of Expression * Expression
| Divide of Expression * Expression</
<code>Lexer.fsl</code>:
<
module Lexer
Line 2,046:
| newline { lexbuf.EndPos <- lexbuf.EndPos.NextLine; token lexbuf }
| eof { EOF }
| _ { failwithf "unrecognized input: '%s'" <| lexeme lexbuf }</
<code>Parser.fsy</code>:
<
open AbstractSyntaxTree
%}
Line 2,074:
| Expr TIMES Expr { Times ($1, $3) }
| Expr DIVIDE Expr { Divide ($1, $3) }
| LPAREN Expr RPAREN { $2 } </
<code>Program.fs</code>:
<
open Lexer
open Parser
Line 2,097:
|> parse
|> eval
|> printfn "%d"</
=={{header|Factor}}==
<
IN: rosetta.arith
Line 2,141:
: evaluate ( string -- result )
expr-ast eval-ast ;</
=={{header|FreeBASIC}}==
<
'Arithmetic evaluation
'
Line 2,340:
if sym <> done_sym then error_msg("unexpected input")
loop
</syntaxhighlight>
{{out}}
Line 2,355:
=={{header|Groovy}}==
Solution:
<
ADD('+', 2),
SUBTRACT('-', 2),
Line 2,498:
}
return elements[0] instanceof List ? parse(elements[0]) : elements[0]
}</
Test:
<
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 }</
{{out}}
Line 2,605:
=={{header|Haskell}}==
<
import Text.Parsec
Line 2,651:
main :: IO ()
main = print $ solution "(1+3)*7"</
{{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
<
write("Usage: Input expression = Abstract Syntax Tree = Value, ^Z to end.")
repeat {
Line 2,767:
procedure exponent()
suspend tab(any('eE')) || =("+" | "-" | "") || digits() | ""
end</
{{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):
<
eval=:monad define
'gerund structure'=:y
Line 2,864:
coerase tmp
r
)</
example use:
<
2.2</
You can also display the syntax tree, for example:
<
┌─────────────────────────────────────────────────────┬───────────────────┐
│┌───┬───────┬───┬───────┬───┬─┬───────┬───┬───────┬─┐│┌───────┬─┬───────┐│
Line 2,879:
││ │└─────┘│ │└─────┘│ │ │└─────┘│ │└─────┘│ ││ │
│└───┴───────┴───┴───────┴───┴─┴───────┴───┴───────┴─┘│ │
└─────────────────────────────────────────────────────┴───────────────────┘</
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).
<
public class ArithmeticEvaluation {
Line 3,051:
}
}
}</
{{out}}
Line 3,066:
Spaces are removed, expressions like <code>5--1</code> are treated as <code>5 - -1</code>
<
s = s.replace(/\s/g,'').replace(/^\+/,'');
var rePara = /\([^\(\)]*\)/;
Line 3,120:
}
}
}</
Line 3,136:
=== PEG operations ===
<
def plus(E): E | (plus(E) // . );
def optional(E): E // .;
def amp(E): . as $in | E | $in;
def neg(E): select( [E] == [] );</
=== Helper functions ===
<
select(.remainder | startswith($s))
| .result += [$s]
Line 3,165:
def parseNumber($re):
consume($re)
| .result = .result + [.match|tonumber] ;</
=== PEG Grammar ===
The PEG grammar for arithmetic expressions follows the one given at the Raku entry.<
def ws: consume(" *");
Line 3,180:
Product | ws | star( (literal("+") // literal("-")) | Product);
Sum;</
=== Evaluation ===
<
def eval:
if type == "array" then
Line 3,204:
{remainder: String}
| Expr.result
| eval;</
=== Example ===
Line 3,214:
From Javascript entry.
<
function evalArithmeticExp(s) {
s = s.replace(/\s/g,'').replace(/^\+/,'');
Line 3,290:
evalArithmeticExp('2*-3--4+-0.25') ==> -2.25
=!EXPECTEND!=
*/</
{{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
<
"2 * (3 -1) + 2 * 5"
Line 3,343:
julia> eval(parse("2 * (3 + ((5) / (7 - 11)))"))
3.5</
=={{header|Kotlin}}==
{{trans|JavaScript}}
<
/* 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)}") }
}</
{{out}}
Line 3,449:
=={{header|Liberty BASIC}}==
<syntaxhighlight 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>
{{out}}
Line 3,703:
=={{header|Lua}}==
<
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())})</
=={{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.
<
y=100
Module CheckEval {
Line 3,761:
}
Call CheckEval
</syntaxhighlight>
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$().
<
Module CheckAst {
Group Eval {
Line 3,819:
}
CheckAst
</syntaxhighlight>
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
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]]</
Example use:
<
evaluate["-1+2(3+4*-5/6)"]</
{{out}}
Line 3,866:
=={{header|MiniScript}}==
<
Expr.eval = 0
Line 3,928:
print ast.eval
end while
</syntaxhighlight>
{{out}}
<pre>Enter expression: 200*42
Line 3,947:
This implementation uses a Pratt parser.
<
import os
Line 4,097:
# In the end, we print out the result.
echo ==ast</
=={{header|OCaml}}==
<
| 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))</
Using the function <code>read_expression</code> in an interactive loop:
<
while true do
print_string "Expression: ";
Line 4,151:
let res = eval expr in
Printf.printf " = %g\n%!" res;
done</
Compile with:
Line 4,157:
=={{header|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>
{{out}}
<pre>
Line 4,410:
The <code>Do</code> procedure automatically threads the input state through a sequence of procedure calls.
<
fun {Expr X0 ?X}
Line 4,497:
{Inspector.configure widgetShowStrings true}
{Inspect AST}
{Inspect {Eval AST}}</
To improve performance, the number of choice points should be limited, for example by reading numbers deterministically instead.
Line 4,506:
=={{header|Perl}}==
<
# 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);}}</
=={{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.
<!--<
<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>
<!--</
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}}==
<
print("Enter an expression: "),
Str = read_line(),
Line 4,873:
Res is Exp,
printf("Result = %w\n", Res).
</syntaxhighlight>
=={{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.
<
(let *L (str Str "")
(aggregate) ) )
Line 4,901:
((= "+" X) (term))
((= "-" X) (list '- (term)))
((= "(" X) (prog1 (aggregate) (pop '*L)))) ) )</
{{out}}
<
-> (+ (+ 1 2) (/ (* 3 (- 4)) (+ 1 2)))
: (ast "(1+2+3)*-4/(1+2)")
-> (/ (* (+ (+ 1 2) 3) (- 4)) (+ 1 2))</
=={{header|Pop11}}==
<
/* Uncomment the following to parse data from standard input
Line 5,059:
;;; Test it
arith_eval(do_expr()) =></
=={{header|Prolog}}==
{{works with|SWI Prolog 8.1.19}}
<
numeric(X) :- 48 =< X, X =< 57.
not_numeric(X) :- 48 > X ; X > 57.
Line 5,113:
% Example use
% calculator("(3+50)*7-9", X).</
=={{header|Python}}==
Line 5,119:
<br>A subsequent example uses Pythons' ast module to generate the abstract syntax tree.
<
class AstNode(object):
Line 5,234:
expr = raw_input("Expression:")
astTree = Lex( expr, Yaccer())
print expr, '=',astTree.eval()</
===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.
<
>>>
>>> expr="2 * (3 -1) + 2 * 5"
Line 5,261:
>>> code_object = compile(node, filename='<string>', mode='eval')
>>> eval(code_object)
16</
=={{header|Racket}}==
<
(require parser-tools/yacc
Line 5,300:
(displayln (parse (λ () (lex i)))))
(calc "(1 + 2 * 3) - (1+2)*-3")</
=={{header|Raku}}==
Line 5,306:
{{Works with|rakudo|2018.03}}
<
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</
=={{header|REXX}}==
Line 5,366:
:::* 12.3D+44 ("double" precision)
:::* 12.3Q+44 ("extended" or "quad" precision)
<
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 $. */</
To view a version of the above REXX program, see this version which has much more whitespace: ──► [[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
<
class TreeNode
Line 5,591:
node_stack.last
end</
Testing:
<
puts("Original: " + exp)
Line 5,600:
puts("Infix: " + tree.to_s(:infix))
puts("Postfix: " + tree.to_s(:postfix))
puts("Result: " + tree.eval.to_s)</
{{out}}
<pre>Original: 1 + 2 - 3 * (4 / 6)
Line 5,609:
=={{header|Rust}}==
<
Line 5,782:
}
</syntaxhighlight>
=={{header|Scala}}==
Line 5,788:
is practically non-existent, to avoid obscuring the code.
<
package org.rosetta.arithmetic_evaluator.scala
Line 5,835:
}
}
</syntaxhighlight>
Example:
Line 5,864:
The parse function uses a recursive-descent parser to follow the precedence rules.
<
(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>
{{out}}
Line 5,974:
=={{header|Sidef}}==
{{trans|JavaScript}}
<
func evalExp(s) {
Line 6,029:
return Number(evalExp(s))
}</
Testing the function:
<
['2+3' => 5],
['-4-3' => -7],
Line 6,044:
assert_eq(num, res)
"%-45s == %10g\n".printf(expr, num)
}</
=={{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.
<
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"</
=={{header|Tailspin}}==
<
def ops: ['+','-','*','/'];
Line 6,147:
'$ast -> evaluateArithmetic;
' -> !OUT::write
</syntaxhighlight>
{{out}}
<pre>
Line 6,155:
If we don't need to get the AST, we could just evaluate right away:
<
composer calculator
(<WS>?) <addition|multiplication|term> (<WS>?)
Line 6,173:
'
' -> !OUT::write
</syntaxhighlight>
{{out}}
<pre>16</pre>
Line 6,182:
in a form that it can be immediately eval-led,
using Tcl's prefix operators.
<
proc ast str {
Line 6,225:
} \n] {
puts "$test ..... [eval $test] ..... [eval [eval $test]]"
}</
{{out}}
<pre>
Line 6,241:
Use TXR text pattern matching to parse expression to a Lisp AST, then evaluate with <code>eval</code>:
<
@(define space)@/ */@(end)
@(define mulop (nod))@\
Line 6,293:
erroneous suffix "@bad"
@ (end)
@(end)</
Run:
Line 6,307:
=={{header|Ursala}}==
with no error checking other than removal of spaces
<
#import nat
#import flo
Line 6,324:
traverse = *^ ~&v?\%ep ^H\~&vhthPX '+-*/'-$<plus,minus,times,div>@dh
evaluate = traverse+ parse+ lex</
test program:
<
test = evaluate*t
Line 6,343:
5-3*2
(1+1)*(2+3)
(2-4)/(3+5*(8-1))]-</
{{out}}
<pre>
Line 6,363:
{{trans|Kotlin}}
{{libheader|Wren-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))") }</
{{out}}
Line 6,470:
=={{header|zkl}}==
In zkl, the compiler stack is part of the language and is written in zkl so ...
<
Compiler.Parser.parseText("1+3*7").dump();</
The ASTs look like
{{out}}
Line 6,493:
</pre>
Evaluating them is just moving up the stack:
<
Compiler.Compiler.compileText("1+3*7").__constructor(); vm.regX;</
{{out}}
<pre>
Line 6,502:
=={{header|ZX Spectrum Basic}}==
<
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>
|