Skip to content
Snippets Groups Projects
Select Git revision
  • eafe2d48a0d4b0c50945bbcfa5a43753a9048fa5
  • feat/feature_engineering default protected
2 results

preprocess.py

Blame
  • StatementParser.java 6.70 KiB
    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));
        }
    }