Trigoli laiendamine

Viktor Karabut 12.12.2010

Ülesanne

Lisada keelele ühemõõtmelised massiivid.

  1. Massivi deklareerimine ja initsialeseerimine:
    ARRAY a[<length_expression>];
    
  2. Massiivi elemendile omistamine.
    a[<index_expression>] := <value_expression>;
    
  3. Lugemine massiivist.
    <variable> := a[<index_expression>];
    

Programmide näided

ext1.tri

#
ARRAY a[4];
a[0]:=1;
a[1]:=2;
a[2]:=3;
a[3]:=a[0]+a[1]+a[2]
#

ext2.tri

Maksimaalse elementi otsimine.

#
alen := 5;
ARRAY a[alen];
a[0] := 23;
a[1] := 85;
a[2] := 10;
a[3] := 47;
a[4] := 62;
max := 0;
i := 1;
WHILE:
	IF a[max] < a[i] THEN max := i;
	i := i + 1;
IF i < alen THEN GOTO WHILE;
maxvalue := a[max]
#

ext3.tri

Massiivi sorteerimine

#
alen := 5;
ARRAY a[alen];
a[0] := 23;
a[1] := 85;
a[2] := 10;
a[3] := 47;
a[4] := 62;
i := 0;
FORi:
	j := i + 1;
	FORj:
		IF a[i] <= a[j] THEN GOTO NOSWAP;
			t := a[i];
			a[i] := a[j];
			a[j] := t;
		NOSWAP:
		j := j + 1;
	IF j < alen THEN GOTO FORj;
	i := i + 1;
IF i < alen-1 THEN GOTO FORi
#

Grammatika täiendus

`masindeks'         ->  [`aritmav']
`masdeklaratrsion'  ->  ARRAY`massiiv'
`operaator'         ->  `masdeklaratrsion'
`operaator'         ->  `masomistamine'
`massiiv'           ->  #i#`masindeks'
`masomistamine'     ->  `massiiv':=`omistamine1'
`masvaartus'        ->  `massiiv'
`tegur'             ->  `masvaartus'

Semantika täiendus

p48=22 $ masdeklaratrsion' ->  ARRAY`masnimi'`masindeks'
p52=23 $ masomistamine'    ->  `massiv':=`omistamine1'
p53=24 $ masvaartus'       ->  #i#`masindeks'

Interpretaatori täiendus

Fail two32.h

  1. Uus struktuur, kuhu salvestatakse trigoli massiiv:
    #define MAX_ARRAY_LEN 1000
    struct tri_array{
    	int len;		/* massivi pikkus */
    	int *data;		/* massivi sissend */
    	};
    
  2. Identifikaatorite tabeli kirjese on lisatud uus väli struct tri_array *arr:
    struct itr{
    	...
    	struct tri_array *arr;	/* interpretaaator: massiv */
    	...
    	};

