Текст программы
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<alloc.h>
#include<stdlib.h>
//--------------------------------------------------------------------------#define STACK_SIZE 5
#define LEXEM_SIZE 20
#define TERMINAL_NUM 5
//--------------------------------------------------------------------------struct analyze_elem{ //элемент таблицы разбора (состояние)
char terminals[TERMINAL_NUM][LEXEM_SIZE]; //терминалы состояния, до 5 возможных терминалов
int jump; //куда перейти?
int accept; //принять лексему?
int stack; //взять из стека?
int ret; //конец вывода нетерминала?
int error; //ошибка?
};
//--------------------------------------------------------------------------//класс синтаксического анализатора
class syntax_analyzer{
private:
int state; //текущее состояние таблицы разбора
int label_num; //число использованных меток
int while_level; //уровень вложенности while, для нумерования меток
int while_number; //число невложенных while, для нумерования меток
int error; //флаг "ошибка"
int accepted; //флаг "принято"
int operation; //вспомогательная переменная
int stack[STACK_SIZE]; //стек, вершина - 0
char lexem[LEXEM_SIZE]; //разбираемая лексема
analyze_elem analyze_table[90]; //таблица разбора
void read_analyze_table(char *filename); //считать таблицу разбора из файла
void print_error(FILE *); //вывести сообщение об ошибке в некотором состоянии анализатора
void generate_code(FILE *out);
public:
syntax_analyzer();
void analyze(char *filein,char *fileout); //выполнить анализ файла лексем
};
//--------------------------------------------------------------------------syntax_analyzer::syntax_analyzer(){
int i;
for(i=0;i<STACK_SIZE;i++)stack[i]=0;
read_analyze_table("table.txt");
state=1; //начальное состояние
error=0;
accepted=0;
while_level=0;
while_number=0;
operation=0;
}
//--------------------------------------------------------------------------void syntax_analyzer::generate_code(FILE *out){
if(state==0) //генерируем объявление переменных
{
fprintf(out,"\n.data\n");
FILE *in;
char str[20];
in=fopen("variables.txt","r");
while(fscanf(in,"%s",str)!=EOF)fprintf(out,"%s dw ?\n",str); //объявляем переменную
fprintf(out,"end start");
fclose(in);
}
if(state==1) //начало
{
fprintf(out,".model small\n.stack 100h\n.code\nstart:\nmov ax,@data\nmov ds,ax\n\n"); //инициализация
}
if(state==63 || state==67) //встретили while
{
while_level++; //увеличить уровень вложенности цикла
fprintf(out,"\n\tstart%d%d:\n",while_level,while_number); //вводим метку с учетом уровня вложенности
fprintf(out,"mov ax,%s\n",lexem); //в ax помещаем значение переменной или константы
}
if(state==83)operation=1; //встретили op1<op2, запомнить
if(state==85)operation=2; //встретили op1>op2, запомнить
if(state==87)operation=3; //встретили op1+op2 в условии, запомнить
if(state==89)operation=4; //встретили op1-op2 в условии, запомнить
if(state==78)operation=5; //встретили op1-op2 в присваивании, запомнить
if(state==76)operation=6; //встретили op1+op2 в присваивании, запомнить
if(operation==1 && (state==80 || state==81)) //встретили op1<op2
{
fprintf(out,"cmp ax,%s\n",lexem); //сравниваем операнды
fprintf(out,"jnb end%d%d\n",while_level,while_number); //если не условие не выполнено, конец цикла
}
if(operation==2 && (state==80 || state==81)) //встретили op1>op2
{
fprintf(out,"cmp ax,%s\n",lexem); //сравниваем операнды
fprintf(out,"jna end%d%d\n",while_level,while_number); //если не условие не выполнено, конец цикла
}
if(operation==3 && (state==80 || state==81)) //встретили op1+op2 в условии
{
fprintf(out,"add ax,%s\n",lexem); //складываем операнды, результат - в ax
fprintf(out,"test ax,ax\n"); //проверяем результат на равенство нулю
fprintf(out,"jz end%d%d\n",while_level,while_number);
}
if(operation==4 && (state==80 || state==81)) //встретили op1-op2 в условии
{
fprintf(out,"sub ax,%s\n",lexem); //вычитаем операнды, результат - в ax
fprintf(out,"test ax,ax\n"); //проверяем результат на равенство нулю
fprintf(out,"jz end%d%d\n",while_level,while_number);
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.