package com.hpctoday.jpip;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import com.hpctoday.jpip.math.LongFactory;
import com.hpctoday.jpip.math.LongInteger;
import com.hpctoday.jpip.math.RationalNumber;
import com.hpctoday.jpip.math.RationalVector;
import com.hpctoday.jpip.solution.NewParameter;
import com.hpctoday.jpip.solution.PipList;
import com.hpctoday.jpip.solution.PipQuast;
import com.hpctoday.jpip.solution.PipSolution;
public class PipOutputReader {
private static final int EOF = -1;
private static final int MODE_COMMENT = 0;
private static final int MODE_RESULT = 1;
private String filename;
private String comment;
private String result = "";
private LongFactory lf;
public PipOutputReader(String filename){
this.filename = filename;
lf = new LongFactory();
}
public void read() throws IOException{
Reader reader = new BufferedReader(new FileReader(filename));
StringBuilder commentBlock = new StringBuilder();
StringBuilder resultBlock = new StringBuilder();
int mode = -1;
int depth = 0;
int c;
while ((c = reader.read()) != EOF) {
if(c == '('){
depth++;
if(depth == 2){
//Go to COMMENT
if(mode == -1){
mode++;
continue;
}
}
} else if(c == ')'){
depth--;
if(depth == 1){
//Go to RESULT
if(mode == MODE_COMMENT){
mode++;
continue;
}
}
}
if(depth == 0){
break;
}
switch(mode){
case MODE_COMMENT:
commentBlock.append((char)c);
break;
case MODE_RESULT:
resultBlock.append((char)c);
break;
}
}
comment = commentBlock.toString().trim();
result = resultBlock.toString().trim();
reader.close();
}
public String getComment() {
return comment;
}
public String getResult() {
return result;
}
public PipSolution<LongInteger> parseResult(){
if(result.length() > 0){
List<PipSolution<LongInteger>> list = parseBlock(result.trim());
if(list.size() > 0)
return list.get(0);
else
return null;
}
return null;
}
private List<PipSolution<LongInteger>> parseBlock(String segment){
ArrayList<PipSolution<LongInteger>> solutionList = new ArrayList<PipSolution<LongInteger>>();
PipSolution<LongInteger> solution = new PipSolution<LongInteger>();
int depth = 0;
StringBuilder buffer = new StringBuilder();
for(int offset = 0; offset < segment.length(); offset++){
char c = segment.charAt(offset);
if(c == '('){
depth++;
if(depth == 1)
continue;
} else if(c == ')'){
depth--;
//End of 1 block
if(depth == 0){
String block = buffer.toString().trim();
if(buffer.length() > 0){
buffer.delete(0, buffer.length());
}
if(block.length() == 0){
solutionList.add(solution);
solution = new PipSolution<LongInteger>();
continue;
}
//Process block
int start = block.indexOf(" ");
if(start == -1){
System.out.println("Unknown block: *" + block + "*");
continue;
}
String type = block.substring(0, start);
if(type.equals("if")){
PipQuast<LongInteger> quast = parseIf(block);
solution.setSolution(quast);
solutionList.add(solution);
solution = new PipSolution<LongInteger>();
} else if(type.equals("newparm")){
NewParameter<LongInteger> parm = parseNewParm(block);
solution.addNewParameter(parm);
} else if(type.equals("list")){
List<RationalVector<LongInteger>> list = parseList(block);
PipList<LongInteger> soln = new PipList<LongInteger>();
soln.addAllRows(list);
solution.setSolution(soln);
solutionList.add(solution);
solution = new PipSolution<LongInteger>();
}
continue;
}
}
if(depth > 0){
buffer.append(c);
}
}
return solutionList;
}
private List<RationalVector<LongInteger>> parseList(String block){
ArrayList<RationalVector<LongInteger>> list = new ArrayList<RationalVector<LongInteger>>();
int start, end = 0;
while(true){
start = block.indexOf("[", end);
if(start == -1) break;
start++;
end = block.indexOf("]", start);
String listing = block.substring(start, end).trim();
RationalVector<LongInteger> vector = new RationalVector<LongInteger>(0);
String[] elements = listing.split(" ");
for(String elem: elements){
int num = 0;
int denom = 1;
if(elem.contains("/")){
String[] parts = elem.split("/");
num = Integer.parseInt(parts[0]);
denom = Integer.parseInt(parts[1]);
} else {
num = Integer.parseInt(elem);
}
RationalNumber<LongInteger> number = new RationalNumber<LongInteger>(lf, num, denom);
vector.addElement(number);
}
list.add(vector);
}
return list;
}
private NewParameter<LongInteger> parseNewParm(String block){
int start, end;
start = block.indexOf(" ") + 1;
end = block.indexOf(" ", start);
String sIndex = block.substring(start, end);
start = block.indexOf("(", end) + 1;
end = block.indexOf(")", start);
String divBlock = block.substring(start, end);
start = divBlock.indexOf("[") + 1;
end = divBlock.indexOf("]", start);
String list = divBlock.substring(start, end).trim();
start = divBlock.indexOf(" ", end);
String sDivisor = divBlock.substring(start).trim();
int index = Integer.parseInt(sIndex);
RationalVector<LongInteger> vector = new RationalVector<LongInteger>(0);
int denom = Integer.parseInt(sDivisor);
String[] elements = list.split(" ");
for(String elem: elements){
int num = Integer.parseInt(elem);
RationalNumber<LongInteger> number = new RationalNumber<LongInteger>(lf, num, denom);
vector.addElement(number);
}
NewParameter<LongInteger> newparm = new NewParameter<LongInteger>(index, vector);
return newparm;
}
private PipQuast<LongInteger> parseIf(String block){
int start, end;
start = block.indexOf("[") + 1;
end = block.indexOf("]", start);
String sCondition = block.substring(start, end).trim();
RationalVector<LongInteger> vector = new RationalVector<LongInteger>(0);
String[] elements = sCondition.split(" ");
for(String elem: elements){
int num = 0;
int denom = 1;
if(elem.contains("/")){
String[] parts = elem.split("/");
num = Integer.parseInt(parts[0]);
denom = Integer.parseInt(parts[1]);
} else {
num = Integer.parseInt(elem);
}
RationalNumber<LongInteger> number = new RationalNumber<LongInteger>(lf, num, denom);
vector.addElement(number);
}
PipQuast<LongInteger> quast = new PipQuast<LongInteger>(vector);
List<PipSolution<LongInteger>> list = parseBlock(block.substring(end));
if(list.size() > 0){
quast.setThen(list.get(0));
}
if(list.size() > 1){
quast.setElse(list.get(1));
}
return quast;
}
}