@@ -0,0 +1,1756 @@
+package alonzo.ast.parser;%0A%0Aimport java.io.ByteArrayInputStream;%0Aimport java.io.IOException;%0Aimport java.io.InputStream;%0Aimport java.nio.charset.Charset;%0Aimport java.nio.charset.StandardCharsets;%0A%0Aimport alonzo.ast.ASTNode;%0Aimport alonzo.common.Validate;%0Aimport alonzo.exc.UnexpectedIssueException;%0A%0A/**%0A * Abstract superclass of any %7B@link ASTNode%7D parsers.%0A */%0Apublic abstract class Parser %7B%0A%0A    /**%0A     * Parser defaults to assuming UTF8 as the charset for read strings.%0A     */%0A    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;%0A%0A    private final Charset charset;%0A%0A    protected Parser(final Charset charset) %7B%0A        this.charset = Validate.notNull(charset, %22null charset%22);%0A    %7D%0A%0A    /**%0A     * Parses an %7B@code ASTNode%7D from the given %7B@code InputStream%7D. All characters are read from%0A     * %7B@code in%7D using the %7B@link Charset%7D this class was constructed with.%0A     * @param in The %7B@code InputStream%7D to read the %7B@code ASTNode%7D from.%0A     * @return the parsed %7B@code ASTNode%7D.%0A     * @throws IOException if %7B@code in%7D had an issue being read from.%0A     */%0A    public abstract ASTNode parse(final InputStream in) throws IOException;%0A%0A    /**%0A     * @return an %7B@code ASTNode%7D parsed from the given %7B@code String%7D.%0A     * @see #parse(InputStream)%0A     */%0A    public ASTNode parse(final String input) %7B%0A        final ByteArrayInputStream in = new ByteArrayInputStream(bytes(input));%0A%0A        try %7B%0A            return parse(in);%0A        %7D catch (final IOException e) %7B%0A            throw new UnexpectedIssueException(%0A                %22This shouldn't happen, as ByteArrayInputStream shouldn't throw IOException.%22, e);%0A        %7D%0A    %7D%0A%0A    protected byte%5B%5D bytes(final String s) %7B%0A        return s.getBytes(charset);%0A    %7D%0A%7D%0A

Add Parser interface.