Другие языки программирования и технологии

Функция-калькулятор выражений

Ищу наипростейшую реализацию калькулятора выражений. В идеале необходима просто функция, которая посчитает выражение из строковой переменной, т.е. f("1+1") вернет 2. Язык любой. Нужна именно простая реализация, без классов, без графического интерфейса и т.п. - просто несколько функций.
php

function f($data){
return eval($data)
}

python

def f(data):
return eval(data)

ну и так далее

---
но если это для написания компилятора - то милости просим в гуголь =)
или же в банк для перевода денюжки =)
Дарын Аккубашов
Дарын Аккубашов
587
Лучший ответ
function calc(a:integer,b:integer):integer;
var
c:integer;
begin
c:=a+b;
end;
На PureBasic.

#EVAL_NUMS = "0123456789" ;Die Zahlen von 0 bis 9
#EVAL_GENAUGK = 65 ;Genauigkeit fьr StrF() - 65 sollte eigentlich genьgen, mehr bringt sowieso nichts
#EVAL_DWARF = 0.00001 ;Alles was kleiner als dieser Wert ist wird wissenschaftlich notiert
#EVAL_GIANT = 1000000 ;Alles was grцЯer-gleich ist wird wissenschaftlich notiert

Procedure.s MyEval(expr.s) ; wird nur intern von Funktion Eval() aufgerufen
Protected exprLeft.s, exprRight.s, exprMid.s, Result.s, exprLen.l, valLeft.f, valRight.f, i.l
;Debug "in: " + expr
EVAL_START:
exprLen = Len(expr)
For i = 1 To exprLen ; In dieser Schleife schauen wir nach der ersten цffnenden Klammer
exprMid = Mid(expr, i, 1)
If exprMid = "("
BracketCount = 1
start = i
For i = i+1 To exprLen ; wurde eine цffnende Klammer gefunden sucht diese Schleife die dazu passende schlieЯende
exprMid = Mid(expr, i, 1)
If exprMid = "(" ;Sch... noch eine Klammerebene
BracketCount + 1
ElseIf exprMid = ")"
BracketCount - 1
If BracketCount = 0 ; gefunden
exprLeft = Left(expr, start-1)
exprRight = Right(expr, exprLen - i)
exprMid = Mid(expr, start+1, exprLen - Len(exprLeft + exprRight) - 2)
exprMid = MyEval(exprMid) ; berechnen des mittleren Abschnitts (der in der Klammer)
If exprMid="x"
ProcedureReturn "x"
EndIf
expr = exprLeft + exprMid + exprRight
Goto EVAL_START ;des Goto musste mal sein, ich brauch's ja sonst nie
EndIf
EndIf
Next
EndIf
Next

For i = exprLen To 1 Step -1
exprMid = Mid(expr, i, 1)
Select exprMid
Case "="
;Debug "ok"
exprLeft = MyEval(Left(expr, i-1))
exprRight = MyEval(Right(expr, exprLen - i))
If exprLeft="x" Or exprRight="x"
ProcedureReturn "x"
EndIf
If exprLeft = exprRight
ProcedureReturn "1"
Else
ProcedureReturn "0.0"
EndIf
Case "<"
;Debug "ok"
exprLeft = MyEval(Left(expr, i-1))
exprRight = MyEval(Right(expr, exprLen - i))
If exprLeft="x" Or exprRight="x"
ProcedureReturn "x"
EndIf
If ValF(exprLeft) < ValF(exprRight)
ProcedureReturn "1"
Else
ProcedureReturn "0.0"
EndIf
Case ">"
;Debug "ok"
exprLeft = MyEval(Left(expr, i-1))
exprRight = MyEval(Right(expr, exprLen - i))
If exprLeft="x" Or exprRight="x"
ProcedureReturn "x"
EndIf
If ValF(exprLeft) > ValF(exprRight)
ProcedureReturn "1"
Else
ProcedureReturn "0.0"
EndIf
EndSelect
Next

For i = exprLen To 1 Step -1
exprMid = Mid(expr, i, 1)
Select exprMid
Case "&"
exprLeft = MyEval(Left(expr, i-1))
exprRight = MyEval(Right(expr, exprLen - i))
If exprLeft="x" Or exprRight="x"
ProcedureReturn "x"
EndIf
intL.l = Val(exprLeft)
intR.l = Val(exprRight)
intR = intR & intL
Result = StrF(intR, #EVAL_GENAUGK)
ProcedureReturn Result
Case "|"
exprLeft = MyEval(Left(expr, i-1))
exprRight = MyEval(Right(expr, exprLen - i))
If exprLeft="x" Or exprRight="x"
ProcedureReturn "x"
EndIf
intL.l = Val(exprLeft)
intR.l = Val(exprRight)
intR = intR | intL
Result = StrF(intR, #EVAL_GENAUGK)
ProcedureReturn Result
EndSelect
Next

For i = exprLen To 1 Step -1 ; + und - Terme ausrechnen
exprMid = Mid(expr, i, 1)
Select exprMid
Case "+"
exprLeft = Left(expr,
Сергей Тарабанов Весь код не влез, если надо, пиши на почту.
Const
cmPUSH = 0;
cmMINUS = 1;
cmPLUS = 2;
cmMUL = 3;
cmDIV = 4;
Type
code_mem=record
a:array[0..1023] of byte;
p:integer;
end;

Var
Stack:array[0..100] of real;

Procedure Parse(s:string;var code:code_mem);
Var
i,j:byte;
a,b:integer;
Begin

j:=0;
for i:=byte(s[0]) downto 1 do
case s[ i] of
')': inc(j);
'(': dec(j);
'-': if j=0 then
begin
parse(copy(s,1,i-1),code);
parse(copy(s,i+1,byte(s[0])-i),code);
code.a[code.p]:=cmMINUS;
inc(code.p);
exit;
end;
'+': if j=0 then
begin
parse(copy(s,1,i-1),code);
parse(copy(s,i+1,byte(s[0])-i),code);
code.a[code.p]:=cmPLUS;
inc(code.p);
exit;
end;
end;

j:=0;
for i:=byte(s[0]) downto 1 do
case s[i ] of
'(': inc(j);
')': dec(j);
'/': if j=0 then
begin
parse(copy(s,1,i-1),code);
parse(copy(s,i+1,byte(s[0])-i),code);
code.a[code.p]:=cmDIV;
inc(code.p);
exit;
end;
'*': if j=0 then
begin
parse(copy(s,1,i-1),code);
parse(copy(s,i+1,byte(s[0])-i),code);
code.a[code.p]:=cmMUL;
inc(code.p);
exit;
end;
end;
val(s,a,b);
if b=0 then
begin
code.a[code.p]:=cmPUSH;
inc(code.p);
code.a[code.p]:=lo(a);
inc(code.p);
exit
end;
if s='' then
begin
code.a[code.p]:=cmPUSH;
inc(code.p);
code.a[code.p]:=0;
inc(code.p);
exit
end;
if (s[1]='(') and (s[byte(s[0])]=')') then
begin
i:=2;
j:=1;
while (i<(byte(s[0])-1)) and (j>0) do
begin
if s[ i]='(' then inc(j);
if s[ i]=')' then dec(j);
inc(i);
end;
if j<>0 then
parse(copy(s,2,byte(s[0])-2),code);
end;
End;

Function Calk(code:code_mem):real;
Var
i:byte;
StackPointer:byte;
Begin
i:=0;
StackPointer:=0;
while (i
Евгений Кривец весь код не поместился =) вот результат выполнения, заинтересует - пиши
Pascal
Var
a, b, x:Integer;
Begin
Write('');
Readln(a);
Write('');
Readln(b);
x:=a+b;
Writeln('=',x);
readln;
End.