import { Constraint, IR, Rule, Ruleset, Sound } from "./ir";
/**
 * Exception thrown by parser when it encounters an error during parsing.
 */
export declare class ParseError extends Error {
    constructor(message: string);
}
/**
 * Represents a sound environment in a rule.
 */
export type SoundEnvironment = {
    left: Sound[];
    right: Sound[];
    explicit: boolean;
};
/**
 * Code parser.
 * Exported only for testing.
 */
export declare class Parser {
    private tokens;
    private index;
    private scope;
    /**
     * @param code - Code to be parsed
     */
    constructor(code: string);
    /**
     * Checks if there are tokens left in the source program.
     */
    private isDone;
    /**
     * Peeks at the token an `offset` number of steps ahead of the current one,
     * without changing the token pointer.
     * Returns `undefined` if there are no tokens left.
     */
    private peek;
    /**
     * Peeks at the next `count` number of tokens.
     * May return fewer tokens than asked for if there are no tokens left in the
     * source program.
     *
     * @param count - Number of tokens to peek at
     */
    private peekN;
    /**
     * Returns the current token and moves the pointer to the next token.
     *
     * If there are no tokens left in the input, returns `undefined`.
     */
    private move;
    /**
     * Consumes a token from the input.
     * The token must match the specified tag.
     * If not, this method throws a `ParseError`.
     *
     * Returns the consumed token.
     *
     * @param tag - Expected tag of the next token
     * @param message - Error message
     */
    private expect;
    /**
     * Parses a sound value.
     * It should be non-empty.
     */
    parseSound(): Sound;
    /**
     * Parses an assignment statement.
     * In general, assignment statements can be written as `A = B`,
     * where `A` is the variable name and `B` is the sound value to be assigned.
     *
     * This method defines the variable in the current scope.
     */
    parseAssignment(): void;
    /**
     * Parses an IPA segment (a terminal).
     */
    parseTerminalSound(): Sound;
    /**
     * Parses a variable that represents a sound value.
     * The value of the variable is resolved during parsing.
     */
    parseVariableSound(): Sound;
    /**
     * Parses a sound value that's enclosed by braces.
     * The value may be a null sound or a union of sounds.
     */
    parseUnionSound(): Sound;
    /**
     * Parses a sequence of sounds.
     * Returns an array of `Sound`s.
     */
    parseSounds(): Sound[];
    /**
     * Parses the sound environment of a rule.
     * In general, a sound environment can be written as `/ A _ B`,
     * where `A` and `B` are sound values.
     *
     * Returns a `SoundEnvironment`.
     * Note that some rules don't specify a sound environment.
     */
    parseEnvironment(): SoundEnvironment;
    /**
     * Parses a simple rule (one that has no constraints).
     * Simple rules can be written as:
     * - `a b c ~ d e f` (transformational rules)
     * - `a ~ b / c _ d` (SPE-style)
     */
    parseSimpleRule(): Rule;
    /**
     * Parses a simple statement.
     * A simple statement can be an assignment statement or a simple rule
     * (one that has no constraints).
     *
     * Returns an array that contains at most one `Rule`.
     */
    parseSimpleStatement(): Rule[];
    /**
     * Parses language code.
     * See docstring for `isLanguageCode` for details on what language codes are
     * supposed to look like.
     *
     * Returns an array of language codes.
     */
    parseLanguageCodes(): string[];
    /**
     * Parses a language selector/constraint.
     * Returns a pair of language codes.
     *
     * A language constraint consists of one or two language codes, and a dot.
     * If the constraint only contains one language, it is assumed that the
     * constraint applies to both sides of a rule.
     *
     * It's the caller's responsibility to check that the next tokens are part of
     * a language constraint.
     * This method doesn't do anything to check.
     */
    parseConstraint(): Constraint;
    /**
     * Parses a multi-line rule.
     * Every line is a simple statement preceded by a "|".
     *
     * Returns an array of `Rule`s.
     */
    parseMultiLineRule(): Rule[];
    /**
     * Parses a compound statement.
     * A compound statement is a rule that has language constraints/selectors.
     * It can be a single-line or a multi-line rule.
     * Returns a `Ruleset`.
     */
    parseCompoundStatement(): Ruleset;
    /**
     * Parses a statement.
     * A statement is either a simple or a compound statement.
     *
     * Hierarchy of statements:
     * - simple
     *   - assignment
     *   - simple rule (no language constraints)
     * - compound
     *   - single-line rule with language constraints
     *   - multi-line rule with constraints (has nested simple statements)
     *
     * Returns the `Ruleset` defined by the statement.
     */
    parseStatement(): Ruleset;
    /**
     * Parses the source program.
     * Throws a `ParseError` if the source program has an error.
     *
     * A program is a sequence of statements.
     */
    parseProgram(): IR;
}
/**
 * Parses code.
 * Returns an intermediate representation if there are no errors in the code.
 * Otherwise, throws a `ParseError`.
 */
export declare function parse(code: string): IR;
//# sourceMappingURL=parser.d.ts.map