Untitled

 avatar
unknown
plain_text
5 months ago
13 kB
3
Indexable
 //flex
// import sekcija
import java_cup.runtime.*;

%%
// sekcija deklaracija
%class MPLexer

%cup

%line
%column

%eofval{
	return new Symbol( sym.EOF );
%eofval}

%{
   public int getLine()
   {
      return yyline;
   }
%}


// Stanja
%x KOMENTAR

// Makroi
slovo = [a-zA-Z]
cifra = [0-9]

%%

// Pravila

// Komentari
\|\*                          { yybegin(KOMENTAR); }
<KOMENTAR>~\*\|               { yybegin(YYINITIAL); }
<KOMENTAR>.                   { /* ignoriše sve */ }

// Razmaci
[\t\r\n]+                     { /* ignoriše razmake */ }

// Separatori
\(                            { return new Symbol(sym.LEFTPAR); }
\)                            { return new Symbol(sym.RIGHTPAR); }
;                             { return new Symbol(sym.SEMICOLON); }
:                             { return new Symbol(sym.COLON); }
,                             { return new Symbol(sym.COMMA); }
\.                            { return new Symbol(sym.DOT); }
:=                            { return new Symbol(sym.ASSIGN); }
=>                            { return new Symbol(sym.ARROW); }

// Relacioni operatori
"<"                           { return new Symbol(sym.LT); }
"<="                          { return new Symbol(sym.LE); }
"=="                          { return new Symbol(sym.EQ); }
"<>"                          { return new Symbol(sym.NE); }
">"                           { return new Symbol(sym.GT); }
">="                          { return new Symbol(sym.GE); }

// Konstante
0[0-7]+                       { return new Symbol( sym.INTCONST, new Integer( yytext() ) ); } 
0x[0-9a-fA-F]+                { return new Symbol( sym.INTCONST, new Integer( yytext() ) ); } 
[1-9][0-9]*                   { return new Symbol( sym.INTCONST, new Integer( yytext() ) ); } 
{cifra}+\.{cifra}*(E[\+\-]?{cifra}+)? { return new Symbol( sym.REALCONST, new Double( yytext() ) ); } 
\.'                           { return new Symbol( sym.REALCONST, new Double( yytext() ) ); } 
'[^]' 						  { return new Symbol( sym.CHARCONST, new Character( yytext().charAt(1) ) ); }
true|false                    { return new Symbol( sym.BOOLCONST, new Boolean( yytext() ) ); } 

// Ključne reči
"program"                     { return new Symbol(sym.PROGRAM); }
"integer"                     { return new Symbol(sym.INTEGER); }
"char"                        { return new Symbol(sym.CHAR); }
"begin"                       { return new Symbol(sym.BEGIN); }
"end"                         { return new Symbol(sym.END); }
"real"                        { return new Symbol(sym.REAL); }
"select"                      { return new Symbol(sym.SELECT); }
"case"                        { return new Symbol(sym.CASE); }
"or"                          { return new Symbol(sym.OR); }
"and"                         { return new Symbol(sym.AND); }

// Identifikatori
({slovo}|\$)({slovo}|{cifra}|\$)* { return new Symbol(sym.ID); }

// Obrada grešaka
.                             { System.err.println("Nepoznat simbol: " + yytext()); }

//cup

pe.BOOLEAN || expr2.tkind != Type.BOOLEAN) {
		            System.out.println("Greska u liniji " + parser.getLine() + ": Logicki operator 'OR' se primenjuje samo na tip bool.");
		            parser.errNo++;
		        }
		        RESULT = parser.symbolTable.getType("boolean");
			:}
            | AndExpression:a
	        {:
	            RESULT = a;
	        :}
            ;
AndExpression ::= AndExpression:expr1 AND RelExpression:expr2
			{:
			    if (expr1.tkind != Type.BOOLEAN || expr2.tkind != Type.BOOLEAN) {
			        System.out.println("Greska u liniji " + parser.getLine() + ": Logicki operator 'AND' se primenjuje samo na tip bool.");
			        parser.errNo++;
			    }
			    RESULT = parser.symbolTable.getType("boolean");
			:}
            | RelExpression:r
	        {:
	            RESULT = r;
	        :}
            ;          

RelExpression ::= Term:t1 RelOp Term:t2
				{:
			    if ((t1.tkind != Type.INTEGER && t1.tkind != Type.REAL) || 
			        (t2.tkind != Type.INTEGER && t2.tkind != Type.REAL)) {
			        System.out.println("Greska u liniji " + parser.getLine() + ": Relacioni operatori se primenjuju samo na numericke tipove.");
			        parser.errNo++;
			    }
			    RESULT = parser.symbolTable.getType("boolean");
				:}
            | Term:t
	        {:
	            RESULT = t;
	        :}
            ;

RelOp ::= LT
        | LE
        | EQ
        | NE
        | GT
        | GE;
Konstanta ::= INTCONST:c
              {:
                 RESULT = new Constant( parser.symbolTable.getType( "integer" ), c );
              :}
            | REALCONST:c
              {:
                 RESULT = new Constant( parser.symbolTable.getType( "real" ), c );
              :}
          	| BOOLCONST:c
              {:
                 RESULT = new Constant( parser.symbolTable.getType( "boolean" ), c );
              :}
			| CHARCONST:c
              {:
                 RESULT = new Constant( parser.symbolTable.getType( "char" ), c );
              :}
            ;
            
Term ::= ID:ime
			{:
			    Variable var = parser.symbolTable.getVar(ime);
			    if (var == null) {
			        System.out.println("Greska u liniji " + parser.getLine() + ": Promenljiva '" + ime + "' nije deklarisana.");
			        parser.errNo++;
			        RESULT = parser.symbolTable.getType("unknown");
			    }
			    else 
			    {
			      	RESULT = var.type;
			      	if ( var.last_def == -1 )
			      	{
			      		System.out.println( "Greska u liniji " + parser.getLine() + 
			      			": promenljiva " + ime + " nije inicijalizovana.");
			      		parser.errNo++;
			      	}
			        var.last_use = parser.getLine();
			    }
			:}
            | Konstanta:c
            {:
              RESULT = c.type;
			:}
            | LEFTPAR Expression:e RIGHTPAR
           	{:
           	   RESULT = e;
           	:}
            ;

//cup2//import sekcija

import java_cup.runtime.*;
import java.io.*;
import java.util.*;

import SymbolTable.*;

parser code {:

   public int errNo = 0;
   public int warnNo = 0;
   
   SymbolTable symbolTable;
   
   public static void main( String[] args )
   {
      try
	  {
		   FileReader file = new FileReader( args[0] );
		   java_cup.runtime.Scanner scanner = new MPLexer( file );
		   MPParser parser = new MPParser( scanner );
		   parser.parse();
		   parser.checkWarnings();
		   if ( parser.errNo == 0 && parser.warnNo == 0 )
		      System.out.println( "Analiza zavrsena. U kodu nema gresaka." );
		   else
		      System.out.println( "Analiza zavrsena. Broj gresaka: " + parser.errNo 
		         + " Broj upozorenja: " + parser.warnNo );
	  }
	  catch( Exception e )
	  {
		   e.printStackTrace();
	  }
   }
   
   public void checkWarnings()
   {
      SymbolNode current = symbolTable.getVariables();
      while ( current != null )
      {
      	Variable var = ( Variable ) current;
      	if ( var.last_def == -1 && var.last_use == -1 )
      	{
      		System.out.println( "Upozorenje: Promenljiva " + var.name + 
      			" je deklarisana, ali se nigde ne koristi." );
      		warnNo++;
      	}
      	else if ( var.last_def > var.last_use )
      	{
      		System.out.println( "Upozorenje: Vrednost dodeljena promeljivoj " +
      		    var.name + " u liniji " + var.last_def + " se nigde ne koristi." );
      		warnNo++;
      	}
      	current = current.next;
     }
   }
   
   public void syntax_error(Symbol cur_token)
   {
   	  
   }
   
   public void report_error(String message, Object info)
   {
   	   System.out.print( message );
   }
   
   public int getLine()
   {
   	  return (( MPLexer) getScanner()).getLine();
   }
:};

init with {:
	symbolTable = new SymbolTable();
:}


terminal String PROGRAM, BEGIN, END, INTEGER, CHAR, REAL, SELECT, CASE, OR, AND, BOOLEAN, TRUE, FALSE;
terminal String ID, CONST;
terminal String ASSIGN, LT, LE, EQ, NE, GT, GE;
terminal String LEFTPAR, RIGHTPAR, COLON, COMMA, DOT, SEMICOLON, ARROW;
terminal Integer INTCONST;
terminal Real REALCONST;
terminal Boolean BOOLCONST;
terminal Character CHARCONST;

// Non-terminali
non terminal Program, Block, Variables, Declaration, StatementList, Statement, SelectStatement, CaseList, Case;
non terminal RelOp;
non terminal Type Tip, Expression, AndExpression, RelExpression, Term;
non terminal ArrayList NameList;
non terminal Constant Konstanta;



precedence nonassoc ID;	

// Pravila
Program ::= PROGRAM Block DOT
         | PROGRAM error
         {:
    	System.out.println(  "Ocekuje se block");
    	parser.errNo++;
		:}
		| error
		{:
    	System.out.println("Nedostaje program na pocetku programa.");
   		parser.errNo++;
		:};
		

