Skip to content

Commit

Permalink
Optimized the compacting algorithm
Browse files Browse the repository at this point in the history
It now uses hashes to find duplicates
Added status message for the compacting algorithm
  • Loading branch information
NoaSenesi committed Oct 31, 2023
1 parent 9b4c797 commit 330c47b
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 91 deletions.
2 changes: 1 addition & 1 deletion mkpkg
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ echo "#!/bin/sh" >> package/usr/local/bin/g2t
echo java -jar /usr/local/bin/g2t.jar \$@ >> package/usr/local/bin/g2t

echo Package: g2t >> package/DEBIAN/control
echo Version: 3.0.3 >> package/DEBIAN/control
echo Version: 3.1.0 >> package/DEBIAN/control
echo Maintainer: Noa Senesi >> package/DEBIAN/control
echo Architecture: all >> package/DEBIAN/control
echo Description: Grammar2Table >> package/DEBIAN/control
Expand Down
2 changes: 1 addition & 1 deletion src/fr/senesi/g2t/Grammar2Table.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import fr.senesi.g2t.tokenizer.Tokenizer;

public class Grammar2Table {
public static final String VERSION = "3.0.3";
public static final String VERSION = "3.1.0";

public static void main(String[] args) {
if (args.length == 0) {
Expand Down
42 changes: 24 additions & 18 deletions src/fr/senesi/g2t/fsm/FiniteStateMachine.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fr.senesi.g2t.fsm;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;

Expand Down Expand Up @@ -115,35 +116,40 @@ public void createAllStates() {

public List<List<State>> findDuplicates() {
List<List<State>> duplicates = new ArrayList<>();
List<State> visited = new ArrayList<>();

List<State> sortedStates = new ArrayList<>(states);

for (int i = 0; i < states.size() - 1; i++) {
State s1 = getStates().get(i);
if (visited.contains(s1)) continue;
Collections.sort(sortedStates, (s1, s2) -> {
if (s1.coreEquals(s2)) return 0;

List<State> duplicate = new ArrayList<>();
return s1.coreHashCode() < s2.coreHashCode() ? -1 : 1;
});

duplicate.add(s1);
visited.add(s1);
for (int i = 1, start = 0; i < states.size(); i++) {
while (sortedStates.get(start).coreEquals(sortedStates.get(i))) {
i++;

for (int j = i + 1; j < states.size(); j++) {
State s2 = getStates().get(j);
if (i >= states.size()) {
//i = states.size() - 1;
break;
}
}

if (visited.contains(s2)) continue;
if (i - start <= 1) {
start = i;
continue;
}

if (s1.coreEquals(s2)) {
duplicate.add(s2);
visited.add(s2);
}
}
List<State> group = new ArrayList<>();
while (start < i) group.add(sortedStates.get(start++));

if (duplicate.size() > 1) duplicates.add(duplicate);
}
duplicates.add(group);
}

return duplicates;
}

public void setQuiet(boolean quiet) {
this.quiet = quiet;
}
}
}
9 changes: 8 additions & 1 deletion src/fr/senesi/g2t/fsm/Rule.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ public int hashCode() {
return code * right.size() * context.size();
}

public int coreHashCode() {
int code = left.hashCode() * cursor;
for (String s : right) code += s.hashCode();

return code * right.size();
}

@Override
public boolean equals(Object o) {
if (!(o instanceof Rule)) return false;
Expand All @@ -127,4 +134,4 @@ public Rule copy() {

return rule;
}
}
}
10 changes: 9 additions & 1 deletion src/fr/senesi/g2t/fsm/State.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ public int hashCode() {
return code * rules.size();
}

public int coreHashCode() {
int code = 0;

for (Rule r : rules) code += r.coreHashCode();

return code * rules.size();
}

@Override
public boolean equals(Object o) {
if (!(o instanceof State)) return false;
Expand Down Expand Up @@ -164,4 +172,4 @@ public void print() {
public String toString() {
return "State: I" + id;
}
}
}
83 changes: 14 additions & 69 deletions src/fr/senesi/g2t/table/Table.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ private void separateConflicts(List<List<State>> duplicates) {
Action[][] table = getTable();
List<List<State>> last = new ArrayList<>();

float compactingRatio = 1;

while (!duplicates.equals(last)) {
last = new ArrayList<>(duplicates);

Expand Down Expand Up @@ -139,8 +141,18 @@ private void separateConflicts(List<List<State>> duplicates) {

if (group.size() == 1) duplicates.remove(i--);
}

if (quiet) continue;

int duplicateCount = -duplicates.size();
for (List<State> duplicate : duplicates) duplicateCount += duplicate.size();
compactingRatio = (float) fsm.getStates().size() / (float) (fsm.getStates().size() - duplicateCount);

System.out.print("Current compacting ratio: " + String.format("%.2f", compactingRatio) + "\r");
}
}

if (!quiet) System.out.println("Final compacting ratio: " + String.format("%.2f", compactingRatio) + " ");
}

