Встроенные
функции.
Введем встроенные функции. БНФ таперь имеет такой вид:
<expr> := <term>
{<add_op><term>}
<term> :=
<signed_factor>{<mul_op><signed_factor>}
<signed_factor> :=
[<add_op>]<factor>
<factor> :=
<float>|”<string>”|(<expr>)|<funcname>([<expr>{,<expr>}])
Далее можно описать, какие же будут функции (funcname). Но мы введем эти функции уже «на словах».
Это StrToDbl(str). Аргумент – строка,
то-есть должен быть в скобках. Если эта строка представляет собой
действительное число, то функция возвратит числовое значение (как раз это
число). Пример использования:
2.3+StrToDbl(“1.1”)
Далее функция
CharToStr(float). Ее аргумент – действительное число (которое она,
кстати, округляет до целого). Далее она возвращает строку из одного символа с
Аски-кодом, соответствующим округленному числу на входе. Пример:
“AAA ”+CharToStr(34)+”123”+CharToStr(34)
Это, кстати, единственный способ ввести в качестве строки кавычки. Напомню, что если вводить их обычным образом
“ABC”
то сканер воспримет кавычки как границы строки и отбросит.
DblToStr(float) – эта функция наоборот число превращает в строку. Тут, кстати, в некоторых случаях возможно появление десятичной точки и нулей после нее.
Пример:
DblToStr(-5*10)
Даст строку –50 ,
А
DblToStr(-5*10)+”H”
Даст
–50.000000H
Для нейтрализации таких эффектов можно применять следующую функцию – округление до N знаков после десятичной точки. И на входе (первый параметр), и на выходе строки. Второй параметр на выходе – число (он сам округляется при работе функции до целого).
Пример:
RoundStr(DblToStr(-5*10),0)+”H”
Даст –50H
И, наконец, пятая функция – запись в файл. На входе 2 строки (в кавычках): первая – имя файла, вторая – строка, которую запишем (причем добавятся и байты 13,10, то-есть получим текстовый файл). На выходе – число записанных байт (не считая 2-х конечных – 13 и 10).
StrToFile(FileName,Str)
Довольно легко ввести новую функцию. При этом «вставки» в программу будут в 4-х местах:
1.В начале (задание имени функции)
2.В функции fact (лексический разбор)
3.В начале функции PostFix (определение знак – не знак)
4.Ближе к концу ф-ии PostFix (обработка польской строки).
При обработке польской строки (ОПЗ) имеется определенная аналогия между обработкой знака (бинарного или унарного) и обработкой функции (см. конкретнее программу).
Нужно заметить еще, что при обработке польской строки первый параметр, который мы достанем из стека (нашего, программного), будет соответствовать последнему аргументу функции.
Скажу честно, проверено на данном этапе (14 ноября 2006 года) лишь наличие у функций одного и двух параметров. Если при других количествах параметров «вылезут» ошибки, подправим.
Вот сама программа:
#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
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();
/**************************************************************/
/*******************/
/**************************************************************/
/******************************/
/*
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==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==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==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;
}
/***/ /* Теперь - односимвольные */
*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();
expr();
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)
{
expr();
}
while(iF>1)
{
iF--;
if(*Lex!=44)
{
ErrorLex(6); /* Не запятой в функции */
return;
}
NextLexema();
expr();
}
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)
{
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 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,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)
{
/****/
*sF1=0;
*sF2=0;
*sF3=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;
}
}
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)
{
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(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();
expr(); /* Это вход в разбор формулы */
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;
}
Этот проект – в папке Gramm6_002.