import java.util.*;

public class Matcher
{
    public Matcher (Rule[] rules, boolean debug)
    {
        _rules = rules;
        _debug = debug;
    }

    public Message[] matchRule (int ruleNumber, Message[] messages)
    {
        String str = "";

        System.out.println("Got "+expandRule(ruleNumber));

        return null;
    }

    public String expandRule (int ruleNumber)
    {
        Rule ruleToMatch = _rules[ruleNumber];
        Vector<String> results = new Vector<String>();
        String str = "";

        if (_debug)
            System.out.println("Looking at rule "+ruleToMatch);

        if (ruleToMatch.isCharacterRule())
            str = ""+ruleToMatch.getMatch();
        else
        {
            int[] leftRules = ruleToMatch.leftRules();

            str += " ( ";

            for (int i = 0; i < leftRules.length; i++)
            {
                str += expandRule(leftRules[i]);
            }

            int[] rightRules = ruleToMatch.rightRules();

            if (rightRules != null)
            {
                str += " | ";

                for (int j = 0; j < rightRules.length; j++)
                {
                    str += expandRule(rightRules[j]);
                }
            }

            str += " ) ";
        }

        return str;
    }

    private Rule[] _rules;
    private boolean _debug;
}
@@ -12,16 +12,69 @@
 .util.*;
+%0Aimport java.util.regex.*;%0Aimport java.util.stream.*;
 %0A%0Apublic
@@ -278,94 +278,8 @@
   %7B%0A
-        String str = %22%22;%0A%0A        System.out.println(%22Got %22+expandRule(ruleNumber));%0A%0A
     
@@ -405,63 +405,8 @@
 r%5D;%0A
-        Vector%3CString%3E results = new Vector%3CString%3E();%0A
     
@@ -1172,32 +1172,32 @@
 ) %22;%0A        %7D%0A%0A
-
         return s
@@ -1203,24 +1203,832 @@
 str;%0A    %7D%0A%0A
+    private final String getRuleRegex (int ruleNumber)%0A    %7B%0A        Rule theRule = _rules%5BruleNumber%5D;%0A%0A        if (theRule.isCharacterRule())%0A            return %22%22+theRule.getMatch();%0A        else%0A        %7B%0A            if (!theRule.hasOrRule())%0A                return String.format(%22(?:%25s)%22, ruleListToRegex(theRule.leftRules()));%0A            else%0A                return String.format(%22(?:%25s%7C%25s)%22, ruleListToRegex(theRule.leftRules()), ruleListToRegex(theRule.rightRules()));%0A        %7D%0A    %7D%0A%0A    private final String ruleListToRegex (int%5B%5D rules)%0A    %7B%0A        Vector%3CInteger%3E v = new Vector%3CInteger%3E();  // convert to stream for this bit%0A%0A        for (int i = 0; i %3C rules.length; i++)%0A            v.add(rules%5Bi%5D);%0A%0A        return v.stream().map(this::getRuleRegex).collect(Collectors.joining());%0A    %7D%0A%0A
     private 

Update Matcher.java