Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Отчет.doc
Скачиваний:
19
Добавлен:
15.06.2014
Размер:
84.48 Кб
Скачать

Омский Государственный Технический Университет

Кафедра информатики и вычислительной техники

Курсовая работа по дисциплине: "спо".

Выполнил:

Иваненко А.А. В-411

Проверил:

Флоренсов А.Н.

ОМСК 2005

Задание №6

Используя компилятор компиляторов BISON или ZUBR разработать интерпретатор с языка программирования, который описательно задается следующими определениями:

  1. язык обеспечивает вычисления на основе типа double языка Си (используемого компилятором компиляторов) и допускает использование одномерных массивов;

  2. для задания массивов используются описания вида:

massive имя_массива[размерность_массива];

где размерность_массива задается целым числом;

  1. переменная определяется либо как идентификатор, либо как идентификатор, за которым в квадратных скобках записано обозначение переменной или константы;

  2. в левой части оператора присваивания может стоять обычная или индексированная переменная;

  3. арифметические выражения могут использоваться сколь угодно сложной структуры, но не должны содержать обращений к функциям;

  4. язык содержит операторы цикла, задаваемые ключевым словом while, и условные операторы if, причем возможно использование этого оператора как с частью else, так и без нее; допускаются операторы break и continue;

  5. условия задаются в виде

выражение опреация_сравнения выражение

- для выдачи результатов служат операторы

оut список_переменных

outn список_переменных

причем оператор outn выдает округленные целые значения переменных, а для ввода оператор in список_переменных

где список_переменных представляет собой перечисление через запятую;

  1. остальные синтаксические элементы языка выбираются разработчиком самостоятельно;

  2. имена программных объектов должны формироваться по общеупотребительному правилу: первым символом должна быть произвольная латинская буква, последующими символами могут быть цифры или латинские буквы.

Листинг программы

comp.yфайл исходника для zubra:

//---------------------------------------------------------------------------------------------------------------

%{

#include"main.h"

%}

%token NUMBER IDENT DOUBLE WHILE DO IF ELSE THEN BEGIN END JE JNE JG JL JGE JLE OUT IN OUTN

%union{

float val;

int postoken;

}

%%

begin : declaration program

;

declaration : DOUBLE IDENT ';' declaration { dobavperem(poiskslova($2.postoken),0); }

| /* e */

;

program : BEGIN cmp_stmt END

;

cmp_stmt : stmt_list

| /* e */

;

stmt_list : stmt_list ';' stmt

| stmt

;

stmt : IDENT '=' expression { if(poiskperem(poiskslova($1.postoken))==0) zubr_error("нет такой переменной");

command('=',poiskslova($1.postoken),0); }

| WHILE { command(WHILE, "while", 0); posWHILE=lentryc; }

cmp DO { command(DO, "do", 0); }

stmt { command(STOPUN,"stopun",posWHILE); }

| IF { command(IF,"if",0); }

cmp THEN { command(THEN,"then",0); }

stmt else

| OUT { command(OUT, "write",0); } indent_list { command(STOP,"stop",0); }

| OUTN { command(OUTN,"writen",0); } indent_list { command(STOP,"stop",0); }

| IN { command(IN, "read",0); } indent_list { command(STOP,"stop",0); }

| program

| /* e */

;

else : ELSE { command(ELSE,"else",0); } stmt { command(STOPIF,"stopif",0); }

| /* e */ { command(STOPIF,"stopif",0); }

;

indent_list: indent_list ',' IDENT { command(IDENT,poiskslova($3.postoken),0); }

| IDENT { command(IDENT,poiskslova($1.postoken),0); }

;

cmp : expression JE expression { command(JE ,"==",0); }

| expression JNE expression { command(JNE,"!=",0); }

| expression JG expression { command(JG ,">", 0); }

| expression JL expression { command(JL ,"<", 0); }

| expression JGE expression { command(JGE,">=",0); }

| expression JLE expression { command(JLE,"<=",0); }

| expression

;

expression : expression '+' terminal { command('+',"+",0); }

| expression '-' terminal { command('-',"-",0); }

| terminal

;

terminal : terminal '*' factor { command('*',"*",0); }

| terminal '/' factor { command('/',"/",0); }

| factor

;

factor : '(' expression ')'

| IDENT { if(poiskperem(poiskslova($1.postoken))==0)

zubr_error("not declaration type");

command(IDENT,poiskslova($1.postoken),0); }

| NUMBER { command(NUMBER,"4uslo",$1.val); }

;

%%

#include"table.c"

#include"stack.c"

#include"perem.c"

#include"interpret.c"

FILE *openfile;

/*--------------------------------- Вывод ошибки ----------------------------------------*/

void zubr_error(char *s) {

printf("Error: %s on %d\n",s,LineStr);

exit(1);

}

/*--------------------------------Сравнение символов---------------------------------------*/

int compare(int ex, int Y, int N) {

int TN=fgetc(openfile);

if(TN==ex)return Y;

ungetc(TN,openfile);

return N;

}

/*---------------------------Лексический анализатор-------------------------------------*/

int zubr_lex(void) {

int c;

while(1)

{

c=fgetc(openfile);

if(c == ' '||c == '\t') ;

else

if(c == '\n') LineStr++; /*считаем строки*/

else if(isdigit(c)) /*считываем число */

{

ungetc(c,openfile);

fscanf(openfile,"%g",&zubr_lval.val);

return NUMBER;

}

else if(isalpha(c)) /*считываем индетификатор */

{

int p,b = 0;

while(isalnum(c))

{

LexBuf[b++]=c;

c=fgetc(openfile);

if(b >= 128)

{

zubr_error("compiler error");

exit(1);

}

}

LexBuf[b]='\0';

if(c!=EOF)

ungetc(c,openfile);

p = poisk(LexBuf);

if(p == 0)

p = dobavit(LexBuf,IDENT);

zubr_lval.postoken=p;

return TableN[p].token;

}

else {

switch(c) {

case '>': return compare('=',JGE,JG);

case '<': return compare('=',JLE,JL);

case '!': return compare('=',JNE,'!');

case '=': return compare('=',JE,'=');

default:

return c;

}

}

}

}

void print(){

int i;

for(i=0;i<=lentryc;i++)

printf("%d %s %d\n",i,COM[i].n1,COM[i].zn1);

}

/*------------------------------ Главная программа -------------------------------------*/

void main(int argc,char *argv[]) {

if((openfile=fopen(argv[1],"r"))==NULL){

printf("not declarate file\n");

exit(1);

}

rezervirov();

zubr_parse();

run();

fclose(openfile);

// print();

}

interpret.c – файл интерпритатора:

//--------------------------------------------------------------------------------------------------------

int lentryc = 0;

struct intercommand{

int pos;

int COMMAND;

char *n1;

float zn1;

}COM[1000];

int command(int com, char *s1,float zn1) {

lentryc++;

COM[lentryc].n1=malloc(strlen(s1)+1);

COM[lentryc].COMMAND = com;

strcpy(COM[lentryc].n1, s1);

COM[lentryc].zn1 = zn1;

return LastEntry;

}

void run(void)

{

int tab,srav;

float t;

float b=0,c=0;

for(tab=1;tab<=lentryc;tab++){

if(COM[tab].COMMAND=='+') {

pop(&b);

pop(&c);

push(c+b);

}

if(COM[tab].COMMAND=='-') {

pop(&b);

pop(&c);

push(c-b);

}

if(COM[tab].COMMAND=='*') {

pop(&b);

pop(&c);

push(c*b);

}

if(COM[tab].COMMAND=='/') {

pop(&b);

pop(&c);

push(c/b);

}

if(COM[tab].COMMAND==IDENT) {

push(poisktipaperem(COM[tab].n1));

}

if(COM[tab].COMMAND==NUMBER) {

push(COM[tab].zn1);

}

if(COM[tab].COMMAND=='=') {

pop(&b);

changeperem(COM[tab].n1,b);

}

if(COM[tab].COMMAND==JG) {

pop(&b);

pop(&c);

push(c>b);

}

if(COM[tab].COMMAND==JL) {

pop(&b);

pop(&c);

push(c<b);

}

if(COM[tab].COMMAND==JE) {

pop(&b);

pop(&c);

push(c==b);

}

if(COM[tab].COMMAND==JNE) {

pop(&b);

pop(&c);

push(c!=b);

}

if(COM[tab].COMMAND==JLE) {

pop(&b);

pop(&c);

push(c<=b);

}

if(COM[tab].COMMAND==JGE) {

pop(&b);

pop(&c);

push(c>=b);

}

if(COM[tab].COMMAND==THEN) {

pop(&b);

push(b);

if(b==0)

while(COM[tab].COMMAND!=ELSE&&COM[tab].COMMAND!=STOPIF)tab++;

}

if(COM[tab].COMMAND==ELSE) {

pop(&b);

if(b==1)

while(COM[tab].COMMAND!=STOPIF)tab++;

}

if(COM[tab].COMMAND==DO) {

pop(&b);

push(b);

if(b==0)

while(COM[tab].COMMAND!=STOPUN)tab++;

}

if(COM[tab].COMMAND==STOPUN) {

pop(&b);

push(b);

if(b==1)

tab=COM[tab].zn1;

}

if(COM[tab].COMMAND==STOPIF) {

pop(&b);

}

if(COM[tab].COMMAND==OUT) {

tab++;

while(COM[tab].COMMAND!=STOP) {

printf("%f ",poisktipaperem(COM[tab].n1));

tab++;

}

}

if(COM[tab].COMMAND==OUTN) {

tab++;

while(COM[tab].COMMAND!=STOP)

{

printf("%f\n",poisktipaperem(COM[tab].n1));

tab++;

}

}

if(COM[tab].COMMAND==IN) {

tab++;

while(COM[tab].COMMAND!=STOP) {

float n;

scanf("%g",&n);

changeperem(COM[tab].n1,n);

tab++;

}

}

}

}

