// Path: src/stone/ast/ASTree.java
// public abstract class ASTree implements Iterable<ASTree> {
//     public abstract ASTree child(int i);
//     public abstract int numChildren();
//     public abstract Iterator<ASTree> children();
//     public abstract String location();
//     public Iterator<ASTree> iterator() { return children(); }
// }
// 
// Path: src/stone/ast/ASTLeaf.java
// public class ASTLeaf extends ASTree {
//     private static ArrayList<ASTree> empty = new ArrayList<ASTree>(); 
//     protected Token token;
//     public ASTLeaf(Token t) { token = t; }
//     public ASTree child(int i) { throw new IndexOutOfBoundsException(); }
//     public int numChildren() { return 0; }
//     public Iterator<ASTree> children() { return empty.iterator(); }
//     public String toString() { return token.getText(); }
//     public String location() { return "at line " + token.getLineNumber(); }
//     public Token token() { return token; }
// }
// 
// Path: src/stone/ast/ASTList.java
// public class ASTList extends ASTree {
//     protected List<ASTree> children;
//     public ASTList(List<ASTree> list) { children = list; }
//     public ASTree child(int i) { return children.get(i); }
//     public int numChildren() { return children.size(); }
//     public Iterator<ASTree> children() { return children.iterator(); }
//     public String toString() {
//         StringBuilder builder = new StringBuilder();
//         builder.append('(');
//         String sep = "";
//         for (ASTree t: children) {
//             builder.append(sep);
//             sep = " ";
//             builder.append(t.toString());
//         }
//         return builder.append(')').toString();
//     }
//     public String location() {
//         for (ASTree t: children) {
//             String s = t.location();
//             if (s != null)
//                 return s;
//         }
//         return null;
//     }
// }


import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import stone.ast.ASTree;
import stone.ast.ASTLeaf;
import stone.ast.ASTList;
            else
                res.add(p.parse(lexer));
        }
        protected boolean match(Lexer lexer) throws ParseException {
            return choose(lexer) != null;
        }
        protected Parser choose(Lexer lexer) throws ParseException {
            for (Parser p: parsers)
                if (p.match(lexer))
                    return p;

            return null;
        }
        protected void insert(Parser p) {
            Parser[] newParsers = new Parser[parsers.length + 1];
            newParsers[0] = p;
            System.arraycopy(parsers, 0, newParsers, 1, parsers.length);
            parsers = newParsers;
        }
    }

    protected static class Repeat extends Element {
        protected Parser parser;
        protected boolean onlyOnce;
        protected Repeat(Parser p, boolean once) { parser = p; onlyOnce = once; }
        protected void parse(Lexer lexer, List<ASTree> res)
            throws ParseException
        {
            while (parser.match(lexer)) {
                ASTree t = parser.parse(lexer);
// Path: src/stone/ast/ASTree.java
// public abstract class ASTree implements Iterable<ASTree> {
//     public abstract ASTree child(int i);
//     public abstract int numChildren();
//     public abstract Iterator<ASTree> children();
//     public abstract String location();
//     public Iterator<ASTree> iterator() { return children(); }
// }
// 
// Path: src/stone/ast/ASTLeaf.java
// public class ASTLeaf extends ASTree {
//     private static ArrayList<ASTree> empty = new ArrayList<ASTree>(); 
//     protected Token token;
//     public ASTLeaf(Token t) { token = t; }
//     public ASTree child(int i) { throw new IndexOutOfBoundsException(); }
//     public int numChildren() { return 0; }
//     public Iterator<ASTree> children() { return empty.iterator(); }
//     public String toString() { return token.getText(); }
//     public String location() { return "at line " + token.getLineNumber(); }
//     public Token token() { return token; }
// }
// 
// Path: src/stone/ast/ASTList.java
// public class ASTList extends ASTree {
//     protected List<ASTree> children;
//     public ASTList(List<ASTree> list) { children = list; }
//     public ASTree child(int i) { return children.get(i); }
//     public int numChildren() { return children.size(); }
//     public Iterator<ASTree> children() { return children.iterator(); }
//     public String toString() {
//         StringBuilder builder = new StringBuilder();
//         builder.append('(');
//         String sep = "";
//         for (ASTree t: children) {
//             builder.append(sep);
//             sep = " ";
//             builder.append(t.toString());
//         }
//         return builder.append(')').toString();
//     }
//     public String location() {
//         for (ASTree t: children) {
//             String s = t.location();
//             if (s != null)
//                 return s;
//         }
//         return null;
//     }
// }


// Path: src/stone/Parser.java
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import stone.ast.ASTree;
import stone.ast.ASTLeaf;
import stone.ast.ASTList;

            else
                res.add(p.parse(lexer));
        }
        protected boolean match(Lexer lexer) throws ParseException {
            return choose(lexer) != null;
        }
        protected Parser choose(Lexer lexer) throws ParseException {
            for (Parser p: parsers)
                if (p.match(lexer))
                    return p;

            return null;
        }
        protected void insert(Parser p) {
            Parser[] newParsers = new Parser[parsers.length + 1];
            newParsers[0] = p;
            System.arraycopy(parsers, 0, newParsers, 1, parsers.length);
            parsers = newParsers;
        }
    }

    protected static class Repeat extends Element {
        protected Parser parser;
        protected boolean onlyOnce;
        protected Repeat(Parser p, boolean once) { parser = p; onlyOnce = once; }
        protected void parse(Lexer lexer, List<ASTree> res)
            throws ParseException
        {
            while (parser.match(lexer)) {
                ASTree t = parser.parse(lexer);
                if (t.getClass() != ASTList.class || t.numChildren() > 0)