Block ::= BEGIN Variables StatementList END
       | BEGIN Variables StatementList error
       {:
    	System.out.println("Nedostaje end");
    	parser.errNo++;
		:};
       

Variables ::= Variables Declaration
           | /* empty */;


Declaration ::= NameList:nl COLON Tip:t SEMICOLON
				{:
				Type tip = (Type) t;
			    for (int i = 0; i < nl.size(); i++) {
			        String ime = (String) nl.get(i);
			        if (!parser.symbolTable.addVar(ime, tip)) {
			            System.out.println("Greska u liniji " + parser.getLine() + ": Promenljiva '" + ime + "' je vec deklarisana.");
			            parser.errNo++;
			        }
			    }
			:}
              | NameList:nl COLON error
    			{:
       			Type t = parser.symbolTable.getType("unknown");
        		for (int i = 0; i < nl.size(); i++) {
			        String ime = (String) nl.get(i);
			        if (!parser.symbolTable.addVar(ime, t)) {
			            System.out.println("Greska u liniji " + parser.getLine() + ": Promenljiva '" + ime + "' je vec deklarisana.");
			            parser.errNo++;
			        }
			    }
        		System.out.println("Greška u liniji " + parser.getLine() + ": Neodgovarajući tip.");
        		parser.errNo++;
    			:}
    		 | NameList:nl error
    			{:
        		Type t = parser.symbolTable.getType("unknown");
        		for (int i = 0; i < nl.size(); i++) {
			        String ime = (String) nl.get(i);
			        if (!parser.symbolTable.addVar(ime, t)) {
			            System.out.println("Greska u liniji " + parser.getLine() + ": Promenljiva '" + ime + "' je vec deklarisana.");
			            parser.errNo++;
			        }
			    }
        		System.out.println("Greška u liniji " + parser.getLine() + ": Nedostaje simbol ':' u deklaraciji.");
        		parser.errNo++;
    			:};

NameList ::= NameList:niz COMMA ID:ime
				{:
			        RESULT = niz;
			        RESULT.add(ime);
			    :}
			    | NameList:niz COMMA error
			    {:
			        System.out.println("Greška u liniji " + parser.getLine() + ": Nedostaje ime promenljive.");
			        parser.errNo++;
			        RESULT = niz;
			    :}
			    | ID:ime
			    {:
			        RESULT = new ArrayList();
			        RESULT.add(ime);
			    :};

          
Tip ::= INTEGER
	    {:
	        RESULT = parser.symbolTable.getType("integer");
	    :}
	    | CHAR
	    {:
	        RESULT = parser.symbolTable.getType("char");
	    :}
	    | REAL
	    {:
	        RESULT = parser.symbolTable.getType("real");
	    :}
	    | BOOLEAN
	    {:
	        RESULT = parser.symbolTable.getType("boolean");
	    :};


StatementList ::= Statement
              | StatementList Statement
				;


Statement ::= SelectStatement
           | ID:ime ASSIGN Expression:i SEMICOLON
           {:
			 Variable var = parser.symbolTable.getVar(ime);
			 if ( var == null )
			 {
			 	System.out.println( "Ggreska u liniji " +
				parser.getLine() + ": promenljiva " + ime + " nije deklarisana.");
			 	parser.errNo++;
			 }
			 else
			 {
			 	var.last_def = parser.getLine();
			 	 if ((var.type.tkind == Type.REAL && i.tkind == Type.INTEGER) ||
               		(var.type.tkind == Type.INTEGER && i.tkind == Type.CHARACTER) || 
               		(var.type.tkind == Type.REAL && i.tkind == Type.CHARACTER)){
               			System.out.println("Implicitna konverzija između tipova " + var.type.name + " i " + i.name);
           		} else {
               			System.out.println( "Greška u liniji " + parser.getLine() + ": Neslaganje tipa u naredbi dodele.");
               			parser.errNo++;
           		}
			 }
			 :} 

           | Block
		   ;

SelectStatement ::= SELECT BEGIN CaseList END
                 | SELECT error 
                 {:
    			System.out.println(  "Ocekuje se begin");
    			parser.errNo++;
				:};

CaseList ::= CaseList Case
          | Case
          | error
          {:
    	System.out.println("Ocekuje se CaseList");
    	parser.errNo++;
			:};

Case ::= CASE Expression:i ARROW Statement
		{:
		 	if ( i.tkind != Type.BOOLEAN )
		 	{
		 	System.out.println("Greska u liniji " + parser.getLine() + ": " +
		 		"Uslov ne moze biti tipa " + i.name );
		 	parser.errNo++;
		 	} 
		 	:};



Expression ::= Expression:expr1 OR AndExpression:expr2
			{:
		        if (expr1.tkind != Ty
Editor is loading...
Leave a Comment