// Path: src/main/java/uk/ac/susx/tag/gramexp/matchers/RegularExpressionMatcher.java
// public class RegularExpressionMatcher extends CustomMatcher {
// 
//     private final Pattern pattern;
// 
//     public RegularExpressionMatcher(String re) {
//         super("Regexp");
//         pattern = Pattern.compile(re);
//     }
// 
//     @Override
//     public boolean isSingleCharMatcher() {
//         return false;
//     }
// 
//     @Override
//     public boolean canMatchEmpty() {
//         return pattern.matcher("").find();
//     }
// 
//     @Override
//     public boolean isStarterChar(char c) {
//         Matcher m = pattern.matcher(c+"");
//         return m.find() && m.start()==0;
//     }
// 
//     @Override
//     public char getStarterChar() {
//         return 0;
//     }
// 
//     @Override
//     public <V> boolean match(MatcherContext<V> context) {
// 
//         int cur = context.getCurrentIndex();
// 
//         InputBuffer buffer = context.getInputBuffer();
//         String content = InputBufferUtils.collectContent(buffer);
//         content = content.substring(cur);
//         Matcher m = pattern.matcher(content);
// 
//         if(m.find()) {
// 
//             int start = m.start();
//             if(start == 0) {
//                 int end = m.end();
// 
//                 int delta = end - start;
// 
//                 context.advanceIndex(delta);
// 
//                 context.createNode();
//                 return true;
// 
//             } else {
//                 return false;
//             }
//         } else {
// 
//             return false;
//         }
// 
//     }
// }
// 
// Path: src/main/java/uk/ac/susx/tag/gramexp/matchers/StartOfLineMatcher.java
// public class StartOfLineMatcher extends CustomMatcher{
// 
//     public StartOfLineMatcher() {
//         super("StartOfLine");
//     }
// 
//     @Override
//     public boolean isSingleCharMatcher() {
//         return true;
//     }
// 
//     @Override
//     public boolean canMatchEmpty() {
//         return true;
//     }
// 
//     @Override
//     public boolean isStarterChar(char c) {
//         return c == '\n';
//     }
// 
//     @Override
//     public char getStarterChar() {
//         return '\n';
//     }
// 
//     @Override
//     public <V> boolean match(MatcherContext<V> context) {
//         int cur = context.getCurrentIndex();
//         if(cur == 0) {
//             context.createNode();
//             return true;
//         }
//         InputBuffer buffer = context.getInputBuffer();
// 
//         if(buffer.charAt(cur-1)=='\n') {
//             context.createNode();
//             return true;
//         }
// 
//         return false;
//     }
// }


import org.parboiled.BaseParser;
import org.parboiled.Rule;
import org.parboiled.annotations.SuppressSubnodes;
import uk.ac.susx.tag.gramexp.matchers.RegularExpressionMatcher;
import uk.ac.susx.tag.gramexp.matchers.StartOfLineMatcher;
import java.util.*;
                Object val = pop();
                if(val instanceof Capture) {
                    captures.add((Capture)val);
                } else {
                    result = val.equals(match);
                    break;
                }
            }catch (IllegalArgumentException e){
                break;
            }
        }

        Collections.reverse(captures);

        for(Capture c: captures) {
            push(c);
        }

        return result;
    }

    @SuppressSubnodes
    public Rule StartOfLine() {

        return new StartOfLineMatcher();
    }

    @SuppressSubnodes
    public Rule Re(String pattern) {

// Path: src/main/java/uk/ac/susx/tag/gramexp/matchers/RegularExpressionMatcher.java
// public class RegularExpressionMatcher extends CustomMatcher {
// 
//     private final Pattern pattern;
// 
//     public RegularExpressionMatcher(String re) {
//         super("Regexp");
//         pattern = Pattern.compile(re);
//     }
// 
//     @Override
//     public boolean isSingleCharMatcher() {
//         return false;
//     }
// 
//     @Override
//     public boolean canMatchEmpty() {
//         return pattern.matcher("").find();
//     }
// 
//     @Override
//     public boolean isStarterChar(char c) {
//         Matcher m = pattern.matcher(c+"");
//         return m.find() && m.start()==0;
//     }
// 
//     @Override
//     public char getStarterChar() {
//         return 0;
//     }
// 
//     @Override
//     public <V> boolean match(MatcherContext<V> context) {
// 
//         int cur = context.getCurrentIndex();
// 
//         InputBuffer buffer = context.getInputBuffer();
//         String content = InputBufferUtils.collectContent(buffer);
//         content = content.substring(cur);
//         Matcher m = pattern.matcher(content);
// 
//         if(m.find()) {
// 
//             int start = m.start();
//             if(start == 0) {
//                 int end = m.end();
// 
//                 int delta = end - start;
// 
//                 context.advanceIndex(delta);
// 
//                 context.createNode();
//                 return true;
// 
//             } else {
//                 return false;
//             }
//         } else {
// 
//             return false;
//         }
// 
//     }
// }
// 
// Path: src/main/java/uk/ac/susx/tag/gramexp/matchers/StartOfLineMatcher.java
// public class StartOfLineMatcher extends CustomMatcher{
// 
//     public StartOfLineMatcher() {
//         super("StartOfLine");
//     }
// 
//     @Override
//     public boolean isSingleCharMatcher() {
//         return true;
//     }
// 
//     @Override
//     public boolean canMatchEmpty() {
//         return true;
//     }
// 
//     @Override
//     public boolean isStarterChar(char c) {
//         return c == '\n';
//     }
// 
//     @Override
//     public char getStarterChar() {
//         return '\n';
//     }
// 
//     @Override
//     public <V> boolean match(MatcherContext<V> context) {
//         int cur = context.getCurrentIndex();
//         if(cur == 0) {
//             context.createNode();
//             return true;
//         }
//         InputBuffer buffer = context.getInputBuffer();
// 
//         if(buffer.charAt(cur-1)=='\n') {
//             context.createNode();
//             return true;
//         }
// 
//         return false;
//     }
// }


// Path: src/main/java/uk/ac/susx/tag/gramexp/CapturingParser.java
import org.parboiled.BaseParser;
import org.parboiled.Rule;
import org.parboiled.annotations.SuppressSubnodes;
import uk.ac.susx.tag.gramexp.matchers.RegularExpressionMatcher;
import uk.ac.susx.tag.gramexp.matchers.StartOfLineMatcher;
import java.util.*;

                Object val = pop();
                if(val instanceof Capture) {
                    captures.add((Capture)val);
                } else {
                    result = val.equals(match);
                    break;
                }
            }catch (IllegalArgumentException e){
                break;
            }
        }

        Collections.reverse(captures);

        for(Capture c: captures) {
            push(c);
        }

        return result;
    }

    @SuppressSubnodes
    public Rule StartOfLine() {

        return new StartOfLineMatcher();
    }

    @SuppressSubnodes
    public Rule Re(String pattern) {

        return new RegularExpressionMatcher(pattern);