Welcome, guest! Login / Register - Why register?
Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so just use oauth login instead. :)

Paste

Pasted as C by dEVIANT ( 15 years ago )
// Interpreter.cpp : Defines the entry point for the console application.
// Implementovane v Microsoft Visual C++ 2008 Express Edition
// tymto sposobom:
// File -> New project -> Win32 | Win32 CLR Application
//
// Rekurzivny interpretator bezkontextoveho jazyka
// Vyhodnocuje zatvorkovane vyrazy s operaciami + a -
// operandami su cele cisla.
// napr. 2, 2+3, 5-(6-2), (((5))), atd.

#include <stdio.h>
#include <conio.h>
#include <ctype.h>

#define SetType unsigned long int

#define SymType int

#define E 1 <<  // napr. E VALUE => 1 equiv {VALUE}, lebo VALUE = 0 

// Typy symbolov a mnozin symbolov

enum Symbols { VALUE, PLUS, MINUS, LPAR, RPAR, SEOF, SERROR, MUL, DIV, COMA, DOT, PRINT }; 
// definicia symbolov VALUE, PLUS, MINUS, atd.

SetType SymbolSet = 0; 
// Nastavenie SymbolSet na prazdnu mnozinu

// Vstupne premenne
char sourceString[100]; // - vstupny retazec
char c; int ic; // vstupny znak a index do vstupneho retazca

// Vystupny symbol lexikalnej analyzy, jeho kod a atribut
SymType symbol; int code, attr;

// Vystupna hodnota value ... hodnota vyrazu Expr

//  Operacie na mnozine symbolov
//  E symbol          equiv     {symbol}
// (E symbol) | set   equiv     {symbol) \cup set
// (E symbol) & set   equiv     symbol \in set


// Lexikalny analyzator 
void getsymbol()
{ 
  c = sourceString[ic++];
  while (c == ' ') {
    c = sourceString[ic++];
  }

  switch (c) {
    case '+': symbol = PLUS; break;
    case '-': symbol = MINUS; break;
    case '*': symbol = MUL; break;
    case '/': symbol = DIV; break;
    case '(': symbol = LPAR; break;
    case ')': symbol = RPAR; break;
    case '\0': symbol = SEOF; break;
    case '.' : symbol = DOT; break;
    case ';' : symbol = COMA; break;
    case 'p' :{ 
         if(sourceString[ic] == 'r'){
         if(sourceString[ic+1]=='i'){
         if(sourceString[ic+2]=='n'){
         if(sourceString[ic+3]=='t'){
              symbol = PRINT;
              ic = ic + 4;
              break;
         }else{symbol = SERROR;}
         }else{symbol = SERROR;}
         }else{symbol = SERROR;}
         }else{symbol = SERROR;}
                      }
    default:
      if (c >= '0' && c <= '9') {
        symbol = VALUE;
        attr = 0;
        while (c >= '0' && c <= '9') {
          attr = attr * 10 + (int) c - (int) '0';
          c = sourceString[ic++];
        }
        ic--;
      } else {
        symbol = SERROR;
      }
  }
}

//// pr(-) < pr(/) = pr(+) < pr(*) N+ L- P* N/
// Interpretator vyrazov s gramatikou

// Prog     -> Seq ('.')                      
// Seq      -> Line { (';') Line}             
// Line     -> ('print') Expr

// Expr -> PlusDiv { "-" PlusDiv }
// PlusDiv -> MulExpr [ "+|/" MulExpr ]
// MulExpr -> UnMinus [ "*" MulExpr ]
// UnMinus -> ["-"] Term 
// Term -> <Value> | (Expr) 
SetType H_Term = (E VALUE) | (E LPAR);
SetType H_Umin = (E MINUS) | H_Term;
SetType H_MulExpr  =  H_Umin;
SetType H_PlusDiv =  H_MulExpr;
SetType H_Expr = H_PlusDiv;
SetType H_Line = (E PRINT);
SetType H_Seq  =  H_Line;
SetType H_Prog =  H_Seq;

int expr(SetType);
int PlusDiv(SetType);
int MulExpr(SetType);
int UnMinus(SetType);
int seq(SetType);
int line(SetType);

void error(const char *msg, SetType K) {
  printf("CHYBA: %s\n", msg);

 // preskocenie neklucovych symbolov
  while (!(E symbol & K)) {
    getsymbol();
  }
}

void check(const char *msg, SetType K) {
  if (!(E symbol & K)) {
    error(msg, K);
  }
}

int Prog(SetType K){
     int leftop = seq((E DOT) | K);
     if((E symbol) & (E DOT)){
      getsymbol();
      }else{error("Chyba bodka .", K);}
   return leftop;
}

//Seq -> Line {';' Line}
int seq(SetType K){
 int leftop;
     SetType Kc = E COMA | H_Line;
     leftop = line(Kc | K);
     check("Ocakava sa ; alebo vyraz",Kc | K);
     while((E symbol)& (Kc)){
      if((E symbol)&(E COMA)){
       getsymbol();
     }else{error("Chyba ;",Kc | K);}
     leftop = line(Kc | K);  
     check("Ocakava sa ; alebo vyraz",Kc | K);       
     }
  return leftop;
}
//Line -> ('print') Expr
int line(SetType K){
   int result;
   int sy = 0;
   if((E symbol)&(E PRINT)){
      getsymbol();
      sy =1;
      }else{error("Chyba slovo print",H_Expr | K);}
      result = expr(K);
      if(sy){
    printf("\n    print;");
       printf("\n\nVysledok vypoctu vyrazu je %d\n", result);
   }
   return result;
}

