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