Data update
This commit is contained in:
parent
4d5544505c
commit
4924dd0264
3073 changed files with 55820 additions and 4408 deletions
|
|
@ -0,0 +1,127 @@
|
|||
type
|
||||
IExprNode = interface
|
||||
function Evaluate: real;
|
||||
end;
|
||||
|
||||
NumberNode = auto class(IExprNode)
|
||||
public
|
||||
value: real;
|
||||
function Evaluate: real := value;
|
||||
end;
|
||||
|
||||
BinaryOpNode = auto class(IExprNode)
|
||||
public
|
||||
op: char;
|
||||
left, right: IExprNode;
|
||||
|
||||
function Evaluate: real;
|
||||
begin
|
||||
case op of
|
||||
'+': Result := left.Evaluate + right.Evaluate;
|
||||
'-': Result := left.Evaluate - right.Evaluate;
|
||||
'*': Result := left.Evaluate * right.Evaluate;
|
||||
'/': Result := left.Evaluate / right.Evaluate;
|
||||
else
|
||||
raise new Exception($'Unknown operator {op}');
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
ExpressionParser = class
|
||||
s: string;
|
||||
pos: integer;
|
||||
|
||||
constructor Create(input: string);
|
||||
begin
|
||||
s := input;
|
||||
pos := 1;
|
||||
end;
|
||||
|
||||
function NextChar: char :=
|
||||
if pos <= s.Length then s[pos] else #0;
|
||||
|
||||
procedure SkipSpaces :=
|
||||
while NextChar = ' ' do pos += 1;
|
||||
|
||||
function ParseNumber: IExprNode;
|
||||
begin
|
||||
SkipSpaces;
|
||||
var start := pos;
|
||||
while NextChar.IsDigit do pos += 1;
|
||||
if NextChar = '.' then
|
||||
begin
|
||||
pos += 1;
|
||||
while NextChar.IsDigit do pos += 1;
|
||||
end;
|
||||
var value := s[start:pos].ToReal;
|
||||
Result := new NumberNode(value);
|
||||
end;
|
||||
|
||||
function ParseFactor: IExprNode;
|
||||
begin
|
||||
SkipSpaces;
|
||||
if NextChar = '(' then
|
||||
begin
|
||||
pos += 1;
|
||||
Result := ParseExpr;
|
||||
SkipSpaces;
|
||||
if NextChar = ')' then
|
||||
pos += 1
|
||||
else raise new Exception('Expected )');
|
||||
end
|
||||
else
|
||||
Result := ParseNumber;
|
||||
end;
|
||||
|
||||
function ParseTerm: IExprNode;
|
||||
begin
|
||||
Result := ParseFactor;
|
||||
while true do
|
||||
begin
|
||||
SkipSpaces;
|
||||
var ch := NextChar;
|
||||
if (ch = '*') or (ch = '/') then
|
||||
begin
|
||||
pos += 1;
|
||||
Result := new BinaryOpNode(ch, Result, ParseFactor);
|
||||
end
|
||||
else break;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ParseExpr: IExprNode;
|
||||
begin
|
||||
Result := ParseTerm;
|
||||
while true do
|
||||
begin
|
||||
SkipSpaces;
|
||||
var ch := NextChar;
|
||||
if (ch = '+') or (ch = '-') then
|
||||
begin
|
||||
pos += 1;
|
||||
Result := new BinaryOpNode(ch, Result, ParseTerm);
|
||||
end
|
||||
else break;
|
||||
end;
|
||||
end;
|
||||
|
||||
function Parse: IExprNode := ParseExpr;
|
||||
|
||||
end;
|
||||
|
||||
begin
|
||||
var inputs := [
|
||||
'2+3*(4-1)',
|
||||
'10 + 2 / 3',
|
||||
'(7+3)*(2+2)',
|
||||
'8*(5+(2-3))',
|
||||
'1/3',
|
||||
'2.5 + 4.1 * (3 - 1.1/2)'];
|
||||
|
||||
foreach var expr in inputs do
|
||||
begin
|
||||
var parser := new ExpressionParser(expr);
|
||||
var tree := parser.Parse;
|
||||
Println($'{expr} = {tree.Evaluate:0.###}');
|
||||
end;
|
||||
end.
|
||||
Loading…
Add table
Add a link
Reference in a new issue