Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
![](images/emoji__ok.png)
Предоплата всего
![](images/emoji__signature.png)
Подписываем
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Предоплата всего
Подписываем
ОМСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
Кафедра информатики и вычислительной техники
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
к курсовой работе
по курсу:
«Системное программное обеспечение»
Выполнил: студент группы ИВТ-425
Шукурова Г. С.
Проверил: к.т.н. доцент
Флоренсов А.Н.
Омск 2009
Задание к курсовому проекту
вариант №23
используя компилятор компиляторов BISON или ZUBR, разработать интерпретатор с языка программирования, который описательно задается следующими определениями:
выражение операция_сравнения выражение
writet список имен переменных
writen список имен переменных
причем оператор writen выдает округленные целые значения переменных, а для ввода оператор
read список имен переменных где список имен переменных представляет собой перечисление через запятую;
Основным результатом работы компилятора должен быть исполняемый фал интерпретатора; в качестве дополнительного фала, выдаваемого компилятором при указании опции запроса для него, должен формироваться файл таблицы символических имен.
Представляемые результаты разработки должны включать пояснительную записку и исходный файл для BISON или ZUBR, детально прокомментированный, с текстами подключаемых файлов, созданных разработчиком.
MAIN.Y
%{
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "symtab.c"
#include "code.c"
#define code2(c1,c2) code(c1); code(c2)
#define code3(c1,c2,c3) code(c1); code(c2); code(c3)
%}
%union
{
SYMBOL *sym;
INST *inst;
}
%token <sym> NUMBER VAR UNDEF STRING
%token <sym> WRITE WRITEN READ READN BREAK IF ELSE CLRSCR DEFAULT
%type <inst> expr assign
%type <inst> stmt stmtlist wrlist wrlistn rdlistn cond if end
%right '='
%left OR
%left AND
%left GT GE LT LE EQ NE
%left '+' '-'
%left '*' '/'
%left UNARYMINUS NOT
%right '^'
%start list
%%
list: /* nothing */
| list '\n'
| list assign '\n' { code2( (INST)void_pop, STOP ); return( 1 ); }
| list stmt '\n' { code ( STOP ); return( 1 ); }
| list expr '\n' { code2( (INST)void_pop, STOP ); return( 1 ); }
| list error '\n'
{
yyerrok;
}
;
stmt: assign
| expr { code ((INST)void_pop); }
| WRITE wrlist { $$ = $2; }
| WRITEN wrlistn { $$ = $2; }
| READ '(' VAR ')' { $$ = code2( (INST)varread, (INST)$3 ); }
| READN '('rdlistn')' {$$ = $3; }
| BREAK { code2 ((INST)breakcode,STOP); }
| CLRSCR { code ((INST)clrscrcode); }
| if cond stmt end
{
($1)[1] = (INST)$3; /* з бвм then */
($1)[3] = (INST)$4; /* end */
}
| if cond stmt end ELSE stmt end
{
($1)[1] = (INST)$3; /* з бвм then */
($1)[2] = (INST)$6; /* з бвм else */
($1)[3] = (INST)$7; /* end */
}
| '{' stmtlist '}' { $$ = $2; }
;
cond: '(' expr ')' { code( STOP ); $$ = $2; }
;
assign: VAR '=' expr { code3( (INST)varpush, (INST)$1, (INST)assign ); }
;\
if: IF
{
$$ = code( (INST)ifcode );
code3( STOP, STOP, STOP );
}
;
end: /* nothing */ { code( STOP ); $$ = pprog; }
;
stmtlist: /* nothing */ { $$ = pprog; }
| stmtlist '\n'
| stmtlist stmt
;
expr: NUMBER { code2( (INST)constpush, (INST)$1 ); }
| VAR { code3( (INST)varpush, (INST)$1, (INST)eval ); }
| assign { code3( (INST)varpush, (INST)$1, (INST)eval ); }
| expr '+' expr { code( (INST)Yadd ); }
| expr '-' expr { code( (INST)Ysub ); }
| expr '*' expr { code( (INST)Ymul ); }
| expr '/' expr { code( (INST)Ydiv ); }
| expr '^' expr { code( (INST)power ); }
| '(' expr ')' { $$ = $2; }
| '-' expr %prec UNARYMINUS { code( (INST)negate ); }
| expr GT expr { code( (INST)gt ); }
| expr GE expr { code( (INST)ge ); }
| expr LT expr { code( (INST)lt ); }
| expr LE expr { code( (INST)le ); }
| expr EQ expr { code( (INST)eq ); }
| expr NE expr { code( (INST)ne ); }
| expr AND expr { code( (INST)and ); }
| expr OR expr { code( (INST)or ); }
| NOT expr { $$ = $2; code( (INST)not ); }
;
wrlist: expr { code( (INST)prexpr ); }
| STRING { $$ = code2( (INST)prstr, (INST)$1 ); }
| wrlist ',' expr { code( (INST)prexpr ); }
| wrlist ',' STRING { $$ = code2( (INST)prstr, (INST)$3 ); }
;
rdlistn: VAR { $$ = code2( (INST)varread, (INST)$1 ); }
| rdlistn ',' VAR { $$ = code2( (INST)varread, (INST)$3 ); }
;
wrlistn: expr { code( (INST)prexprn ); }
| STRING { $$ = code2( (INST)prstr, (INST)$1 ); }
| wrlistn ',' expr { code( (INST)prexprn ); }
| wrlistn ',' STRING { $$ = code2( (INST)prstr, (INST)$3 ); }
;
%%
static struct
{
char *name;
int kval;
}
keywords[] =
{
"if", IF,
"else", ELSE,
"break", BREAK,
"write", WRITE,
"writen", PRINTN,
"read", INPUT,
"readn", READN,
"clrscr", CLRSCR,
"case", CASE,
"default" ,DEFAULT,
"and", AND,
"or", OR,
0, 0
};
static struct
{
char *name;
int cval;
}
;
void init( void )
{
int i;
SYMBOL *s;
for( i = 0; keywords[i].name; i++ )
install( keywords[i].name, keywords[i].kval, 0.0 );
}
char *progname;
FILE *input_file;
char *input_file_name;
int lineno = 1;
int warning( char *s, char *t )
{
if (t) fprintf( stderr, " %s", t );
fprintf( stderr, "®иЁЎЄ бва®ЄҐ ь %d %s\n", lineno,s );
}
int yyerror( char *s )
{
warning( s, (char *)0 );
}
int follow( int expect, int ifyes, int ifno )
{
register FILE *f = input_file;
register int c;
c = getc( f );
if( c == expect ) return( ifyes );
ungetc( c, f );
return( ifno );
}
int backslash( int c )
{
register FILE *f = input_file;
static char tabl[] = "b\bf\fn\nr\rt\t";
char *p = (char *)0;
if( c != '\\' ) return( c );
c = getc( f );
p = (char *)strchr( tabl, c );
if( islower( c ) && p != (char *)0 )
return( p[1] );
return( c );
}
int yylex( void )
{
register FILE *f = input_file;
register int c;
register int SC, EC;
while( (c = getc( f )) == ' ' || c == '\t' || c == '\r' );
/* Љ®¬¬Ґв аЁЁ */
while (c=='/' && follow('*',SC,'/')==SC) {
while (((c=getc(f))!='*' && follow('/',EC,'*')!= EC) && c!=EOF);
if (c=='*' && follow('/',EC,'*')==EC)
while( (c = getc( f )) == ' ' || c == '\t' || c == '\r' ); }
if( c == EOF ) return( 0 );
if( c == '.' || isdigit( c ) )
{
double d = 0.0;
int n = getc( f );
/* ¬®Ґ© дгЄжЁЁ scanf() Ґ«м§п ®в¤ ў вм зЁб«® "." */
if( c == '.' && !isdigit( n ) )
{
ungetc( n, f );
yylval.sym = install( "", NUMBER, d );
return( NUMBER );
}
ungetc( n, f );
/* number */
ungetc( c, f );
n = fscanf( f, "%lf", &d );
yylval.sym = install ("", NUMBER, d);
return( NUMBER );
}
if( isalpha( c ) )
{
SYMBOL *sp;
char sbuf[100], *p = sbuf;
do
{
*p++ = tolower(c);
} while( (c=getc( f )) != EOF && isalnum( c ) );
ungetc( c, f );
*p = '\0';
if( (sp = lookup( sbuf ) ) == (SYMBOL *)0 )
sp = install( sbuf, UNDEF, 0.0 );
yylval.sym = sp;
return( sp->type == UNDEF ? VAR : sp->type );
}
if( c == '\n' ) { lineno++; return( c ); }
// Џ®«гз Ґ¬ бва®зЄг
if( c == '"' )
{
SYMBOL *sp;
char sbuf[256], *p;
for( p =sbuf; (c = getc( f )) != '"'; p++ )
{
if( c == '\n' || c == EOF )
warning( "вॡговбп Є ўлзЄЁ", "\"" );
if( p >= sbuf + sizeof( sbuf ) - 1 )
{
*p = '\0';
warning( "бва®Є б«ЁиЄ®¬ ¤«Ё п", sbuf );
}
*p = backslash( c );
}
*p = '\0';
yylval.sym = (SYMBOL *)emalloc( strlen( sbuf ) + 1 );
strcpy( (char *)yylval.sym, sbuf );
return( STRING );
}
switch( c )
{
case '>': return follow( '=', GE, GT );
case '<': return follow( '=', LE, LT );
case '=': return follow( '=', EQ, '=' );
case '!': return follow( '=', NE, NOT );
default : return( c );
}
}
int main( int argc, char *argv[] )
{
clrscr();
progname = argv[0];
if (argc < 2)
{
printf (" trans Ё¬п_Їа®Ја ¬¬л\n");
exit( 1 );
}
input_file_name = argv[1];
if( (input_file = fopen( input_file_name, "rb" )) == NULL )
{
printf(" ЌҐ ¬®Јг ®вЄалвм д ©«:: %s\n", input_file_name );
exit( 1 );
}
printf ("ђ Ў®в trans\n‚室®© д ©« = '%s'\n",input_file_name);
init();
for( initcode(); yyparse(); initcode() )
{
execute( prog );
}
if( input_file ) fclose( input_file );
return( 0 );
}
SYMTAB.C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SymTab.h"
static SYMBOL *symlist = 0; /* указатель на таблицу символов */
char * emalloc( unsigned n )
{
char *p;
p = (char *)malloc( n );
if( p == 0 )
{
/*
при неудачном выполнении malloc()
завершаем работу
*/
printf( "calc: ERROR: out of memory\n" );
exit( 1 );
}
return( p );
}
SYMBOL *lookup( char *s )
{
SYMBOL *sp;
for( sp = symlist; sp != (SYMBOL *)0; sp = sp->next )
if( strcmp( sp->name, s ) == 0 ) return( sp );
return( 0 ); /* запись не найдена */
}
SYMBOL *install( char *s, int t, double d )
{
SYMBOL *sp;
sp = (SYMBOL *)emalloc( sizeof( SYMBOL ) );
sp->name = emalloc( strlen( s ) + 1 );
strcpy( sp->name, s );
sp->type = t;
sp->u.val = d;
sp->next = symlist; /* alloc in begin of list */
symlist = sp;
return( sp );
}
CODE.C
#include <math.h>
#include <stdio.h>
#include "code.h"
#define NSTACK 512
static DATUM stack[NSTACK]; /* стек */
static DATUM *pstack; /* первое свободное метсо в стеке */
#define NPROG 1024
INST prog[NPROG]; /*массив в котором лежит программа*/
INST *pprog; /* первое свободное место для инструкций в программе*/
INST pc; /*счетчик комманд*/
int breakmask;
void initcode( void )
{
pstack = stack;
pprog = prog;
breakmask=0;
}
void push( DATUM d )
{
if( pstack >= &stack[NSTACK] )
warning( "стек переполнен, (char *)0 );
*pstack++ = d;
}
DATUM pop( void )
{
if( pstack <= stack )
warning( "стек пуст", (char *)0 );
return( *--pstack );
}
void void_pop( void )
{
pop();
}
INST *code( INST f )
{
INST *opprog = pprog;
if( pprog >= &prog[NPROG] ) //если процедура code пытается положить в массив больше чем он имеет размер
warning( "программа слишком большая ", (char *)0 );
*pprog++ = f;
return( opprog );
}
void execute( INST *p )
{
for( pc = p; *pc != STOP; ) (*(*pc++))(); //выполняется до тех пор пока не встретит команду STOP
}
void constpush( void )
{
DATUM d;
d.val = ((SYMBOL *) *pc++)->u.val;
push( d );
}
void varpush( void )
{
DATUM d;
d.sym = (SYMBOL *)(*pc++);
push( d );
}
void breakcode( void )
{
breakmask=1;
}
void clrscrcode( void )
{
clrscr();
}
void ifcode( void )
{
DATUM d;
INST *savepc = pc; /* часть "then" */
execute( savepc + 3 ); /* условие */
d = pop();
if( d.val ) execute( *((INST **)(savepc)) );
else if( *((INST **)(savepc + 1)) ) /* часть "else" ? */
execute( *((INST **)(savepc + 1)) );
pc = *((INST **)(savepc + 2)); /* следующий оператор */
}
void Yadd( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val += d2.val;
push( d1 );
}
void Ysub( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val -= d2.val;
push( d1 );
}
void Ymul( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val *= d2.val;
push( d1 );
}
void Ydiv( void )
{
DATUM d1, d2;
d2 = pop();
if( d2.val == 0.0 ) warning( "ñѽѡ¿Ñ ¡á ¡«½∞", (char *)0 );
d1 = pop();
d1.val /= d2.val;
push( d1 );
}
void negate( void )
{
DATUM d;
d = pop();
d.val = -d.val;
push( d );
}
void power( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val = ZPow( d1.val, d2.val );
push( d1 );
}
void gt( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val > d2.val);
push( d1 );
}
void ge( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val >= d2.val);
push( d1 );
}
void lt( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val < d2.val);
push( d1 );
}
void le( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val <= d2.val);
push( d1 );
}
void eq( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val == d2.val);
push( d1 );
}
void ne( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val != d2.val);
push( d1 );
}
void and( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val != 0.0 && d2.val != 0.0);
push( d1 );
}
void or( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val = (double)(d1.val != 0.0 || d2.val != 0.0);
push( d1 );
}
void not( void )
{
DATUM d;
d = pop();
d.val = (double)(d.val == 0.0);
push( d );
}
void eval( void )
{
DATUM d;
d = pop();
if( d.sym->type == UNDEF )
warning( "»ÑαѼѡ¡á∩ ¡Ñ «íΩ∩ó½Ñ¡á", d.sym->name );
d.val = d.sym->u.val;
push( d );
}
void assign( void )
{
DATUM d1, d2;
d1 = pop();
d2 = pop();
if( d1.sym->type != VAR && d1.sym->type != UNDEF )
warning( "φΓ« ¡Ñ »ÑαѼѡ¡á∩", d1.sym->name );
d1.sym->u.val = d2.val;
d1.sym->type = VAR;
push( d2 );
}
void wrexpr( void )
{
DATUM d;
d = pop();
printf( "\t%.10g\n", d.val );
}
void wrexprn( void )
{
DATUM d;
double ho;
d = pop();
ho=d.val-floor(d.val);
if (ho<0.5) {printf( "\t%.10g\n", floor(d.val));} else
{printf( "\t%.10g\n", ceil(d.val));}
}
void prstr( void )
{
printf( "%s", (char *)*pc++ );
}
void varread( void )
{
DATUM d;
FILE *f = stdin;
SYMBOL *var = (SYMBOL *)*pc++;
again:
fprintf( stderr, "Æ¿» τ¿ß½«: %s = ", var->name );
switch( fscanf( f, "%lf", &var->u.val) )
{
case EOF:
d.val = var->u.val = 0.0;
break;
case 0:
warning( "»α«τ¿Γá¡« ¡Ñ τ¿ß½«", var->name );
break;
default:
d.val = 1.0;
break;
}
var->type = VAR;
push( d );
}
void mathfunc( void )
{
DATUM d;
d = pop();
d.val = (*(double (*) ())(*pc++))( d.val );
push( d );
}
void mathfunc2( void )
{
DATUM d1, d2;
d2 = pop();
d1 = pop();
d1.val = (*(double (*) ())(*pc++))( d1.val, d2.val );
push (d1);
}
/******************* END OF FILE CODE.C *********************/
Список использованной литературы
Пер. с англ.;
А.М. Березко, В.А.Иващенко. М.: Финансы и статистика. 1992. 304с.: ил.
2. сайт linux.yaroslavl.ru