Trigoli laiendamine

Viktor Massalogin - 3.05.2006

Ülesanne

Lisada keelele:

  1. Eel- ja Järelkontrolliga kordus kujul
  2. WHILE <tingimus> DO
      <operaator>
    
    
    DO
      <operaator>
    WHILE <tingimus>
  3. Plokklause kujul
  4. BEGIN
      <operaator>;
      <operaator>;
      <operaator>
    END

Programmi näidis:

#
READ n; F := 1; I := 0;
WHILE I <= n DO
  BEGIN
    I := I + 1;
    F := F * I
  END;
WRITE F
#

Grammatika täiendus

`operaator' -> `plokk'
`plokk' -> `plokk1'END
`plokk1' -> BEGIN`operaatorid'

`operaator' -> `loop'
`loop' -> `whiletingimus'DO`operaator'
`loop' -> `loop1'`whiletingimus'
`loop1' -> DO`operaator'
`whiletingimus' -> WHILE`loogilav'

Semantika täiendus

P49=27 $ P49: `plokk' -> `plokk1' END
P51=28 $ P51: `loop' -> `whiletingimus' DO `operaator'
P52=28 $ P52: `loop' -> `loop1' `whiletingimus'
P54=29 $ P53: `whiletingimus' -> WHILE `loogilav'

Interpretaatori täiendus

...
#define plokk 27	// S E M A N T I C S
#define loop 28
#define whilet 29 

...
// Operaatori trükk
void tprop(int s) {
    switch(s) {
        ...
        case plokk:   fprintf(Logi,"PLOKK ");   break;
        case loop:    fprintf(Logi,"LOOP ");    break;
        case whilet:  fprintf(Logi,"WHILE ");   break;
        ...
    }
}

// Tabulaatorid programmide trükiks
void tabs(int n) {
    while( n-- )
        fprintf(Logi,"  ");
}

// Operaatori teksti trükk analüüsi puu järgi - on ümberkirjutatud
//   tabulaatoritega programmi teksti trükiks,
//   levels   - tabulaatorite tase,
//   levels=0 - trükk reasse,
//   tagastab järgmisele operaatorile viit,
//     kuna trükib korraga ka IF()THEN järgnevat

struct top* print_Op( struct top *t, char levels )  {
    struct top* d;
    char levels1;

    if( !t )  return NULL;

    switch( t->sem )
    {
        case labl:
            d=t->down;
            fprintf(Logi,"%s: ",T[d->leks]); if(levels) ps();
            break;

        case lugem:
        case kirjut:
            if(levels) tabs(levels);
            tprop(t->sem);
            d=t->down;
            fprintf(Logi,"%s",T[d->leks]); if(levels) ps();
            break;
            
        case suunam:
            if(levels) tabs(levels);
            tprop(t->sem);
            d=t->down->down;
            fprintf(Logi,"%s",T[d->leks]); if(levels) ps();
            break;

        case kuisiis:
            if(levels) tabs(levels);
            fprintf(Logi,"IF ");
            print_Op( t->down, 0 );
            fprintf(Logi," THEN ");
            if(levels) {
                ps();
                t = t->right;
                levels1 = levels+1;
                print_Op( t, levels1 );
            }
            break;

        case loop:
            if(levels) tabs(levels);
            d = t->down;
            levels1 = levels ? levels+1 : 0;
            if( d->sem == whilet )  {
                print_Op( d, 0 );                       // WHILE ()
                fprintf(Logi," DO"); if(levels) ps();   //          DO
                print_Op( d->right, levels1 );          //     ..
            }
            else  {
                fprintf(Logi,"DO "); if(levels) ps();   // DO
                print_Op( d, levels1 );                 //     ..
                if(levels) tabs(levels);
                print_Op( d->right, levels );           // WHILE ()
            }
            break;

        case whilet:
            fprintf(Logi,"WHILE ");
            print_Op( t->down, 0 );
            if(levels) ps();
            break;

        case plokk:
            if( !levels )
                fprintf(Logi," PLOKK ");    // Do not scribe blokk in line
            else  {
                tabs(levels);
                fprintf(Logi,"BEGIN"); ps();
                d = t->down;
                levels1 = levels+1;
                do
                    d = print_Op( d, levels1 );
                while( d );
                tabs(levels);
                fprintf(Logi,"END"); ps();
            }
            break;

        case omist:
            if(levels) tabs(levels);
            d=t->down;
            print_Op( d, 0 );
            tprop(t->sem);
            print_Op( d->right, 0 );
            if(levels) ps();
            break;

        default:            
            d=t->down;
            if( d )
                fprintf(Logi,"(");
            print_Op( d, 0 );
            if(t->leks)
                fprintf(Logi,"%s",T[t->leks]);
            else
                tprop(t->sem);          
            if( d ) {
                print_Op( d->right, 0 );
                fprintf(Logi,")");
            }
            if(levels) ps();
            break;
    }

    return t->right;
}

// TRIGOL-keelsete programmide trükk puu järgi
void p_prog(struct top *root){
    struct top *t;
    t=root->down;
    fprintf(Logi,"</FONT><PRE>#<BR>");
    while( t = print_Op(t,1) );
    fprintf(Logi,"#</PRE>");
}


// TRIGOL-keelsete programmide interpretaator
void trigol_Int(struct top *root)  {
    ...
    switch(op) {
        ...
        case whilet: {
            x=get_x(i,1);
            freestack(i,1);
            i-=1;
            if( x==0 ) {
                if( t->right )
                    t = t->right;  // out from loop
                t = t->up;
                goto naaber;
            }           
            break;            
        }
        case loop:   goto down;
        case plokk:  break;
        
        ...
}
...

Failid

Logifailid