Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
|
|
@ -0,0 +1,82 @@
|
|||
type Priority is range 1..4;
|
||||
type Infix is record
|
||||
Precedence : Priority;
|
||||
Expression : Unbounded_String;
|
||||
end record;
|
||||
package Expression_Stack is new Generic_Stack (Infix);
|
||||
use Expression_Stack;
|
||||
|
||||
function Convert (RPN : String) return String is
|
||||
Arguments : Stack;
|
||||
procedure Pop
|
||||
( Operation : Character;
|
||||
Precedence : Priority;
|
||||
Association : Priority
|
||||
) is
|
||||
Right, Left : Infix;
|
||||
Result : Infix;
|
||||
begin
|
||||
Pop (Right, Arguments);
|
||||
Pop (Left, Arguments);
|
||||
Result.Precedence := Association;
|
||||
if Left.Precedence < Precedence then
|
||||
Append (Result.Expression, '(');
|
||||
Append (Result.Expression, Left.Expression);
|
||||
Append (Result.Expression, ')');
|
||||
else
|
||||
Append (Result.Expression, Left.Expression);
|
||||
end if;
|
||||
Append (Result.Expression, ' ');
|
||||
Append (Result.Expression, Operation);
|
||||
Append (Result.Expression, ' ');
|
||||
if Right.Precedence < Precedence then
|
||||
Append (Result.Expression, '(');
|
||||
Append (Result.Expression, Right.Expression);
|
||||
Append (Result.Expression, ')');
|
||||
else
|
||||
Append (Result.Expression, Right.Expression);
|
||||
end if;
|
||||
Push (Result, Arguments);
|
||||
end Pop;
|
||||
Pointer : Integer := RPN'First;
|
||||
begin
|
||||
while Pointer <= RPN'Last loop
|
||||
case RPN (Pointer) is
|
||||
when ' ' =>
|
||||
Pointer := Pointer + 1;
|
||||
when '0'..'9' =>
|
||||
declare
|
||||
Start : constant Integer := Pointer;
|
||||
begin
|
||||
loop
|
||||
Pointer := Pointer + 1;
|
||||
exit when Pointer > RPN'Last
|
||||
or else RPN (Pointer) not in '0'..'9';
|
||||
end loop;
|
||||
Push
|
||||
( ( 4,
|
||||
To_Unbounded_String (RPN (Start..Pointer - 1))
|
||||
),
|
||||
Arguments
|
||||
);
|
||||
end;
|
||||
when '+' | '-' =>
|
||||
Pop (RPN (Pointer), 1, 1);
|
||||
Pointer := Pointer + 1;
|
||||
when '*' | '/' =>
|
||||
Pop (RPN (Pointer), 2, 2);
|
||||
Pointer := Pointer + 1;
|
||||
when '^' =>
|
||||
Pop (RPN (Pointer), 4, 3);
|
||||
Pointer := Pointer + 1;
|
||||
when others =>
|
||||
raise Constraint_Error with "Syntax";
|
||||
end case;
|
||||
end loop;
|
||||
declare
|
||||
Result : Infix;
|
||||
begin
|
||||
Pop (Result, Arguments);
|
||||
return To_String (Result.Expression);
|
||||
end;
|
||||
end Convert;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
|
||||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
with Generic_Stack;
|
||||
|
||||
procedure RPN_to_Infix is
|
||||
-- The code above
|
||||
begin
|
||||
Put_Line ("3 4 2 * 1 5 - 2 3 ^ ^ / + = ");
|
||||
Put_Line (Convert ("3 4 2 * 1 5 - 2 3 ^ ^ / +"));
|
||||
Put_Line ("1 2 + 3 4 + ^ 5 6 + ^ = ");
|
||||
Put_Line (Convert ("1 2 + 3 4 + ^ 5 6 + ^"));
|
||||
end RPN_to_Infix;
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
OPS = {
|
||||
"^" => { prio: 4, assoc: :right },
|
||||
"*" => { prio: 3, assoc: :left },
|
||||
"/" => { prio: 3, assoc: :left },
|
||||
"+" => { prio: 2, assoc: :left },
|
||||
"-" => { prio: 2, assoc: :left },
|
||||
}
|
||||
|
||||
class Op
|
||||
property op : String, left : Op | Float64, right : Op | Float64
|
||||
|
||||
def initialize (@op, @left, @right)
|
||||
end
|
||||
def prio
|
||||
OPS[@op][:prio]
|
||||
end
|
||||
def assoc
|
||||
OPS[@op][:assoc]
|
||||
end
|
||||
|
||||
def operand_infix (operand, side)
|
||||
if operand.is_a? Float64
|
||||
operand.to_s
|
||||
elsif operand.prio < self.prio ||
|
||||
operand.prio == self.prio && side != self.assoc
|
||||
"(" + operand.infix + ")"
|
||||
else
|
||||
operand.infix
|
||||
end
|
||||
end
|
||||
|
||||
def infix
|
||||
operand_infix(@left, :left) + " " + @op + " " + operand_infix(@right, :right)
|
||||
end
|
||||
end
|
||||
|
||||
def make_ast (tokens)
|
||||
stack = [] of Op | Float64
|
||||
tokens.each do |token|
|
||||
if token.is_a? Float64
|
||||
stack.push token
|
||||
else
|
||||
raise "Unknown operator '#{token}'" unless token.in? OPS.keys
|
||||
right = stack.pop
|
||||
left = stack.pop
|
||||
stack.push Op.new token, left, right
|
||||
end
|
||||
puts "%4s [%s]" % {token, stack.map {|t| t.is_a?(Op) ? t.infix : t.to_s }.join(", ")}
|
||||
end
|
||||
raise "Unbalanced expression" unless stack.size == 1
|
||||
stack[0]
|
||||
end
|
||||
|
||||
def tokenize (s)
|
||||
s.split.map {|t| t.to_f rescue t }
|
||||
end
|
||||
|
||||
make_ast tokenize "10 9 8 - + 7 ^ 6 ^" # check associativity
|
||||
puts
|
||||
make_ast tokenize "3 4 2 * 1 5 - 2 3 ^ ^ / +"
|
||||
puts
|
||||
make_ast tokenize "1 2 + 3 4 + ^ 5 6 + ^"
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
$DEBUG = true
|
||||
rpn = RPNExpression.new("3 4 2 * 1 5 - 2 3 ^ ^ / +")
|
||||
infix = rpn.to_infix
|
||||
ruby = rpn.to_ruby
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue