Advertisement
Guest User

Untitled

a guest
Jun 27th, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.29 KB | None | 0 0
  1. package labos2.ppj.zemris.fer.hr;
  2.  
  3. import java.io.*;
  4. import java.util.*;
  5. import java.util.Map.Entry;
  6.  
  7. public class Generator {
  8.  
  9.     private HashMap<String, String> actionMap;
  10.  
  11.     private HashMap<String, String> gotoMap;
  12.  
  13.     private ArrayList<String> nonterminalSymbols;
  14.  
  15.     private HashMap<String, HashSet<String>> grammarProductions;
  16.  
  17.     private HashSet<String> grammarSymbols;
  18.  
  19.     private List<Node> DFA;
  20.  
  21.     private HashMap<String, HashSet<String>> zapocinjeZnakom = new HashMap<String, HashSet<String>>();
  22.     private HashSet<String> bio = new HashSet<String>();
  23.     private HashSet<String> prazniZnakovi = new HashSet<String>();
  24.  
  25.     public Generator() throws IOException {
  26.  
  27.         ParserDatoteke2 parser = new ParserDatoteke2();
  28.  
  29.         grammarProductions = parser.getProdukcijeGramatike();
  30.  
  31.         grammarSymbols = ParserDatoteke2.getGrammarSymbols();
  32.  
  33.         actionMap = new HashMap<String, String>();
  34.  
  35.         gotoMap = new HashMap<String, String>();
  36.  
  37.         nonterminalSymbols = ParserDatoteke2.getNezavrsniZnakovi();
  38.  
  39.         for (Entry<String, HashSet<String>> entry : grammarProductions
  40.                 .entrySet()) {
  41.             String nezavrsniZnak = entry.getKey();
  42.             HashSet<String> desnaStranaProdukcije = entry.getValue();
  43.             izracunajZapocinjeZnakom(nezavrsniZnak, desnaStranaProdukcije);
  44.         }
  45.  
  46.         for (Entry<String, HashSet<String>> entry : grammarProductions
  47.                 .entrySet()) {
  48.  
  49.             HashSet<String> tempSet = new HashSet<String>();
  50.  
  51.             for (String s : entry.getValue()) {
  52.                 tempSet.add(" " + s + " ");
  53.             }
  54.             grammarProductions.put(entry.getKey(), tempSet);
  55.         }
  56.  
  57.         // ispisiMapu(zapocinjeZnakom);
  58.  
  59.         DFA = generateItems();
  60.         System.out.println("DKA izgeneriran...");
  61.         System.out.println(DFA.size());
  62.         System.out.println();
  63.  
  64.         generateTables();
  65.         // System.out.println("Action MAP:");
  66.         // for (Entry<String, String> e : actionMap.entrySet()) {
  67.         // System.out.println(e.getKey() + "\t" + e.getValue());
  68.         // }
  69.         // System.out.println("Reduction MAP:");
  70.         // for (Entry<String, String> e : reductionMap.entrySet()) {
  71.         // System.out.println(e.getKey() + "\t" + e.getValue());
  72.         // }
  73.         // System.out.println("GoTo MAP:");
  74.         // for (Entry<String, String> e : gotoMap.entrySet()) {
  75.         // System.out.println(e.getKey() + "\t" + e.getValue());
  76.         // }
  77.         //
  78.         // System.out.println(actionMap.size() + " " + reductionMap.size() + " "
  79.         // + gotoMap.size());
  80.  
  81.         // upis tablica u datoteku
  82.         BufferedWriter writer = new BufferedWriter(new FileWriter(
  83.                 "actionMap.txt"));
  84.         for (String key : actionMap.keySet()) {
  85.             writer.write(key + "&" + actionMap.get(key) + '\n');
  86.         }
  87.         writer.close();
  88.  
  89.         writer = new BufferedWriter(new FileWriter("gotoMap.txt"));
  90.         for (String key : gotoMap.keySet()) {
  91.             writer.write(key + "&" + gotoMap.get(key) + '\n');
  92.         }
  93.         writer.close();
  94.  
  95.         writer = new BufferedWriter(new FileWriter(new File("izlaz.txt")));
  96.  
  97.         for (Node n : DFA) {
  98.  
  99.             writer.write(n.toString());
  100.         }
  101.  
  102.         writer.flush();
  103.         writer.close();
  104.     }
  105.  
  106.     private void generateTables() {
  107.         int i = 0;
  108.         for (Node node : DFA) {
  109.  
  110.             actionTable(node);
  111.             // System.out.println(i);
  112.             gotoTable(node);
  113.             // System.out.println(i);
  114.             i++;
  115.         }
  116.     }
  117.  
  118.     private void gotoTable(Node node) {
  119.  
  120.         for (Entry<String, Integer> entry : node.getTransitionMap().entrySet()) {
  121.  
  122.             String nonTerminalSymbol = entry.getKey();
  123.  
  124.             Integer nodePosition = entry.getValue();
  125.  
  126.             if (nonTerminalSymbol.startsWith("<")) {
  127.                 gotoMap.put(node.getID() + "#" + nonTerminalSymbol, Integer
  128.                         .toString(nodePosition));
  129.             }
  130.  
  131.         }
  132.  
  133.         // for (String nonTerminalSymbol : nonterminalSymbols) {
  134.         //
  135.         // Node newNode = GOTO(nonTerminalSymbol, node, -1);
  136.         //
  137.         // int nodePosition = DFA.indexOf(newNode);
  138.         //
  139.         // if (nodePosition != -1) {
  140.         // gotoMap.put(node.getID() + "#" + nonTerminalSymbol, Integer
  141.         // .toString(nodePosition));
  142.         // }
  143.         // }
  144.  
  145.     }
  146.  
  147.     private void actionTable(Node node) {
  148.         Set<Production> nodeProductions = node.getProductionSet();
  149.  
  150.         for (Production p : nodeProductions) {
  151.            
  152. //          System.out.println(p.getContext()); //aj da vidimo
  153.            
  154.             String futureSymbols = p.getRightSide().split("\\*", 2)[1];
  155.  
  156.             if (!futureSymbols.startsWith("<")) {
  157.  
  158.                 // String terminalSymbol = futureSymbols.split(" ", 2)[0];
  159.                 //
  160.                 // Node newNode = GOTO(terminalSymbol, node, -1);
  161.  
  162.                 for (Entry<String, Integer> entry : node.getTransitionMap()
  163.                         .entrySet()) {
  164.  
  165.                     String terminalSymbol = entry.getKey();
  166.  
  167.                     int nodePosition = entry.getValue();
  168.                     if (!terminalSymbol.startsWith("<")) {
  169.                         if (actionMap.containsKey(node.getID() + "#"
  170.                                 + terminalSymbol)
  171.                                 && !actionMap
  172.                                         .containsValue("s#" + nodePosition)) {
  173.                             System.out.println("Proturjecje! "
  174.                                     + node.getID()
  175.                                     + "#"
  176.                                     + terminalSymbol
  177.                                     + " "
  178.                                     + actionMap.get(node.getID() + "#"
  179.                                             + terminalSymbol) + " != " + "s#"
  180.                                     + nodePosition);
  181.                             if (actionMap.get(
  182.                                     node.getID() + "#" + terminalSymbol)
  183.                                     .startsWith("s#")) {
  184.                                 System.out.println("WTF?");
  185.                             } else if (actionMap.get(
  186.                                     node.getID() + "#" + terminalSymbol)
  187.                                     .startsWith("r#")) {
  188.                                 actionMap.put(node.getID() + "#"
  189.                                         + terminalSymbol, "s#" + nodePosition);
  190.                                 System.out
  191.                                         .println("Redukcija zamijenjena pomakom!");
  192.                             }
  193.                         } else {
  194.                             actionMap.put(node.getID() + "#" + terminalSymbol,
  195.                                     "s#" + nodePosition);
  196.                         }
  197.                     }
  198.                 }
  199.  
  200.                 // int nodePosition = DFA.indexOf(newNode);
  201.                 // if (nodePosition != -1) {
  202.                 // actionMap.put(node.getID() + "#" + terminalSymbol, "s"
  203.                 // + nodePosition);
  204.                 // }
  205.  
  206.             }
  207.  
  208.             if (futureSymbols.length() == 0) {
  209. // kako to da kontekst vraca samo jedan zavrsni znak? trebalo bi ih biti vise?
  210.                 if (!p.getLeftSide().equals("<S0>")) {
  211.                     if (actionMap.containsKey(node.getID() + "#"
  212.                             + p.getContext())
  213.                             && !actionMap.containsValue("r#"
  214.                                     + p.getLeftSide()
  215.                                     + "->"
  216.                                     + p.getRightSide().split("\\*")[0]
  217.                                             .substring(1))) {
  218.                         System.out
  219.                                 .println("Proturjecje! "
  220.                                         + node.getID()
  221.                                         + "#"
  222.                                         + p.getContext()
  223.                                         + " "
  224.                                         + actionMap.get(node.getID() + "#"
  225.                                                 + p.getContext())
  226.                                         + " != "
  227.                                         + "r#"
  228.                                         + p.getLeftSide()
  229.                                         + "->"
  230.                                         + p.getRightSide().split("\\*")[0]
  231.                                                 .substring(1));
  232.                         if (actionMap.get(node.getID() + "#" + p.getContext())
  233.                                 .startsWith("s#")) {
  234.                             System.out.println("Ne diraj! s > r");
  235.                         } else if (actionMap.get(
  236.                                 node.getID() + "#" + p.getContext())
  237.                                 .startsWith("r#")) {
  238.                             // actionMap.put(node.getID() + "#" +
  239.                             // p.getContext(), "r#"
  240.                             // + p.getLeftSide()
  241.                             // + "->"
  242.                             // + p.getRightSide().split("\\*")[0].substring(1));
  243.                             System.out
  244.                                     .println("Kako najlakse odluciti koju redukciju ostaviti?");
  245.                         }
  246.                     } else {
  247.                         actionMap
  248.                                 .put(node.getID() + "#" + p.getContext(), "r#"
  249.                                         + p.getLeftSide()
  250.                                         + "->"
  251.                                         + p.getRightSide().split("\\*")[0]
  252.                                                 .substring(1));
  253.                     }
  254.                 }
  255.  
  256.                 else {
  257.                     actionMap.put(node.getID() + "#@", "accept");
  258.                 }
  259.             }
  260.  
  261.         }
  262.     }
  263.  
  264.     private List<Node> generateItems() {
  265.         List<Node> nodeContainer = new ArrayList<Node>();
  266.  
  267.         HashSet<String> initialSet = grammarProductions.get("<S0>");
  268.  
  269.         Production initialProduction = createProduction("<S0>->*"
  270.                 + ((String) (initialSet.toArray())[0]).substring(1), "@");
  271.  
  272.         int i = 0;
  273.  
  274.         Node initialNode = new Node(i);
  275.  
  276.         initialNode.addProduction(initialProduction);
  277.  
  278.         Node node = closure(initialNode);
  279.  
  280.         nodeContainer.add(node);
  281.  
  282.         Stack<Node> stackOfNodes = new Stack<Node>();
  283.  
  284.         stackOfNodes.push(node);
  285.  
  286.         while (!stackOfNodes.empty()) {
  287.  
  288.             Node stackedNode = stackOfNodes.pop();
  289.  
  290.             for (String grammarSymbol : grammarSymbols) {
  291.                 i++;
  292.                 Node newNode = GOTO(grammarSymbol, stackedNode, i);
  293.  
  294.                 if (newNode.getProductionSet().size() != 0) {
  295.  
  296.                     if (!nodeContainer.contains(newNode)) {
  297.  
  298.                         stackOfNodes.push(newNode);
  299.                         stackedNode.addTransition(grammarSymbol, i);
  300.                         nodeContainer.add(newNode);
  301.                     } else {
  302.                         stackedNode.addTransition(grammarSymbol, nodeContainer
  303.                                 .indexOf(newNode));
  304.                         i--;
  305.                     }
  306.                 } else
  307.                     i--;
  308.  
  309.             }
  310.         }
  311.         return nodeContainer;
  312.     }
  313.  
  314.     private Node GOTO(String grammarSymbol, Node node, int i) {
  315.  
  316.         Node newNode = new Node(i);
  317.  
  318.         for (Production p : node.getProductionSet()) {
  319.  
  320.             String[] tempRightSide = p.getRightSide().split("\\*", 2);
  321.  
  322.             if (tempRightSide[1].length() > 0) {
  323.  
  324.                 String X = tempRightSide[1].split(" ", 2)[0];
  325.  
  326.                 if (grammarSymbol.equals(X)) {
  327.  
  328.                     String newRightSide = tempRightSide[1].replaceFirst(" ",
  329.                             "\\*");
  330.                     if (!newRightSide.endsWith("\\*")) {
  331.  
  332.                         newNode.addProduction(createProduction(p.getLeftSide()
  333.                                 + "->" + tempRightSide[0] + " " + newRightSide,
  334.                                 p.getContext()));
  335.  
  336.                     } else {
  337.  
  338.                         newNode.addProduction(createProduction(p.getLeftSide()
  339.                                 + "->" + tempRightSide[0] + " " + newRightSide
  340.                                 + " ", p.getContext()));
  341.  
  342.                     }
  343.                 }
  344.             }
  345.  
  346.         }
  347.  
  348.         return closure(newNode);
  349.     }
  350.  
  351.     private Node closure(Node node) {
  352.  
  353.         Stack<Production> stackOfProductions = new Stack<Production>();
  354.  
  355.         for (Production production : node.getProductionSet()) {
  356.             stackOfProductions.push(production);
  357.         }
  358.  
  359.         while (!stackOfProductions.empty()) {
  360.  
  361.             Production stackedProduction = stackOfProductions.pop();
  362.  
  363.             String[] productionItems = stackedProduction.getRightSide().split(
  364.                     "\\*", 2);
  365.  
  366.             // String alfa = productionItems[0].trim();
  367.  
  368.             String[] productionSubItems = productionItems[1].split(" ", 2);
  369.  
  370.             String B = "";
  371.  
  372.             // System.out.println(stackedProduction.getRightSide());
  373.  
  374.             String beta = "";
  375.  
  376.             if (productionSubItems.length > 1) {
  377.                 B = productionSubItems[0];
  378.  
  379.                 beta = productionSubItems[1];
  380.             }
  381.  
  382.             String a = stackedProduction.getContext();
  383.  
  384.             // System.out.println("alfa = " + alfa + " B = " + B + " beta = "
  385.             // + beta + " a = " + a);
  386.  
  387.             Production production = null;
  388.  
  389.             if (grammarProductions.get(B) != null)
  390.                 for (String rightSide : grammarProductions.get(B)) {
  391.  
  392.                     for (String terminal : first(beta, a)) {
  393.  
  394.                         String productionName = B + "->*"
  395.                                 + rightSide.substring(1);
  396.  
  397.                         production = createProduction(productionName, terminal);
  398.                         if (!node.containsProduction(production)) {
  399.                             node.addProduction(production);
  400.                             stackOfProductions.push(production);
  401.                         }
  402.                     }
  403.                 }
  404.  
  405.         }
  406.  
  407.         return node;
  408.     }
  409.  
  410.     private HashSet<String> first(String beta, String a) {
  411.  
  412.         if (beta.length() == 0) {
  413.  
  414.             HashSet<String> tempSet = new HashSet<String>();
  415.  
  416.             tempSet.add(a);
  417.  
  418.             return tempSet;
  419.  
  420.         }
  421.  
  422.         if (!beta.split(" ", 2)[0].startsWith("<")) {
  423.  
  424.             HashSet<String> tempSet = new HashSet<String>();
  425.  
  426.             beta = beta.replace("<", " ");
  427.  
  428.             tempSet.add(beta.split(" ", 2)[0]);
  429.  
  430.             return tempSet;
  431.         }
  432.  
  433.         int position = beta.indexOf(">");
  434.         return zapocinjeZnakom.get(beta.substring(0, position + 1));
  435.     }
  436.  
  437.     private Production createProduction(String productionName, String context) {
  438.  
  439.         String leftSide = productionName.split("->")[0];
  440.         String rightSide = productionName.split("->")[1];
  441.  
  442.         Production production = new Production(leftSide, rightSide, context);
  443.  
  444.         return production;
  445.     }
  446.  
  447.     // private static void ispisiMapu(HashMap<String, HashSet<String>> mapa) {
  448.     // for (Entry<String, HashSet<String>> entry : mapa.entrySet()) {
  449.     // String kljuc = entry.getKey();
  450.     // HashSet<String> vrijednost = entry.getValue();
  451.     // // System.out.println(kljuc + " => " + vrijednost);
  452.     // }
  453.     // }
  454.  
  455.     public boolean prazniZnak(String nezavrsniZnak) {
  456.         return prazniZnakovi.contains(nezavrsniZnak);
  457.     }
  458.  
  459.     private void izracunajZapocinjeZnakom(String lijevaStranaProdukcije,
  460.             HashSet<String> desnaStranaProdukcije) {
  461.         for (String s : desnaStranaProdukcije) {
  462.             String[] svi = s.split(" ");
  463.             String first = svi[0];
  464.             HashSet<String> zapocinjeTmp = new HashSet<String>();
  465.             if (first.startsWith("<") && !bio.contains(first)) {
  466.                 bio.add(first);
  467.                 izracunajZapocinjeZnakom(first, grammarProductions.get(first));
  468.                 zapocinjeTmp.addAll(zapocinjeZnakom.get(first));
  469.                 int i = 0;
  470.                 while (grammarProductions.get(first).contains("$")
  471.                         && i < svi.length - 1) {
  472.                     first = svi[++i];
  473.                     if (!first.startsWith("<")) {
  474.                         zapocinjeTmp.add(first);
  475.                         break;
  476.                     }
  477.                     bio.add(first);
  478.                     izracunajZapocinjeZnakom(first, grammarProductions
  479.                             .get(first));
  480.                     zapocinjeTmp.addAll(zapocinjeZnakom.get(first));
  481.                 }
  482.             } else {
  483.                 if (!first.equals("$")) {
  484.                     if (!first.startsWith("<"))
  485.                         zapocinjeTmp.add(first);
  486.                 } else
  487.                     prazniZnakovi.add(lijevaStranaProdukcije);
  488.             }
  489.             int i = 0;
  490.             while (first.startsWith("<") && i < svi.length - 1
  491.                     && prazniZnakovi.contains(first)) {
  492.                 first = svi[++i];
  493.             }
  494.             if (first == svi[svi.length - 1] && first.startsWith("<"))
  495.                 prazniZnakovi.add(lijevaStranaProdukcije);
  496.             HashSet<String> set = zapocinjeZnakom.get(lijevaStranaProdukcije);
  497.             if (set == null)
  498.                 zapocinjeZnakom.put(lijevaStranaProdukcije, zapocinjeTmp);
  499.             else {
  500.                 set.addAll(zapocinjeTmp);
  501.             }
  502.         }
  503.     }
  504.  
  505.     public HashMap<String, String> getActionMap() {
  506.         return actionMap;
  507.     }
  508.  
  509.     public void setActionMap(HashMap<String, String> actionMap) {
  510.         this.actionMap = actionMap;
  511.     }
  512.  
  513.     public HashMap<String, String> getGotoMap() {
  514.         return gotoMap;
  515.     }
  516.  
  517.     public void setGotoMap(HashMap<String, String> gotoMap) {
  518.         this.gotoMap = gotoMap;
  519.     }
  520.  
  521.     public ArrayList<String> getNonterminalSymbols() {
  522.         return nonterminalSymbols;
  523.     }
  524.  
  525.     public void setNonterminalSymbols(ArrayList<String> nonterminalSymbols) {
  526.         this.nonterminalSymbols = nonterminalSymbols;
  527.     }
  528.  
  529.     public HashMap<String, HashSet<String>> getGrammarProductions() {
  530.         return grammarProductions;
  531.     }
  532.  
  533.     public void setGrammarProductions(
  534.             HashMap<String, HashSet<String>> grammarProductions) {
  535.         this.grammarProductions = grammarProductions;
  536.     }
  537.  
  538.     public HashSet<String> getGrammarSymbols() {
  539.         return grammarSymbols;
  540.     }
  541.  
  542.     public void setGrammarSymbols(HashSet<String> grammarSymbols) {
  543.         this.grammarSymbols = grammarSymbols;
  544.     }
  545.  
  546.     public List<Node> getDFA() {
  547.         return DFA;
  548.     }
  549.  
  550.     public void setDFA(List<Node> dFA) {
  551.         DFA = dFA;
  552.     }
  553.  
  554. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement