diff options
| author | Joshua Rahm <joshua.rahm@colorado.edu> | 2015-01-27 18:40:32 -0700 |
|---|---|---|
| committer | Joshua Rahm <joshua.rahm@colorado.edu> | 2015-01-27 18:40:32 -0700 |
| commit | 5f3fb9afece2125cbeba79d61a8d88460b7878d7 (patch) | |
| tree | b0e1e60bae9927a9449561bf7fe9431a54d12be9 /project/JavaCommon/src/com/modulus/dataread/expressions/impl | |
| download | LegacyQBar-5f3fb9afece2125cbeba79d61a8d88460b7878d7.tar.gz LegacyQBar-5f3fb9afece2125cbeba79d61a8d88460b7878d7.tar.bz2 LegacyQBar-5f3fb9afece2125cbeba79d61a8d88460b7878d7.zip | |
initial commit
Diffstat (limited to 'project/JavaCommon/src/com/modulus/dataread/expressions/impl')
7 files changed, 631 insertions, 0 deletions
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 { + +} |