if(operation==6 && (state==80 || state==81)) //встретили op1+op2 в присваивании
{
fprintf(out,"add ax,%s ;add operands\n",lexem); //складываем операнды, результат - в ax
fprintf(out,"mov [bx],ax ;write to variable\n",lexem); //помещаем результат по адресу присваиваимой переменной
}
if(operation==5 && (state==80 || state==81)) //встретили op1-op2 в присваивании
{
fprintf(out,"sub ax,%s ;subtract operands\n",lexem); //вычитаем операнды, результат - в ax
fprintf(out,"mov [bx],ax ;write to variable\n",lexem); //помещаем результат по адресу присваиваимой переменной
}
if(state==79) //встретили op1 в присваивании
{
fprintf(out,"mov [bx],ax ;write to variable\n",while_level);
}
if(state==90) //встретили op1 в условии
{
fprintf(out,"test ax,ax\n"); //проверяем результат на равенство нулю
fprintf(out,"jz end%d%d\n",while_level,while_number);
fprintf(out,";body of the loop\n");
}
if(while_level && (state==33 || state==43 || state==53 || state==61)) //генерируем остальную часть кода для всех вложенных while
{
while(while_level) //заканчиваем все while
{
fprintf(out,";end of the loop\n");
fprintf(out,"jmp start%d%d\n",while_level,while_number); //переход на проверку условия
fprintf(out,"\n\tend%d%d: ;end of while\n",while_level,while_number); //метка конца цикла
while_level--;
}
while_number++;
}
if(state==29 || state==39 || state==49 || state==57) //встретили начало операции присваивания
{
fprintf(out,"mov bx,offset %s ;beginning of id=A;\n",lexem); //в bx помещаем адрес левой части присваивания
}
if(state==71 || state==73) //встретили начало присваиваемого выражения
{
fprintf(out,"mov ax,%s ;first operand\n",lexem); //в ax помещаем значение переменной или константы
}
fflush(out);
}
//--------------------------------------------------------------------------void syntax_analyzer::print_error(FILE *out){
if(state==2 || state==7 || state==5 || state==10)fprintf(out,"\nОжидается while или присваивание!\n");
if(state==24)fprintf(out,"\nОжидается идентификатор или константа!\n");
if(state==26 || state==36 || state==47 || state==55)fprintf(out,"\nОжидается (!\n");
if(state==65 || state==69)fprintf(out,"\nОжидается )!\n");
if(state==65 || state==69)fprintf(out,"\nОжидается )!\n");
else fprintf(out,"\nНеопознанная ошибка!\n");
}
//--------------------------------------------------------------------------void syntax_analyzer::analyze(char *filein,char *fileout){
FILE *in,*out;
int b,c;
int i,tmp,tmp2;
int type; //тип лексемы, определяется номером таблицы
in=fopen(filein,"r");
out=fopen(fileout,"w");
fscanf(in,"%d %d %d %19s",&type,&b,&c,lexem);
generate_code(out);
while(!feof(in) && !error)//до конца файла или до ошибки
{
if(accepted)
{
fscanf(in,"%d %d %d %s",&type,&b,&c,lexem); //если предыдущая лексема обработана, считать следующую
accepted=0;
}
if(!feof(in))
{
//type: 1 - переменная 2- константа, 3 - ключевое слово, 4 - разделитель
//переменная, ищем id в списке терминалов, до 5 терминалов
tmp=(type==1);
for(i=0,tmp2=0;i<TERMINAL_NUM;i++)tmp2=tmp2 || strcmp("id\0",analyze_table[state].terminals[i])==0;
tmp=tmp && tmp2;
//константа, ищем const в списке терминалов
for(i=0,tmp2=0;i<TERMINAL_NUM;i++)tmp2=tmp2 || strcmp("const\0",analyze_table[state].terminals[i])==0;
tmp=tmp || (tmp2 && type==2);
//ключевое слово или разделитель, проверяем буквальное совпадение по списку терминалов
for(i=0,tmp2=0;i<TERMINAL_NUM;i++)tmp2=tmp2 || strcmp(lexem,analyze_table[state].terminals[i])==0;
tmp=tmp || tmp2;
if(tmp) //если текущая лексема есть в списке терминалов текущего состояния
{
if(analyze_table[state].accept)accepted=1; //можно ли принять текущую лексему?
if(analyze_table[state].ret) //если только что закончили вывод нетерминала
{
if(stack[0]) //если стек не пуст
{
state=stack[0]; //переходим к состоянию из стека
for(i=0;stack[i]!=0;i++)stack[i]=stack[i+1]; //обновляем стек
}
}
else //иначе переходим к состоянию из поля jump
{
if(analyze_table[state].stack) //если требуется положить следующее состояние в стек
{
//обновляем стек
i=0;
while(stack[i]!=0)i++;
for(;i>0;i--) stack[i+1]=stack[i];
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.