Skip to content
Snippets Groups Projects
Unverified Commit 7692931d authored by p9malino26's avatar p9malino26 Committed by GitHub
Browse files

Added the main files

parent 12c622ff
No related branches found
No related tags found
No related merge requests found
clear x ;
incr x;
incr x;
incr x;
#comment
while x not 0 do;
decr x;
end;
public class ClearParser extends Unary {
public ClearParser() {
super("clear");
}
@Override
public void _execute() throws OperationError {
getInterpreter().executeClear(getVariable(0));
}
@Override
public String getChangeMessage() {
return "Cleared " + getVariableString(getVariable());
}
}
public class Comment extends StatementParser {
public Comment() {
super("#");
}
@Override
protected RegexChecker[] initializeStages() {
return new RegexChecker[] {
new RegexChecker(".*(\\n)?")
};
}
@Override
protected String getStageErrorMessage(int stagePosition) {
return null;
}
@Override
public void _execute() throws OperationError {
}
@Override
public String getChangeMessage() {
return "Executed comment.";
}
//does nothing
@Override
public void printChange() {
}
}
public class DecrParser extends Unary {
public DecrParser() {
super("decr");
}
@Override
public void _execute() throws OperationError {
setNewValue(getInterpreter().executeDecr(getVariable()));
}
@Override
public String getChangeMessage() {
return "Decremented " + getVariableString(getVariable()) + "to " + getNewValue();
}
}
public class EndParser extends StatementParser {
public EndParser() {
super("end");
}
@Override
protected RegexChecker[] initializeStages() {
return new RegexChecker[] {
fundamentalChecker(FundamentalChecker.END_OF_STATEMENT)
};
}
@Override
protected String getStageErrorMessage(int stagePosition) {
return "Missing semicolon";
}
@Override
public void _execute() throws OperationError {
getInterpreter().executeEnd();
}
@Override
public String getChangeMessage() {
return "Going back to my while loop";
}
}
import java.util.HashMap;
public class Environment {
HashMap<String, Integer> varInfo;
public Environment () {
varInfo = new HashMap<>();
}
public void clear (String var) {
varInfo.put(var, 0);
}
public int incr (String var) throws OperationError{
assertContainsKey(var, "increment");
int oldValue = varInfo.get(var);
varInfo.put(var, oldValue + 1);
return varInfo.get(var);
}
public int decr (String var) throws OperationError {
assertContainsKey(var, "decrement");
int oldValue = varInfo.get(var);
if (oldValue == 0) {
throw new OperationError("[ERROR] Attempt to decrement variable " + var + "which is equal to zero.");
}
varInfo.put(var, oldValue - 1);
return varInfo.get(var);
}
public boolean equalsZero (String var) throws OperationError{
assertContainsKey(var, "check equaling of zero for");
return varInfo.get(var) == 0;
}
private void assertContainsKey(String key, String operation) throws OperationError {
if (!varInfo.containsKey(key)) {
throw new OperationError(String.format("[ERROR] Attempt to increment %s which does not exist.", key));
}
}
//public void printVars
}
public class IncrParser extends Unary {
public IncrParser() {
super("incr");
}
@Override
public void _execute() throws OperationError {
setNewValue(getInterpreter().executeIncr(getVariable(0)));
}
@Override
public String getChangeMessage() {
return getVariableString(getVariable()) + "incremented to " + getNewValue();
}
}
//package com.patryk.spacecadets.barebones;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.EmptyStackException;
import java.util.Stack;
public class Interpreter {
private String code;
private int index;
private StatementParser[] possibleStatements;
private RegexChecker anyBreakChecker;
private Environment environment;
private Stack<Integer> loopStack;
//maps the beginning of a while to its corresponding done statement
enum StatementParserName {CLEAR_PARSER, INCR_PARSER, DECR_PARSER, WHILE_PARSER, END_PARSER};
public Interpreter(String code) throws FileNotFoundException, IOException {
this.code = code;
StatementParser.setInterpreter(this);
environment = new Environment();
loopStack = new Stack<Integer>();
anyBreakChecker = new RegexChecker(StatementParser.OPTIONAL_ANY_BREAK_STR, code);
possibleStatements = new StatementParser[] {new ClearParser(), new IncrParser(), new DecrParser(), new WhileParser(), new EndParser(), new Comment()};
}
private StatementParser getStatementParser(StatementParserName name) {
int id = name.ordinal();
return possibleStatements[id];
}
public String getCode() {
return code;
}
private int getIndex() {
return index;
}
public String getLineAndCol() {
return getLineAndCol(this.index);
}
public String getLineAndCol(int index) {
return Util.getLineAndCol(getCode(), index).toString();
}
public Environment getEnvironment() {
return environment;
}
private void skipWhitespace() {
anyBreakChecker.matches(index);
index = anyBreakChecker.end();
}
//the command respond methods. Will be called by a StatementParser
public void executeClear(String var) {
environment.clear(var);
}
public int executeIncr(String var) {
return environment.incr(var);
}
public int executeDecr(String var) {
return environment.decr(var);
}
public boolean executeWhile(String var) throws OperationError{
//TODO come back here!
if (environment.equalsZero(var)) { // i.e. skip to the end
index = getEndOfThisWhileLoop();
return true;
} else { // go into this loop and push the start of the loop on the stack
loopStack.push(getStatementParser(StatementParserName.WHILE_PARSER).start());
return false;
}
}
public void executeEnd() throws OperationError{
try {
index = loopStack.pop();
} catch (EmptyStackException e) {
throw new OperationError("Have no while loop to go to!");
}
}
private int getEndOfThisWhileLoop() throws OperationError{
/* Summary:
* Get index of closest end. Then, get index of next while loop. If there isn't a while loop, that's it! If there is, go to the end of that while loop and repeat the same process.
*/
//t=TODO
int whileStart = getStatementParser(StatementParserName.WHILE_PARSER).start();
boolean anotherEndExists = getStatementParser(StatementParserName.END_PARSER).fullyMatchesAfter(index);
//if not, complain!
if (!anotherEndExists) {
throw new OperationError("No end exists after this while loop!");
}
//otherwise
int endEnd = getStatementParser(StatementParserName.END_PARSER).end();
//currently, the while parser has executed you while statement
int whileEnd = getStatementParser(StatementParserName.WHILE_PARSER).end();
int steps = 0;
do {
if(getStatementParser(StatementParserName.WHILE_PARSER).fullyMatchesAfter(whileEnd)) { // if there is another while loop
whileEnd = getStatementParser(StatementParserName.WHILE_PARSER).end();
if (whileEnd > endEnd) {
break;
} else {
steps++;
}
} else {
break;
}
} while(true);
for (int i = 0; i < steps; i++) {
boolean success = getStatementParser(StatementParserName.END_PARSER).fullyMatchesAfter();
if(!success) {
throw new OperationError(WhileParser.getNoEndMessage());
}
}
getStatementParser(StatementParserName.WHILE_PARSER).fullyMatchesAfter(whileStart);
return getStatementParser(StatementParserName.END_PARSER).end();
}
//needs to be un-fd-up
public void run() throws SyntaxError, OperationError{
while (index != code.length()) {
boolean matchFound = false;
for (StatementParser parser : possibleStatements) {
if (parser.initiallyMatches(index)) {
parser.checkSyntaxFully();
index = parser.end();
parser.execute();
parser.printChange();
skipWhitespace();
matchFound = true;
break;
}
}
if (!matchFound) {
throw new SyntaxError(getLineAndCol() + ": Unrecognized command.");
}
}
}
/*public RegexChecker CreateFromCommand(String command) {
String[] words = command.split(" ");
String regex = OPTIONAL_ANY_BREAK;
for(int i = 0; i < words.length; i++) {
regex += words[i];
if (i < words.length - 1) {
regex += BREAK;
} else {
regex += END_OF_STATEMENT;
}
}
return new RegexChecker(regex, code);
}*/
}
/*class WhileChecker {
RegexChecker syntax;
RegexChecker variableName;
RegexChecker semiColon;
public WhileChecker(String code) {
syntax = RegexChecker("while ")
}
}*/
//unused
/*
public int getEndOfNextEnd (Matcher whileMatcher, Matcher endMatcher) {
//if there are no more whiles
endMatcher.find(index);
int startOfNextEnd = endMatcher.start();
//int nextWhile = 0;
int steps = 0;
do {
//we see if there are any more while loops before the next end
if (!whileMatcher.find()) {
break;
}
if (whileMatcher.start() > startOfNextEnd) {
break;
}
//so there is a while before the end
steps ++;
}while(true);
for(int i = 0; i < steps; i++) {
endMatcher.find();
}
return endMatcher.end();
}
*/
public class LineAndCol {
public int lineNumber, columnNumber;
public LineAndCol (int lineNumber, int columnNumber) {
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
}
public String toString() {
return String.format("Line %d, col %d", lineNumber, columnNumber);
}
}
\ No newline at end of file
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Main {
private static final String DEFAULT_FILENAME = "sample.bb";
//handles syntax errors locally, but still may throw file not found errors.
private Main(String fileName) throws FileNotFoundException, IOException{
String code = getStringFromFile(new FileReader(fileName));
try {
Interpreter interpreter = new Interpreter(code);
interpreter.run();
//then print the values of the variables optionally
} catch (RuntimeException e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
private String getStringFromFile (FileReader reader) throws IOException {
String code = "";
int charCode;
while ((charCode = reader.read()) != -1) {
code += (char) charCode;
}
return code;
}
public static void main(String[] args) {
int filenamePos = 1;
String fileName;
//if no filename was specified, set the file name to default
if (args.length <= filenamePos ){
fileName = DEFAULT_FILENAME;
} else {
fileName = args[filenamePos];
}
try {
Main main = new Main(fileName);
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
}
import java.lang.RuntimeException;
public class OperationError extends RuntimeException {
public OperationError(String message) {
super(message);
}
}
\ No newline at end of file
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class RegexChecker {
private Pattern pattern;
private Matcher matcher;
public RegexChecker(String patternRegex) {
pattern = Pattern.compile(patternRegex);
}
public RegexChecker(String patternRegex, String code) {
pattern = Pattern.compile(patternRegex);
setCode(code);
}
public void setCode(String code) {
matcher = pattern.matcher(code);
}
public boolean matches(int index) {
if (matcher.find(index)) {
int regexStart = matcher.start();
if(!(regexStart == index)) {
return false;
}
return true;
}
return false;
}
public boolean matchesAfter() {
return matcher.find();
}
public boolean matchesAfter(int index) {
return matcher.find(index);
}
public String group(int groupID) {
return matcher.group(groupID);
}
public int start() {
return matcher.start();
}
public int end() {
return matcher.end();
}
}
\ No newline at end of file
public enum SampleStrings {
VARIABLE_NAME_STR ( "([A-Za-z]*)"),
OPTIONAL_ANY_BREAK_STR ( "[\\n\\s]*" ),
BREAK_STR ( "\\s+" ),
OPTIONAL_BREAK_STR ( "\\s*" ),
SEMI_COLON_STR ( ";" );
private String value;
SampleStrings(String value) {
this.value = value;
}
}
import java.util.HashSet;
//not thread safe! Only one instance per program!
public abstract class StatementParser {
private String commandName;
private RegexChecker initialRegexChecker;
private RegexChecker[] checkingStages; // to be initialized in sub class
private static Interpreter interpreter;
//private int startIndex;
private int tempIndex;
protected static final String VARIABLE_NAME_STR = "([A-Za-z]*)";
public static final String OPTIONAL_ANY_BREAK_STR = "[\\n\\s]*";
protected static final String BREAK_STR = "\\s+";
protected static final String OPTIONAL_BREAK_STR = "\\s*";
protected static final String SEMI_COLON_STR = ";";
protected static final int VAR_NAME_GROUP = 0;
private static HashSet<String> reservedWords = new HashSet<>();
enum FundamentalChecker {VARIABLE_NAME, OPTIONAL_ANY_BREAK, BREAK, OPTIONAL_BREAK, SEMI_COLON, END_OF_STATEMENT};
protected static RegexChecker[] fundamentalCheckers = { new RegexChecker(VARIABLE_NAME_STR),
new RegexChecker(OPTIONAL_ANY_BREAK_STR),
new RegexChecker(BREAK_STR),
new RegexChecker(OPTIONAL_BREAK_STR),
new RegexChecker(SEMI_COLON_STR),
new RegexChecker(OPTIONAL_BREAK_STR + SEMI_COLON_STR)};
protected static RegexChecker fundamentalChecker(FundamentalChecker checkerType) {
return fundamentalCheckers[checkerType.ordinal()];
}
//call this first ASAP!
public static void setInterpreter(Interpreter _interpreter) {
//the fundamental checkers will be set the code of the parser.
//Then when the constructor is called, the initial string will be instantiated with that
//code.
interpreter = _interpreter;
for (RegexChecker fundamentalChecker : fundamentalCheckers) {
fundamentalChecker.setCode(interpreter.getCode());
}
}
protected static boolean isValidVariableName(String name) {
return !reservedWords.contains(name);
}
public StatementParser(String commandName) {
this.commandName = commandName;
this.initialRegexChecker = new RegexChecker(commandName, interpreter.getCode());
checkingStages = initializeStages();
for (RegexChecker stage: checkingStages) {
stage.setCode(interpreter.getCode());
}
reservedWords.add(commandName);
}
protected abstract RegexChecker[] initializeStages();
public static Interpreter getInterpreter() {
return interpreter;
}
public boolean initiallyMatches(int index ) {
//first set the fundamental checkers to this
boolean success = initialRegexChecker.matches(index);
return processInitialMatch(success);
}
public boolean initiallyMatchesAfter(int index) {
boolean success = initialRegexChecker.matchesAfter(index);
return processInitialMatch(success);
}
private boolean processInitialMatch(boolean success) {
if(success) {
setIndex(initialRegexChecker.end());
//startIndex = initialRegexChecker.start();
}
return success;
}
public boolean fullyMatchesAfter(int index) throws SyntaxError{
if (initiallyMatchesAfter(index)) {
checkSyntaxFully();
return true;
}
return false;
}
public boolean fullyMatchesAfter() {
return fullyMatchesAfter(end());
}
public String getCommandName() {
return commandName;
}
private int getIndex() {
return tempIndex;
}
private void setIndex(int newIndex) {
tempIndex = newIndex;
}
public int start() {
return initialRegexChecker.start();
}
public int end() {
return tempIndex;
}
protected String getVariable(int varID) { return null;}
//maps stage id (in for loop) to variable id
protected int getVarIDFromStageID(int varID) { return -1;}
protected static String getVariableNameErrorMessage(String varName) {
return "Invalid variable name: " + varName;
}
protected static String getVariableNameErrorMessage() {
return "Invalid variable name.";
}
protected void assertVariableName(String name) throws SyntaxError{
if (!isValidVariableName(name)) {
throwSyntaxError(getVariableNameErrorMessage(name));
}
}
private String getOperationContext(int index) {
return commandName + ": " + interpreter.getLineAndCol(index);
}
private String getOperationContext() {
return getOperationContext(getIndex());
}
//YOU MUST call setParser before constructing!
protected abstract String getStageErrorMessage(int stagePosition);
public void checkSyntaxFully() throws SyntaxError {
for (int i = 0; i < checkingStages.length; i++) {
if (!checkingStages[i].matches(getIndex())) {
throwSyntaxError(getStageErrorMessage(i));
}
//do something after the stage has been passed, such as setting up the variable
afterStagePass(i);
int varID = getVarIDFromStageID(i);
//if we are at a variable, we must check it
if (varID != -1) {
String var = getVariable(varID);
assertVariableName(var);
}
setIndex(checkingStages[i].end());
}
}
//for there to be overridden
protected void afterStagePass(int stageID) {}
public void execute() throws OperationError {
try {
_execute();
} catch (OperationError e) {
throwOperationError(e.getMessage());
}
}
protected abstract void _execute() throws OperationError;
public abstract String getChangeMessage();
public void printChange() {
System.out.println(formatMessage("INFO", start(),getChangeMessage()));
}
protected static String getVariableString(String var) {
return "variable \'" + var + "\' ";
}
private String formatMessage(String messageIdentifier, int index, String mainMessage) {
return String.format("[%s] %s: %s", messageIdentifier, getOperationContext(index), mainMessage);
}
public void throwSyntaxError(String message) throws SyntaxError {
throw new SyntaxError(formatMessage("SYNTAX ERROR", getIndex(), message));
}
public void throwOperationError(String message) throws OperationError {
throw new OperationError(formatMessage("OPERATION ERROR", start(), message));
}
}
public class SyntaxError extends RuntimeException {
public SyntaxError(String message) {
super(message);
}
}
\ No newline at end of file
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class Test {
public static void main(String[] args) {
String command = "while; incr; decr";
Pattern commandPattern = Pattern.compile("([while,incr,decr])");
Matcher matcher = commandPattern.matcher(command);
if (matcher.find()) {
System.out.println(String.format("Group: %s", matcher.group(1)));
}
}
}
public abstract class Unary extends StatementParser{
private String var;
private int newValue;
enum Stage {BREAK, VARNAME, END};
public Unary(String commandName) {
super(commandName);
}
protected int getNewValue() {
return newValue;
}
protected void setNewValue(int x) {
newValue = x;
}
protected String getVariable() {
return var;
}
@Override
protected RegexChecker[] initializeStages() {
return new RegexChecker[] {
fundamentalChecker(FundamentalChecker.BREAK),
fundamentalChecker(FundamentalChecker.VARIABLE_NAME),
fundamentalChecker(FundamentalChecker.END_OF_STATEMENT)
};
}
@Override
protected String getVariable(int varID) {
return var;
}
@Override
protected int getVarIDFromStageID(int stageID) {
if (stageID == Stage.VARNAME.ordinal()) {
return 0;
}
return -1;
}
@Override
protected void afterStagePass(int stageID) {
if (stageID == Stage.VARNAME.ordinal()) {
var = fundamentalChecker(FundamentalChecker.VARIABLE_NAME).group(VAR_NAME_GROUP);
}
}
@Override
protected String getStageErrorMessage(int stagePosition) {
Stage stage = Stage.values()[stagePosition];
switch (stage) {
case BREAK:
return "Expected break after \'" + getCommandName() + "\'";
case VARNAME:
return getVariableNameErrorMessage();
case END:
return "Missing semicolon after variable name";
default:
return "Unknown error";
}
}
}
public class Util {
static LineAndCol getLineAndCol(String text, int index) {
int lineNumber = 1;
int lastNewLineIndex = 0;
for (int i = 0; i < index; i++) {
if (text.charAt(i) == '\n') {
lastNewLineIndex = i;
lineNumber ++;
}
}
int colNumber = index - lastNewLineIndex;
if (colNumber == 0) {
colNumber = 1;
}
return new LineAndCol(lineNumber, colNumber);
}
}
\ No newline at end of file
public class WhileParser extends StatementParser {
enum Stage {BREAK_1, VAR, BREAK_2, NOT_0_DO, END};
public WhileParser() {
super("while");
}
private String variable;
private boolean skipped;
@Override
protected String getVariable(int varID) {
return variable;
}
@Override
protected int getVarIDFromStageID(int stageID) {
if (stageID == Stage.VAR.ordinal()) {
return 0;
}
return -1;
}
@Override
protected RegexChecker[] initializeStages() {
return new RegexChecker[] {
fundamentalChecker(FundamentalChecker.BREAK),
fundamentalChecker(FundamentalChecker.VARIABLE_NAME),
fundamentalChecker(FundamentalChecker.BREAK),
new RegexChecker("not" + BREAK_STR + "0" + BREAK_STR + "do"),
fundamentalChecker(FundamentalChecker.END_OF_STATEMENT)
};
}
@Override
protected String getStageErrorMessage(int stagePosition) {
Stage stage = Stage.values()[stagePosition];
switch (stage) {
case BREAK_1:
return "Expected break after \'while\'";
case VAR:
return getVariableNameErrorMessage();
case BREAK_2:
return "Expected break after variable name.";
case NOT_0_DO:
return "Expected \'not 0 do;\' after variable name";
case END:
return "No semicolon after valid variable name.";
default:
return "Unknown error.";
}
}
@Override
protected void afterStagePass(int stageID){
if(Stage.values()[stageID] == Stage.VAR) {
variable = fundamentalChecker(FundamentalChecker.VARIABLE_NAME).group(VAR_NAME_GROUP);
}
}
/*public int getStartOfStatement() {
return
}*/
@Override
public void _execute() throws OperationError {
skipped = getInterpreter().executeWhile(variable);
}
@Override
public String getChangeMessage() {
if (skipped) {
return getVariableString(variable) + " is 0. Skipped loop.";
} else {
return getVariableString(variable) + " not 0. Went into loop.";
}
}
public static String getNoEndMessage() {
return "No end exists after this while loop!";
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment