Untitled
unknown
plain_text
a year ago
13 kB
4
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