Языки программирования и трансляторы.Синтаксический анализатор с использованием одного из табличных методов, страница 4



Текст программы


#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);

}