Постановка задачи. Составить программу на Си для лексического анализа программы на модифицированном языке SPL. Вывести в файл "getrez.dan" и на экран таблицу идентификаторов и их адресов.
Программа на модифицированном языке SPL (вычисляет xy)
exp(a,b)
begin int z;
z=1;
while b do
if b%2 then z=z*a end;
a=a*a;b=b/2
end;
return z
end
main()
begin int x,y;
read x;
read y;
print exp(x,y)
#include
/*Коды лексем языка SPL*/
enum{BEGINL=257,ENDL,IFL,THENL,WHILEL,DOL,RETRL,READL,PRITL,INTL,CONSTL,IDEN,NUMB};
int nst=0;
int lval,lex;
static char nch='n';
FILE*PF,*padres;
void get(void);
void number(void);
void word(void);
char*add(char*nm);
void main(int ac,char*av[])
{
clrscr();
if(!ac)
puts("Hет исходного файла");
PF=fopen(av[1],"r");
padres=fopen("getrez.dan","w");
if(!PF)
puts("Файл не открывается");
else
get();
}
void get()
while(nch!=EOF)
while(isspace(nch))
if(nch=='n')
nst++;
nch=getc(PF);
if(isdigit(nch))
number();
if(isalpha(nch))
word();
if(nch=='('||nch==')'||nch==','||nch==';'||nch=='='||nch=='+'||nch=='-'||nch=='*'||nch=='/'||nch=='%')
lex=nch;
if(nch==EOF)
lex=EOF;
puts("Hедопустимый символ");
return;
void number()
for(lval=0;isdigit(nch);nch=getc(PF))
lval=lval*10+nch-'0';
lex=NUMB;
void word()
static int cdl[]={BEGINL,ENDL,IFL,THENL,WHILEL,DOL,RETRL,READL,
PRITL,INTL,CONSTL,IDEN,NUMB};
static char*serv[]={"begin","end","if","then","while","do","return","read",
"print","int","const"};
int i;
char tx[40];
char*p,*add();
for(p=tx;isdigit(nch)||isalpha(nch);nch=getc(PF))
*(p++)=nch;
*p='';
for(i=0;i<11;i++)
if(strcmp(tx,serv[i])==0)
lex=cdl[i];
lex=IDEN;
lval=(int)add(tx);
printf("Адрес для %s =%pn",tx,lval);
fprintf(padres,"Адрес для %s =%pn",tx,lval);
char TNM[400];
char*ptn=TNM;
char*add(char*nm)
char*p,*strcpy();
for(p=TNM;p
if(strcmp(p,nm)==0)
return p;
if((ptn+=strlen(nm)+1)>TNM+400)
puts("Переполнение таблицы");
exit(0);
return(strcpy(p,nm));
Образец результата работы программы
Адрес для exp =0586
Адрес для a =058B
Адрес для b =058D
Адрес для z =058F
и т. д.