Tried to convert JavaScript code of this RegexEngine to Java
import java.util.Scanner;
import java.util.*;
public class RegexEngine {
public static String insertExplicitConcatOperator(String exp) {
String output = "";
for (int i = 0; i < exp.length()-1; i++) {
char token = exp.charAt(i);
output += token;
if (token == '(' || token == '|') {
continue;
}
if (i < exp.length() - 1) {
char lookahead = exp.charAt(i + 1);
if (lookahead == '*' || lookahead == '?' || lookahead == '+' || lookahead == '|' || lookahead == ')') {
continue;
}
output += '.';
}
}
return output;
};
//public static String peek(Stack stack) {
// if (stack.size()>0) {
// return stack.get(stack.size() - 1); }
//}
public static int operatorPrecedence(char token2) {
// '|': 0,
// '.': 1,
// '?': 2,
// '*': 2,
// '+': 2
if (token2 == '|'){
return 0;
}
else if(token2 == '.'){
return 1;
}
else if(token2 == '?'){
return 2;
}
else if(token2 == '*'){
return 2;
}
else if(token2 == '+'){
return 2;
}
return 0;
};
// public int operatorPrecedence() {
// switch (char token) {
// case '|': return 0;
// case '.': return 1;
// case '?': return 2;
// case '*': return 2;
// case '+': return 2;
// }
// return 0;
// }
public static String toPostfix(String exp) {
String output = "";
//ArrayList<String> operatorStack = new ArrayList<String>();
Stack<Character> operatorStack = new Stack<Character>();
for(int i = 0; i <=exp.length()-1; i++) {
// char token;
char token = exp.charAt(i);
if (token == '.' || token == '|' || token == '*' || token == '?' || token == '+') {
while (operatorStack.size()>0 && (operatorStack.peek() != '(') && operatorPrecedence(operatorStack.peek()) >= operatorPrecedence(token)) {
output += operatorStack.pop();
}
operatorStack.push(token);
} else if (i == '(' || i == ')') {
if (i == '(') {
operatorStack.push(token);
} else {
while (operatorStack.peek() != '(') {
output += operatorStack.pop();
}
operatorStack.pop();
}
} else {
output += token;
}
}
while (operatorStack.size()>0) {
output += operatorStack.pop();
}
return output;
};
public class State{
boolean isEnd;
HashMap<Character, State> transition = new HashMap<Character, State>();
ArrayList<State> epsilonTransitions = new ArrayList<State>();
}
public void addEpsilonTransition(State from, State to) {
from.epsilonTransitions.add(to);
}
public void addTransition(State from, State to, char symbol) {
from.transition.put(symbol,to);
}
public ArrayList<State> fromEpsilon() {
ArrayList<State> EpsilonStates = new ArrayList<State>();
State start = new State();
start.isEnd = false;
State end = new State();
end.isEnd = true;
addEpsilonTransition(start, end);
EpsilonStates.add(start);
EpsilonStates.add(end);
return (EpsilonStates);
}
public ArrayList<State> fromSymbol(char symbol) {
ArrayList<State> SymbolStates = new ArrayList<State>();
State start = new State();
start.isEnd = false;
State end = new State();
end.isEnd = true;
addTransition(start, end, symbol);
//SymbolStates.get(0)
SymbolStates.add(start);
//SymbolStates.get(1)
SymbolStates.add(end);
return (SymbolStates);
}
public ArrayList<State> concat(ArrayList<State> first, ArrayList<State> second) {
ArrayList<State> returnStates = new ArrayList<State>();
addEpsilonTransition(first.get(1), second.get(0));
first.get(0).isEnd = false;
returnStates.add(first.get(0));
returnStates.add(second.get(1));
return (returnStates);
}
public ArrayList<State> union(ArrayList<State> first, ArrayList<State> second) {
ArrayList<State> returnStates = new ArrayList<State>();
State start = new State();
start.isEnd = false;
addEpsilonTransition(start, first.get(0));
addEpsilonTransition(start, second.get(0));
State end = new State();
end.isEnd = true;
addEpsilonTransition(first.get(1), end);
first.get(1).isEnd = false;
addEpsilonTransition(second.get(1), end);
second.get(1).isEnd = false;
returnStates.add(start);
returnStates.add(end);
return (returnStates);
}
public ArrayList<State> closure(ArrayList<State> nfa) {
ArrayList<State> returnStates = new ArrayList<State>();
State start = new State();
start.isEnd = false;
State end = new State();
end.isEnd = true;
addEpsilonTransition(start, end);
addEpsilonTransition(start, nfa.get(0));
addEpsilonTransition(nfa.get(1), end);
addEpsilonTransition(nfa.get(1), nfa.get(0));
nfa.get(1).isEnd = false;
returnStates.add(start);
returnStates.add(end);
return (returnStates);
}
public ArrayList<State> toNFA(String postfixExp) {
ArrayList<State> finalSetofStates = new ArrayList<State>();
if(postfixExp.isEmpty()) {
return fromEpsilon();
}
Stack<ArrayList<State>> stack = new Stack<ArrayList<State>>();
for (int i = 0; i <=postfixExp.length() - 1; i++) {
char token = postfixExp.charAt(i);
if(token == '*') {
stack.push(closure(stack.pop()));
} else if (token == '|') {
ArrayList<State> right = stack.pop();
ArrayList<State> left = stack.pop();
stack.push(union(left, right));
} else if (token == '.') {
ArrayList<State> right = stack.pop();
ArrayList<State> left = stack.pop();
stack.push(concat(left, right));
} else {
stack.push(fromSymbol(token));
}
}
finalSetofStates = stack.pop();
return (finalSetofStates);
}
public void addNextState(State state, ArrayList<State> nextStates, ArrayList<State> visited) {
if (state.epsilonTransitions.size()>0) {
for (int i = 0; i <= state.epsilonTransitions.size() - 1; i++) {
if (!visited.contains(state.epsilonTransitions.get(i))) {
visited.add(state.epsilonTransitions.get(i));
addNextState(state.epsilonTransitions.get(i), nextStates, visited);
}
}
} else {
nextStates.add(state);
}
}
public boolean search(ArrayList<State> nfa, String word) {
ArrayList<State> currentStates = new ArrayList<State>();
ArrayList<State> visited = new ArrayList<State>();
/* The initial set of current states is either the start state or
the set of states reachable by epsilon transitions from the start state */
addNextState(nfa.get(0), currentStates, visited);
for (int i = 0; i <=word.length() - 1; i++) {
char token = word.charAt(i);
ArrayList<State> nextStates = new ArrayList<State>();
for (int j = 0; j <= currentStates.size() - 1; j++) {
State nextState = new State();
nextState = (currentStates.get(j)).transition.get(token);
addNextState(nextState, nextStates, visited);
}
currentStates = nextStates;
}
boolean b = false;
for(int k = 0; k <= currentStates.size() - 1; k++){
if((currentStates.get(k)).isEnd = true){
b = true;
return true;
}
if (b == false){
return false;
}
}
return false;
}
public static void main(String[] args) {
//inputs and validation
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
char[] len= input.toCharArray();
int InputLengthCounter=0;
for(char ch : len)
{
InputLengthCounter++;
}
System.out.println("Length of a string is :"+InputLengthCounter);
for (int i = 0; i < InputLengthCounter; i++){
if((len[i] >= 'a' && len[i] <= 'z') || (len[i] >= '0' && len[i] <= '9') || len[i]=='|' || len[i]=='+' || len[i]=='*' || len[i]=='.' || len[i]=='?' || len[i]=='(' || len[i]==')'){
}
else{
System.out.println("Invalid Input!");
System.exit(1);
}
}
//Parse an basic regular expression from standard input
//Generate a ε-NFA to evaluate the regular expression
//code for REGEX to NFA
//READY MESSAGE
//Evaluate the subsequent inputs against the regular expression.
//CODE TO ACCEPTS INPUT AND VALIDATE
//CODE TO SEND INPUT IN NFA AND VALIDATE
//PRINT TRUE OR FALSE
String insertExplicitConcatOperatorInput = insertExplicitConcatOperator(input);
String postfixInput = toPostfix(insertExplicitConcatOperatorInput);
ArrayList<State> nfa = new ArrayList<State>();
nfa = toNFA(postfixInput);
System.out.println("ready");
while(true){
Scanner matcher = new Scanner(System.in);
String word = matcher.nextLine();
if(search(nfa, word)){
System.out.println("true");
}else {
System.out.println("false");
}
}
}
}
I am not experienced with Java or JavaScript at all but how can I fix this error?
RegexEngine.java:362: error: non-static method toNFA(String) cannot be referenced from a static context
nfa = toNFA(postfixInput);
RegexEngine.java:370: error: non-static method search(ArrayList<RegexEngine.State>,String) cannot be referenced from a static context
if(search(nfa, word)){