private void mergeLines(Action[] line1, Action[] line2) {
// Lines are supposedly non-conflictual
Expand Down Expand Up @@ -219,73 +231,6 @@ public void compact() {
updateStateCount(duplicates);
}

public void print() {
int[] width = new int[tokens.size() + 1];
width[0] = 5;

for (int i = 1; i < width.length; i++) {
if (tokens.get(i-1).length() > width[i]) width[i] = tokens.get(i-1).length();
}

for (Action[] line : getTable()) {
for (int i = 0; i < line.length; i++) {
if (line[i].toString().length() > width[i+1]) width[i+1] = line[i].toString().length();
}

for (State s : fsm.getStates()) {
if (("I" + s.getId()).length() > width[0]) width[0] = ("I" + s.getId()).length();
}
}

System.out.print("┌");
for (int i = 0; i < width.length; i++) {
for (int j = 0; j < width[i] + 2; j++) System.out.print("─");
if (i != width.length - 1) System.out.print("┬");
if (i == fsm.getGrammar().getTerminals().size() + 1 || i == 0) System.out.print("┬");
}
System.out.println("┐");

System.out.print("│ State ");
for (int i = 0; i < width[0] - 5; i++) System.out.print(" ");
System.out.print("│");
for (int i = 1; i < width.length; i++) {
System.out.print("│ ");
System.out.print(tokens.get(i-1));
for (int j = 0; j < width[i] - tokens.get(i-1).length() + 1; j++) System.out.print(" ");
if (i == fsm.getGrammar().getTerminals().size() + 1) System.out.print("│");
}
System.out.println("│");

System.out.print("├");
for (int i = 0; i < width.length; i++) {
for (int j = 0; j < width[i] + 2; j++) System.out.print("─");
if (i != width.length - 1) System.out.print("┼");
if (i == fsm.getGrammar().getTerminals().size() + 1 || i == 0) System.out.print("┼");
}
System.out.println("┤");

for (int i = 0; i < getTable().length; i++) {
System.out.print("│ I" + i + " ");
for (int j = 0; j < width[0] - ("I" + i).length(); j++) System.out.print(" ");
System.out.print("│");
for (int j = 0; j < getTable()[i].length; j++) {
System.out.print("│ ");
System.out.print(getTable()[i][j]);
for (int k = 0; k < width[j+1] - getTable()[i][j].toString().length() + 1; k++) System.out.print(" ");
if (j == fsm.getGrammar().getTerminals().size()) System.out.print("│");
}
System.out.println("│");
}

System.out.print("└");
for (int i = 0; i < width.length; i++) {
for (int j = 0; j < width[i] + 2; j++) System.out.print("─");
if (i != width.length - 1) System.out.print("┴");
if (i == fsm.getGrammar().getTerminals().size() + 1 || i == 0) System.out.print("┴");
}
System.out.println("┘");
}

public void save(String filename) {
File file = new File(filename);
if (file.exists()) file.delete();
Expand Down Expand Up @@ -431,4 +376,4 @@ else if (action.getType() == ActionType.REDUCE) {
e.printStackTrace();
}
}
}
}

0 comments on commit 330c47b

Please sign in to comment.