Fail int32.c

  1. Semantika koodid:
    ...
    #define massdekl  22    /* massiivi deklareerimine */
    #define massomist 23    /* massiivi omistamine */
    #define mvaartus  24    /* massiivi vaartus */
    ...
    
  2. On muudatud operaatori teksti trükk analüüsi puu järgi
    int print_Op(struct top *t){
    	int fg=0;
    	if(t!=(struct top *)NULL){
    		...
    		if(t->sem==massdekl) {
    			fprintf(Logi,"ARRAY ");
    			print_Op(t->down);
    			fprintf(Logi,"[");
    			print_Op(t->down->right);
    			fprintf(Logi,"]");
    			return(0);
    			}
    		if(t->sem==massomist) {
    			print_Op(t->down);
    			fprintf(Logi,"[");
    			print_Op(t->down->right);
    			fprintf(Logi,"]:=");
    			print_Op(t->down->right->right);
    			return(0);
    			}
    		if(t->sem==mvaartus) {
    			print_Op(t->down);
    			fprintf(Logi,"[");
    			print_Op(t->down->right);
    			fprintf(Logi,"]");
    			return(0);
    			}
    		...
    	}
    	...
    }
    
    void tprop(int s){
    	switch(s){
    		...
    		case massdekl:fprintf(Logi,"ARRAY"); break;
    		case massomist:fprintf(Logi,"[]:="); break;
    		case mvaartus:fprintf(Logi, "->"); break;
    		...
    		}
    }
  3. Funktsioonid struktuuriga struct tri_array töötamiseks:
    /* uue massiivi mälueraldus */
    struct tri_array *make_tri_array(int len){
    	struct tri_array *c;
    	c=(struct tri_array *)malloc(sizeof(struct tri_array));
    	if(c==NULL) ExIT();
    	c->data = (int *)malloc(sizeof(int)*len);
    	if(c->data == NULL) {
    		free(c);
    		ExIT();
    	}
    	memset(c->data,'\0',sizeof(int)*len);
    	c->len = len;
    	return(c);
    }
    
    /* trigoli massiivi kustutamine ja mäluvabastamine */
    void free_tri_array(struct tri_array *arr) {
    	if (arr->data != NULL) {
    		free(arr->data);
    	}
    	free(arr);
    }
  4. Ja interpretaatori täendus.
    /* Luua uus massiiv */
    void create_tri_array(int len, int i) {
    	struct item *s;
    	struct itr *id;
    	if(len <= 0) {
    		red("Error, array length should be posititive integer.");
    		ExIT();
    	}
    	if(len > MAX_ARRAY_LEN) {
    		red("Error, so big array.");
    		ExIT();
    	}	
    	s=stack[i-2];
    	id=s->id;
    	if(id->arr != NULL) {
    		free_tri_array(id->arr);
    	}
    	id->arr = make_tri_array(len);
    	fprintf(Logi,"<BR>Created new array %s<BR>",T[id->nr]);
    	p_tri_array(T[id->nr], id->arr);
    }
    
    /* Kontrollida massiivi indeks */
    void check_index(struct tri_array *arr, int index) {
    	if(arr == NULL) {
    		red("Error, array is not initialized");
    		ExIT();
    	}
    	if (index < 0) {
    		red("Error, array index should be greater or equal than 0");
    		ExIT();
    	}
    	if (index >= arr->len) {
    		red("Error, so big index");
    		ExIT();
    	}
    }
    
    /* Kirjuta massiivisse */
    void write_to_cell(int value, int index, int i) {
    	struct item *s;
    	struct itr *id;
    	s=stack[i-3];
    	id=s->id;
    	check_index(id->arr, index);	
    	id->arr->data[index] = value;
    	fprintf(Logi,"<BR>Writed value %d to %s[%d]<BR>", value, T[id->nr], index);
    	p_tri_array(T[id->nr], id->arr);
    }
    
    /* Lugeda massiivist  */
    void tri_array_value(int index, int i) {
    	struct item *s1, *s2;
    	struct itr *id;
    	int res;
    	s1=stack[i-2];
    	id=s1->id;
    	check_index(id->arr, index);
    	res = id->arr->data[index];
    	fprintf(Logi,"%s[%d]=%d",T[id->nr], index, res);
    	freestack(i,2);
    	s2=make_item();
    	s2->liik=0;
    	s2->index=res;
    	stack[i-2]=s2;
    }
    
    /* TRIGOL-keelsete programmide interpretaator  */
    void trigol_Int(struct top *root){
    	...
    	switch(op){
    		...
    		case massdekl:{ 
    			x=get_x(i,1);
    			create_tri_array(x,i);
    			freestack(i,2);
    			i-=2;
    			break;
    			}
    		case massomist:{		
    			x=get_x(i,1);
    			y=get_x(i,2);
    			write_to_cell(x, y, i);
    			freestack(i,3);
    			i-=3;
    			break;
    			}
    		case mvaartus:{
    			x=get_x(i,1);
    			tri_array_value(x, i);
    			i-=1;
    			break;
    			}
    		}
    	...
    }