Скачиваний:
20
Добавлен:
22.05.2015
Размер:
36.35 Кб
Скачать

Лабораторная работа 8

Символьные преобразования

1. Парсер.

Нижеприведённый парсер преобразует строку, представляющую собой арифметическое выражение, в структуру с польской записью. Например, строка «4+X» парсер преобразует в структуру плюс(число(4),перем(X)). Такое преобразование необходимо осуществлять перед символьными операциями. Например, для калькуляторов, символьного дифференцирования, интегрирования, упрощения выражений, решения уравнений и т.п.

domains выраж = число(real);  перем(string);     унар_минус(выраж);     плюс(выраж,выраж);  минус(выраж,выраж);     умнож(выраж,выраж);  делен(выраж,выраж);     степень(выраж,выраж);     ln(выраж); cos(выраж);sin(выраж);tan(выраж). class predicates анализ:(string,выраж [out])determ. сканер:(string,string* [out]). парсер:(string*,string*,выраж) determ(i,i,o) (i,o,o). оп3:(string*,string* [out],выраж [out]) determ. опер3:(string*,string* [out],выраж,выраж [out]) determ. оп2:(string*,string* [out],выраж [out])determ. опер2:(string*,string* [out],выраж,выраж [out])determ. оп1:(string*,string*,выраж) determ(i,i,o) (i,o,o). опер1:(string*,string*,выраж,выраж) determ(i,o,i,o) (i,i,i,o). эл_выр:(string*,string* [out],выраж [out]) determ. clauses анализ(Строка,Выражение):-сканер(Строка,Спис),    парсер(Спис,[],Выражение). сканер(Строка,[Лексема|Спис]):-    fronttoken(Строка,Лексема,Строка1),!,    сканер(Строка1,Спис). сканер(_,[]). парсер(Спис,Ост,Выраж):-оп1(Спис,Ост,Выраж). оп1(Спис,Ост,Выраж2):-оп2(Спис,Ост1,Выраж1),    опер1(Ост1,Ост,Выраж1,Выраж2). опер1(["+"|Спис],Ост,Выраж1,Выраж3):-!,оп2(Спис,Ост1,Выраж2),    опер1(Ост1,Ост,плюс(Выраж1,Выраж2),Выраж3). опер1(["-"|Спис],Ост,Выраж1,Выраж3):-!,оп2(Спис,Ост1,Выраж2),    опер1(Ост1,Ост,минус(Выраж1,Выраж2),Выраж3). опер1(Спис,Спис,Выраж,Выраж). оп2(Спис,Ост,Выраж2):-оп3(Спис,Ост1,Выраж1),    опер2(Ост1,Ост,Выраж1,Выраж2). опер2(["*"|Спис],Ост,Выраж1,Выраж3):-!,    оп3(Спис,Ост1,Выраж2),    опер2(Ост1,Ост,умнож(Выраж1,Выраж2),Выраж3). опер2(["/"|Спис],Ост,Выраж1,Выраж3):-!,    оп3(Спис,Ост1,Выраж2),    опер2(Ост1,Ост,делен(Выраж1,Выраж2),Выраж3). опер2(Спис,Спис,Выраж,Выраж). оп3(Спис,Ост,Выраж2):-эл_выр(Спис,Ост1,Выраж1),    опер3(Ост1,Ост,Выраж1,Выраж2),!. опер3(["^"|Спис],Ост,Выраж1,Выраж3):-!,    эл_выр(Спис,Ост1,Выраж2),    опер3(Ост1,Ост,степень(Выраж1,Выраж2),Выраж3). опер3(Спис,Спис,Выраж,Выраж). эл_выр(["("|Спис],Ост,Выраж):- парсер(Спис,Ост1,Выраж),Ост1=[")"|Ост],!.  эл_выр(["ln","("|Спис],Ост,ln(Выраж)):- парсер(Спис,Ост1,Выраж),Ост1=[")"|Ост],!. эл_выр(["sin","("|Спис],Ост,sin(Выраж)):- парсер(Спис,Ост1,Выраж),Ост1=[")"|Ост],!. эл_выр(["cos","("|Спис],Ост,cos(Выраж)):- парсер(Спис,Ост1,Выраж),Ост1=[")"|Ост],!. эл_выр(["tan","("|Спис],Ост,tan(Выраж)):- парсер(Спис,Ост1,Выраж),Ост1=[")"|Ост],!. эл_выр(["-",Лексема|Спис],Спис,число(-Число)):-Число=tryToReal(Лексема),!. эл_выр(["-"|Спис],Ост,унар_минус(Выраж)):-эл_выр(Спис,Ост,Выраж),!. эл_выр([Лексема|Спис],Спис,перем(Лексема)):-isName(Лексема),!. эл_выр([Лексема|Спис],Спис,число(tryToReal(Лексема))).     run():-init(),         Строка = "-Sin(1.3*X+0.6)",         Строка1 = toLowerCase(Строка),         анализ(Строка1,Выражение),         write(Выражение),nl,         _=readchar(),!;         write("Ошибка"),nl,         _=readchar().

Задание 1. Исследовать парсер на различных входных строках и составить описание каждого предиката.

Задание 2. Написать программу для вычисления выражений, не содержащих переменные. Подсказка: вычислитель имеет следующую логику:

вычислитель(число(Число),Число).

вычислитель(плюс(Выраж1,Выраж2),Значение):-

вычислитель(Выраж1,Значение1),вычислитель(Выраж2,Значение2),

Значение = Значение1 + Значение2.

вычислитель(минус(Выраж1,Выраж2),Значение):-

вычислитель(Выраж1,Значение1),вычислитель(Выраж2,Значение2),

Значение = Значение1 - Значение2.

Задание 3. Написать программу символьного дифференцирования. Подсказка: правила дифференцирования описываются так:

дифф(число(_),0).

дифф(перем(_),1).

дифф(степень(перем(X),число(N)),умнож(число(N), степень(перем(X),число(N-1)))).

дифф(sin(перем(X)), cos(перем(X)).

Здесь первый операнд описывает дифференцируемое выражение, второй операнд – дифференциал.

Задание 5. Написать программу преобразования польской записи в инфиксную запись.

Задание 4. Написать программу символьного интегрирования.

Соседние файлы в папке Лабораторные работы