Аналіз та обчислення дужкових виразів
СОДЕРЖАНИЕ: Реферат на тему: Аналіз та обчислення дужкових виразів У розділі 9 розглядалися дужкові арифметичні вирази, мова яких породжується розширеною LA(1)-граматикою
Реферат на тему:
Аналіз та обчислення дужкових виразів
У розділі 9 розглядалися дужкові арифметичні вирази, мова яких породжується розширеною LA(1)-граматикою G 2 :
( { 0, … , 9, ., c, i, n, o, s, +, *, -, /, (, ) },
{ E , T , F , A , C , D , N },
{ E ® T { +T | -T }, T ® F { *F | /F }, F ® (E ) | C | A ,
C ® N (E ), N ® sin | cos,
A ® D { D } [ . { D } ], D ® 0 | … | 9 },
E ).
Імена A , C, N є скороченнями фраз A rithmetic constant, C all of function, N ame of function відповідно, тобто Арифметична стала, Виклик функції, Імя функції.
Побудуємо програму Aexval аналізу та обчислення арифметичних виразів на основі програми Aexan із попереднього підрозділу. Нехай вираз подається в кількох рядках, і ознакою кінця є порожній рядок. Читання лексем виразу задається модулями Glx та Inbuf, означеними в розділі 20. Замість функції getc добування наступного символу з програми Aexan використовується функція getlx добування наступної лексеми, а замість поточного символу ch – поточна лексема lx типу Tlx. Ознака наявності лексеми, що повертається з функції getlx, присвоюється бульовій змінній islx.
Підпрограми для нетерміналів A , N тут не створюються, оскільки аналіз лексем, позначених ними, уже задаєно в модулі Glx. Кожна з процедур E, T, F перетворюється на функцію обчислення тієї частини виразу, яка аналізується при виконанні її виклику. Побудуємо їх таким чином, щоб за помилкового виразу з них поверталося значення 1.
Згідно з продукціями граматики G 2 , функція F обчислення множника у виразі має такий вигляд:
function F : real;
begin
if ( lx.lxt = par ) and ( lx.prt = ( ) then
begin
islx := getlx ( lx ); F := E;
if islx and ( lx.lxt = par ) and ( lx.prt = ) )
then islx := getlx ( lx )
else begin error; F := 1 end
end
else
if lx.lxt = con then
begin F := lx.numb; islx := getlx ( lx ) end
else
if lx.lxt = nam then F := C
else begin error; F := 1 end
end
Функція C задає обчислення значення, що має повернутися з указаного у виразі виклику функції sin чи cos:
function C : real;
var lx1 : Tlx; v : real;
begin
lx1 := lx; islx := getlx ( lx );
if islx and ( lx.lxt = par ) and ( lx.prt = ( ) then
begin
islx := getlx ( lx ); v := E;
if islx and ( lx.lxt = par ) and ( lx.prt = ) )
then islx := getlx ( lx )
else begin error; C := 1 end ;
if ok then
if lx1.name = sin then C := sin ( v )
else C := cos ( v )
else begin error; C := 1 end
end
else begin error; C := 1 end
end
Функція E задає обчислення виразу, вивідного з E :
function E : real;
var lx1 : Tlx; v : real;
begin
v := T;
while ok and ( lx.lxt = ops )
and ( lx.sig in [+, -] ) do
begin
lx1 := lx; islx := getlx ( lx );
case lx1.sig of
+ : v := v + T;
- : v := v - T
end
end;
if ok then E := v else E := 1
end
Функцію T обчислення доданка у виразі, яка має аналогічну функції E структуру, залишаємо для самостійної розробки. Головна програма подібна до програми Aexan:
program Aexval ( input, output );
uses Inbuf, Glx
var islx, ok : boolean;
v : real; lx : Tlx;
procedure error;
begin ok := false ; islx := false end ;
function E : real; forward ;
function C : real; … end ;
function F : real; … end ;
function T : real; … end ;
function E; { скорочений заголовок } … end ;
begin
ok := true ;
v := 0;
islx := getlx ( lx );
v := E;
if ok and not islx then writeln ( v )
else writeln ( ***error*** )
end .