//-------------------------------------------------------------------------------------------------------------------

main.h – файл переменных:

//-------------------------------------------------------------------------------------------------------------------

#include<string.h>

#include<ctype.h>

#include<stdio.h>

#define MAX_TABLE 128

#define MAX_STR 1000

#define STOP 1001

#define STOPUN 1002

#define STOPIF 1003

extern int dobavit(char s[],int t);

extern char *poiskslova(int t);

extern int poisk(char s[]);

extern void rezervirov(void);

extern void zubr_error(char *s);

extern int dobavperem(char s[],int type);

extern int poiskperem(char s[]);

extern int command(int command,char *s1,float zn1);

extern void run(void);

//-------------------------------------------------------------------------------------------------------------------

perem.c – файл работы с переменными:

//-------------------------------------------------------------------------------------------------------------------

struct peremen{

char *name;

float DOUB;

int type;

}PR[MAX_TABLE];

int lentryp = 0;

int lcharp = -1;

int poiskperem(char s[]) {

int tab;

for(tab=lentryp;tab>0;tab--)

if(strcmp(PR[tab].name,s) == 0)

return tab;

return 0;

}

int dobavperem(char s[],int type) {

if(poiskperem(s)==0) {

int len;

len=strlen(s);

if(lentryp+1>=MAX_TABLE)

zubr_error("table symbol is full");

if(lentryp + len + 1>=MAX_STR)

zubr_error("lexemes size of");

lentryp++;

PR[lentryp].type = type;

PR[lentryp].name = &LexWords[lcharp+1];

lcharp +=len+1;

strcpy(PR[lentryp].name, s);

return lentryp;

}else {

zubr_error("not second declarate");

}

}

float poisktipaperem(char *s) {

int tab;

for(tab=lentryp;tab>0;tab--)

if(strcmp(PR[tab].name,s) == 0)

return PR[tab].DOUB;

return -1;

}

int poiskperemzn(char *s) {

int tab;

for(tab=lentryp;tab>0;tab--)

if(strcmp(PR[tab].name,s) == 0)

return PR[tab].type;

return -1;

}

float changeperem(char *s,float n) {

int tab;

for(tab=lentryp;tab>0;tab--)

if(strcmp(PR[tab].name,s) == 0){

PR[tab].DOUB=n;

return PR[tab].DOUB;

}

return -1;

}

stack.c – файл стека:

//-------------------------------------------------------------------------------------------------------------------

float stack[100]; //СТЕК

int istack=0; //позиция курсора в стеке

void push(float n){

if(istack!=999){

stack[istack]=n;

istack++;

}

}

void pop(float *n){

if(istack!=0){

istack--;

*(n)=stack[istack];

}

}

//-------------------------------------------------------------------------------------------------------------------

table.c – файл таблицы символов:

//-------------------------------------------------------------------------------------------------------------------

int posIF;

int posWHILE;

char LexWords[MAX_STR];

int LastChar = -1;

struct TableContents

{

char *nameword;

int token;

};

struct TableContents TableN[MAX_TABLE];

int LastEntry = 0;

struct TableContents words[]=

{

"double", DOUBLE,

"begin" , BEGIN,

"end" , END,

"while" , WHILE,

"do" , DO,

"if" , IF,

"then" , THEN,

"else" , ELSE,

"outn" , OUTN,

"out" , OUT,

"in" , IN,

0 , 0

};

int LineStr=1;

char LexBuf[128];

void rezervirov(void) {

struct TableContents *tab;

for(tab=words;tab->token;tab++)

dobavit(tab->nameword,tab->token);

}

int poisk(char s[]) {

int tab;

for(tab=LastEntry;tab>0;tab--)

if(strcmp(TableN[tab].nameword,s) == 0)

return tab;

return 0;

}

int dobavit(char s[],int t) {

int Len;

Len=strlen(s);

if(LastEntry+1>=MAX_TABLE)

zubr_error("symbol table full");

if(LastEntry + Len + 1>=MAX_STR)

zubr_error("lexemes array full");

LastEntry++;

TableN[LastEntry].token = t;

TableN[LastEntry].nameword = &LexWords[LastChar+1];

LastChar +=Len+1;

strcpy(TableN[LastEntry].nameword, s);

return LastEntry;

}

char *poiskslova(int t) {

int tab;

for(tab=LastEntry;tab>0;tab--)

if(tab == t)

return TableN[tab].nameword;

return 0;

}

Соседние файлы в предмете Системное программное обеспечение