Advertisement
Guest User

Untitled

a guest
May 21st, 2018
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 40.76 KB | None | 0 0
  1. package ba140645d.mjcompiler;
  2.  
  3.  
  4. import ba140645d.mjcompiler.ast.*;
  5. import ba140645d.mjcompiler.ast.Condition;
  6. import ba140645d.mjcompiler.utilities.StructLinkedList;
  7. import com.sun.istack.internal.NotNull;
  8. import com.sun.istack.internal.Nullable;
  9. import rs.etf.pp1.symboltable.Tab;
  10. import rs.etf.pp1.symboltable.concepts.Obj;
  11. import rs.etf.pp1.symboltable.concepts.Struct;
  12. import rs.etf.pp1.symboltable.structure.SymbolDataStructure;
  13.  
  14. import java.util.Iterator;
  15.  
  16. public class SemanticAnalyzer extends VisitorAdaptor{
  17.  
  18.     // kod za Bool tip
  19.     private static final int Bool = 5;
  20.  
  21.     private static final Struct boolType = new Struct(Bool);
  22.     // da li je semanticka provera
  23.     private boolean semanticCheck = true;
  24.  
  25.     // trenutni tip
  26.     private Type currentType = null;
  27.  
  28.     // objekat trenutnog tipa
  29.     private Obj currentTypeObj = Tab.noObj;
  30.  
  31.     //struktura trenutnog tipa
  32.     private Struct currentTypeStruct = Tab.noType;
  33.  
  34.     // objekat trenutnog metoda
  35.     private Obj currentMethod = Tab.noObj;
  36.  
  37.     // broj formalnih parametara metode
  38.     private int currentMethodFormParNum = 0;
  39.  
  40.     // objekat pocetnog designatora
  41.     private Obj designatorObj = Tab.noObj;
  42.  
  43.     // fleg da li smo u petlji
  44.     boolean insideLoop = false;
  45.  
  46.     /****************************************************************************
  47.      ****************************************************************************
  48.      *****************         KONSTANTNE VREDNOSTI         *********************
  49.      ****************************************************************************
  50.      ****************************************************************************/
  51.  
  52.     private static final String ARR_INDEX_TYPE_ERR = "Indeks niza mora biti tipa Int!";
  53.  
  54.     private static final String NOT_ARR_TYPE_ERR_MSG = "Tip mora biti niz!";
  55.  
  56.     private static final String INCOMPATIBLE_TYPE_ERR_MSG = "Tipovi nisu kompatabilni!";
  57.  
  58.     private static final String REF_TYPE_RELOP_ERR_MSG = "Nedozvoljen relacioni operator za reference";
  59.  
  60.     private static final String BREAK_STMT_ERR_MSG = "Break naredba se moze koristiti samo u petlji!";
  61.  
  62.     private static final String CONTINUE_STMT_ERR_MSG = "Continue naredba se moze koristiti samo u petlji!";
  63.  
  64.  
  65.     /****************************************************************************
  66.      ****************************************************************************
  67.      ***********************          KONSTRUKTOR          **********************
  68.      ****************************************************************************
  69.      ****************************************************************************/
  70.  
  71.     public SemanticAnalyzer(){
  72.         Tab.init();
  73.  
  74.  
  75.         Tab.currentScope().addToLocals(new Obj(Obj.Type, "bool", boolType));
  76.     }
  77.  
  78.  
  79.     /****************************************************************************
  80.      ****************************************************************************
  81.      *******************          PRIVATNE METODE           *********************
  82.      ****************************************************************************
  83.      ****************************************************************************/
  84.  
  85.     private boolean isDefinedInCurrentScope(String symName){
  86.         return Tab.currentScope().findSymbol(symName) != null;
  87.     }
  88.  
  89.     private boolean isDefined(String symName){
  90.         return Tab.find(symName) != Tab.noObj;
  91.     }
  92.  
  93.  
  94.     private boolean areEquivalentTypes(Obj typeObj1, Obj typeObj2){
  95.         if (typeObj1.getKind() != Obj.Type || typeObj2.getKind() != Obj.Type) {
  96.             System.err.println("FATAL ERROR!!! in function areEquivalentTypes! ");
  97.             System.err.println("obj1 type is : " + symbolTypeToString(typeObj1.getKind()));
  98.             System.err.println("obj2 type is : " + symbolTypeToString(typeObj2.getKind()));
  99.  
  100.             return false;
  101.         }
  102.  
  103.         boolean areArrays = typeObj1.getType().getKind() == Struct.Array
  104.                 && typeObj2.getType().getKind() == Struct.Array;
  105.  
  106.         return typeObj1.getName().equals(typeObj2.getName()) || typeObj1.getType().equals(typeObj2.getType());
  107.     }
  108.  
  109.  
  110.  
  111.  
  112.     private void logInfo(String message, SyntaxNode node){
  113.         String lineInfo = "Na liniji (" + node.getLine() + "): ";
  114.         System.out.println(lineInfo + message);
  115.     }
  116.  
  117.     private void logError(String message, SyntaxNode node){
  118.         String lineInfo = "Greska na liniji (" + node.getLine() + "): ";
  119.         System.err.println(lineInfo + message);
  120.     }
  121.  
  122.     private String formatAlreadyDefinedMessage(String symbolName){
  123.         return "Simbol [" + symbolName + "] je vec definisan!";
  124.     }
  125.  
  126.     private String formatSymbolNotDefinedMessage(String symbolName){
  127.         return "Simbol [" + symbolName + "] nije definisan!";
  128.     }
  129.  
  130.     private String formatAssignmentMessage(Struct leftSideType, Struct rightSideType, @Nullable Struct expectedType){
  131.         String leftSideTypeName = symbolTypeToString(leftSideType.getKind());
  132.         String rightSideTypeName = symbolTypeToString(rightSideType.getKind());
  133.         String expectedTypeName = (expectedType != null)? symbolTypeToString(expectedType.getKind()) : null;
  134.  
  135.         String message = "Na levoj strani je tip : {" + leftSideTypeName + "}. Na desnoj strani je tip : {" + rightSideTypeName +"}. ";
  136.  
  137.         if (expectedType != null)
  138.             message += "Ocekivani tip je : {" + expectedTypeName + "}";
  139.  
  140.         return message;
  141.     }
  142.  
  143.  
  144.     private String formatWrongSymbolKindMessage(int actualSymbolKind, int expectedSymbolKind){
  145.         return "Stvarna vrsta simbola je : {" + symbolKindToString(actualSymbolKind) + "}. Ocekivana vrsta simbola je : {" + symbolKindToString(expectedSymbolKind) + "}";
  146.     }
  147.  
  148.     private String formatWrongTypeMessage(Struct expectedType, Struct actualType){
  149.         String expectedTypeName = symbolTypeToString(expectedType.getKind());
  150.         String actualTypeName = symbolTypeToString(actualType.getKind());
  151.  
  152.         return "Tip je : {" + actualTypeName +"}. Ocekivan tip je : {" + expectedTypeName + "} ";
  153.     }
  154.  
  155.     private String formatClassMemberDoesntExistMessage(Obj classObj, String fieldName){
  156.         String className = classObj.getName();
  157.  
  158.         return "U klasi : {" + className + "} ne postoji polje sa nazivom : {" + fieldName + "} ";
  159.     }
  160.  
  161.     private String formatWrongTypeMessage(int expectedType, int actualType){
  162.         String expectedTypeName = symbolTypeToString(expectedType);
  163.         String actualTypeName = symbolTypeToString(actualType);
  164.  
  165.         return "Tip je : {" + actualTypeName +"}. Ocekivan tip je : {" + expectedTypeName + "} ";
  166.     }
  167.  
  168.     private String formatAssignmentMessage(String leftSideType, String rightSideType, @Nullable String expectedType){
  169.  
  170.         String message = "Na levoj strani je tip : {" + leftSideType+ "}. Na desnoj strani je tip : {" + rightSideType +"}. ";
  171.  
  172.         if (expectedType != null)
  173.             message += "Ocekivani tip je : {" + expectedType + "}";
  174.  
  175.         return message;
  176.     }
  177.  
  178.     private String formatSymbolName(String symbolName){
  179.         return "Simbol [" + symbolName + "]";
  180.     }
  181.  
  182.     /**
  183.      * Konvertuje kod vrste simbola u string
  184.      * @param symbolKind kod vrste simbola
  185.      * @return vrsta simbola kao string
  186.      */
  187.     private String symbolKindToString(int symbolKind){
  188.         String retVal = "Unknown";
  189.         switch(symbolKind){
  190.             case Obj.Con :  retVal =  "Con";    break;
  191.             case Obj.Elem : retVal = "Elem";    break;
  192.             case Obj.Fld : retVal = "Fld";      break;
  193.             case Obj.Meth : retVal = "Meth";    break;
  194.             case Obj.Prog : retVal = "Prog";    break;
  195.             case Obj.Type : retVal = "Type";    break;
  196.             case Obj.Var : retVal = "Var";      break;
  197.         }
  198.  
  199.         return retVal;
  200.     }
  201.  
  202.     /**
  203.      * Konvertuje kod tipa simbola u string
  204.      * @param symbolType tip simbola predstavljen celobrojnom vrednoscu
  205.      * @return vraca zeljeni tip simbola u vidu stringa
  206.      */
  207.     private String symbolTypeToString(int symbolType){
  208.         String retVal = "Unknown";
  209.  
  210.         switch(symbolType){
  211.             case Struct.Array : retVal = "Array";       break;
  212.             case Struct.Char :  retVal = "Char";        break;
  213.             case Struct.Int :   retVal = "Int";         break;
  214.             case Struct.None :  retVal = "None";        break;
  215.             case Bool :         retVal = "Bool";        break;
  216.         }
  217.  
  218.         return retVal;
  219.     }
  220.  
  221.     /**
  222.      * Formatira opste informacije simbola za ispis ( naziv, vrsta, tip)
  223.      * @param symbol zeljeni simbol za ispis
  224.      * @return formatirana poruka sa opstim informacijama simbola
  225.      */
  226.     private String formatSymbolInfo(Obj symbol){
  227.         String symbolNameFormat = formatSymbolName(symbol.getName());
  228.         String symbolKind = symbolKindToString(symbol.getKind());
  229.         String symbolType = symbolTypeToString(symbol.getType().getKind());
  230.  
  231.         String format = symbolNameFormat + " kind : " + symbolKind + ", type : " + symbolType;
  232.  
  233.         if (symbol.getType().getKind() == Struct.Array)
  234.             format += " of " + symbolTypeToString(symbol.getType().getElemType().getKind());
  235.  
  236.  
  237.         return format;
  238.  
  239.     }
  240.  
  241.  
  242.     /**
  243.      * Formatira ispis koji naglasava koliko parametara ima data metoda
  244.      * @param funcObj simbol metode
  245.      * @return formatirana poruka za ispis
  246.      */
  247.     private String formatFuncParNumIncorrectMessage(@NotNull Obj funcObj){
  248.  
  249.         if (funcObj.getLevel() == 0)
  250.             return "Funkcija : {" + funcObj.getName() + "} ne prima parametre";
  251.         else if (funcObj.getLevel() == 1)
  252.             return "Funkcija : {" + funcObj.getName() + "} ima " + funcObj.getLevel() + " parametar";
  253.         else
  254.             return "Funkcija : {" + funcObj.getName() + "} ima " + funcObj.getLevel() + " parametra";
  255.     }
  256.  
  257.  
  258.     /**
  259.      * Formatira ispis greske kada tip formalnog i stvarnog parametra metode nije kompatabilan pri dodeli
  260.      * @param actualType tip stvarnog parametra metode
  261.      * @param formalType tip formalnog parametra metode
  262.      * @param paramNum redni broj parametra u metodi
  263.      * @return formatirana poruka za ispis
  264.      */
  265.     private String formatFuncWrongParTypeMessage(@NotNull Struct actualType, @NotNull Struct formalType, int paramNum){
  266.         String wrongTypeMsg = formatWrongTypeMessage(formalType.getKind(), actualType.getKind());
  267.  
  268.         return "Parametar broj : " + paramNum + ". " + wrongTypeMsg;
  269.     }
  270.  
  271.  
  272.     /**
  273.      * Funkcija koja obmotava ponasanje za visit metode vezane za izraze
  274.      * Moze biti maksimalno jedan od tipova operanda izostavljen, ali ne i oba ( smatra se greskom )
  275.      * @param leftOperandType tip levog operanda, mooze biti izostavljen
  276.      * @param rightOperandType tip desnog operanda, moze biti izostavljen
  277.      * @return vraca tip koji je rezultat izraza
  278.      */
  279.     private Struct checkIfValidExpr(@Nullable  Struct leftOperandType, @Nullable Struct rightOperandType, SyntaxNode visitedNode){
  280.         Struct returnType = Tab.intType;
  281.  
  282.         if (leftOperandType == null && rightOperandType == null){
  283.             System.err.println("FATAL ERROR!!! Function checkIfValidExpr has null left and right parameter");
  284.  
  285.             return returnType;
  286.         }
  287.  
  288.         // postoji samo jedan operand i samo se vratimo
  289.         if (rightOperandType == null)
  290.             return leftOperandType;
  291.         else if (leftOperandType == null)
  292.             return rightOperandType;
  293.  
  294.  
  295.         if (leftOperandType.equals(Tab.intType) && rightOperandType.equals(Tab.intType))
  296.             return Tab.intType;
  297.         else if (!leftOperandType.equals(Tab.noType) || !rightOperandType.equals(Tab.noType))
  298.             logError("Aritmeticki izrazi zahtevaju da operandi budu tipa Int", visitedNode);
  299.  
  300.  
  301.         return returnType;
  302.     }
  303.  
  304.     /**
  305.      *  Formatira poruku za ispis koja navodi da nisu navedeni parametri za poziv funkcije
  306.      * @param funcObj simbol funkcije
  307.      * @return string poruke
  308.      */
  309.     private String formatMissingFuncActParsMessage(@NotNull Obj funcObj){
  310.         // dohvatamo vrstu simbola
  311.         int objKind = funcObj.getKind();
  312.  
  313.  
  314.         if (objKind != Obj.Meth){
  315.             System.err.println("FATAL ERROR!!! In function formatMissingFuncActParsMessage. Obj kind is : " + symbolKindToString(objKind));
  316.  
  317.             return "";
  318.         }
  319.  
  320.         // naziv fje
  321.         String funcName = funcObj.getName();
  322.  
  323.         return "Naveden je poziv funkcije {" + funcName + "} bez stvarnih argumenata!";
  324.     }
  325.  
  326.  
  327.     /**
  328.      *
  329.      * @param actualParsList lista stvarnih argumenata
  330.      * @param funcObj simbol funkcije
  331.      * @param syntaxNode referentni cvor stabla u slucaju da treba da se ispise greska
  332.      * @return fleg koji oznacava da li je sve u redu ili ne
  333.      */
  334.     private boolean checkFuncFormalAndActualPars(@NotNull StructLinkedList actualParsList, @NotNull Obj funcObj, @NotNull SyntaxNode syntaxNode){
  335.         // proverimo da li je broj elemenata liste jednak broju formalnih parametara fje
  336.         // ukoliko nije jednostavno se vratimo nazad
  337.         if (actualParsList.size() != funcObj.getLevel()){
  338.             logError(formatFuncParNumIncorrectMessage(funcObj), syntaxNode);
  339.  
  340.             return false;
  341.         }
  342.  
  343.         // kolekcija svih lokalnih simbola fje
  344.         // prvih N simbola su formalni parametri funkcije
  345.         Iterator<Obj> formalParsIt = funcObj.getLocalSymbols().iterator();
  346.  
  347.         // broj formalnih parametara
  348.         int parNum = funcObj.getLevel();
  349.  
  350.         boolean allOk = true;
  351.  
  352.         for(int i = 0; i <  parNum; ++i){
  353.             // formalni tip parametra
  354.             Struct formParType = formalParsIt.next().getType();
  355.  
  356.             // stvarni tip parametra
  357.             Struct actualParType = actualParsList.get(i);
  358.  
  359.             // ako nije moguce dodeliti onda treba ispisati gresku
  360.             if (!actualParType.assignableTo(formParType)) {
  361.                 logError(formatFuncWrongParTypeMessage(actualParType, formParType, i + 1), syntaxNode);
  362.  
  363.                 allOk = false;
  364.             }
  365.         }
  366.  
  367.         return allOk;
  368.     }
  369.  
  370.  
  371.     /****************************************************************************
  372.      ****************************************************************************
  373.      *******************       VISIT METODE ZA PROGRAM       ********************
  374.      **********************    KONSTANTE I PROMENLJIVE     **********************
  375.      ****************************************************************************/
  376.  
  377.     @Override
  378.     public void visit(Program program) {
  379.  
  380.         // pronalazimo simbol programa u tabeli simbola
  381.  
  382.         Obj programObj = Tab.find(program.getProgramName().getProgramName());
  383.  
  384.         logInfo(formatSymbolInfo(programObj), program);
  385.  
  386.         // ulancamo u njega sve lokalne simbole
  387.         Tab.chainLocalSymbols(programObj);
  388.  
  389.         // zatvorimo opseg
  390.         Tab.closeScope();
  391.     }
  392.  
  393.     @Override
  394.     public void visit(ProgramName programName){
  395.         // ubacujemo Program u tabelu simbola
  396.         Tab.insert(Obj.Prog, programName.getProgramName(), Tab.noType);
  397.  
  398.         // otvaramo opseg vazenja
  399.         Tab.openScope();
  400.     }
  401.  
  402.  
  403.     @Override
  404.     public void visit(ConstDefinition constDefinition){
  405.  
  406.         // ako tip ne postoji, odnosno nismo ga prepoznali u tabeli simbola
  407.         // to znaci da nema potrebe da proveravamo definiciju konstante
  408.         if (currentTypeObj == Tab.noObj)
  409.             return;
  410.  
  411.         // naziv konstante
  412.         String constName = constDefinition.getConstName();
  413.  
  414.         if (isDefined(constName))
  415.             logError(formatAlreadyDefinedMessage(constName), constDefinition);
  416.         else{
  417.             // dohvatanje vrste tipa podatka
  418.             Struct type = currentTypeObj.getType();
  419.  
  420.             // produkcija koja je jedna od 3 moguce konstante
  421.             ConstValue constValue = constDefinition.getConstValue();
  422.             // vrednost konstante
  423.             int value = 0;
  424.  
  425.             // tip sa desne strane dodele
  426.             Struct rightSide = Tab.noType;
  427.  
  428.  
  429.             // postavljamo tip podatka sa desne strane i citamo vrednost
  430.             if (constValue instanceof NumConst){
  431.                 rightSide = Tab.intType;
  432.  
  433.                 value = ((NumConst) constValue).getNumConst();
  434.             }else if (constValue instanceof CharConst){
  435.                 rightSide = Tab.charType;
  436.  
  437.                 value = ((CharConst) constValue).getCharConst();
  438.             }else if (constValue instanceof BoolConst){
  439.                 rightSide = Tab.find("bool").getType();
  440.  
  441.                 value = ((BoolConst) constValue).getBoolConst()  ? 1 : 0;
  442.             }
  443.  
  444.             // ispitujemo da li je dodela moguca
  445.             if (type.assignableTo(rightSide)){
  446.                 Obj constObj = Tab.insert(Obj.Con, constName, type);
  447.  
  448.                 logInfo(formatSymbolInfo(constObj), constDefinition);
  449.  
  450.                 constObj.setAdr(value);
  451.             }else{
  452.                 String assigmentErrorMsg = formatAssignmentMessage(currentTypeObj.getName(), symbolTypeToString(rightSide.getKind()), currentTypeObj.getName());
  453.  
  454.                 logError(assigmentErrorMsg, constDefinition);
  455.             }
  456.  
  457.  
  458.         }
  459.     }
  460.  
  461.     @Override
  462.     public void visit(Type type){
  463.  
  464.  
  465.         String typeName = type.getTypeName();
  466.  
  467.         currentTypeObj = Tab.noObj;
  468.  
  469.         currentType = type;
  470.  
  471.         if (!isDefined(typeName)){
  472.             logError(formatSymbolNotDefinedMessage(typeName), type);
  473.  
  474.             return;
  475.         }
  476.  
  477.  
  478.         // simbol je vec definisan,sada treba videti da li je u pitanju tip
  479.         Obj typeObj = Tab.find(typeName);
  480.  
  481.         if (typeObj.getKind() == Obj.Type)
  482.             currentTypeObj = typeObj;
  483.         else
  484.             logError(formatSymbolName(typeObj.getName()) + " nije tip!", type);
  485.  
  486.         currentTypeStruct = currentTypeObj.getType();
  487.     }
  488.  
  489.     @Override
  490.     public void visit(VarDeclDefinition varDeclDefinition){
  491.         String varName = varDeclDefinition.getVarName();
  492.  
  493.         // simbol vec definisan
  494.         if (isDefinedInCurrentScope(varName)) {
  495.             logError("Simbol[" + varName + "] je vec definisan u trenutnom opsegu!", varDeclDefinition);
  496.             return;
  497.         }
  498.  
  499.         // vracamo se takodje i ako nismo naisli na validan tip podatka
  500.         if (currentTypeObj == Tab.noObj)
  501.             return;
  502.  
  503.         boolean isArrayDecl = (varDeclDefinition.getOptArrayDecl() instanceof OptArrayDeclared);
  504.  
  505.         // u slucaju da je tip podatka niz nekog tipa, potrebna nam je struktura
  506.         // koja predstavlja niz tog tipa
  507.         Struct arrayStruct = new Struct(Struct.Array, currentTypeObj.getType());
  508.  
  509.         Obj varObj = null;
  510.         // ako je deklaracija niza, onda postavljamo za tip array strukturu
  511.         // inace postavljamo sam tip koji je naveden
  512.         if (isArrayDecl)
  513.             varObj = Tab.insert(Obj.Var, varName, arrayStruct);
  514.         else
  515.             varObj = Tab.insert(Obj.Var, varName, currentTypeObj.getType());
  516.  
  517.         logInfo(formatSymbolInfo(varObj), varDeclDefinition);
  518.     }
  519.  
  520.     /****************************************************************************
  521.      * **************************************************************************
  522.      ***************     VISIT METODE ZA DEFINISANJE METODA     *****************
  523.      ***************************    I PARAMETARA   ******************************
  524.      ****************************************************************************/
  525.  
  526.     @Override
  527.     public void visit(MethodName methodName){
  528.         String name = methodName.getMethodName();
  529.  
  530.         // uzimamo da je podrazumevano noObj
  531.         currentMethod = Tab.noObj;
  532.  
  533.         // inicijalizujemo broj formalnih parametara na 0
  534.         currentMethodFormParNum = 0;
  535.  
  536.         // ako je vec definisano onda prijavimo gresku
  537.         if (isDefined(name))
  538.             logError(formatAlreadyDefinedMessage(name), methodName);
  539.         else
  540.             currentMethod = Tab.insert(Obj.Meth, name, currentTypeStruct);
  541.  
  542.         // otvorimo opseg
  543.         Tab.openScope();
  544.     }
  545.  
  546.     @Override
  547.     public void visit(MethodDecl methodDecl){
  548.  
  549.         // uvezujemo lokalne simbole samo ukoliko je
  550.         // metoda dodata u tabelu simbola
  551.         if (currentMethod != Tab.noObj) {
  552.             Tab.chainLocalSymbols(currentMethod);
  553.  
  554.             // postavljamo broj formalnih parametara
  555.             currentMethod.setLevel(currentMethodFormParNum);
  556.  
  557.             logInfo(formatSymbolInfo(currentMethod), methodDecl);
  558.            /// logInfo(Integer.toString(currentMethodFormParNum) + " je broj formalnih parametara", methodDecl);
  559.             //logInfo(for);
  560.         }
  561.  
  562.         // zatvorimo doseg
  563.         Tab.closeScope();
  564.     }
  565.  
  566.  
  567.     @Override
  568.     public void visit(ReturnTypeVoid voidReturnType){
  569.         currentTypeStruct = Tab.noType;
  570.     }
  571.  
  572.     @Override
  573.     public void visit(FormParDecl formParDecl){
  574.         // naziv parametra
  575.         String formParName = formParDecl.getFormParName();
  576.  
  577.         // ako je vec definisan samo napisati gresku i vratiti se
  578.         if (isDefinedInCurrentScope(formParName)){
  579.             logError(formatAlreadyDefinedMessage(formParName), formParDecl);
  580.             return;
  581.         }
  582.  
  583.         // da li je niz?
  584.         OptArrayDecl isArray = formParDecl.getOptArrayDecl();
  585.  
  586.         // niz struktura u slucaju da je tip niz nekog tipa podatka (npr int[])
  587.         Struct arrayStruct = new Struct(Struct.Array, currentTypeStruct);
  588.  
  589.         Obj paramObj = null;
  590.  
  591.         if (isArray instanceof  OptArrayDeclared)
  592.             paramObj = Tab.insert(Obj.Var, formParName, arrayStruct);
  593.         else
  594.             paramObj = Tab.insert(Obj.Var, formParName, currentTypeStruct);
  595.  
  596.         // uvecavamo broj formalnih parametara
  597.         currentMethodFormParNum++;
  598.  
  599.         // informativno logovanje
  600.         logInfo(formatSymbolInfo(paramObj), formParDecl);
  601.     }
  602.  
  603.     /****************************************************************************
  604.      ****************************************************************************
  605.      *************     VISIT METODE ZA PRISTUP PROMENLJIVAMA     ****************
  606.      ****************************************************************************
  607.      ****************************************************************************/
  608.  
  609.  
  610.     @Override
  611.     public void visit(Designator designator){
  612.         designator.obj = designator.getDesignatorRepeatList().obj;
  613.     }
  614.  
  615.     @Override
  616.     public void visit(DesignatorInitialName designatorInitialName){
  617.         logInfo(designatorInitialName.getDesignatorName() +" initial", designatorInitialName);
  618.  
  619.         designatorObj = Tab.find(designatorInitialName.getDesignatorName());
  620.  
  621.         if (designatorObj == Tab.noObj)
  622.             logError(formatSymbolNotDefinedMessage(designatorInitialName.getDesignatorName()), designatorInitialName);
  623.     }
  624.  
  625.     @Override
  626.     public void visit(DesignatorRepeatListDeclared designatorRepeatListDeclared){
  627.  
  628.  
  629.         designatorRepeatListDeclared.obj = Tab.noObj;
  630.  
  631.  
  632.         Obj designatorObj = designatorRepeatListDeclared.getDesignatorRepeatList().obj;
  633.         //Obj designatorRepeatObj = designatorRepeatListDeclared.getDesignatorRepeat().obj;
  634.  
  635.         DesignatorRepeat designatorRepeat = designatorRepeatListDeclared.getDesignatorRepeat();
  636.  
  637.         // da li je u pitanju pristup polju ili elementu niza
  638.         if (designatorRepeat instanceof DesignatorRepeatField){
  639.             boolean isClass = designatorObj.getType().getKind() == Struct.Class;
  640.             String message = "";
  641.  
  642.             String fieldName = ((DesignatorRepeatField) designatorRepeat).getFieldName();
  643.  
  644.             // pristup preko tacke je moguc samo za podatke koji su tipa Class
  645.             // ukoliko nisu tipa class, jednostavno treba da prijavimo gresku i vratimo se
  646.             if (!isClass){
  647.                 message = formatWrongTypeMessage(Struct.Class, designatorObj.getType().getKind());
  648.                 logError(message, designatorRepeatListDeclared);
  649.  
  650.                 return;
  651.             }
  652.  
  653.             // dohvatimo sve clanove klase(funkcije i metode)
  654.             SymbolDataStructure classMembers = designatorObj.getType().getMembers();
  655.  
  656.             // trazimo simbol sa datim nazivom
  657.             Obj fieldObj = classMembers.searchKey(fieldName);
  658.  
  659.             // ukoliko dato polje ne postoji u klasi
  660.             // javiti gresku
  661.             if (fieldObj == null){
  662.                 message = formatClassMemberDoesntExistMessage(designatorObj, fieldName);
  663.                 logError(message, designatorRepeatListDeclared);
  664.  
  665.                 return;
  666.             }
  667.  
  668.             // nasli smo dato polje, samo taj objekat dodelimo cvoru AST-a
  669.             designatorRepeatListDeclared.obj = fieldObj;
  670.  
  671.         }else{ // slucaj kada je DesignatorRepeat zapravo DesignatorRepeatExpr(pristup elementu niza)
  672.             Expr arraySize = ((DesignatorRepeatExpr)designatorRepeatListDeclared.getDesignatorRepeat()).getExpr();
  673.  
  674.             if (!arraySize.struct.equals(Tab.intType)){
  675.                 logError(ARR_INDEX_TYPE_ERR, designatorRepeatListDeclared);
  676.  
  677.                 return;
  678.             }
  679.  
  680.             if (designatorObj.getType().getKind() != Struct.Array){
  681.                 logError(NOT_ARR_TYPE_ERR_MSG, designatorRepeatListDeclared.getDesignatorRepeatList());
  682.             }
  683.  
  684.             // naziv elementa
  685.             String elementName = designatorObj.getName();
  686.  
  687.             // sam tip elementa
  688.             // posto je tip designatorObj niz nekog tipa, treba da dohvatimo taj tip
  689.             Struct elementType = designatorObj.getType().getElemType();
  690.  
  691.             //objekat koji je tipa element niza
  692.             designatorRepeatListDeclared.obj = new Obj(Obj.Elem, elementName, elementType);
  693.         }
  694.     }
  695.  
  696.  
  697.     @Override
  698.     public void visit(DesignatorRepeatListEpsilon designatorRepeatListEpsilon){
  699.         designatorRepeatListEpsilon.obj = designatorObj;
  700.     }
  701.  
  702.     @Override
  703.     public void visit(DesignatorRepeatField designatorRepeatField){
  704.         //logInfo(designatorRepeatField.getFieldName(), designatorRepeatField);
  705.     }
  706.  
  707.     /***********************************************************************************
  708.      ***********************************************************************************
  709.      ********************       VISIT METODE NAREDBI DESIGNATORA       *****************
  710.      ***********************************************************************************
  711.      ***********************************************************************************/
  712.  
  713.  
  714.     @Override
  715.     public  void visit(DesignatorStatementAssign assignStatement){
  716.         // promenljiva kojoj dodeljujemo vrednost
  717.         Obj designatorObj = assignStatement.getDesignator().obj;
  718.  
  719.         // tip rezultata izraza
  720.         Struct exprType = assignStatement.getExpr().struct;
  721.  
  722.         // tip promenljive
  723.         Struct designatorType = designatorObj.getType();
  724.  
  725.         // ukoliko nisu kompatabilni pri dodeli prijavi se greska
  726.         if (!designatorType.assignableTo(exprType)){
  727.             logError(formatWrongTypeMessage(designatorType.getKind(), exprType.getKind()), assignStatement.getExpr());
  728.         }
  729.     }
  730.  
  731.  
  732.     @Override
  733.     public void visit(DesignatorStatementActualPars designatorFuncCall){
  734.         Obj funcObj = designatorFuncCall.getDesignator().obj;
  735.  
  736.         if (funcObj.getKind() != Obj.Meth){
  737.             logError(formatWrongSymbolKindMessage(funcObj.getKind(), Obj.Meth), designatorFuncCall.getDesignator());
  738.  
  739.             return;
  740.         }
  741.  
  742.         checkFuncFormalAndActualPars(designatorFuncCall.getOptActPars().structlinkedlist, funcObj, designatorFuncCall);
  743.     }
  744.  
  745.     @Override
  746.     public void visit(DesignatorStatementIncrement statementIncrement){
  747.         // objekat promenljive
  748.         Obj designatorObj = statementIncrement.getDesignator().obj;
  749.  
  750.         // tip promenljive
  751.         Struct designatorType = designatorObj.getType();
  752.  
  753.         // ako nije tipa int, prijaviti gresku
  754.         if (designatorType.getKind() !=  Struct.Int){
  755.             logError(formatWrongSymbolKindMessage(designatorType.getKind(), Struct.Int), statementIncrement.getDesignator());
  756.         }
  757.     }
  758.  
  759.  
  760.     @Override
  761.     public void visit(DesignatorStatementDecrement statementDecrement){
  762.         // objekat promenljive
  763.         Obj designatorObj = statementDecrement.getDesignator().obj;
  764.  
  765.         // tip promenljive
  766.         Struct designatorType = designatorObj.getType();
  767.  
  768.         // ako nije tipa int, prijaviti gresku
  769.         if (designatorType.getKind() !=  Struct.Int){
  770.             logError(formatWrongSymbolKindMessage(designatorType.getKind(), Struct.Int), statementDecrement.getDesignator());
  771.         }
  772.     }
  773.  
  774.  
  775.     /**********************************************************************
  776.      **********************************************************************
  777.      ********************       VISIT METODE IZRAZA       *****************
  778.      **********************************************************************
  779.      ********************************************************************/
  780.  
  781.     @Override
  782.     public void visit(Expr expr){
  783.         // cvor koji predstavlja unarni minus
  784.         OptMinus optMinus = expr.getOptMinus();
  785.  
  786.         // u pocetku stavljamo da je expr noType
  787.         expr.struct = Tab.noType;
  788.  
  789.         // tip podatka iz cvora Term
  790.         Struct leftOperandType = expr.getTerm().struct;
  791.  
  792.         // da li je naveden unarni operator
  793.         // ako jeste onda term mora biti integer
  794.         if (optMinus instanceof OptMinusDeclared){
  795.  
  796.             if (!leftOperandType.equals(Tab.intType)){
  797.                 logError("Operator unarni - ocekuje tip Int", expr);
  798.  
  799.                 return;
  800.             }
  801.         }
  802.  
  803.         Struct rightOperandType = expr.getAddopTermList().struct;
  804.  
  805.  
  806.         expr.struct = checkIfValidExpr(leftOperandType, rightOperandType, expr.getTerm());
  807.     }
  808.  
  809.     @Override
  810.     public void visit(AddopTerm addopTerm){
  811.         addopTerm.struct = addopTerm.getTerm().struct;
  812.     }
  813.  
  814.  
  815.     @Override
  816.     public void visit(AddopTermListEpsilon addopTermListEpsilon){
  817.         addopTermListEpsilon.struct = null;
  818.     }
  819.  
  820.     @Override
  821.     public void visit(AddopTermListDeclared addopTermListDeclared){
  822.         // tip levog operanda
  823.         Struct leftOperandType = addopTermListDeclared.getAddopTermList().struct;
  824.  
  825.         // tip desnog operanda
  826.         Struct rightOperandType = addopTermListDeclared.getAddopTerm().struct;
  827.  
  828.        addopTermListDeclared.struct =  checkIfValidExpr(leftOperandType, rightOperandType, addopTermListDeclared.getAddopTermList());
  829.     }
  830.  
  831.  
  832.     @Override
  833.     public void visit(Term term){
  834.         // tip levog operanda
  835.         Struct leftOperandType = term.getFactor().struct;
  836.  
  837.         // tip desnog operanda
  838.         Struct rightOperandType = term.getMulopFactorList().struct;
  839.  
  840.         term.struct = checkIfValidExpr(leftOperandType, rightOperandType, term);
  841.  
  842.     }
  843.  
  844.     @Override
  845.     public void visit(MulopFactor mulopFactor){
  846.         mulopFactor.struct = mulopFactor.getFactor().struct;
  847.     }
  848.  
  849.     @Override
  850.     public void visit(MulopFactorListEpsilon mulopFactorListEpsilon){
  851.         mulopFactorListEpsilon.struct = null;
  852.     }
  853.  
  854.     @Override
  855.     public void visit(MulopFactorListDeclared mulopFactorListDeclared){
  856.         // sve je isto kao i za addopTermListDeclared
  857.         mulopFactorListDeclared.struct = Tab.noType;
  858.  
  859.         Struct leftOperandType = mulopFactorListDeclared.getMulopFactorList().struct;
  860.  
  861.         Struct rightOperandType = mulopFactorListDeclared.getMulopFactor().struct;
  862.  
  863.         mulopFactorListDeclared.struct = checkIfValidExpr(leftOperandType, rightOperandType, mulopFactorListDeclared.getMulopFactorList());
  864.     }
  865.  
  866.  
  867.     @Override
  868.     public void visit(FactorFuncCallOrVar factorFuncCallOrVar){
  869.  
  870.         // dohvatamo objekat
  871.         Obj funcObj = factorFuncCallOrVar.getDesignator().obj;
  872.  
  873.         factorFuncCallOrVar.struct = funcObj.getType();
  874.  
  875.         // cvor koji sadrzi parametre fje
  876.         OptParenthesesActPars funcPars = factorFuncCallOrVar.getOptParenthesesActPars();
  877.  
  878.         // ako nije poziv f-je, a ima prosledjene parametre
  879.         if (funcObj.getKind() != Obj.Meth && funcPars instanceof  OptParenthesesActParsDeclared){
  880.             logError(formatWrongSymbolKindMessage(funcObj.getKind(), Obj.Meth), factorFuncCallOrVar);
  881.  
  882.             return;
  883.         }
  884.  
  885.         // ako nije metoda, jednostavno se vratimo
  886.         if (funcObj.getKind() != Obj.Meth)
  887.             return;
  888.  
  889.  
  890.         // ukoliko jeste metoda a parametri nisu postavljeni onda treba da prijavimo gresku
  891.         if (funcPars instanceof OptParenthesesActParsEpsilon){
  892.             logError(formatMissingFuncActParsMessage(funcObj), factorFuncCallOrVar);
  893.  
  894.             return;
  895.         }
  896.  
  897.  
  898.         // dohvatimo listu stvarnih parametara
  899.         StructLinkedList actualParsList = factorFuncCallOrVar.getOptParenthesesActPars().structlinkedlist;
  900.  
  901.  
  902.         checkFuncFormalAndActualPars(actualParsList, funcObj, factorFuncCallOrVar);
  903.     }
  904.  
  905.     @Override
  906.     public  void visit(FactorConst factorConst){
  907.         factorConst.struct = Tab.noType;
  908.  
  909.         ConstValue constValue = factorConst.getConstValue();
  910.  
  911.         if (constValue instanceof NumConst)
  912.             factorConst.struct = Tab.intType;
  913.         else if (constValue instanceof CharConst)
  914.             factorConst.struct = Tab.charType;
  915.         else
  916.             factorConst.struct = boolType;
  917.  
  918.     }
  919.  
  920.     @Override
  921.     public void visit(FactorNew factorNew){
  922.         factorNew.struct = Tab.noType;
  923.     }
  924.  
  925.     @Override
  926.     public void visit(FactorExpr factorExpr) {
  927.         factorExpr.struct = factorExpr.getExpr().struct;
  928.     }
  929.  
  930.  
  931.     @Override
  932.     public void visit(OptExprDeclared optExpr){
  933.         optExpr.struct = optExpr.getExpr().struct;
  934.     }
  935.  
  936.     @Override
  937.     public void visit(OptExprEpsilon optExpr){
  938.         optExpr.struct = Tab.noType;
  939.     }
  940.  
  941.  
  942.  
  943.     /**********************************************************************
  944.      **********************************************************************
  945.      ********************     VISIT METODE LOGICKIH      *****************
  946.      ****************************     IZRAZA    **************************
  947.      ********************************************************************/
  948.  
  949.     @Override
  950.     public void visit(Condition condition){
  951.  
  952.         // tip levog operanda
  953.         Struct leftOperandType = condition.getCondTerm().struct;
  954.  
  955.         // tip desnog operanda
  956.         Struct rightOperandType = condition.getConditionRepeatList().struct;
  957.  
  958.  
  959.         if (leftOperandType != boolType || rightOperandType != boolType)
  960.             condition.struct = Tab.noType;
  961.         else
  962.             condition.struct = boolType;
  963.     }
  964.  
  965.     @Override
  966.     public void visit(ConditionRepeatListDeclared conditionRepeatList){
  967.         conditionRepeatList.struct = conditionRepeatList.getConditionRepeat().struct;
  968.     }
  969.  
  970.     @Override
  971.     public void visit(ConditionRepeatListEpsilon conditionRepeatListEpsilon){
  972.         conditionRepeatListEpsilon.struct = null;
  973.     }
  974.  
  975.     @Override
  976.     public void visit(ConditionRepeat conditionRepeat){
  977.         conditionRepeat.struct = conditionRepeat.getCondTerm().struct;
  978.     }
  979.  
  980.     @Override
  981.     public void visit(CondTerm condTerm){
  982.         // tip levog operanda
  983.         Struct leftOperandType = condTerm.getCondFact().struct;
  984.  
  985.         // tip desnog operanda
  986.         Struct rightOperandType = condTerm.getCondFactRepeatList().struct;
  987.  
  988.         // rezultat operacija mora da je bool
  989.         condTerm.struct = boolType;
  990.  
  991.         if (rightOperandType == null)
  992.             return;
  993.  
  994.         // tipovi nisu kompatabilni
  995.         if (!leftOperandType.compatibleWith(rightOperandType)){
  996.             logError(INCOMPATIBLE_TYPE_ERR_MSG,condTerm.getCondFact().getExpr());
  997.  
  998.             return;
  999.         }
  1000.     }
  1001.  
  1002.     @Override
  1003.     public void visit(CondFact condFact){
  1004.         // tip levog operanda
  1005.         Struct leftOperandType = condFact.getExpr().struct;
  1006.  
  1007.         // tip desnog operanda
  1008.         Struct rightOperandType = condFact.getOptRelopExpr().struct;
  1009.  
  1010.         condFact.struct = boolType;
  1011.  
  1012.         // ne postoji desni operand
  1013.         if (rightOperandType == null)
  1014.             return;
  1015.  
  1016.  
  1017.         // tipovi nisu kompatabilni
  1018.         if (!leftOperandType.compatibleWith(rightOperandType)){
  1019.             logError(INCOMPATIBLE_TYPE_ERR_MSG,condFact.getExpr());
  1020.  
  1021.             return;
  1022.         }
  1023.  
  1024.         Relop relop = ((OptRelopExprDeclared)condFact.getOptRelopExpr()).getRelop();
  1025.  
  1026.         boolean areRefType = leftOperandType.compatibleWith(Tab.nullType) && rightOperandType.compatibleWith(Tab.nullType);
  1027.  
  1028.         boolean relopIsEqualsOrNotEquals = (relop instanceof RelopEquals) || (relop instanceof  RelopNotEquals);
  1029.  
  1030.         // ako je referencijalni tip i ako nije operator == il i!= onda je to greska
  1031.         if (areRefType && !relopIsEqualsOrNotEquals){
  1032.             logError(REF_TYPE_RELOP_ERR_MSG, condFact);
  1033.         }
  1034.     }
  1035.  
  1036.     @Override
  1037.     public void visit(OptRelopExprDeclared relopExpr){
  1038.         relopExpr.struct = relopExpr.getExpr().struct;
  1039.     }
  1040.  
  1041.     @Override
  1042.     public void visit(CondFactRepeatListDeclared condFactList){
  1043.         Struct leftOperandType = condFactList.getCondFactRepeatList().struct;
  1044.  
  1045.         Struct rightOperandType = condFactList.getCondFactRepeat().struct;
  1046.  
  1047.         condFactList.struct = boolType;
  1048.     }
  1049.  
  1050.     @Override
  1051.     public void visit(CondFactRepeatListEpsilon condFactEpsilonList){
  1052.         condFactEpsilonList.struct = null;
  1053.     }
  1054.  
  1055.  
  1056.  
  1057.     /**********************************************************************
  1058.      **********************************************************************
  1059.      ****************   VISIT METODE Stvarnih Parametara  *****************
  1060.      **********************************************************************
  1061.      ********************************************************************/
  1062.  
  1063.     @Override
  1064.     public void visit(OptParenthesesActParsEpsilon noParams){
  1065.  
  1066.         noParams.structlinkedlist = new StructLinkedList();
  1067.  
  1068.        // logInfo("Visited OptParanthesesActParsEpsilon", noParams);
  1069.     }
  1070.  
  1071.     @Override
  1072.     public void visit(OptParenthesesActParsDeclared params){
  1073.         params.structlinkedlist = params.getOptActPars().structlinkedlist;
  1074.     }
  1075.  
  1076.     @Override
  1077.     public void visit(OptActParsDeclared actualPars){
  1078.         actualPars.structlinkedlist = actualPars.getActPars().structlinkedlist;
  1079.     }
  1080.  
  1081.     @Override
  1082.     public void visit(OptActParsEpsilon noPars){
  1083.         // epsilon cvor, ovde samo kreiramo listu
  1084.         noPars.structlinkedlist = new StructLinkedList();
  1085.     }
  1086.  
  1087.     @Override
  1088.     public void visit(ActPars actPars){
  1089.         // dohvatimo parametra iz izraza
  1090.         Struct paramType = actPars.getExpr().struct;
  1091.  
  1092.         // dodamo tip stvarnog parametra u listu na pocetak
  1093.         // iz razloga sto ce se prvi element obici tek na kraju
  1094.         // a ostali elementi ce se obici po normalnom redosledu
  1095.         // stoga prvi treba da stavimo na pocetak
  1096.         (actPars.structlinkedlist = actPars.getActParsRepeatList().structlinkedlist).addFirst(paramType);
  1097.     }
  1098.  
  1099.     @Override
  1100.     public void visit(ActParsRepeatListDeclared actParsRepeatListDeclared){
  1101.         actParsRepeatListDeclared.structlinkedlist = actParsRepeatListDeclared.getActParsRepeatList().structlinkedlist;
  1102.  
  1103.         actParsRepeatListDeclared.structlinkedlist.add(actParsRepeatListDeclared.getActParsRepeat().struct);
  1104.     }
  1105.  
  1106.  
  1107.     @Override
  1108.     public void visit(ActParsRepeatListEpsilon actParsRepeatListEpsilon){
  1109.         actParsRepeatListEpsilon.structlinkedlist = new StructLinkedList();
  1110.     }
  1111.  
  1112.     @Override
  1113.     public void visit(ActParsRepeat actualPars){
  1114.         actualPars.struct = actualPars.getExpr().struct;
  1115.     }
  1116.  
  1117.     /**********************************************************************
  1118.      **********************************************************************
  1119.      ******************      VISIT METODE NAREDBI     *********************
  1120.      **********************************************************************
  1121.      ********************************************************************/
  1122.  
  1123.  
  1124.     @Override
  1125.     public void visit(DoWhileBegin loopBegin){
  1126.         insideLoop = true;
  1127.     }
  1128.  
  1129.     @Override
  1130.     public void visit(DoWhileEnd loopEnd){
  1131.         insideLoop = false;
  1132.     }
  1133.  
  1134.  
  1135.     @Override
  1136.     public void visit(BreakStatement breakStatement){
  1137.         if (!insideLoop)
  1138.             logError(BREAK_STMT_ERR_MSG, breakStatement);
  1139.     }
  1140.  
  1141.     @Override
  1142.     public void visit(ContinueStatement continueStatement){
  1143.         if (!insideLoop)
  1144.             logError(CONTINUE_STMT_ERR_MSG, continueStatement);
  1145.     }
  1146.  
  1147.     @Override
  1148.     public void visit(ReturnStatement returnStatement){
  1149.         // ako nije metoda definisana vratimo se nazad
  1150.         if (currentMethod == Tab.noObj)
  1151.             return;
  1152.  
  1153.  
  1154.  
  1155.  
  1156.     }
  1157.  
  1158.  
  1159.  
  1160.  
  1161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement