Skip to content

Instantly share code, notes, and snippets.

@gmenard
Last active February 21, 2023 10:50
Show Gist options
  • Save gmenard/6161825 to your computer and use it in GitHub Desktop.
Save gmenard/6161825 to your computer and use it in GitHub Desktop.
Convert regular expression from infix to postfix notation using Shunting-yard algorithm. Insert a '.' as explicit concatenation operator.
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
public class RegExConverter {
/** Operators precedence map. */
private static final Map<Character, Integer> precedenceMap;
static {
Map<Character, Integer> map = new HashMap<Character, Integer>();
map.put('(', 1);
map.put('|', 2);
map.put('.', 3); // explicit concatenation operator
map.put('?', 4);
map.put('*', 4);
map.put('+', 4);
map.put('^', 5);
precedenceMap = Collections.unmodifiableMap(map);
};
/**
* Get character precedence.
*
* @param c character
* @return corresponding precedence
*/
private static Integer getPrecedence(Character c) {
Integer precedence = precedenceMap.get(c);
return precedence == null ? 6 : precedence;
}
/**
* Transform regular expression by inserting a '.' as explicit concatenation
* operator.
*/
private static String formatRegEx(String regex) {
String res = new String();
List<Character> allOperators = Arrays.asList('|', '?', '+', '*', '^');
List<Character> binaryOperators = Arrays.asList('^', '|');
for (int i = 0; i < regex.length(); i++) {
Character c1 = regex.charAt(i);
if (i + 1 < regex.length()) {
Character c2 = regex.charAt(i + 1);
res += c1;
if (!c1.equals('(') && !c2.equals(')') && !allOperators.contains(c2) && !binaryOperators.contains(c1)) {
res += '.';
}
}
}
res += regex.charAt(regex.length() - 1);
return res;
}
/**
* Convert regular expression from infix to postfix notation using
* Shunting-yard algorithm.
*
* @param regex infix notation
* @return postfix notation
*/
public static String infixToPostfix(String regex) {
String postfix = new String();
Stack<Character> stack = new Stack<Character>();
String formattedRegEx = formatRegEx(regex);
for (Character c : formattedRegEx.toCharArray()) {
switch (c) {
case '(':
stack.push(c);
break;
case ')':
while (!stack.peek().equals('(')) {
postfix += stack.pop();
}
stack.pop();
break;
default:
while (stack.size() > 0) {
Character peekedChar = stack.peek();
Integer peekedCharPrecedence = getPrecedence(peekedChar);
Integer currentCharPrecedence = getPrecedence(c);
if (peekedCharPrecedence >= currentCharPrecedence) {
postfix += stack.pop();
} else {
break;
}
}
stack.push(c);
break;
}
}
while (stack.size() > 0)
postfix += stack.pop();
return postfix;
}
}
@DCplayer
Copy link

Thanks for the help buddy, I'm starting to do my Compiler project and this help me out a lot reducing my time :D

@arr15334
Copy link

DCplayer sukz, but thx for the program fam, really helped me

@arliemoore
Copy link

Hey nice code, helped me a lot. I converted this to python and it is on my github

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment