Interpreterji in prevajalniki

Iz E-študij, proste zakladnice študentskega znanja

Skoči na: navigacija, iskanje

Interpreter

Preprosti interpreter prologa, napisan v prologu, obsega vsega štiri stavke:

izvajaj((Ciljl,Cilji)) :- izvajaj(Cilj1),izvajaj(Cilji).
izvajaj((Cilj 1 ;Cilji)) :- izvajaj(Cilj1);izvajaj(Cilji).
izvajaj(Cilj) :- clause(Cilj,Cilji), izvajaj(Cilji).
izvajaj(Cilj) :- call(Cilj).

Clause(Glava,Telo) je vgrajena procedura, ki poišče prvi stavek v programu z glavo Glava in telesom Telo. Če je stavek dejstvo, je Telo = true.

Prevajalnik

Primer prevajalnika, ki izpiše zaporedje ukazov za izračunavanje nekega aritmetičnega izraza:

prevedi(Izraz) :- tell(output),prev(Izraz),told.

prev(X+Y) :- prev(X),prev(Y),write(add),nl.
prev(X-Y) :- prev(X),prev(Y),write(subtract),nl.
prev(X*Y) :- prev(X),prev(Y),write(multiply),nl.
prev(X/Y) :- prev(X),prev(Y),write(divide),n1.
prev(X) :- atomic(X),write(load),write(' '),write(X),nl.
load x
postavi x na vrh sklada
add
sešteje dva vrhnja elementa sklada in shrani rezultat v spodnjega, sklad se zniža za en element
subtract
analogno add, le da odšteje vrhnji element od spodnjega
multiply
analogno add, le da elementa zmnoži
divide
analogno add, le da deli spodnji element z zgornjim
?- prevedi(a+(b-100/12*(2-x))-3).
load a
load b
load 100
load 12
divide
load 2
load x
subtract
multiply
subtract
add
load 3
subtract

Interpreter podmnožice pascala

Gramatika:

<program> ::= program <Ime> ;
  var <Imena> begin <Stavki> end .

<Imena> ::= <Ime> | <Ime> , <Imena>
<Ime> ::= <atom> 

<Stavki> ::= <Stavek> l <Stavek> ; <Stavki>
<Stavek> ::= <Ime> :_ <Izraz>
<Stavek> ::= write ( <Ime> )
<Stavek> ::= write (' <Znaki> ' )%poljuben niz znakov
<Stavek> ::= while <Pogoj> do ( <Stavki> )
<Stavek> ::= repeat ( <Stavki> ) until <Pogoj>
<Stavek> ::= <ifthen>
<Stavek> ::= <ifthen> else ( <Stavki> )

<ifthen> ::= if <Pogoj> then ( <Stavki> )

<Pogoj> ::= <Izraz> <Primerjava> <Izraz>
<Primerjava> ::= =:= | =\= | < | =< | > | >=

<Izraz><Izraz> + <Sumand>
<Izraz><Izraz> - <Sumand>|<Sumand>
<Sumand> ::= <Sumand> * <Faktor>
<Sumand> ::= <Sumand> / <Faktor> | <Faktor>
<Faktor> ::= ( <Izraz> ) | <Stevilo>

:- op(200,fx,program).
:- op(1099,fx,var).
:- op(1150,xfx,begin).
:- op(800,xfx, :* ).
:- op(800,fx,if).
:- op(799,xfx,then).
:- op(798,xfx,else). 
:- op(800,fx,vhile).
:- op(799,xfx,do).
:- op(800,fx,repeat).
:- op(799,xfx,until).
:- op(1140,xf,end).
var i,j
begin
 write(' vtipkaj stevilo :');
read(i);j:= 1;
while j =< i do
 (write(j); write(' '); j := j + 1)
end.


Interpreter sprejeme celoten program kot vprašanje, inicializira vrednosti spremenljivkam in nato interpretira vsak stavek posebej:

program Ime; var Vars begin Statements end :-
inicializiraj(Vars),
interpret(Statements).

Trenutne vrednosti spremenljivk bodo shranjene kot dejstva oblike:

vrednost(Ime.spremenljivke, Vrednost).

Na začetku procedura inicializiraj postavi vrednosti vseh spremenljivk napoljubno (neopredeljeno) vrednost:

inicializiraj((X,Vars)) :- !, % več kot ena spremenljivka
  inicializiraj(X),
  inicializiraj(Vars).
inicializiraj(X) :-
  assert(vrednost(X,_)).

Interpreter interpretira stavke enega za drugim. Če je potrebno spremenitivrednost spremenljivke, interpreter pokliče proceduro spremeni:

% spremeni vrednost spremenljivke na dano vrednost
spremeni(Var,Vr) :-
  retract(vrednost(Var,_)),
  assert(vrednost(Var,Vr)).




%napravi pogoj izračunljiv
pogoj(P,I) :=
  P =..[Op,A1,A2],
  spr(A1,I1),
  spr(A2,I2),
  I =..[Op, I1, I2].
spr(X,X) :-
  number(X),!.
spr(Var,Vrednost) :-
  atom(Var),
  vrednost(Var,Vrednost).
spr(Izraz,Izrac) :-
  Izraz =..[F|Args],
  spr_seznam(Args,Izrac_arg),
  izrac =..[F|Izrac_arg].
% sestavi seznam izračunljivih argumentov
spr_seznam([],[]).
spr_seznam([X|Xs],[I|Is]) : -
  spr(X,I),
  spr_seznam(Xs,Is).

Če bi imeli npr. shranjene vrednosti spremenljivk:

vrednost(i,15).vrednost (j, 22) .

bi procedura pogoj delovala takole:

?-pogoj(i+3 >= 2*j*j,Pogoj).Pogoj = 15+3 > 2*22*22


interpret((S;Statements)) :- !, %več kot en stavek
  interpret(S),
  interpret(Statements).

%preberi vrednost spremenljivke
interpret(read(Var)) :-
  read(Vrednost),
  spremeni(Var,Vrednost).

%izpiši vrednost spremenljivke ali niz znakov
interpret(write(Var)) :-
vrednost(Var,Vrednost),!,
write(Vrednost).

interpret(write(Niz)) :-
  write(Niz).

%if - then - else
interpret(if Pogoj then S1 else S2) :- !,
pogoj(Pogoj,Izracunljiv),!,
if Izracunljiv
  then interpret(Sl)
  else interpret(S2).

%while - do
interpret(while Pogoj do S) :- pogoj(Pegoj,Izracunljiv),!,
  if Izracunljiv
    then (interpret(S),!,interpret(while Pogoj do S))
    else true.

% repeat - until
interpret(repeat S until Pogoj)interpret(S),!,
pogoj(Pogoj,Izracunljiv),!,
if Izracunljiv
  then true
  else interpret(repeat S until Pogoj).

%priredi vrednost aritmetičnega izraza spremenljivki
interpret(Var := Arith) :-
  spr(Arith,Izrac),
  Vrednost is Izrac,
  spremeni(Var,Vrednost)
Osebna orodja
Imenski prostori
Različice
Dejanja
navigacija

Tiskanje/izvoz
orodja