Сравнения
и логические операции.
Теперь введем сравнения как бинарные операции. То-есть, если то, что мы записали, истинно, то результат операции 1. Если же ложно, то результат – 0.
Пример (операция =) –
1=1
результат – 1
А 1=3
результат – 0.
Аналогично другие бинарные операции сравнения:
<
>
<=
>=
!= (не равно).
Введем также логические операции: унарную ! и бинарные || и && (НЕ,ИЛИ и И) . Смысл их такой же, как у аналогичных операций языка Си.
Если операнды операции || оба равны 0, то результат – 0. Иначе – 1.
Если хотя бы один операнд операции && равен 0, то результат – 0. Иначе – 1.
Ну а насчет операции ! – если единственный операнд равен 0, то результат – 1. Иначе – 0.
Действуют эти операции только на числа, не на строки (в БНФ это никак не отражено, контроль типов – при обработке ОПЗ).
Приведем БНФ:
<expr2> := <expr1> {<бинарная, логическая><expr1>}
<expr1> := <expr> {<операция сравнения><expr>}
<expr> := <term>
{<add_op><term>}
<term> :=
<signed_factor>{<mul_op><signed_factor>}
<signed_factor> := [<add_op или лог-е отрицание>]<factor>
<factor> :=
<float>|”<string>”|(<expr2>)|<funcname>([<expr2>{,<expr2>}])
Теперь – исходник программы (пришлось, кстати, немного и сканер подправить):
#include
<stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "Str_ex.h"
#include "QnS.h"
int
I=0;
int
n=5;
char Lex[150]; /* Это для лексем */
char Res[250]; /* Это для результирующей постфиксной
польской строки */
char End[3]; /* Это конец строки в текстовом файле */
/* Переменные относятся к сканеру */
char Prog[64000]; /* Это для текста программы */
char *pProg; /* Указатель, двигающийся по строке программы */
char LastLex[150]; /* Это для последней лексемы */
char *pProgLast; /* Здесь указатель на начало последней
полученной лексемы */
char *pProgLast2;
/**********************************/
char DelimPol[2]; /* Разделитель в стеке */
char S1[150];
char
*pRes;
char
Sign1[2]={43,0}; /* плюс */
char
Sign2[2]={45,0}; /* минус */
char
Sign3[2]={42,0}; /* умнож-е */
char
Sign4[2]={47,0}; /* деление */
char
Sign5[3]={43,85,0}; /* унарный плюс +U
*/
char
Sign6[3]={45,85,0}; /* унарный минус -U
*/
char
Sign7[2]={61,0}; /* равно */
char
Sign8[2]={60,0}; /* меньше < */
char
Sign9[2]={62,0}; /* больше > */
char
Sign10[2]={33,0}; /* лог.отр-е */
char Sign10_1[3]={33,85,0}; /* лог.отр-е с "постфиксом" U (признак унарности)*/
char Sign11[3]={60,61,0}; /* меньше или равно <= */
char Sign12[3]={62,61,0}; /* больше или равно >= */
char Sign13[3]={33,61,0}; /* не равно */
char Sign14[3]={124,124,0}; /* ИЛИ */
char
Sign15[3]={38,38,0}; /* И */
/*
Имена функций */
char
sFunc1[9]={'S','t','r','T','o','D','b','l',0};
char
sFunc2[]="CharToStr";
char
sFunc3[]="DblToStr";
char
sFunc4[]="RoundStr";
char
sFunc5[]="StrToFile";
/* Конец имен функций */
void expr();
void expr1();
void expr2();
/**************************************************************/
/*******************/
/**************************************************************/
/******************************/
/* sprintf(A,"n=%d",n);*/
/******************************/
int is_Space(int S) /* Является ли знак
пробелом,концом строки,таб-й? */
{
if(S==32|| /* Пробел */
S==10|| /* Перевод строки */
S==13|| /* Возврат каретки */
S==9|| /* Табуляция */
S==11|| /* Верт.табуляция */
S==25) /* Конец носителя */
{
return
1;
}
else
{
return
0;
};
}
int is_Alpha(int S) /* Является ли знак
лат.буквой или _ (подчеркиванием)? */
{
if((S>=65&&S<=90)||
(S>=97&&S<=122)||
S==95)
{
return
1;
}
else
{
return
0;
};
}
int isDelim(int S) /* Является ли знак разделителем, */
{
if(S==43|| /* - */
S==45|| /* + */
S==42|| /* * */
S==47|| /* / */
S==37|| /* % */
S==61|| /* = */
S==60|| /* < */
S==62|| /* > */
S==59|| /* ; */
S==40|| /* ( */
S==41|| /* ) */
S==33|| /* ! */
S==44|| /* , */
S==124|| /* | - новая (для лог.)*/
S==38|| /* & - новая (для лог.)*/
S==46)
/* . */
{
return
1;
}
else
{
return 0;
};
}
int isDelim1(int S,int SNext) /* Является ли знак разделителем, плюс
учет того, что если после точки цифра, то точка уже не разделитель
(чтобы действительное число с дробной точкой не разбивалось) */
{
if(S==43|| /* - */
S==45|| /* + */
S==42|| /* * */
S==47|| /* / */
S==37|| /* % */
S==61|| /* = */
S==60|| /* < */
S==62|| /* > */
S==59|| /* ; */
S==40|| /* ( */
S==41|| /* ) */
S==33|| /* ! */
S==44|| /* , */
S==124|| /* | - новая (для лог.)*/
S==38|| /* & - новая (для лог.)*/
S==46)
/* . */
{
if(S=='.')
{
if(isdigit(SNext)!=0)
{
return 0;
}
else
{
return
1;
};
}
else
{
return 1;
};
}
else
{
return
0;
};
}
void
ErrorScaner(int N)
{
;
if(N==1) WrStr("Err_sc.txt",End,"Unknown Sign - 1-st in
Lexema! ",1);
if(N==2) WrStr("Err_sc.txt",End,"No 2-nd quota",1);
return;
}
void
NextLexema() /* Получает очередную лексему */
{
char *pLex=(char *)Lex;
if(*pProg==0) /* Если на входе пустая строка */
{
*pLex=0;
return;
}
/* Сохраняем положение указателя на позицию
в тексте программы (если вдруг придется
возвращаться назад): */
pProgLast2=pProgLast;
pProgLast=pProg;
*pLex=0; /* Для борьбы с "последней лексемой" */
while(is_Space(*pProg)) ++pProg; /* Убираем лидирующие пробелы */
if(*pProg==47&&*(pProg+1)==42) /* Обработка комментария */
{
pProg++;
pProg++;
while(!(*pProg==42&&*(pProg+1)==47))
{
if(*pProg==0) return;
pProg++;
}
pProg++;
pProg++;
/*return;*/
}
while(is_Space(*pProg)) ++pProg; /*
Убираем пробелы после комментария */
if(*pProg==45|| /* - */
*pProg==43|| /* + */
*pProg==42|| /* * */
*pProg==47|| /* / */
*pProg==37|| /* % */
*pProg==61|| /* = */
*pProg==60|| /* < */
*pProg==62|| /* > */
*pProg==59|| /* ; */
*pProg==40|| /* ( */
*pProg==41|| /* ) */
*pProg==33|| /* ! */
*pProg==44|| /* , */
*pProg==124|| /* | - новая (для лог.)*/
*pProg==38|| /* & - новая (для лог.)*/
*pProg==46) /* . */
{ /* Это мы рассматриваем знаки */
/***/ /* Обработка двухсимвольных знаков */
if(*pProg==60&&*(pProg+1)==61)
{
*pLex=*pProg;
pProg++;
pLex++;
*pLex=*pProg;
pProg++;
pLex++;
*pLex=0;
return;
}
if(*pProg==62&&*(pProg+1)==61)
{
*pLex=*pProg;
pProg++;
pLex++;
*pLex=*pProg;
pProg++;
pLex++;
*pLex=0;
return;
}
if(*pProg==60&&*(pProg+1)==62)
{
*pLex=*pProg;
pProg++;
pLex++;
*pLex=*pProg;
pProg++;
pLex++;
*pLex=0;
return;
}
if(*pProg==33&&*(pProg+1)==61)
{
*pLex=*pProg;
pProg++;
pLex++;
*pLex=*pProg;
pProg++;
pLex++;
*pLex=0;
return;
}
/* Еще 2-символьные */
if(*pProg==124&&*(pProg+1)==124)
{
*pLex=*pProg;
pProg++;
pLex++;
*pLex=*pProg;
pProg++;
pLex++;
*pLex=0;
return;
}
if(*pProg==38&&*(pProg+1)==38)
{
*pLex=*pProg;
pProg++;
pLex++;
*pLex=*pProg;
pProg++;
pLex++;
*pLex=0;
return;
}
/***/ /* Теперь - односимвольные */
*pLex=*pProg;
pProg++;
pLex++;
*pLex=0;
return;
}
if(*pProg==34) /* Обработка выражения в кавычках */
{
*pLex=34;
pProg++;
pLex++;
while(*pProg!=34)
{
if(*pProg==0)
{
ErrorScaner(2);
return;
}
*pLex++=*pProg++;
}
pProg++;
/*
*pLex=34;
pLex++;
*/
*pLex=0;
return;
}
if(isdigit(*pProg)) /* Начинаем рассматривать число */
{
int k=0;
while(k>-1)
{
if(*pProg==0)
{
*pLex=0;
return;
}
/*if(*pProg==13)
{
*pLex=0;
return;
}
if(*pProg==10)
{
*pLex=0;
return;
}*/
if(is_Space(*pProg)==1)
{
*pLex=0;
return;
}
if(isDelim1(*pProg,*(pProg+1))==1)
{
*pLex=0;
return;
}
*pLex=*pProg;
pLex++;
pProg++;
}
}
if(is_Alpha(*pProg)) /* Начинаем рассматривать имя переменной или
ключевое слово языка */
{
int k=0;
while(k>-1)
{
if(*pProg==0)
{
*pLex=0;
return;
}
/*if(*pProg==13)
{
*pLex=0;
return;
}
if(*pProg==10)
{
*pLex=0;
return;
}*/
if(is_Space(*pProg)==1)
{
*pLex=0;
return;
}
if(isDelim(*pProg)==1)
{
*pLex=0;
return;
}
*pLex=*pProg;
pLex++;
pProg++;
}
}
if(!(is_Space(*pProg)!=0||*pProg==0))
ErrorScaner(1);
pProg++;
return;
}
/* Конец "сканерной" части */
void ErrorLex(int N)
{
if(N==1)
{
WrStr("err_lex.txt",End," ",1);
WrStr("err_lex.txt",End,"No
Bracket! ",1);
WrStr("err_lex.txt",End,"---",1);
};
if(N==2)
{
WrStr("err_lex.txt",End," ",1);
WrStr("err_lex.txt",End,"ERROR
- 0-lexema, probably phrase is not finished! ",1);
WrStr("err_lex.txt",End,"---",1);
};
if(N==3)
{
WrStr("err_lex.txt",End," ",1);
WrStr("err_lex.txt",End,"ERROR
- Wrong lexema! ",1);
WrStr("err_lex.txt",End,"---",1);
};
if(N==4)
{
WrStr("err_lex.txt",End," ",1);
WrStr("err_lex.txt",End,"ERROR
- Last lexema exists! ",1);
WrStr("err_lex.txt",End,"---",1);
};
if(N==5)
{
WrStr("err_lex.txt",End," ",1);
WrStr("err_lex.txt",End,"ERROR
- Long string! ",1);
WrStr("err_lex.txt",End,"---",1);
};
if(N==6)
{
WrStr("err_lex.txt",End," ",1);
WrStr("err_lex.txt",End,"ERROR
- No comma in function! ",1);
WrStr("err_lex.txt",End,"---",1);
};
if(N==7)
{
WrStr("err_lex.txt",End," ",1);
WrStr("err_lex.txt",End,"ERROR
- No 2-nd bracket OR too many p-s in function! ",1);
WrStr("err_lex.txt",End,"---",1);
};
}
void fact() /* Это множитель - конечный пункт рекурсии */
{
int iF;
char ResF1[50];
char Lex_1[50];
*ResF1=0;
*Lex_1=0;
if(*Lex==40)
{
NextLexema();
expr2();
if(*Lex!=41)
{
*Res=0;
/*sprintf(Res,"Lexema: %d
",J-1);
StrCat("ERROR - No Bracket
!!! ",Res);*/
ErrorLex(1);
}
else
{
NextLexema();
}
}
else
{
if(testnum_p(Lex)==0&&(*Lex>47&&*Lex<58)) /* Проверка - является ли действ. числом */
{
StrCat(Lex,Res);
StrCat(DelimPol,Res); /* Добавляем разделитель в стеке */
NextLexema();
}
else
{
if(*Lex==34) /* Кавычка */
{
if(lenstr(Lex)<100) /* Чересчур длинная лексема */
{
StrCat(Lex,Res);
StrCat(DelimPol,Res);
}
else
{
ErrorLex(5);
}
NextLexema();
}
else
{
if(*Lex==0)
{
*Res=0;
/*sprintf(Res,"Lexema: %d
",J-1);
StrCat("ERROR - 0-lexema,
probably phrase is not finished!
",Res);*/
ErrorLex(2);
}
else
{
if(*Lex>=65&&*Lex<=90) /* Переменная или функция */
{
StrCat(Lex,ResF1);
StrCat(Lex,Lex_1);
NextLexema();
if(*Lex==40) /* Значит похоже на функцию */
{
/* Сравниваем с именами существ. функций */
if(COMPstr(ResF1,sFunc1)==0)
{
iF=1;
}
if(COMPstr(ResF1,sFunc2)==0)
{
iF=1;
}
if(COMPstr(ResF1,sFunc3)==0)
{
iF=1;
}
if(COMPstr(ResF1,sFunc4)==0)
{
iF=2;
}
if(COMPstr(ResF1,sFunc5)==0)
{
iF=2;
}
/* Конец сравн-я с именами существ. функций */
NextLexema();
if(iF>0)
{
expr2();
}
while(iF>1)
{
iF--;
if(*Lex!=44)
{
ErrorLex(6); /* Не запятой в функции */
return;
}
NextLexema();
expr2();
}
if(*Lex!=41)
{
ErrorLex(7); /* Нет 2-й скобки в функции (или слишком много пар-в) */
return;
}
else
{
StrCat(ResF1,Res); /* пишем в результ.строку имя функции */
StrCat(DelimPol,Res);
*Lex=0;
NextLexema();
}
;
}
else
{
/* Просто переменная */
StrCat(ResF1,Res);
StrCat(DelimPol,Res);
}
}
else
{
*Res=0;
/*sprintf(Res,"Lexema: %d
",J-1);
StrCat("ERROR - Wrong lexema! ",Res);*/
ErrorLex(3);
}
}
}
};
};
}
void sfact() /* Это множитель со знаком (унарным) */
{
char
Lex1[150];
Lex1[0]=0;
if(*Lex==43||*Lex==45||*Lex==33)
{
CpStr(Lex,Lex1);
NextLexema();
}
fact();
if(*Lex1!=0)
{
StrCat(Lex1,Res);
StrCat("U",Res);
StrCat(DelimPol,Res);
}
}
void term() /* Обработка умножения-деления */
{
char
Lex1[150];
Lex1[0]=0;
sfact();
while(*Lex==42||*Lex==47)
{
CpStr(Lex,Lex1);
NextLexema();
sfact();
StrCat(Lex1,Res);
StrCat(DelimPol,Res);
}
}
void expr() /* Обработка сложения-вычитания */
{
char
Lex1[150];
Lex1[0]=0;
term();
while(*Lex==43||*Lex==45)
{
CpStr(Lex,Lex1);
NextLexema();
term();
StrCat(Lex1,Res);
StrCat(DelimPol,Res);
}
}
void expr1() /* Обработка сравнений */
{
char
Lex1[150];
Lex1[0]=0;
expr();
/*while(COMPstr("+",Lex)==0||COMPstr("+",Lex)==0)*/
while(*Lex==60||*Lex==61||*Lex==62||*Lex==33)
{
CpStr(Lex,Lex1);
NextLexema();
expr();
StrCat(Lex1,Res);
StrCat(DelimPol,Res);
}
}
void expr2() /* Обработка логических операций */
{
char
Lex1[150];
Lex1[0]=0;
expr1();
/*while(COMPstr("+",Lex)==0||COMPstr("+",Lex)==0)*/
while(*Lex==124||*Lex==38)
{
CpStr(Lex,Lex1);
NextLexema();
expr1();
StrCat(Lex1,Res);
StrCat(DelimPol,Res);
}
}
/********************************/
/* Обработка строки с польской обратной
записью */
void
ErrorStack(int N)
{
if(N==-2)
{
WrStr("err_st.txt",End," ",1);
WrStr("err_st.txt",End,"Empty
Stack! ",1);
};
if(N==-3)
{
WrStr("err_st.txt",End," ",1);
WrStr("err_st.txt",End,"Stack
Error - Adding! ",1);
};
if(N==-4)
{
WrStr("err_st.txt",End," ",1);
WrStr("err_st.txt",End,"Stack
Error - getting (1)! ",1);
};
if(N==-5)
{
WrStr("err_st.txt",End," ",1);
WrStr("err_st.txt",End,"Stack
Error - getting (2)! ",1);
};
if(N==-6)
{
WrStr("err_st.txt",End," ",1);
WrStr("err_st.txt",End,"Stack
Error - Adding! ",1);
};
if(N==-7)
{
WrStr("err_st.txt",End," ",1);
WrStr("err_st.txt",End,"Stack Error - getting in the end! ",1);
};
/* Ощибки с действиями */
if(N==-8)
{
WrStr("err_st.txt",End," ",1);
WrStr("err_st.txt",End,"+
No number! ",1);
};
if(N==-9)
{
WrStr("err_st.txt",End," ",1);
WrStr("err_st.txt",End,"-
No number! ",1);
};
if(N==-10)
{
WrStr("err_st.txt",End," ",1);
WrStr("err_st.txt",End,"*
No number! ",1);
};
if(N==-11)
{
WrStr("err_st.txt",End," ",1);
WrStr("err_st.txt",End,"/
No number! ",1);
};
if(N==-12)
{
WrStr("err_st.txt",End," ",1);
WrStr("err_st.txt",End,"+(unar)
No number! ",1);
};
if(N==-13)
{
WrStr("err_st.txt",End," ",1);
WrStr("err_st.txt",End,"Wrong
type in function (inline)! ",1);
}; return;
}
int
iPF=1;
int
PostFix(char *S,char *Dest)
{
void * pSt;
char St[100];
int i,res;
int iPF1;
int iPF2;
int iPF3;
char *S1;
void *pS1;
/*char S2[50];
char S3[50];
char S4[100];*/
int r=0;
double F1,F2,F3; /* Для действий с числами */
char sF1[100]; /* Для работы со строками */
char sF2[100];
char sF3[100];
char sF2_1[100]; /* Для выч-я строк */
int l1;
int isStr1,isStr2; /* Для контроля типов */
int iL1;
if(*S==0)
{
ErrorStack(-2);
return -2;
}
sF1[0]=0;
sF2[0]=0;
sF3[0]=0;
int iStrW=0; /* Если 0, результат - число (тоже конт.типов)*/
pS1=malloc(100);
if(pS1==NULL)
{
return
-1;
}
S1=(char *)pS1;
*S1=0;
/*WrStr("PostFix.txt",End,"Coming",1);*/
pSt=CreateStack(10000);
while(iPF>0)
{
/*WrStr("PostFix.txt",End,"Cycle",1);*/
iPF1=CpWordN(S,S1,DelimPol[0],iPF);
/* Использ. разд-ль в стеке */
if(iPF1<0)
{
break;
}
iPF++;
if(!(COMPstr(S1,Sign1)==0||COMPstr(S1,Sign2)==0||
COMPstr(S1,Sign3)==0||COMPstr(S1,Sign4)==0||
COMPstr(S1,Sign5)==0||COMPstr(S1,Sign6)==0||
/* Новые знаки - сравнение и логические */
COMPstr(S1,Sign7)==0||COMPstr(S1,Sign8)==0||
COMPstr(S1,Sign9)==0||COMPstr(S1,Sign10_1)==0||
COMPstr(S1,Sign11)==0||COMPstr(S1,Sign12)==0||
COMPstr(S1,Sign13)==0||COMPstr(S1,Sign14)==0||
COMPstr(S1,Sign15)==0
/* функции (встроенные) */
||COMPstr(S1,sFunc1)==0
||COMPstr(S1,sFunc2)==0
||COMPstr(S1,sFunc3)==0
||COMPstr(S1,sFunc4)==0
||COMPstr(S1,sFunc5)==0
))
/* Если символ не знак, помещаем в стек */
{
for(i==0;i<100;i++)
*(St+i)=0;
CpStr(S1,St);
res=AddArrayToStackNoPart(pSt,St,100);
if(res!=100)
{
r=-3;
ErrorStack(-3);
}
}
else /* Если символ - знак */
{
if(COMPstr(S1,Sign1)==0||COMPstr(S1,Sign2)==0
||COMPstr(S1,Sign3)==0||COMPstr(S1,Sign4)==0
/* Теперь - дополн-е (сравнение и логика) */
||COMPstr(S1,Sign7)==0||COMPstr(S1,Sign8)==0
||COMPstr(S1,Sign9)==0||COMPstr(S1,Sign11)==0
||COMPstr(S1,Sign12)==0||COMPstr(S1,Sign13)==0
||COMPstr(S1,Sign14)==0||COMPstr(S1,Sign15)==0)
{ /* то-есть если бинарный знак */
/****/
*sF1=0;
*sF2=0;
*sF3=0;
F1=0;
F2=0;
F3=0;
/****/
for(i==0;i<100;i++) *(St+i)=0;
res=GetArrayFromStack(pSt,St,100);
if(res!=100)
{
r=-4;
ErrorStack(-4);
}
if(*St!=34)
{
F1=atof(St);
isStr1=0; /* Для контроля типов */
}
else
{
CpStr(St+1,sF1);
isStr1=1; /* Для контроля типов */
}
for(i==0;i<100;i++) *(St+i)=0;
res=GetArrayFromStack(pSt,St,100);
if(res!=100)
{
r=-5;
ErrorStack(-5);
}
if(*St!=34)
{
F2=atof(St);
isStr2=0;
}
else
{
CpStr(St+1,sF2);
isStr2=1;
}
if(COMPstr(S1,Sign1)==0) /* Если
сложение */
{
if(isStr1==0&&isStr2==0)
{
F3=F2+F1;
iStrW=0;
}
else
{
if(isStr1==1&&isStr2==1)
{
*sF3=34;
*(sF3+1)=0;
StrCat(sF2,sF3);
StrCat(sF1,sF3);
iStrW=1;
*sF1==0;
*sF2==0;
}
else
{
*sF1=0;
*sF2=0;
*sF3=0;
r=-8;
ErrorStack(-8);
return
r;
}
}
}
if(COMPstr(S1,Sign2)==0) /* Если
вычитание */
{
if(isStr1==0&&isStr2==0)
{
F3=F2-F1;
iStrW=0;
}
else
{
if(isStr1==1&&isStr2==1)
{
*sF3=34;
*(sF3+1)=0;
l1=SearchOnFrag(sF2,sF1);
if(l1==0)
{
CpStrNLast(sF2,sF2_1,lenstr(sF1));
StrCat(sF2_1,sF3);
}
else
{
StrCat(sF2,sF3);
}
iStrW=1;
*sF1==0;
*sF2==0;
}
else
{
*sF1=0;
*sF2=0;
*sF3=0;
r=-9;
ErrorStack(-9);
return
r;
}
}
}
if(COMPstr(S1,Sign3)==0) /* Если
умножение */
{
if(isStr1==0&&isStr2==0)
{
F3=F2*F1;
iStrW=0;
}
else
{
*sF1=0;
*sF2=0;
*sF3=0;
r=-10;
ErrorStack(-10);
return
r;
}
}
if(COMPstr(S1,Sign4)==0) /* Если
деление */
{
if(isStr1==0&&isStr2==0)
{
F3=F2/F1;
iStrW=0;
}
else
{
*sF1=0;
*sF2=0;
*sF3=0;
r=-11;
ErrorStack(-11);
return
r;
}
}
/*****/ /* Обработка новых знаков - сравнения и логических (1-ИСТИНА)*/
if(COMPstr(S1,Sign7)==0) /* Если знак равно */
{
if(isStr1==0&&isStr2==0)
{
if(F1==F2)
F3=1;
else
F3=0;
iStrW=0;
}
else
{
*sF1=0;
*sF2=0;
*sF3=0;
r=-11;
ErrorStack(-11);
return
r;
}
}
if(COMPstr(S1,Sign8)==0) /* Если
знак меньше < */
{
if(isStr1==0&&isStr2==0)
{
if(F1>F2)
F3=1;
else
F3=0;
iStrW=0;
}
else
{
*sF1=0;
*sF2=0;
*sF3=0;
r=-11;
ErrorStack(-11);
return
r;
}
}
if(COMPstr(S1,Sign9)==0) /* Если
знак больше > */
{
if(isStr1==0&&isStr2==0)
{
if(F1<F2)
F3=1;
else
F3=0;
iStrW=0;
}
else
{
*sF1=0;
*sF2=0;
*sF3=0;
r=-11;
ErrorStack(-11);
return r;
}
}
if(COMPstr(S1,Sign11)==0) /* Если знак меньше или равно <= */
{
if(isStr1==0&&isStr2==0)
{
if(F1>=F2)
F3=1;
else
F3=0;
iStrW=0;
}
else
{
*sF1=0;
*sF2=0;
*sF3=0;
r=-11;
ErrorStack(-11);
return r;
}
}
if(COMPstr(S1,Sign12)==0) /* Если знак больше или равно >= */
{
if(isStr1==0&&isStr2==0)
{
if(F1<=F2)
F3=1;
else
F3=0;
iStrW=0;
}
else
{
*sF1=0;
*sF2=0;
*sF3=0;
r=-11;
ErrorStack(-11);
return
r;
}
}
if(COMPstr(S1,Sign13)==0) /* Если
знак не равно */
{
if(isStr1==0&&isStr2==0)
{
if(F1!=F2)
F3=1;
else
F3=0;
iStrW=0;
}
else
{
*sF1=0;
*sF2=0;
*sF3=0;
r=-11;
ErrorStack(-11);
return
r;
}
}
if(COMPstr(S1,Sign14)==0) /* Если
знак ИЛИ || */
{
if(isStr1==0&&isStr2==0)
{
if(F1==0&&F2==0)
F3=0;
else
F3=1;
iStrW=0;
}
else
{
*sF1=0;
*sF2=0;
*sF3=0;
r=-11;
ErrorStack(-11);
return
r;
}
}
if(COMPstr(S1,Sign15)==0) /* Если
знак И && */
{
if(isStr1==0&&isStr2==0)
{
if(F1==0||F2==0)
F3=0;
else
F3=1;
iStrW=0;
}
else
{
*sF1=0;
*sF2=0;
*sF3=0;
r=-11;
ErrorStack(-11);
return
r;
}
}
/*****/
if(iStrW==0)
{
sprintf(St,"%f",F3);
}
else
{
/*
*/
*St=34;
*(St+1)=0;
/*
*/
CpStr(sF3,St);
iStrW=0;
}
/*Кладем результат в стек*/
/* for(i==0;i<100;i++)
*(St+i)=0; */
res=AddArrayToStackNoPart(pSt,St,100);
if(res!=100)
{
r=-6;
ErrorStack(-6);
}
}
if(COMPstr(S1,Sign5)==0||COMPstr(S1,Sign6)==0
||COMPstr(S1,Sign10_1)==0)
{ /* а это если унарные знаки */
for(i==0;i<100;i++) *(St+i)=0;
res=GetArrayFromStack(pSt,St,100);
if(res!=100)
{
r=-4;
ErrorStack(-4);
}
/*F1=atof(St);*/
if(*St!=34)
{
F1=atof(St);
isStr1=0;
}
else
{
CpStr(St+1,sF1);
isStr1=1;
}
if(COMPstr(S1,Sign6)==0) /* Если
унарный минус */
{
/*F3=-F1;*/
if(isStr1==0)
{
F3=-F1;
iStrW=0;
}
else
{
InversStr(sF1,sF3);
iStrW=1;
*sF1=0;
}
}
if(COMPstr(S1,Sign5)==0) /* Если унарный
плюс */
{
/*F3=F1;*/
if(isStr1==0)
{
F3=F1;
iStrW=0;
}
else
{
*sF1==0;
*sF2==0;
*sF3==0;
r=-12;
ErrorStack(-12);
return r;
}
}
/***/ /* новая унарная операция */
if(COMPstr(S1,Sign10_1)==0) /* Если унарное отрицание */
{
if(isStr1==0)
{
if(F1==0)
F3=1;
else
F3=0;
iStrW=0;
}
else
{
*sF1==0;
*sF2==0;
*sF3==0;
r=-12;
ErrorStack(-12);
return
r;
}
}
/***/
if(iStrW==0)
{
sprintf(St,"%f",F3);
}
else
{
*St=34;
*(St+1)=0;
StrCat(sF3,St);
iStrW=0;
}
/*Кладем результат в стек*/
/*for(i==0;i<100;i++)
*(St+i)=0;*/
res=AddArrayToStackNoPart(pSt,St,100);
if(res!=100)
{
r=-6;
ErrorStack(-6);
}
}
/* Теперь - обработка разных функций */
/*****/
if(COMPstr(S1,sFunc1)==0) /* Если функция StrToDbl */
{
/*WrStr("Result.txt",End,"FFF",1); */
for(i==0;i<100;i++) *(St+i)=0;
res=GetArrayFromStack(pSt,St,100);
if(res!=100)
{
r=-4;
ErrorStack(-4);
}
if(*St!=34)
{
/*WrStr("Result.txt",End," No
kavychka",1);*/
isStr1=0;
ErrorStack(-13);
return
r;
}
else
{
/*WrStr("Result.txt",End,"
kavychka!!!",1);*/
CpStr(St+1,sF1);
if(testnum_p(sF1)!=0)
{
r=-13;
ErrorStack(-13);
}
}
F3=atof(sF1);
*sF1=0;
sprintf(St,"%f",F3);
/*Кладем результат в стек*/
/*for(i==0;i<100;i++)
*(St+i)=0;*/
res=AddArrayToStackNoPart(pSt,St,100);
if(res!=100)
{
r=-6;
ErrorStack(-6);
}
}
/*****/
/*****/
if(COMPstr(S1,sFunc2)==0) /* Если функция CharToStr */
{
for(i==0;i<100;i++) *(St+i)=0;
res=GetArrayFromStack(pSt,St,100);
if(res!=100)
{
r=-4;
ErrorStack(-4);
}
if(*St!=34)
{
if(testnum_p(St)!=0)
{
r=-13;
ErrorStack(-13);
}
ROUND(St,sF1,0);
iL1=atol(sF1);
}
else
{
ErrorStack(-13);
return
r;
}
*sF3=(char)iL1;
*(sF3+1)=0;
*St=34;
*(St+1)=0;
StrCat(sF3,St);
/*Кладем результат в стек*/
/*for(i==0;i<100;i++)
*(St+i)=0;*/
res=AddArrayToStackNoPart(pSt,St,100);
if(res!=100)
{
r=-6;
ErrorStack(-6);
}
}
/*****/
/*****/
if(COMPstr(S1,sFunc3)==0) /* Если функция DblToStr */
{
for(i==0;i<100;i++) *(St+i)=0;
res=GetArrayFromStack(pSt,St,100);
if(res!=100)
{
r=-4;
ErrorStack(-4);
}
if(*St!=34)
{
if(testnum_p(St)!=0)
{
r=-4;
ErrorStack(-13);
}
CpStr(St,sF3);
}
else
{
ErrorStack(-13);
return
r;
}
*St=34;
*(St+1)=0;
StrCat(sF3,St);
/*Кладем результат в стек*/
/*for(i==0;i<100;i++)
*(St+i)=0;*/
res=AddArrayToStackNoPart(pSt,St,100);
if(res!=100)
{
r=-6;
ErrorStack(-6);
}
}
/*****/
/*****/
if(COMPstr(S1,sFunc4)==0) /* Если функция RoundStr */
{
/*WrStr("Result.txt",End,"FFF",1); */
/* Берем из стека 1-й пар-р */
for(i==0;i<100;i++) *(St+i)=0;
res=GetArrayFromStack(pSt,St,100);
if(res!=100)
{
r=-4;
ErrorStack(-4);
}
/* */
if(*St!=34)
{
if(testnum_p(St)!=0)
{
r=-13;
ErrorStack(-13);
}
ROUND(St,sF3,0);
F1=atof(sF3);
*sF3=0;
}
else
{
r=-13;
ErrorStack(-13);
return
r;
}
/* */
/* Берем из стека 2-й пар-р */
for(i==0;i<100;i++) *(St+i)=0;
res=GetArrayFromStack(pSt,St,100);
if(res!=100)
{
r=-4;
ErrorStack(-4);
}
if(*St!=34)
{
ErrorStack(-13);
return
r;
}
else
{
CpStr(St+1,sF1);
if(testnum_p(sF1)!=0)
{
r=-13;
ErrorStack(-13);
}
}
ROUND(sF1,sF3,F1);
*St=34;
*(St+1)=0;
StrCat(sF3,St);
/*Кладем результат в стек*/
/*for(i==0;i<100;i++)
*(St+i)=0;*/
res=AddArrayToStackNoPart(pSt,St,100);
if(res!=100)
{
r=-6;
ErrorStack(-6);
}
}
/*****/
/*****/
if(COMPstr(S1,sFunc5)==0) /* Если функция StrToFile */
{
/*WrStr("Result.txt",End,"FFF",1); */
/* Берем из стека 1-й пар-р */
for(i==0;i<100;i++) *(St+i)=0;
res=GetArrayFromStack(pSt,St,100);
if(res!=100)
{
r=-4;
ErrorStack(-4);
}
/* */
if(*St!=34)
{
ErrorStack(-13);
return
r;
}
else
{
CpStr(St+1,sF2);
}
/* */
/* Берем из стека 2-й пар-р */
for(i==0;i<100;i++) *(St+i)=0;
res=GetArrayFromStack(pSt,St,100);
if(res!=100)
{
r=-4;
ErrorStack(-4);
}
if(*St!=34)
{
ErrorStack(-13);
return
r;
}
else
{
CpStr(St+1,sF1);
}
F3=WrStr(sF1,End,sF2,1);
sprintf(St,"%f",F3);
/*Кладем результат в стек*/
/*for(i==0;i<100;i++)
*(St+i)=0;*/
res=AddArrayToStackNoPart(pSt,St,100);
if(res!=100)
{
r=-6;
ErrorStack(-6);
}
}
/*****/
}
}
/*Извлекаем из стека результат*/
for(i==0;i<100;i++) *(St+i)=0;
res=GetArrayFromStack(pSt,St,100);
if(res!=100)
{
r=-7;
ErrorStack(-7);
}
*S1=0;
StrCat(St,S1);
/*WrStr("PostFix.txt",End,"Result
in stack: ",1);
WrStr("PostFix.txt",End,S1,1);*/
/* Конец извлечения результата из стека*/
Del0Last(S1);
/*if(*S1==34)
{
CpStr(S1+1,Dest);
}
else
{
CpStr(S1,Dest);
} Убираем предшеств. кавычку*/
CpStr(S1,Dest);
DeleteStack(pSt);
free(pS1);
return r;
}
/********************************/
/*******************/
void
main(void)
{
Lex[0]=0;
Res[0]=0;
End[0]=13;
End[1]=10;
End[2]=0;
DelimPol[0]=4; /* Задаем разделитель в стеке */
DelimPol[1]=0;
char dest[200];
/* Чтение файла с программой */
/*****/
FILE *f1;
int Ch;
char ch;
int jc,J;
pProg=Prog;
pProgLast=Prog;
pProgLast2=Prog;
f1=fopen("pr_str.txt","rb");
if(f1==NULL)
{
return;
}
jc=0;
J=0;
/* Чтение программы из файла в строку */
while(jc>-1)
{
Ch=fgetc(f1);
if(Ch==EOF)
{
fclose(f1);
break;
};
ch=(char)Ch;
*(pProg+J)=ch;
J++;
}
/*****/
/* Конец чтения файла с программой */
NextLexema();
expr2(); /* Это вход в разбор формулы */
WrStr("Result.txt",End,Res,1); /* Записываем результирующую
польскую постфиксную строку
в файл */
PostFix(Res,dest);
WrStr("Result.txt",End,"А
число:",1);
WrStr("Result.txt",End,dest,1);
/*Lex[0]=0;
NextLexema();*/
if(*Lex!=0) /* Это тоже для борьбы с последней лексемой */
{
WrStr("Result.txt",End,"Last lexema
exists!",1);
WrStr("Result.txt",End,Lex,1);
ErrorLex(4);
}
return;
}
Этот проект – в папке Gramm7_001.