diff options
Diffstat (limited to 'project/JavaCommon/src/com')
30 files changed, 1858 insertions, 0 deletions
diff --git a/project/JavaCommon/src/com/modulus/access/ArrayFunction.java b/project/JavaCommon/src/com/modulus/access/ArrayFunction.java new file mode 100644 index 0000000..89ce636 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/access/ArrayFunction.java @@ -0,0 +1,24 @@ +package com.modulus.access; + +/** + * Any kind of function that takes an array of type <code>E</code> + * and returns an object of type <code>T</code>. + * + * Usually, the return type and the argument types are the same type. + * + * @author jrahm + * + * @param <T> the return type of this function + * @param <E> the argument type of the function + */ +public interface ArrayFunction< T, E > { + + /** + * Executes this function using the arguments <code>args</code> + * and returns an object of type <code>T</code> + * + * @param args the arguments to execute this function with. + * @return some value of type <code>T</code> + */ + public T execute( E[] args ); +} diff --git a/project/JavaCommon/src/com/modulus/common/TwoTypeBean.java b/project/JavaCommon/src/com/modulus/common/TwoTypeBean.java new file mode 100644 index 0000000..28e1e41 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/common/TwoTypeBean.java @@ -0,0 +1,44 @@ +package com.modulus.common; + +/** + * Class that simply holds two different (or same) object + * types. It is a rough implementation of what a tuple can be + * considered + * + * @author jrahm + * + * @param <T> type of object 1 + * @param <E> type of object 2 + */ +public class TwoTypeBean<T, E> { + private T obj1; + private E obj2; + + /** + * Creates a new TwoTypeBean from the two + * objects. + * + * @param obj1 object 1 + * @param obj2 object 2 + */ + public TwoTypeBean(T obj1, E obj2){ + this.obj1 = obj1; + this.obj2 = obj2; + } + + /** + * Returns the first object + * @return the first object + */ + public T getObject1(){ + return obj1; + } + + /** + * Returns the second object + * @return the second object + */ + public E getObject2(){ + return obj2; + } +} diff --git a/project/JavaCommon/src/com/modulus/common/collections/ArrayStack.java b/project/JavaCommon/src/com/modulus/common/collections/ArrayStack.java new file mode 100644 index 0000000..17dfcb1 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/common/collections/ArrayStack.java @@ -0,0 +1,101 @@ +package com.modulus.common.collections; + +import java.io.Serializable; + +/** + * Class which uses an array to be used to + * implement a stack. + * + * This class is most efficient for + * nearly every purpose. + * + * @author jrahm + * + * @param <T> the type this stack holds + */ +public class ArrayStack<T> implements Stack<T>, Serializable{ + + private Object[] arr; + private int pointer = -1; + + /** + * Creates a new ArrayStack with a + * default starting size of 10 + */ + public ArrayStack(){ + this(10); + } + + /** + * Creates a new ArrayStack with + * a default starting size of <code>size</code> + * @param size + */ + public ArrayStack( int size ){ + arr = new Object[size]; + } + + /** + * Ensures that this ArrayStack has enough space + * to store <code>size</code> number of elements. + * + * @param size the number of elements needed to store + */ + public void ensureSize( int size ){ + + if(arr.length > size) + return; + + Object[] tmp = new Object[size*2]; + for ( int i = 0;i < arr.length; i ++ ){ + tmp[i] = arr[i]; + } + + arr = tmp; + } + + @Override + public boolean isEmpty() { + return pointer == -1; + } + + @SuppressWarnings("unchecked") + @Override + public T peek() { + return (T)arr[pointer]; + } + + @SuppressWarnings("unchecked") + @Override + public T pop() { + return (T) arr[ pointer -- ]; + } + + @Override + public void push(T obj) { + pointer ++; + this.ensureSize(pointer); + arr[pointer] = obj; + } + + @Override + public int size() { + return pointer + 1; + } + + @Override + public void clear(){ + pointer = 0; + } + + @Override + public String toString(){ + StringBuffer buf = new StringBuffer("["); + + for( int i = pointer; i >= 1; i --) + buf.append(arr[i] + ", "); + + buf.append(arr[0] + "]"); + return buf.toString(); + } +} diff --git a/project/JavaCommon/src/com/modulus/common/collections/BaseModelData.java b/project/JavaCommon/src/com/modulus/common/collections/BaseModelData.java new file mode 100644 index 0000000..250f980 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/common/collections/BaseModelData.java @@ -0,0 +1,29 @@ +package com.modulus.common.collections; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class BaseModelData<T> implements ModelData<T>{ + private Map<Object, T> map = new HashMap<Object, T>(); + + @Override + public T get(Object key) { + return map.get(key); + } + + @Override + public Object[] keys() { + Set<Object> keys = map.keySet(); + + return keys.toArray( new Object[keys.size()] ); + } + + @Override + public void set(Object key, Object obj) { + // TODO Auto-generated method stub + + } + + +} diff --git a/project/JavaCommon/src/com/modulus/common/collections/Collections2.java b/project/JavaCommon/src/com/modulus/common/collections/Collections2.java new file mode 100644 index 0000000..65bcc60 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/common/collections/Collections2.java @@ -0,0 +1,28 @@ +package com.modulus.common.collections; + +public class Collections2 { + + static public Integer[] rangeAsObjects(int start, int stop) + { + Integer[] result = new Integer[stop-start]; + + for(int i=0;i<stop-start;i++) + result[i] = start+i; + + return result; + } + + static public int[] range(int start, int stop) + { + int[] result = new int[stop-start]; + + for(int i=0;i<stop-start;i++) + result[i] = start+i; + + return result; + } + + static public int[] range(int stop){ + return range(0, stop); + } +} diff --git a/project/JavaCommon/src/com/modulus/common/collections/Grid.java b/project/JavaCommon/src/com/modulus/common/collections/Grid.java new file mode 100644 index 0000000..817a36c --- /dev/null +++ b/project/JavaCommon/src/com/modulus/common/collections/Grid.java @@ -0,0 +1,35 @@ +package com.modulus.common.collections; + +/** + * Interface describing an immutable grid interface. + * + * @author jrahm + * + * @param <T> the type of object this grid holds + */ +public interface Grid<T> { + /** + * Returns the object stored in + * row <code>row</code> and column + * <code>col</code> + * + * @param row the row of the object + * @param col the column of the object + * @return the object stored in that row and column + */ + public T get(int row, int col); + + /** + * Returns the number of columns in this grid + * + * @return the number of columns in this grid + */ + public int numberOfColumns(); + + /** + * Returns the number of columns in this grid. + * + * @return the number of columns in this grid + */ + public int numberOfRows(); +} diff --git a/project/JavaCommon/src/com/modulus/common/collections/IntMap.java b/project/JavaCommon/src/com/modulus/common/collections/IntMap.java new file mode 100644 index 0000000..558cd9f --- /dev/null +++ b/project/JavaCommon/src/com/modulus/common/collections/IntMap.java @@ -0,0 +1,84 @@ +package com.modulus.common.collections; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class IntMap<T> implements Map<Integer, T> { + private List<T> list = new ArrayList<T>(); + + @Override + public void clear() { + this.list.clear(); + } + + @Override + public boolean containsKey(Object arg0) { + if( arg0 instanceof Integer) + return ((Integer) arg0) < this.list.size(); + + return false; + } + + @Override + public boolean containsValue(Object arg0) { + return list.contains(arg0); + } + + @Override + public Set<java.util.Map.Entry<Integer, T>> entrySet() { + throw new RuntimeException("Not Implemented (At The Moment)"); + } + + @Override + public T get(Object arg0) { + try{ + return list.get( (Integer)arg0 ); + } catch(ClassCastException e){ + return null; + } + } + + @Override + public boolean isEmpty() { + return list.isEmpty(); + } + + @Override + public Set<Integer> keySet() { + return new HashSet<Integer>( Arrays.asList( Collections2.rangeAsObjects(0, list.size()) ) ); + } + + @Override + public T put(Integer arg0, T arg1) { + return list.set(arg0, arg1); + } + + @Override + public void putAll(Map<? extends Integer, ? extends T> arg0) { + throw new RuntimeException("Not Implemented At the Moment"); + } + + @Override + public T remove(Object arg0) { + // TODO Auto-generated method stub + return null; + } + + @Override + public int size() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public Collection<T> values() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/project/JavaCommon/src/com/modulus/common/collections/MArrays.java b/project/JavaCommon/src/com/modulus/common/collections/MArrays.java new file mode 100644 index 0000000..08d9540 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/common/collections/MArrays.java @@ -0,0 +1,180 @@ +package com.modulus.common.collections; + +import java.lang.reflect.Array; +import java.util.AbstractList; +import java.util.List; + +public class MArrays { + public static int indexOf( Object[] objs , Object obj, int start ){ + for ( int i = start; i < objs.length; i ++) + if(objs[i].equals(obj)) + return i; + return -1; + } + + public static int lastIndexOf( Object[] objs , Object obj, int end ){ + for ( int i = end; i >= 0; i --) + if(objs[i].equals(obj)) + return i; + return -1; + } + + public static int indexOf( Object[] objs, Object obj ){ + return indexOf( objs, obj, 0 ); + } + + public static int lastIndexOf( Object[] objs, Object obj ){ + return lastIndexOf( objs, obj, objs.length - 1 ); + } + + public static String concat(String[] args, int off, int len, String sep){ + StringBuffer buf = new StringBuffer(); + int lastDex = len + off; + + for(int i = off;i < lastDex-1;i++) + buf.append(args[i] + sep); + buf.append(args[lastDex-1]); + + return buf.toString(); + } + + public static String concat(String[] args, int off, String sep){ + return concat(args, off, args.length-off, sep); + } + + public static String concat(String[] args, String sep){ + return concat(args, 0, args.length, sep); + } + + public static String concat(String[] args, int off){ + return concat(args, off, ""); + } + + public static String concat(String[] args){ + return concat(args, ""); + } + + public static String concat(String[] args, int off, int len){ + return concat(args, off, len, ""); + } + + public static List<Byte> asList( final byte[] bytes ){ + return new AbstractList<Byte>() { + + @Override + public Byte get(int arg0) { + return bytes[arg0]; + } + + @Override + public int size() { + return bytes.length; + } + }; + } + + public static List<Character> asList( final char[] chars ){ + return new AbstractList<Character>() { + + @Override + public Character get(int arg0) { + return chars[arg0]; + } + + @Override + public int size() { + return chars.length; + } + }; + } + + public static List<Integer> asList( final int[] ints ){ + return new AbstractList<Integer>() { + + @Override + public Integer get(int arg0) { + return ints[arg0]; + } + + @Override + public int size() { + return ints.length; + } + }; + } + + public static List<Long> asList( final long[] longs ){ + return new AbstractList<Long>() { + + @Override + public Long get(int arg0) { + return longs[arg0]; + } + + @Override + public int size() { + return longs.length; + } + }; + } + + public static List<Double> asList( final double[] doubles ){ + return new AbstractList<Double>() { + + @Override + public Double get(int arg0) { + return doubles[arg0]; + } + + @Override + public int size() { + return doubles.length; + } + }; + } + + public static List<Float> asList( final float[] floats ){ + return new AbstractList<Float>() { + + @Override + public Float get(int arg0) { + return floats[arg0]; + } + + @Override + public int size() { + return floats.length; + } + }; + } + + public static List<Short> asList( final short[] shorts ){ + return new AbstractList<Short>() { + + @Override + public Short get(int arg0) { + return shorts[arg0]; + } + + @Override + public int size() { + return shorts.length; + } + }; + } + + public static List<Boolean> asList( final boolean[] bools ){ + return new AbstractList<Boolean>() { + + @Override + public Boolean get(int arg0) { + return bools[arg0]; + } + + @Override + public int size() { + return bools.length; + } + }; + } +} diff --git a/project/JavaCommon/src/com/modulus/common/collections/ModelData.java b/project/JavaCommon/src/com/modulus/common/collections/ModelData.java new file mode 100644 index 0000000..245015b --- /dev/null +++ b/project/JavaCommon/src/com/modulus/common/collections/ModelData.java @@ -0,0 +1,9 @@ +package com.modulus.common.collections; + +public interface ModelData<T> { + public T get(Object key); + + public void set(Object key, T obj); + + public Object[] keys(); +} diff --git a/project/JavaCommon/src/com/modulus/common/collections/Stack.java b/project/JavaCommon/src/com/modulus/common/collections/Stack.java new file mode 100644 index 0000000..1d2c36c --- /dev/null +++ b/project/JavaCommon/src/com/modulus/common/collections/Stack.java @@ -0,0 +1,57 @@ +package com.modulus.common.collections; + +/** + * Class defines a better used stack than what is + * in the java api. This stack is an interface + * with many different implementations. + * + * @author jrahm + * + * @param <T> the type this stack stores + */ +public interface Stack<T> { + /** + * Removes and returns the element that is on + * the top of the stack. + * + * @return the element which is on the top of the stack. + */ + public T pop(); + + /** + * Places object <code>obj</code> on the top of + * the stack + * + * @param obj the object to push on the stack. + */ + public void push(T obj); + + /** + * Returns the object on the top of the stack + * but does <b>not</b> remove it. + * + * @return the object on the top of the stack + */ + public T peek(); + + /** + * Returns the number of elements in this + * stack. + * + * @return the number of elements in this stack. + */ + public int size(); + + /** + * Returns true of this stack has no elements, + * returns false otherwise. + * + * @return true it this stack has no elements, false otherwise + */ + public boolean isEmpty(); + + /** + * Empties the stack. + */ + public void clear(); +} diff --git a/project/JavaCommon/src/com/modulus/common/collections/UpdateableGrid.java b/project/JavaCommon/src/com/modulus/common/collections/UpdateableGrid.java new file mode 100644 index 0000000..a48ee31 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/common/collections/UpdateableGrid.java @@ -0,0 +1,21 @@ +package com.modulus.common.collections; + +/** + * Interface that extends grid to make a grid + * mutable. + * + * @author jrahm + * + * @param <T> the type this grid holds + */ +public interface UpdateableGrid<T> extends Grid<T>{ + /** + * sets the reference in row <code>row</code> and column <code>col</code> + * to <code>obj</code> + * + * @param row the row + * @param col the column + * @param obj the object + */ + public void set(int row, int col, T obj); +} diff --git a/project/JavaCommon/src/com/modulus/common/strings/Tokenizer.java b/project/JavaCommon/src/com/modulus/common/strings/Tokenizer.java new file mode 100644 index 0000000..80363cd --- /dev/null +++ b/project/JavaCommon/src/com/modulus/common/strings/Tokenizer.java @@ -0,0 +1,48 @@ +package com.modulus.common.strings; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Class that tokenizes strings based on which groups + * the characters fit into. + * + * If the group is -1, then that tells the tokenizer to + * not include those tokens and instead delete the characters + * that belong to that group in the process of splitting. + * + * @author jrahm + * + */ +public abstract class Tokenizer { + + public String[] tokenize(String str){ + if(str.length() == 0) + return new String[]{}; + + List<String> tokens = new ArrayList<String>(); + StringBuffer buffer = new StringBuffer(); + + int curGroup = groupOf(str.charAt(0)); + for(int i = 0;i < str.length();i++){ + char ch = str.charAt(i); + + int temp = groupOf(ch); + if(temp != curGroup && curGroup != -1){ + curGroup = temp; + tokens.add(buffer.toString()); + + buffer = new StringBuffer(); + } + + if(temp != -1) + buffer.append(ch); + } + tokens.add(buffer.toString()); + + return tokens.toArray(new String[tokens.size()]); + } + + public abstract int groupOf(char ch); +} diff --git a/project/JavaCommon/src/com/modulus/console/InputReader.java b/project/JavaCommon/src/com/modulus/console/InputReader.java new file mode 100644 index 0000000..0cda313 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/console/InputReader.java @@ -0,0 +1,9 @@ +package com.modulus.console; + +public class InputReader { + private StringBuffer buffer = new StringBuffer(); + + public String getBuffer(){ + return buffer.toString(); + } +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/AbstractStatement.java b/project/JavaCommon/src/com/modulus/dataread/expressions/AbstractStatement.java new file mode 100644 index 0000000..c2ec699 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/AbstractStatement.java @@ -0,0 +1,125 @@ +package com.modulus.dataread.expressions; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * this class outlines a rough diagram of what a statement + * looks like. The major importance is how it already + * correctly implements the tree fasion that statements + * should in theory be ordered in. + * + * @author jrahm + * + */ +public abstract class AbstractStatement implements Statement, Serializable{ + private static final long serialVersionUID = -6717726729821743941L; + private Collection<Statement> children; + private int line = -1; + + /** + * the header of this statement. + */ + protected String header; + + /** + * Creates a new AbstractStatement with the + * default header being an empty string. + */ + public AbstractStatement(){ + this.children = new ArrayList<Statement>(); + this.header = ""; + } + + @Override + public void addChild(Statement child) { + this.children.add(child); + } + + @Override + public Statement[] getChildren() { + return children.toArray(new Statement[children.size()]); + } + + @Override + public String getHeader() { + return header; + } + + @Override + public void removeChild(Statement child) { + this.children.remove(child); + } + + @Override + public String toString(){ + return toString(0); + } + + public String toString( int recur ){ + StringBuffer buffer = new StringBuffer(); + String tab = ""; + for(int i = 0;i < recur;i++) + tab += '\t'; + + + buffer.append(tab + header); + + if(children.size() > 0){ + buffer.append("{\n"); + for(Statement child : children){ + buffer.append(child.toString( recur + 1 ) + "\n"); + } + buffer.append(tab + "}"); + } else{ + buffer.append(";"); + } + + return buffer.toString(); + } + + @Override + public Statement getChildByHeader(String header){ + + for(Statement child : children){ + String chHeader = child.getHeader(); + + if(chHeader.equals(header)) + return child; + } + + return null; + } + + @Override + public Statement[] getChildrenByHeader(String header){ + List<Statement> ret = new ArrayList<Statement>(); + + for(Statement child : children){ + String chHeader = child.getHeader(); + + if(chHeader.equals(header)) + ret.add(child); + } + + return ret.toArray(new Statement[ret.size()]); + } + + public int getLineNumber(){ + return line; + } + + public void setLineNumber(int line){ + this.line = line; + } + + public boolean hasChildren(){ + return !children.isEmpty(); + } + + public void clearChildren(){ + this.children.clear(); + } +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionParser.java b/project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionParser.java new file mode 100644 index 0000000..c62243a --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionParser.java @@ -0,0 +1,5 @@ +package com.modulus.dataread.expressions; + +public interface ExpressionParser { + ExpressionPart parseExpressions( String exp ); +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionPart.java b/project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionPart.java new file mode 100644 index 0000000..bf4e8d8 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/ExpressionPart.java @@ -0,0 +1,136 @@ +package com.modulus.dataread.expressions; + +/** + * This class is used to help to assemble the code into more + * readable code for the computer, it sets the system based on + * a more of a stack-ish way so the virtual machine can linearly + * push/pop arguments and call functions. + * + * @author jrahm + * + */ +public abstract class ExpressionPart { + + // Null if function is global + private ExpressionPart caller; + private ExpressionPart[] args; + + private String function; + private boolean primary = false; + + private ExpressionPart(){} + + /** + * This creates a new Expression part meant to handle multi-part + * expressions such as expressions with parenthesis, functions + * inside of functions and so on. + * + * Q-Bar is set up to be very functional, to the point where every entity is made + * of functions being called on arguments and such. + * + * @param caller the caller of the function (null if the function is global) + * @param function the function to be called + * @param args the arguments of the function + * @return an expression part that describes this layout + */ + public static ExpressionPart makePrimaryExpressionPart( ExpressionPart caller, String function, ExpressionPart[] args ){ + ExpressionPart ths = new ExpressionPart(){ + private String compile; + @Override + public String compilePart() { + + if( compile == null ){ + StringBuffer buf = new StringBuffer(); + ExpressionPart caller = this.getCaller(); + + // else + // buf.append( "$global$" ); + for(ExpressionPart part : this.getArgs()){ + buf.append(' '); + buf.append( part.compilePart() ); + } + + if(caller != null) + buf.append( " " + caller.compilePart() ); + + buf.append(' '); + if(this.getFunction().trim().length() > 0){ + if(caller != null){ + // \u00FF is the marker for what is an instance function + buf.append( "\u00FF" + this.getFunction() ); + } + else{ + // \u00FE is the marker for a global function + buf.append( "\u00FE" + this.getFunction() ); + } + } + compile = buf.toString().replaceAll("\\s+", " "); + } + + return compile; + } + }; + + ths.caller = caller; + ths.function = function; + ths.args = args; + + ths.primary = true; + + return ths; + } + + /** + * This method returns an expression part that is made entirely up + * of one single variable name. On a side note, these parts are the + * recursive base case for the compilation. + * + * The name of the variable is stored in the function value, as a variable + * name can be thought of as a function that returns that point in + * memory. + * + * @param name the name of the variable. + * @return A base case ExpressionPart + */ + public static ExpressionPart makeExpressionPart( String name ){ + ExpressionPart ths = new ExpressionPart(){ + @Override + public String compilePart() { + return this.getFunction(); + } + }; + ths.function = name; + + return ths; + } + + /** + * @return the caller + */ + public ExpressionPart getCaller() { + return caller; + } + + /** + * @return the args + */ + public ExpressionPart[] getArgs() { + return args; + } + + /** + * @return the function + */ + public String getFunction() { + return function; + } + + /** + * @return the primary + */ + public boolean isPrimary() { + return primary; + } + + public abstract String compilePart(); +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/FlowStatement.java b/project/JavaCommon/src/com/modulus/dataread/expressions/FlowStatement.java new file mode 100644 index 0000000..df51f2b --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/FlowStatement.java @@ -0,0 +1,3 @@ +package com.modulus.dataread.expressions; + +public enum FlowStatement { WHILE, FOR, IF, ELSE, RETURN, NONE } diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/LineNumberException.java b/project/JavaCommon/src/com/modulus/dataread/expressions/LineNumberException.java new file mode 100644 index 0000000..29cb0a1 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/LineNumberException.java @@ -0,0 +1,25 @@ +package com.modulus.dataread.expressions; + +public class LineNumberException extends RuntimeException{ + private int line; + + public LineNumberException( int line ) { + super(); + this.line = line; + } + + public LineNumberException(String message, int line) { + super(message + " line " + line); + this.line = line; + } + + public LineNumberException(String message, Throwable cause, int line) { + super(message + " line " + line, cause); + this.line = line; + } + + public int getLine(){ + return line; + } + +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/ParseRules.java b/project/JavaCommon/src/com/modulus/dataread/expressions/ParseRules.java new file mode 100644 index 0000000..a48f3b9 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/ParseRules.java @@ -0,0 +1,84 @@ +package com.modulus.dataread.expressions; + +/** + * Interface defines a set of rules used to parse + * text files. These rules include such rules like + * in string or folder start and end etc. + * + * @author jrahm + * + */ +public interface ParseRules { + /** + * First formats the code to make + * life much easier for the parser. + * + * This should be the first method to be + * called at all times. + */ + void format(); + + /** + * Signals these parse rules that the user has read the character at + * the point <code>off</code> of which the parser dictates how much + * code to skip. + * + * @param off point in the code which was read + * @return how many characters the parser should skip. + */ + int read( int off ); + + /** + * Returns true if the parser is in quotes, false otherwise. + * + * @return true if the parser is in quotes, false otherwuse. + */ + boolean inQuotes(); + + /** + * Returns true if the parser is in a + * comment or not. + * + * @return true if the parser is in a + * comment or not. + */ + boolean inComment(); + + /** + * returns true if at position <code>off</code> + * a folder is being opened. + * + * @param off the position in the code + * @return true if at position <code>off</code> a + * folder is being opened. + */ + boolean openFolder( int off ); + + /** + * returns true if at position <code>off</code> + * a folder is being closed in the code. + * + * @param off the position of the parser + * @return if a folder is being closed at position <code>off</code> + */ + boolean closeFolder( int off ); + + /** + * returns true if a statement is terminated at position <code>off</code> + * + * @param off the position in the code. + * @return true if a statement is terminated at position <code>off</code> + */ + boolean statementTerminated( int off ); + + /** + * Returns the code which these parse rules are using. + * @return the code which these parse rules are using. + */ + String getCode(); + + /** + * Returns the line number of this reader + */ + int getLineNumber(); +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/Statement.java b/project/JavaCommon/src/com/modulus/dataread/expressions/Statement.java new file mode 100644 index 0000000..27df480 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/Statement.java @@ -0,0 +1,105 @@ +package com.modulus.dataread.expressions; + +/** + * This interface is used to store interpreted + * information from a text file in a way that + * most represents a tree. for easy parsing + * for an interpreter or compiler. + * + * @author jrahm + * + */ +public interface Statement { + + /** + * Returns the child statements of this class + * + * @return the child statements of this class + */ + Statement[] getChildren(); + + /** + * Adds a child statement to this Statement + * + * @param child the child statement to add + */ + void addChild(Statement child); + + /** + * Removes a child statement from this Statement object + * + * @param child this child to remove from this statement + */ + void removeChild(Statement child); + + /** + * Sets the header for this statement object + * + * @param header the header for this statement. + */ + void setHeader(String header); + + /** + * returns the header for this statement object + * @return + */ + String getHeader(); + + /** + * side effect method to get nicely formatted printouts + * of the statement class. + * @param recur + * @return + */ + String toString( int recur ); + + /** + * Returns the child of this Statement that has + * the header <code>header</code>. If there is no + * child with that header, then the method should + * then return <code>null</code>. If there are multiple + * children with the same header, then the first one should + * be returned. If all children with that header should be + * returned, then use the <code>getChildrenByHeader</code> method. + * + * @param header the header of the child to return + * @return a child with the header <code>header</code> + */ + Statement getChildByHeader(String header); + + /** + * Returns an array of children of this Statement that have + * the header <code>header</code>. If no children have that header, + * then an empty array is returned. + * + * @param header the header of the children to return. + * @return an array of children that have the header <code>header</code> + */ + Statement[] getChildrenByHeader(String header); + + /** + * Returns the line number that this statement starts on. + * @return the line number that this statement starts on. + */ + int getLineNumber(); + + /** + * Sets the line number that this statement + * starts on. + * + * @param line the line this statement starts on. + */ + void setLineNumber(int line); + + /** + * Returns true if this statement has children, false otherwise. + * + * @return true if this statement has children. + */ + boolean hasChildren(); + + /** + * Deletes all children from this statement + */ + void clearChildren(); +}
\ No newline at end of file diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/StatementFactory.java b/project/JavaCommon/src/com/modulus/dataread/expressions/StatementFactory.java new file mode 100644 index 0000000..16da8aa --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/StatementFactory.java @@ -0,0 +1,28 @@ +package com.modulus.dataread.expressions; + +import java.util.Map; + +/** + * Interface describes how an object is supposed to + * generate statements. This class is to be used int tandem + * with the ExpressionParser interface to generate + * Statements of a specific type; + * + * @author jrahm + * + * @param <T> the type of statement this StatementFactory creates + */ +public interface StatementFactory<T extends Statement> { + + /** + * Creates a new statement with the type <code>T</code> based + * on what the parameters contain. + * + * The parameters contain useful information about where the parser + * currently is and how to create the new statement. + * + * @param params the parameters + * @return a new statement of type <code>T</code> based off of the parameters. + */ + T generateStatement(Map<String, Object> params); +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/StatementFormatter.java b/project/JavaCommon/src/com/modulus/dataread/expressions/StatementFormatter.java new file mode 100644 index 0000000..8070034 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/StatementFormatter.java @@ -0,0 +1,26 @@ +package com.modulus.dataread.expressions; + +import java.io.Serializable; + +/** + * Classes that implement this interface are used + * to format string before they become a part of + * a statement. + * + * These classes are the classes responsible for making + * sure the headers are formatted in such a way that they might + * be easy to parse. + * + * @author jrahm + */ +public interface StatementFormatter extends Serializable{ + /** + * Given the String <code>header</code> as a header of a statement, + * format it so it can easily be parsed by custom parsing + * techniques. + * + * @param header the header to parse + * @return a formatted version of the header. + */ + String formatHeader(String header); +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/StatementTreeParser.java b/project/JavaCommon/src/com/modulus/dataread/expressions/StatementTreeParser.java new file mode 100644 index 0000000..854d4d2 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/StatementTreeParser.java @@ -0,0 +1,21 @@ +package com.modulus.dataread.expressions; + +/** + * Interface which describes how an expression parser + * will handle information from an interpreter file. + * + * @author jrahm + * + * @param S the statement type which is used to create this class + */ +public interface StatementTreeParser { + + /** + * Parse a block of code into statements using the statement factory <code>factory</code> + * to generate the statements to use. + * @param <T> the type of statement to use. + * @param factory the factory to generate the statements + * @return a Statement of type <code>T</code> that represents the code parsed + */ + <T extends Statement> Statement parseStatements(StatementFactory<T> factory); +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/AbstractParseRules.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/AbstractParseRules.java new file mode 100644 index 0000000..ebdb2dc --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/AbstractParseRules.java @@ -0,0 +1,197 @@ +package com.modulus.dataread.expressions.impl; + +import com.modulus.dataread.expressions.ParseRules; + +/** + * Class which implements ParseRules with rules + * of a language which is very close to the C Programming + * Language and others based off it. + * + * @author jrahm + */ +public abstract class AbstractParseRules implements ParseRules{ + private static final String w = "\\s"; + + private int lineNumber = 0; + /* + * the code this class will follow + */ + private String code; + /* + * value which tells this class + * if it is in quotes or not. + */ + private boolean inQuotes = false; + + /* + * value which dictates if the parser + * is in comments. + */ + private boolean inComments = false; + + /* + * this tells if the parser is in + * a comment delimited by '//' + */ + private boolean inLineComment = false; + /** + * Constructs a new CBasedParseRules object with <code>code</code> + * as the code which is being parsed. + * + * @param code the code to be parsed. + */ + public AbstractParseRules(String code){ + this.code = code; + format(); + + deleteComments(); + } + + @Override + public boolean closeFolder(int off) { + + return code.startsWith(this.getCloseFolderString(), off); + } + + @Override + public boolean inComment() { + return inComments || inLineComment; + } + + @Override + public boolean inQuotes() { + return inQuotes; + } + + @Override + public boolean openFolder(int off) { + return code.startsWith( this.getOpenFolderString(), off ); + } + + /* + * this is where most of the logic + * goes for this class, this method is + * what dictates the flow of the parser + * and whether or not the parser is in + * quotes or comments etc. + * + * @see com.modulus.dataread.expressions.ParseRules#read(int) + */ + @Override + public int read(int off) { + // Here we will handle to see if the parser + // has run into a string literal. + + // System.out.print( code.charAt(off) ); + if(code.charAt(off) == '"'){ + if( off == 0 || code.charAt(off - 1) != '\\' ){ + inQuotes = !inQuotes; + } + } + + return 1; + } + + public boolean statementTerminated( int off ){ + boolean tmp = code.startsWith( this.getStatementTerminatingCharacter(), off ) && !inQuotes(); + + // if(tmp) { + // System.out.printf("%s\t%s\t%s\n", code.substring(off), off, inQuotes ); + // } + + return tmp; + } + + @Override + public void format() { + // for most C-based languages white space can just be + // Truncated like so. + // this.code = this.code.replaceAll(w+"+\n"+w+"+", "\n"); + this.code = this.code.replace('\n', '\u0088'); + // this.code = this.code.replaceAll(w+"+", " "); + // this.code = this.code.replaceAll(w+"*\\}"+w+"*", "}"); + // this.code = this.code.replaceAll(w+"*;"+w+"*", ";"); + StringBuffer total = new StringBuffer(); + + int i = 0; + int old = 0; + + boolean inQuotes = false; + + while( i != this.code.length() ) { + old = i; + i = code.indexOf('"', i+1); + + if( i == -1 ) + i = this.code.length(); + + String sub = code.substring(old, i); + + if(!inQuotes) { + sub = sub.replaceAll(w+"+", " "); + sub = sub.replaceAll(w+"*\\}"+w+"*", "}"); + sub = sub.replaceAll(w+"*;"+w+"*", ";"); + } + + total.append(sub); + + inQuotes = !inQuotes; + } + total.append( code.substring(old) ); + + code = total.toString(); + //this.code = this.code.replaceAll("[^;]\\}", ";}"); + + // System.out.println("Format: " + this.code); + } + + public String getCode(){ + return code.replace('\u0088', '\n'); + } + + @Override + public int getLineNumber() { + return lineNumber; + } + + private void deleteComments(){ + StringBuffer code2 = new StringBuffer(); + + for( int i = 0;i < code.length(); i ++){ + if(code.startsWith( this.getCommentOpen(), i )){ + while(!code.startsWith( this.getCommentClose(), i)){ + if(code.charAt(i) == '\u0088') + code2.append(code.charAt(i)); + i ++; + } + i += this.getCommentClose().length(); + } + + if(code.startsWith( this.getLineCommentDelimeter(), i)){ + while(code.charAt(i) != '\u0088'){ + i++; + } + } + + code2.append( code.charAt(i) ); + } + + code = code2.toString(); + } + + public abstract String getOpenFolderString(); + + public abstract String getCloseFolderString(); + + public abstract String getStatementTerminatingCharacter(); + + public abstract String getStringDelimiter(); + + public abstract String getEscapeSequence(); + + public abstract String getCommentOpen(); + + public abstract String getCommentClose(); + + public abstract String getLineCommentDelimeter(); +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/CBasedParseRules.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/CBasedParseRules.java new file mode 100644 index 0000000..33dad25 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/CBasedParseRules.java @@ -0,0 +1,57 @@ +package com.modulus.dataread.expressions.impl; + +public class CBasedParseRules extends AbstractParseRules{ + + public CBasedParseRules(String code) { + super(code); + } + + @Override + public String getOpenFolderString() { + // TODO Auto-generated method stub + return "{"; + } + + @Override + public String getCloseFolderString() { + // TODO Auto-generated method stub + return "}"; + } + + @Override + public String getStatementTerminatingCharacter() { + // TODO Auto-generated method stub + return ";"; + } + + @Override + public String getStringDelimiter() { + // TODO Auto-generated method stub + return "\""; + } + + @Override + public String getEscapeSequence() { + // TODO Auto-generated method stub + return "\\"; + } + + @Override + public String getCommentOpen() { + // TODO Auto-generated method stub + return "/*"; + } + + @Override + public String getCommentClose() { + // TODO Auto-generated method stub + return "*/"; + } + + @Override + public String getLineCommentDelimeter() { + // TODO Auto-generated method stub + return "//"; + } + +}
\ No newline at end of file diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/FormatStatement.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/FormatStatement.java new file mode 100644 index 0000000..8a4b3ad --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/FormatStatement.java @@ -0,0 +1,52 @@ +package com.modulus.dataread.expressions.impl; + +import com.modulus.dataread.expressions.AbstractStatement; +import com.modulus.dataread.expressions.StatementFormatter; + +/** + * This class that extends AbstractStatement will first + * format its header before it sets the actual header to + * what the user sends, using a statement formatter. + * + * @author jrahm + * + */ +public class FormatStatement extends AbstractStatement{ + private static final long serialVersionUID = -4973798175965745298L; + private StatementFormatter formatter; + + /** + * This creates a new Statement with <code>formatter</code> + * as the default formatter for this Statement. + * + * @param formatter the formatter for this statement + */ + public FormatStatement(StatementFormatter formatter){ + this.formatter = formatter; + } + + protected FormatStatement(){ + } + + @Override + public void setHeader(String header) { + this.header = formatter.formatHeader(header); + } + + /** + * Returns the formatter for this Statement + * @return the formatter for this Statement + */ + public StatementFormatter getFormatter(){ + return formatter; + } + + /** + * Sets the formatter for this statement + * @param formatter the formatter for this statement + */ + public void setFormatter(StatementFormatter formatter){ + this.formatter = formatter; + } + +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleExpressionParser.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleExpressionParser.java new file mode 100644 index 0000000..22f1be5 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleExpressionParser.java @@ -0,0 +1,139 @@ +package com.modulus.dataread.expressions.impl; + +import com.modulus.common.TwoTypeBean; +import com.modulus.dataread.expressions.StatementTreeParser; +import com.modulus.dataread.expressions.ParseRules; +import com.modulus.dataread.expressions.Statement; +import com.modulus.dataread.expressions.StatementFactory; + +/** + * This simple expression parser is meant not to do anything fancy + * all it does is break up the file into a tree based on the folders + * in the file. + * + * @author jrahm + * + */ +public class SimpleExpressionParser implements StatementTreeParser{ + /* + * used by methods to keep track of + * the number of lines + */ + private int line = 0; + /* + * The rules to parse by + */ + private ParseRules rules; + + /** + * Creates a new <code>SimpleExpressionParser</code> based + * off of the rules that was given to it. + * + * @param rules the rules to parse by + */ + public SimpleExpressionParser(ParseRules rules){ + this.rules = rules; + } + + @Override + public <T extends Statement> Statement parseStatements(StatementFactory<T> factory) { + // set the line counter to 1 + this.line = 1; + return recurParseStatement(factory, 0).getObject1(); + } + + /* + * Setup a recursive parser to + * return a tree of statements + */ + private <T extends Statement> TwoTypeBean<T, Integer> recurParseStatement(StatementFactory<T> factory, int off){ + // System.out.println(" parseStatements"); + final String code = rules.getCode(); + + // statement which will be returned in the end, + // this statement is the parent of all the other + // statements + T ret = factory.generateStatement(null); + int i = off; + + + // start an iteration through the + // string + for( ;i < code.length(); i ++ ){ + + // if the next character is a new line character, + // the increment the line counter + if(code.charAt(i) == '\n') + line ++; + + // check to see if the rules say that here a statement + // is to be terminated + if( rules.statementTerminated(i) ){ + + // if so, then it is time to manifest a new statement + // header is equal to the substring of the code from + // off to i + String header = code.substring(off, i); + + // create a new child from the type provided + T child = factory.generateStatement(null); + + // set the line number to what it should be + child.setLineNumber( this.line ); + + // set the header + child.setHeader( header ); + + // we are done with creating this beam, so it is time to + // return it + return new TwoTypeBean<T, Integer>(child, i); + } + + // if the rules say that at this point, + // a folder is opened, then it is time to + // use recursion to implement a tree. + else if ( rules.openFolder(i) ){ + + // the header is from off to when the + // folder is being closed + String header = code.substring(off, i); + + // set the header + ret.setHeader(header); + + // set the line number + ret.setLineNumber(line); + + // it is time to increment i by the + // amount the rules say to. + i += rules.read(i); + + // while the folder is not closed + while( !rules.closeFolder(i) ){ + + // read the next statement + TwoTypeBean<T, Integer> bean = recurParseStatement(factory, i); + + // the second object is the offset + //that the previous call terminated with + i = bean.getObject2(); + + // add this child to the main bean + ret.addChild(bean.getObject1()); + + // increment the incrementer by how + // much the rules say to + i += rules.read(i); + } + + // When finished reading this file, it is time + // to return the main bean. + return new TwoTypeBean<T, Integer>(ret, i); + } + } + + // System.out.println(" /parseStatements"); + return new TwoTypeBean<T, Integer>(ret, i); + } + +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatement.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatement.java new file mode 100644 index 0000000..f32cfca --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatement.java @@ -0,0 +1,19 @@ +package com.modulus.dataread.expressions.impl; + +import com.modulus.dataread.expressions.AbstractStatement; + +public class SimpleStatement extends AbstractStatement { + private static final long serialVersionUID = -8730515046885236907L; + + public SimpleStatement(){} + + public SimpleStatement(String string) { + super(); + this.setHeader(string); + } + + @Override + public void setHeader(String header) { + this.header = header; + } +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatementTreeParser.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatementTreeParser.java new file mode 100644 index 0000000..70ebd95 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/SimpleStatementTreeParser.java @@ -0,0 +1,162 @@ +package com.modulus.dataread.expressions.impl; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Map; + +import com.modulus.common.TwoTypeBean; +import com.modulus.dataread.expressions.LineNumberException; +import com.modulus.dataread.expressions.StatementFormatter; +import com.modulus.dataread.expressions.StatementTreeParser; +import com.modulus.dataread.expressions.ParseRules; +import com.modulus.dataread.expressions.Statement; +import com.modulus.dataread.expressions.StatementFactory; + +/** + * This simple expression parser is meant not to do anything fancy + * all it does is break up the file into a tree based on the folders + * in the file. + * + * @author jrahm + * + */ +public class SimpleStatementTreeParser implements StatementTreeParser{ + + /* + * used by methods to keep track of + * the number of lines + */ + private int line = 0; + /* + * The rules to parse by + */ + private ParseRules rules; + + /** + * Creates a new <code>SimpleExpressionParser</code> based + * off of the rules that was given to it. + * + * @param rules the rules to parse by + */ + public SimpleStatementTreeParser(ParseRules rules){ + this.rules = rules; + } + + @Override + public <T extends Statement> Statement parseStatements(StatementFactory<T> factory) { + // set the line counter to 1 + this.line = 0; + return recurParseStatement(factory, 0).getObject1(); + } + + /* + * Setup a recursive parser to + * return a tree of statements + */ + private <T extends Statement> TwoTypeBean<T, Integer> recurParseStatement(StatementFactory<T> factory, int off){ + try{ + // System.out.println(" parseStatements"); + final String code = rules.getCode(); + + // statement which will be returned in the end, + // this statement is the parent of all the other + // statements + T ret = factory.generateStatement(null); + int i = off; + int n = 0; + + // start an iteration through the + // string + for( ;i < code.length(); n++, i += rules.read(i) ){ + // if the next character is a new line character, + // the increment the line counter + // System.out.println( i ); + if(code.charAt(i) == '\n'){ + line ++; + // that is all a new line does; + continue; + } + + // check to see if the rules say that here a statement + // is to be terminated + if( rules.statementTerminated(i) ){ + + // if so, then it is time to manifest a new statement + // header is equal to the substring of the code from + // off to i + String header = code.substring(off, i); + + // create a new child from the type provided + T child = factory.generateStatement(null); + + // set the header + child.setHeader( header ); + + // set the line number to what it should be + child.setLineNumber( this.line ); + + // we are done with creating this beam, so it is time to + // return it + return new TwoTypeBean<T, Integer>(child, i); + } + + // if the rules say that at this point, + // a folder is opened, then it is time to + // use recursion to implement a tree. + else if ( rules.openFolder(i) ){ + + // the header is from off to when the + // folder is being closed + String header = code.substring(off, i); + + // set the header + ret.setHeader(header); + + // set the line number + ret.setLineNumber(line); + + // it is time to increment i by the + // amount the rules say to. + i += rules.read(i); + + // while the folder is not closed + while( !rules.closeFolder(i) ){ + + // read the next statement + TwoTypeBean<T, Integer> bean = recurParseStatement(factory, i); + + // the second object is the offset + //that the previous call terminated with + i = bean.getObject2(); + + // add this child to the main bean + ret.addChild(bean.getObject1()); + + // increment the incrementer by how + // much the rules say to + i += rules.read(i); + + while(code.charAt(i) == '\n'){ + line ++; + i++; + } + } + + // When finished reading this file, it is time + // to return the main bean. + return new TwoTypeBean<T, Integer>(ret, i); + } + + } + + // System.out.println(" /parseStatements"); + return new TwoTypeBean<T, Integer>(ret, i); + } catch( Exception e ){ + throw new LineNumberException("Sytax error", e, line); + } + } + +} diff --git a/project/JavaCommon/src/com/modulus/dataread/expressions/impl/StatementParser.java b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/StatementParser.java new file mode 100644 index 0000000..7a91585 --- /dev/null +++ b/project/JavaCommon/src/com/modulus/dataread/expressions/impl/StatementParser.java @@ -0,0 +1,5 @@ +package com.modulus.dataread.expressions.impl; + +public class StatementParser { + +} |