<litem> à <lfactor> & {G2} <lfactor2>
<litem> à <lfactor>
<lfactor2> à <lfactor> {G3} & {G2} <lfactor2>
<lfactor2> à <lfactor> {G3}
<lfactor> à <arithm> < {G2} <arithm> {G3}
<lfactor> à <arithm> > {G2} <arithm> {G3}
<lfactor> à <arithm> = {G2} <arithm> {G3}
<lfactor> à <arithm> <= {G2} <arithm> {G3}
<lfactor> à <arithm> >= {G2} <arithm> {G3}
<lfactor> à <arithm> <> {G2} <arithm> {G3}
<arithm> à <item> + {G2} <item2>
<arithm> à <item> - {G2} <item2>
<arithm> à <item>
<item2> à <item> {G3}+ {G2} <item2>
<item2> à <item> {G3}- {G2} <item2>
<item2> à <item> {G3}
<item> à <factor> * {G2} <factor2>
<item> à < factor> / {G2} < factor 2>
<item> à < factor>
<factor2> à <factor> {G3} * {G2} <factor2>
<factor2> à <factor> {G3} / {G2} <factor2>
<factor2> à <factor> {G3}
<factor> à <prim> ** {G2} <factor> {G3} //возведение в степень
<factor> à <prim>
<prim> à - {G2} <prim> {G3}
<prim> à ! {G2} <prim> {G3}
<prim> à F {G2} (<expr>){G3} //функция одной переменной
<prim> à D {G2} (<expr>,<expr>){G3} //функция двух переменных
<prim> à (<expr>)
<prim> à l {G1}
И наконец, изменения в тексте программы
#include <stdio.h>
. . .
char stack[80], *top, /* стек знаков операций */
ibuf[80], *pr, /* входной буфер */
obuf[80], *pw; /* выходной буфер */
void expr(void), litem(void), lfactor(void),
operand(void), arithm(void),
item(void), item2(void), factor(void),
factor2(void), prim(void), ident(void);
. . .
item();
if (*pr=='+' || *pr=='-'){
*top++ = *pr++;
item2();
}
Головная процедура
. . .
strcpy(ibuf,Edit1->Text.c_str());
pr=ibuf; pw=obuf; top=stack;
expr();
*pw='\0';
Edit2->Text= obuf;
. . .
void expr(void){
litem();
if (*pr=='|'){
*top++ = *pr++;
litem2();
}
}
void litem2(void){
litem();
*pw++=*--top;
if (*pr=='|'){
*top++ = *pr++;
litem2();
}
}
void litem(void){
lfactor();
if (*pr=='&'){
*top++ = *pr++;
lfactor2();
}
}
void lfactor2(void){
lfactor();
*pw++=*--top;
if (*pr=='&'){
*top++ = *pr++;
lfactor2();
}
}
void lfactor(void){
arithm();
if (*pr =='='|| *pr=='#'|| *pr=='>'|| *pr=='<'){
*top++ = *pr++;
arithm();
*pw++ = *--top;
}
}
void arithm(void){
item();
if (*pr=='+' || *pr=='-'){
*top++ = *pr++;
item2();
}
}
void item2(void){
item();
*pw++ = *--top;
if (*pr=='+' || *pr=='-'){
*top++ = *pr++;
item2();
}
}
void item(void){
factor();
if (*pr=='*' || *pr=='/'){
*top++ = *pr++;
factor2();
}
}
void factor2(void){
factor();
*pw++ = *--top;
if (*pr=='*' || *pr=='/'){
*top++ = *pr++;
factor2();
}
}
void factor(void){
prim();
if (*pr=='^'){
*top++ = *pr++;
factor();
*pw++ = *--top;
}
}
void prim(void){
if (*pr=='-'){
*top++ = '_'; pr++; //меняем минус - на унарный минус _
prim();
*pw++ = *--top;
}else
if (*pr=='!'){
*top++ = *pr++;
prim();
*pw++ = *--top;
}else
if (*pr=='('){
pr++;
expr();
if(*pr==')') pr++;
else ErrMes("Нарушен баланс скобок");
}else
if (*pr=='F'){
*top++ = *pr++;
if(*pr=='(') {pr++;
expr();
if(*pr==')'){ pr++;*pw++ = *--top;}
else ErrMes ("Нарушен баланс скобок");
} else ErrMes ("Нет отрывающей скобки");
}else
if (*pr=='D'){
*top++ = *pr++;
if(*pr=='('){ pr++;
expr();
if(*pr==','){
pr++;
expr();
if(*pr==')'){ pr++; *pw++ = *--top;}
else ErrMes ("Нарушен баланс скобок");
} else ErrMes ("Нет запятой");
} else ErrMes ("Нет открывающей скобки");
}else
if( isalpha(*pr) || isdigit(*pr)) *pw++ = *pr++;
ErrMes ("Неверный операнд");
}
#define G1 FPRT; NS
#define G2 *top++=symbol; NS
#define G3 fprintf(out,"%02d ",*--top);pos=sprintf(postr,"%02d ",*top);postr+=pos
Вместо
*pr=='*'
писать
symbol==MUL и т.д.
Ввести глобальные переменные
int stack[80], *top;
и перед вызовом
Snt();
вставить
top=stack;
Еще один пример: реализация функций, у которых аргументом является список из двух и более элементов.
. . .
<prim> à - {G2} <prim> {G3}
<prim> à ! {G2} <prim> {G3}
<prim> à F {G2} (<expr>){G3} //функция одной переменной
<prim> à D {G2} (<expr>,<expr>){G3} //функция двух переменных
<prim> à M {G2} (<expr>,<listexpr>){G32} //функция двух и более переменных
<prim> à (<expr>)
<prim> à l {G1}
. . .
<listexpr> à <expr>{G31}, (<listexpr> | <expr>){G31}
void prim(void){
if (*pr=='M'){
*top++=*pr++;
if(*pr=='('){ pr++; expr();
if (*pr==','){pr++; listexpr();
if(*pr==')'){ pr++; --top;
}
}
}
}else . . .
}
void listexpr(void){
expr();
*pw++=*(top-1);
if(*pr==','){
pr++;
listexpr();
}
}
Здесь:
#define G1 *pw++=*pr++
#define G2 *top++=*pr++
#define G3 * pw++=*--top
#define G31 * pw++=*(top-1)
#define G32 --top
Для КП:
#define G1 FPRT; NS
#define G2 *top++=symbol; NS
#define G3 fprintf(out,"%02d ",*--top);pos=sprintf(postr,"%02d ",*top);postr+=pos
#define G31 fprintf(out,"%02d ",*(top-1));pos=sprintf(postr,"%02d ",*(top-1));postr+=pos
#define G32 top--
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.