// Term -> <Value> | (Expr) 
int term(SetType K)
{ int value = 0;
    check("Ocakava sa cislo alebo (", E VALUE | E LPAR | K);
 switch (symbol)
 {
  case LPAR : getsymbol(); value = expr(K | E RPAR); 
   if((E symbol)&(E RPAR)){
            getsymbol();
            }else{error("Chyba )",K);}
   break;
  case VALUE: value = attr;
   printf("\n    push %d;", value);
   getsymbol(); break;
  default: error("Chyba cislo alebo (",K);
 }
 return value;
}

// Expr -> PlusDiv { "-" PlusDiv }
int expr(SetType K)
{ int leftOp, rightOp; SymType sy; 
    SetType Kc = E MINUS | H_PlusDiv;
 leftOp = PlusDiv(K | Kc); 
 check("Ocakava sa - alebo vyraz", Kc | K);
 while ((E symbol) & ( E MINUS)) // operator - : asociativita zlava, najnizsia priorita
 {
          if((E symbol)&(E MINUS)){
           getsymbol();
          }else{error("\nChyba -", Kc | K);}
          rightOp = PlusDiv(K | Kc);
          leftOp = leftOp - rightOp;
     printf("\n    sub;");
    check("Ocakava sa - alebo vyraz", Kc | K);
 } 
 return leftOp;
}

// UnMinus -> ["-"] Term 
int UnMinus(SetType K)
{
 int sign = 1; 
 check("Ocakava sa - alebo vyraz", E MINUS | H_Term | K);
 if (symbol == MINUS) {
    getsymbol();
 sign = -1;
 printf("\n    neg;");
  }

 return sign * term(K);
}

// MulExpr -> UnMinus [ "*" MulExpr ]
int MulExpr(SetType K) // * vpravo asociativny, najvacsia priorita
{ int leftOp, rightOp; SymType sy; 
    SetType Kc = (E MUL) | H_Umin;
 leftOp = UnMinus(K | Kc); 
 check("Ocakava sa * alebo vyraz", K | Kc);
 if ((E symbol) & (E MUL))
 {
   if((E symbol)&(E MUL)){
         getsymbol();
         }else{error("Chyba *", K | Kc);}
   rightOp = MulExpr(K | Kc);
         leftOp = leftOp * rightOp ;
   printf("\n    mul;");
 } 
 return leftOp;
}

// PlusDiv -> MulExpr [ "+|/" MulExpr ]
int PlusDiv(SetType K) //neasociativny
{ int leftOp, rightOp; SymType sy; 
 leftOp = MulExpr(K | E PLUS | E DIV); 
 check("Ocakava sa /,+ alebo vyraz", K | E DIV | E PLUS);
 if ((E symbol) & (E PLUS | E DIV))
 {
  sy = symbol;
  if((E symbol)&(E DIV | E PLUS)){
            getsymbol();
        }else{error("Chyba + alebo /", K | E DIV | E PLUS);}
  rightOp = MulExpr(K);
  switch(sy)
  {
                  
      case PLUS :  leftOp = leftOp + rightOp;
    printf("\n    add;"); break;
      case DIV :  leftOp = leftOp / rightOp; 
    printf("\n    div;"); break;
        }
 } 
 return leftOp;
}

int main(int argc, char* argv[])
{ char tc; int i; 
    printf("\nSeparatna lexikalna analyza a interpretator vyrazov\n");
 printf("\nKody symbolov: VALUE=0, PLUS=1, MINUS=2, LPAR=3, RPAR=4, SEOF=5, SERROR=6, MUL=7, DIV=8");
 printf("\n-------------------------------------------------------------------------\n\n");

 printf("Vstupny vyraz (retazec znakov): "); 
// Citanie vstupneho retazca
 for (i = 0; (i < 100) && ((c = getchar()) != '\n'); i++)
    {
        sourceString[i] = c;
    } 
// Ukoncenie retazca znakom `\0` 
    sourceString[i] = '\0';
// 
 ic=0; // nastavenie na 1. znak
    printf("\nTest lexikalnej analyzy ------------> \n");
 printf( "\nVystup lexikalnej analyzy (retazec symbolov)\n\n", sourceString);
 /*do {
  getsymbol(); 
  printf("[%d] ",symbol); 
  if (symbol==VALUE) printf("<%d> ",attr); 
  tc=getch(); printf("\n");
 } while (symbol != SEOF);*/

  printf("\n  2. SYNTAXOU RIADENY PREKLAD");
  printf("\n  ---------------------------\n\n");
  // opatovne nastavenie indexu vstupneho retazca na prvy znak
  ic = 0;
  getsymbol();
  printf("  generovany postfixny kod:\n");
  int a = Prog(E SEOF);
  if (!(E symbol & E SEOF)){
        error("\nNespravne ukonceny program", E SEOF);}
  getchar();
  printf("\n");
  return 0;

 //printf("\n<------------Koniec testu lexikalnej analyzy a obnova vstupu\n"); tc=getch();
 //   printf("\nZaciatok syntaxou riadenej interpretacie\n\n");
 //ic=0; // opatovne nastavenie na 1. znak
 //getsymbol();
 //printf("Vysledok vypoctu vyrazu je %d\n\n", expr());
 //getchar();
 //   return 0;
}

 

Revise this Paste

Your Name: Code Language: