package com.grits.griti;
import com.grits.objects.Function;
import com.grits.objects.Variable;
import com.grits.util.Console;
import com.grits.util.GritsException;
import com.grits.util.GritsFile;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JTextArea;
public class GritsParser
{
String meta_string;
int meta_int;
Variable in_var;
boolean isVariable = false;
GritsException ge = new GritsException();
int var_value;
public JTextArea txt = new JTextArea();
PrintStream out;
InputStream input;
StringBuffer sb = new StringBuffer();
Console c = null;
List<Variable> vars = new ArrayList();
List<String> varnames = new ArrayList();
List<Function> functions = new ArrayList();
List<String> lines;
String line = "";
String[] symbols = {
"+", "-","*", "/",
"'", "%", "^", "$",
"!", "?", "??", "[",
"]", "{", "}", "(",
")", "@", ":", "#",
"~", "_", "|", "."};
public GritsParser(GritsFile gf)
throws Exception
{
if(gf.exists())
{
/*for(int i = 0; i < gf.getLines().size(); i++)
{
line = gf.getLines().get(i);
parse(line);
}*/
for(String l : gf.getLines())
{
parse(l);
}
}
else
ge.throwGrits(ge.GE_FILE_NOT_FOUND, null);
}
public void registerOutputStream(PrintStream out)
{
this.out = out;
}
public void registerInputStream(InputStream in)
{
this.input = in;
}
public void parse(String line)
throws Exception
{
parseIndent(line);
parseComments(line);
parseImports(line);
parseVars(line);
popVars();
parseReasign(line);
parseMetaString(line);
parseMetaInt(line);
parseOutput(line);
parseMaths(line);
parseConcat(line);
parseIfs(line);
parseWhiles(line);
parseFunctions(line);
parseFunctionCalls(line);
parseRedefines(line);
parseConsole(line);
}
public void parseImports(String line)
throws Exception
{
if(line.startsWith(symbols[17]))
{
for(int i = 0; i < getImportLines(line).size(); i++)
{
try
{
parse(getImportLines(line).get(i));
}
catch(NullPointerException npe)
{
ge.throwGrits(0, line);
}
}
}
}
public List<String> getImportLines(String line)
throws Exception
{
GritsFile gf;
GritsParser gp;
String ext_fname;
if(line.startsWith(symbols[17]))
{
ext_fname = line.replace(symbols[17], "");
gf = new GritsFile(ext_fname);
gp = new GritsParser(gf);
if(gf.exists())
{
try
{
lines = gf.getLines();
}
catch(NullPointerException e)
{
ge.throwGrits(0, line.replace(symbols[17], ""));
}
}
}
return lines;
}
public void parseFunctions(String line)
{
parseIndent(line);
String function_name = "";
String action_list = "";
String[] actions;
String[] args;
if(line.startsWith(symbols[8]) && line.contains(symbols[13]) && line.contains(symbols[14]))
{
line = line.replaceAll("[!]", "");
line = line.replaceAll("\\{|\\}", " ");
line = line.replace(symbols[8], "");
function_name = line.substring(0, line.indexOf(" "));
action_list = line.substring(line.indexOf(" ") + 1);
//function_name = line.substring(line.indexOf(symbols[8]) + 1, line.indexOf(symbols[13]));
//action_list = line.substring(line.indexOf(symbols[13]) + 1, line.lastIndexOf(symbols[14]));
actions = action_list.split(" ");
Function f = new Function(function_name, actions, this);
functions.add(f);
}
}
public void parseFunctionCalls(String line)
throws Exception
{
parseIndent(line);
String f_name = "";
if(line.startsWith(symbols[8]) && !line.contains(symbols[13]) && !line.contains(symbols[14]))
{
f_name = line.replace(symbols[8], "");
for(int i = 0; i < functions.size(); i++)
{
if(functions.get(i).getName().equals(f_name))
{
functions.get(i).execute(this);
}
}
}
}
public boolean containsVar(String varname)
{
return varnames.contains(varname);
}
public Function getByNameF(String name)
{
for(int i = 0; i < functions.size(); i++)
{
if(functions.get(i).getName().equals(name))
return functions.get(i);
}
return null;
}
public void parseWhiles(String line)
throws Exception
{
if(line.startsWith(symbols[10]) && (line.indexOf(symbols[13])>-1) && (line.indexOf(symbols[14])>-1))
{
line = line.replace(symbols[10], "");
String test = line.substring(0, line.indexOf(symbols[13]));
String[] actions = line.substring(line.indexOf(symbols[13]) + 1, line.lastIndexOf(symbols[14])).split(" ");
if(test.indexOf(symbols[23]) > -1)
{
String testl = test.substring(0, test.indexOf(symbols[23]));
String testr = test.substring(test.indexOf(symbols[23]) + symbols[23].length());
if(isNum(testl) && isNum(testr))
{
while(Integer.parseInt(testl) > Integer.parseInt(testr))
{
for(String a : actions)
parse(a);
}
}
else if(varnames.contains(testl) && isNum(testr))
{
}
}
}
}
/*public void parseWhiles(String line)
throws Exception
{
parseIndent(line);
String test_left = "";
String test_right = "";
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String in_val = "";
int left_val = 0;
int right_val = 0;
String l_val = null;
String r_val = null;
String do_while = "";
String var_name = "";
if(line.startsWith(symbols[10]) && line.contains(symbols[23]) && line.contains(symbols[13]) && line.contains(symbols[14]))
{
test_left = line.substring(line.indexOf(symbols[10]) + 2, line.indexOf(symbols[23]));
test_right = line.substring(line.indexOf(symbols[23]) + 1, line.indexOf(symbols[13]));
do_while = line.substring(line.indexOf(symbols[13]) + 1, line.lastIndexOf(symbols[14]));
if(test_left.equals(symbols[19]))
{
log(">> ");
in_val = in.readLine();
if(Character.isDigit(in_val.charAt(0)))
left_val = Integer.parseInt(in_val);
else
l_val = in_val;
}
if(test_right.equals(symbols[19]))
{
log(">> ");
in_val = in.readLine();
if(Character.isDigit(in_val.charAt(0)))
right_val = Integer.parseInt(in_val);
else
r_val = in_val;
}
if(Character.isDigit(test_left.charAt(0)))
left_val = Integer.parseInt(test_left);
if(Character.isDigit(test_right.charAt(0)))
right_val = Integer.parseInt(test_right);
if(test_left.startsWith("\"") && test_left.endsWith("\""))
l_val = test_left.replaceAll("\"", "");
if(test_right.startsWith("\"") && test_right.endsWith("\""))
r_val = test_right.replaceAll("\"", "");
for(int i = 0; i < vars.size(); i++)
{
if(test_left.equals(vars.get(i).getName()) && vars.get(i).getType() == 1)
{
left_val = (Integer) vars.get(i).getValue();
var_name = vars.get(i).getName();
}
if(test_right.equals(vars.get(i).getName()) && vars.get(i).getType() == 1)
{
right_val = (Integer) vars.get(i).getValue();
var_name = vars.get(i).getName();
}
if(test_left.equals(vars.get(i).getName()) && vars.get(i).getType() == 0)
{
l_val = vars.get(i).getValue().toString();
var_name = vars.get(i).getName();
}
if(test_right.equals(vars.get(i).getName()) && vars.get(i).getType() == 0)
{
r_val = vars.get(i).getValue().toString();
var_name = vars.get(i).getName();
}
}
if(l_val instanceof String && l_val instanceof String && l_val == null && r_val == null)
{
while(left_val != right_val)
{
parse(do_while);
left_val = (Integer) getByName(var_name).getValue();
}
}
else
{
while(!l_val.equals(r_val))
parse(do_while);
}
}
}*/
private void redefine(String from, String to)
{
int index = 0;
String s = "";
for(int i = 0; i < symbols.length; i++)
{
if(symbols[i].equals(from))
{
index = i;
s = "not null";
}
}
if(s.equals("not null"))
{
symbols[index] = to;
}
}
public void parseRedefines(String line)
{
String from, to;
if(line.startsWith(symbols[20]) && line.contains(";"))
{
line = line.replaceFirst(symbols[20], "");
line = line.replace(";", " ");
from = line.substring(0, line.indexOf(" "));
to = line.substring(line.indexOf(" ") + 1);
redefine(from, to);
}
}
public void parseIfs(String line)
throws Exception
{
if(line.startsWith(symbols[9]) && line.contains(symbols[13]) && line.contains(symbols[14]) && line.contains(symbols[23]) && (line.indexOf(symbols[13]) < line.indexOf(symbols[14])))
{
line = line.replace(symbols[9], "");
String left_val = line.substring(0, line.indexOf(symbols[23]));
String right_val = line.substring(line.indexOf(symbols[23]) + symbols[23].length(), line.indexOf(symbols[13]));
String left_arg = "";
String right_arg = "";
if(line.contains(symbols[22]))
{
left_arg = line.substring(line.indexOf(symbols[13]) + symbols[13].length(), line.indexOf(symbols[22]));
right_arg = line.substring(line.indexOf(symbols[22]) + symbols[22].length(), line.indexOf(symbols[14]));
}
else
left_arg = line.substring(line.indexOf(symbols[13]) + symbols[13].length(), line.indexOf(symbols[14]));
for(Variable var : vars)
{
if(left_val.equals(var.getName()))
{
if(var.getType() == 0)
left_val ="'" + var.getValue().toString() + "'";
else
left_val = var.getValue().toString();
}
else if(right_val.equals(var.getName()))
{
if(var.getType() == 0)
right_val ="'" + var.getValue().toString() + "'";
else
right_val = var.getValue().toString();
}
}
if(isNum(left_val) && isNum(right_val))
{
if(Integer.parseInt(left_val) == Integer.parseInt(right_val))
parse(left_arg);
else
parse(right_arg);
}
else if(isString(left_val) && isString(right_val))
{
if(left_val.equals(right_val))
parse(left_arg);
else
parse(right_arg);
}
else if(isMaths(left_val) && isMaths(right_val))
{
if(parseMaths(left_val) == parseMaths(right_val))
parse(left_arg);
else
parse(right_arg);
}
else if(isMaths(left_val) && isNum(right_val))
{
if(parseMaths(left_val) == Integer.parseInt(right_val))
parse(left_arg);
else
parse(right_arg);
}
else if(isNum(left_val) && isMaths(right_val))
{
if(Integer.parseInt(left_val) == parseMaths(right_val))
parse(left_arg);
else
parse(right_arg);
}
}
}
public boolean isVar(String s)
throws Exception
{
if(!isNum(s) && !isMaths(s) && !isConcat(s) && !isArray(s) && !isString(s) && !isMeta(s))
return true;
else
return false;
}
public void parseComments(String line)
{
parseIndent(line);
if(line.startsWith(">") && line.endsWith("<"))
line = "";
}
public void parseIndent(String line)
{
if(line.startsWith("\t"))
line = line.replace("\t", "");
}
public boolean isMaths(String s)
{
if(s.matches("\\(.*[\\+|\\-|\\*|\\/|\\%].*\\)"))
return true;
else
return false;
}
public boolean isConcat(String s)
{
if(s.matches("\\{.*[\\+|\\-|\\*|\\/].*\\}"))
return true;
else
return false;
}
public boolean hasVar(String s)
{
List<String> names = new ArrayList();
for(int i = 0; i < vars.size(); i++)
names.add(vars.get(i).getName());
if(names.contains(s))
return true;
else
return false;
}
public String parseConcat(String line)
{
String result = "";
String l = "";
String r = "";
String op = "";
Pattern p;
Matcher m;
if(isConcat(line))
{
op = line.replaceAll("[^\\+|\\-|\\*|\\/]", "");
l = line.substring(line.indexOf(symbols[13]) + 1, line.indexOf(op));
r = line.substring(line.indexOf(op) + 1, line.lastIndexOf(symbols[14]));
for(int i = 0; i < vars.size(); i++)
{
if(vars.get(i).getName().equals(l))
l = vars.get(i).getValue().toString();
if(vars.get(i).getName().equals(r))
r = vars.get(i).getValue().toString();
}
}
if(op.equals(symbols[0]))
result = l.replaceAll(symbols[4], "") + r.replaceAll(symbols[4], "");
else if(op.equals(symbols[1]))
result = l.replaceAll(symbols[4], "").replace(r.replaceAll(symbols[4], ""), "");
else if(op.equals(symbols[2]))
{
l = l.replaceAll(symbols[4], "");
r = r.replaceAll(symbols[4], "");
p = Pattern.compile(r);
m = p.matcher(l);
if(m.find())
result = l.replaceAll(r, "");
}
else if(op.equals(symbols[3]))
{
l = l.replaceAll(symbols[4], "");
r = r.replaceAll(symbols[4], "");
p = Pattern.compile(r);
m = p.matcher(l);
if(m.find())
result = "true";
else
result = "false";
}
return result;
}
public int parseMaths(String line)
{
int result = 0;
String op = "";
String l = "";
String r = "";
if(isMaths(line))
{
op = line.replaceAll("[^\\+|\\-|\\*|\\/|\\%]", "");
l = line.substring(1, line.indexOf(op));
r = line.substring(line.indexOf(op) + 1, line.indexOf(symbols[16]));
for(int i = 0; i < vars.size(); i++)
{
if(vars.get(i).getName().equals(l))
l = vars.get(i).getValue().toString();
if(vars.get(i).getName().equals(r))
r = vars.get(i).getValue().toString();
}
}
if(isNum(l) && isNum(r))
{
if(op.equals(symbols[0]))
result = Integer.parseInt(l) + Integer.parseInt(r);
if(op.equals(symbols[1]))
result = Integer.parseInt(l) - Integer.parseInt(r);
if(op.equals(symbols[2]))
result = Integer.parseInt(l) * Integer.parseInt(r);
if(op.equals(symbols[3]))
result = Integer.parseInt(l) / Integer.parseInt(r);
if(op.equals(symbols[5]))
result = Integer.parseInt(l) % Integer.parseInt(r);
}
return result;
}
public Variable getByName(String name)
{
for(int i = 0; i < vars.size(); i++)
{
if(vars.get(i).getName().equals(name))
{
this.isVariable = true;
return vars.get(i);
}
else
{
this.isVariable = false;
return new Variable(1);
}
}
return new Variable(1);
}
public String getInput()
throws Exception
{
String input_str = "";
if(c == null)
{
log(">> ");
BufferedReader b = new BufferedReader(new InputStreamReader(System.in));
input_str = b.readLine();
}
else
{
c.txt.setText(">> ");
ByteArrayInputStream bin = new ByteArrayInputStream(c.txt.getText().getBytes());
System.setIn(bin);
}
return input_str;
}
public void parseOutput(String line)
throws Exception
{
if(line.startsWith(symbols[18]))
{
line = line.replace(symbols[18], "");
//if(containsVar(line))
// log(getByName(line).getValue());
for(int i = 0; i < vars.size(); i++)
{
if(vars.get(i).getName().equals(line))
log(vars.get(i).getValue());
else if(line.startsWith(vars.get(i).getName()) && line.contains(symbols[23]))
log(parseReasign(line));
}
if(isNum(line) && !isMaths(line))
log(Integer.parseInt(line));
else if(isString(line))
log(line.replaceAll(symbols[4], ""));
else if(isMaths(line))
log(parseMaths(line));
else if(isConcat(line))
log(parseConcat(line));
else if(line.equals(symbols[7]))
log(getMetaInt());
else if(line.equals(symbols[6]))
log(getMetaString());
else if(line.equals(symbols[19]))
log(getInput());
}
}
public void parseConsole(String line)
{
if(line.equals("==="))
{
c = new Console(this);
}
}
public void parseMetaString(String line)
throws Exception
{
if(isMeta(line))
{
line = line.replaceAll("[\\(,\\)]", "");
getByName(line);
if(isString(line))
this.meta_string = line.replaceAll(symbols[4], "");
else if(isConcat(line))
this.meta_string = parseConcat(line);
for(int i = 0; i < vars.size(); i++)
{
if(vars.get(i).getName().equals(line))
this.meta_string = vars.get(i).getValue().toString();
}
}
}
public boolean isMeta(String s)
{
if(s.startsWith(symbols[11]) && s.endsWith(symbols[12]) || s.startsWith(symbols[15]) && s.endsWith(symbols[16]) || s.equals(symbols[7]) || s.equals(symbols[6]))
return true;
else
return false;
}
public void parseMetaInt(String line)
throws Exception
{
if(isMeta(line))
{
line = line.replaceAll("[\\[,\\]]", "");
getByName(line);
if(isNum(line))
this.meta_int = Integer.parseInt(line);
else if(isMaths(line))
this.meta_int = parseMaths(line);
for(int i = 0; i < vars.size(); i++)
{
if(vars.get(i).getName().equals(line))
this.meta_int = Integer.parseInt(vars.get(i).getValue().toString());
}
}
}
public Object getArrayElement(Variable v, int index)
{
Object o = v.getArrayValue()[index];
for(int i = 0; i < vars.size(); i++)
{
if(vars.get(i).getName().equals(o.toString()))
o = vars.get(i).getValue();
}
return o;
}
public String getMetaString()
{
return this.meta_string;
}
public int getMetaInt()
{
return this.meta_int;
}
public void popVars()
{
for(int i = 0; i < vars.size(); i++)
varnames.add(vars.get(i).getName());
}
public boolean isNum(String s)
{
if(s.matches("^\\d+$"))
return true;
else
return false;
}
public boolean isString(String s)
{
if(s.startsWith(symbols[4]) && s.endsWith(symbols[4]))
return true;
else
return false;
}
public boolean isArray(String s)
{
if(s.startsWith(symbols[11]) && s.endsWith(symbols[12]))
return true;
else
return false;
}
public String parseReasign(String line)
{
String name = "";
String value = "";
String result = "";
for(int i = 0; i < vars.size(); i++)
{
if(line.startsWith(vars.get(i).getName()) && line.contains(symbols[23]))
{
name = vars.get(i).getName();
value = line.substring(line.indexOf(symbols[23]) + 1);
if(isNum(value))
{
vars.get(i).setType(1);
vars.get(i).setValue(Integer.parseInt(value));
result = vars.get(i).getValue().toString();
}
else if(isString(value))
{
vars.get(i).setType(0);
vars.get(i).setValue(value);
result = vars.get(i).getValue().toString();
}
else if(isMaths(value))
{
vars.get(i).setType(1);
vars.get(i).setValue(parseMaths(value));
result = vars.get(i).getValue().toString();
}
else if(isConcat(value))
{
vars.get(i).setType(0);
vars.get(i).setValue(parseConcat(value));
result = vars.get(i).getValue().toString();
}
for(int j = 0; j < vars.size(); j++)
{
if(vars.get(j).getName().equals(value))
{
vars.get(i).setType(vars.get(j).getType());
vars.get(i).setValue(vars.get(j).getValue());
result = vars.get(i).getValue().toString();
}
}
}
}
return result;
}
public void parseVars(String line)
throws Exception
{
Variable v = null;
String name = "";
String value = "";
if(line.startsWith(symbols[5]) && line.contains(symbols[23]))
{
name = line.substring(line.indexOf(symbols[5]) + 1, line.indexOf(symbols[23]));
value = line.substring(line.indexOf(symbols[23]) + 1);
if(name.equals("") || value.equals(""))
ge.throwGrits(ge.GE_BAD_SYNTAX, line);
if(isNum(value))
{
v = new Variable(1);
v.setName(name);
v.setValue(Integer.parseInt(value));
}
else if(isString(value))
{
v = new Variable(0);
v.setName(name);
v.setValue(value);
for(int i = 0; i < value.length(); i++)
{
Variable string_pos = new Variable(0);
string_pos.setName(name + symbols[21] + i);
string_pos.setValue(value.charAt(i));
vars.add(string_pos);
}
Variable string_length = new Variable(1);
string_length.setName(name + symbols[21] + symbols[2]);
string_length.setValue(value.length());
vars.add(string_length);
}
else if(isMaths(value))
{
v = new Variable(1);
v.setName(name);
v.setValue(parseMaths(value));
}
else if(value.equals(symbols[19]))
{
v = new Variable(0);
v.setName(name);
v.setValue(getInput());
}
else if(isConcat(value))
{
v = new Variable(0);
v.setName(name);
v.setValue(parseConcat(value));
}
else if(isArray(value))
{
v = new Variable(2);
v.setName(name);
value = value.replaceAll("[\\[\\]]", "");
v.setArrayValue(value.split(" "));
}
else if(value.startsWith(symbols[15]) && value.endsWith(symbols[16]))
{
int x = parseMaths(value.replaceAll("[\\(,\\)]", ""));
v = new Variable(1);
v.setName(name);
v.setValue(x);
}
else if(value.equals(symbols[7]))
{
v = new Variable(1);
v.setName(name);
v.setValue(this.meta_int);
}
else if(value.equals(symbols[6]))
{
v = new Variable(0);
v.setName(name);
v.setValue(this.meta_string);
}
for(int n = 0; n < vars.size(); n++)
{
if(vars.get(n).getName().equals(value))
{
v = new Variable(vars.get(n).getType());
v.setName(name);
v.setValue(vars.get(n).getValue());
}
}
if(v.getType() == 2)
{
Variable size = new Variable(1);
size.setName(name + symbols[21] + symbols[2]);
size.setValue(v.getArrayValue().length);
vars.add(size);
for(int i = 0; i < v.getArrayValue().length; i++)
{
if(isNum(v.getArrayValue()[i].toString()))
{
Variable v2 = new Variable(1);
v2.setName(name + symbols[21] + i);
v2.setValue(Integer.parseInt(v.getArrayValue()[i].toString()));
vars.add(v2);
}
else if(isString(v.getArrayValue()[i].toString()))
{
Variable v2 = new Variable(0);
v2.setName(name + symbols[21] + i);
v2.setValue(v.getArrayValue()[i].toString());
vars.add(v2);
}
for(int j = 0; j < vars.size(); j++)
{
if(vars.get(j).getName().equals(v.getArrayValue()[i].toString()))
{
Variable v2 = new Variable(0);
v2.setName(name + symbols[21] + i);
v2.setValue(vars.get(j).getValue());
vars.add(v2);
}
}
}
}
if(v != null)
vars.add(v);
else
ge.throwGrits(ge.GE_BAD_SYNTAX, line);
}
}
public void log(Object o)
{
if(c == null)
System.out.println(o);
else
{
sb.append(o.toString() + "\n");
c.pan.setText(sb.toString());
}
}
}