diff --git a/GrammarAnalyzer/.classpath b/GrammarAnalyzer/.classpath new file mode 100644 index 0000000..63b7e89 --- /dev/null +++ b/GrammarAnalyzer/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/GrammarAnalyzer/.gitignore b/GrammarAnalyzer/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/GrammarAnalyzer/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/GrammarAnalyzer/.project b/GrammarAnalyzer/.project new file mode 100644 index 0000000..2d7eadb --- /dev/null +++ b/GrammarAnalyzer/.project @@ -0,0 +1,17 @@ + + + GrammarAnalyzer + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/GrammarAnalyzer/.settings/org.eclipse.jdt.core.prefs b/GrammarAnalyzer/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..ace45ce --- /dev/null +++ b/GrammarAnalyzer/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/GrammarAnalyzer/src/grammarAnalyzer/Grammar.java b/GrammarAnalyzer/src/grammarAnalyzer/Grammar.java new file mode 100644 index 0000000..28d6628 --- /dev/null +++ b/GrammarAnalyzer/src/grammarAnalyzer/Grammar.java @@ -0,0 +1,67 @@ + +package grammarAnalyzer; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.concurrent.ConcurrentSkipListSet; + + +public class Grammar { + + ArrayList VT; + ArrayList VN; + Metasymbol S; + ArrayList rules; + ConcurrentSkipListSet yesEpsilon; + + public Grammar() { + rules = new ArrayList<>(); + yesEpsilon = new ConcurrentSkipListSet(); + } + + public Grammar(ArrayList VT, ArrayList VN, + Metasymbol S) { + this(); + this.VT = VT; + this.VN = VN; + this.S = S; + + } + + void newRule(Metasymbol head, PhraseForm body) { + Rule rule = new Rule(this, head, body); + rules.add(rule); + } + + private ConcurrentSkipListSet starterSymbols(Metasymbol M) { + ConcurrentSkipListSet ss = new ConcurrentSkipListSet(); + for (Rule R : rules) { + if (R.getLeftside().equals(M)) { + ss.addAll(digFirstTerminal(R)); + } + } + return ss; + } + + private ConcurrentSkipListSet digFirstTerminal(Rule R) { + ConcurrentSkipListSet termList = new ConcurrentSkipListSet<>(); + ArrayList body = R.getRightside().getArray(); + Iterator iter = body.iterator(); + Symbol h = iter.next(); + if (h.getClass().equals(Terminal.class)) { + termList.add((Terminal) h); + return termList; + } else if (h.getClass().equals(Metasymbol.class)) { + + termList.addAll(starterSymbols((Metasymbol) h)); + + if (yesEpsilon.contains(h)) { + if (iter.hasNext()) { + termList.addAll(starterSymbols((Metasymbol) iter.next())); + } + } + } + return termList; + } + +} diff --git a/GrammarAnalyzer/src/grammarAnalyzer/Metasymbol.java b/GrammarAnalyzer/src/grammarAnalyzer/Metasymbol.java new file mode 100644 index 0000000..cfdde99 --- /dev/null +++ b/GrammarAnalyzer/src/grammarAnalyzer/Metasymbol.java @@ -0,0 +1,38 @@ + +package grammarAnalyzer; + +public class Metasymbol extends Symbol { + + String M; + + public Metasymbol() { + M = null; + } + + public Metasymbol(String M) { + this.M = M; + } + + public Metasymbol(char c) { + this.M = c + ""; + } + + boolean equals(Symbol O) { + if (M == O.toString()) { + return true; + } + return false; + } + + boolean equals(String S) { + if (M == S) { + return true; + } + return false; + } + + public String toString() { + return M; + } + +} diff --git a/GrammarAnalyzer/src/grammarAnalyzer/PhraseForm.java b/GrammarAnalyzer/src/grammarAnalyzer/PhraseForm.java new file mode 100644 index 0000000..ab57f9c --- /dev/null +++ b/GrammarAnalyzer/src/grammarAnalyzer/PhraseForm.java @@ -0,0 +1,51 @@ + +package grammarAnalyzer; + +import java.util.ArrayList; + + +public class PhraseForm { + + ArrayList arr; + String s; + + public PhraseForm(String S) { + arr = new ArrayList(); + this.s = S; + char[] ca = S.toCharArray(); + for (char c : ca) { + if (Character.isLowerCase(c)) { + arr.add(new Terminal(c)); + } else if (Character.isUpperCase(c)) { + arr.add(new Metasymbol(c)); + } + } + + } + + public Symbol get(int i) { + return arr.get(i); + } + + @Override + public String toString() { + return s; + } + + public String print() { + String s = ""; + for (Symbol sym : arr) { + s = s + sym.getClass() + " " + sym.toString() + " "; + } + + return s; + } + + public int size() { + return arr.size(); + } + + public ArrayList getArray(){ + return arr; + } +} diff --git a/GrammarAnalyzer/src/grammarAnalyzer/Rule.java b/GrammarAnalyzer/src/grammarAnalyzer/Rule.java new file mode 100644 index 0000000..db32fdb --- /dev/null +++ b/GrammarAnalyzer/src/grammarAnalyzer/Rule.java @@ -0,0 +1,37 @@ + +package grammarAnalyzer; + +import java.util.ArrayList; + + +public class Rule { + + Grammar grammar; + Metasymbol leftside; // This is for context-free+ only... + PhraseForm rightside; // Is this the right way? should I make a + // specific class? If I do, I would be able to specify + // rules through BNF + + // ..Later that day: yeah, you should have + + public Metasymbol getLeftside() { + return this.leftside; + }; + + public PhraseForm getRightside() { + return this.rightside; + }; + + public Rule(Grammar grammar, Metasymbol leftSide, PhraseForm body) { + this.grammar = grammar; + this.leftside = leftSide; + this.rightside = body; + } + + public Rule(String leftside, String rightside) { + grammar = null; + this.leftside = new Metasymbol(leftside); + this.rightside = new PhraseForm(rightside); + } + +} diff --git a/GrammarAnalyzer/src/grammarAnalyzer/Symbol.java b/GrammarAnalyzer/src/grammarAnalyzer/Symbol.java new file mode 100644 index 0000000..8094560 --- /dev/null +++ b/GrammarAnalyzer/src/grammarAnalyzer/Symbol.java @@ -0,0 +1,7 @@ + +package grammarAnalyzer; + +public abstract class Symbol { + + public abstract String toString(); +} diff --git a/GrammarAnalyzer/src/grammarAnalyzer/Terminal.java b/GrammarAnalyzer/src/grammarAnalyzer/Terminal.java new file mode 100644 index 0000000..cf6f635 --- /dev/null +++ b/GrammarAnalyzer/src/grammarAnalyzer/Terminal.java @@ -0,0 +1,21 @@ + +package grammarAnalyzer; + +public class Terminal extends Symbol { + + char c; + + public Terminal(char c) { + this.c = c; + } + + public Terminal(String string) { + this.c = string.toCharArray()[0]; + } + + @Override + public String toString() { + return c + ""; + } + +} diff --git a/GrammarAnalyzer/src/grammarAnalyzer/Test.java b/GrammarAnalyzer/src/grammarAnalyzer/Test.java new file mode 100644 index 0000000..0a9128c --- /dev/null +++ b/GrammarAnalyzer/src/grammarAnalyzer/Test.java @@ -0,0 +1,19 @@ + +package grammarAnalyzer; + +public class Test { + + public static void main(String[] args) { + + Rule r = new Rule("A", "bC"); + if (r.getLeftside().equals("A")) { + System.out.println(r.getLeftside().toString()); + Symbol h = r.getRightside().get(0); + if (h.getClass().equals(Terminal.class)) { + System.out.println(r.getRightside().toString()); + System.out.println(r.getRightside().print()); + } + } + } + +}