All Downloads are FREE. Search and download functionalities are using the official Maven repository.

parsley.errors.ErrorBuilder.scala Maven / Gradle / Ivy

The newest version!
package parsley.errors

/**
  * This typeclass specifies how an error generated by a parser should be
  * formatted. An instance of this trait is required when calling `parse`
  * (or similar). By default, Parsley defines its own instance for
  * `ErrorBuilder[String]` found in the ErrorBuilder companion object.
  *
  * To implement this trait, you will need to define a number of methods
  * as well as decide on the representation types for a variety of different
  * components. The relation between the various methods is closely linked
  * to the types that they both produce and consume. If you only want to change
  * the basics of formatting without having to define the entire instance, you
  * can inherit from `DefaultErrorBuilder`, but this will lock in your
  * implementation types (type aliases cannot be overriden in Scala).
  *
  * @tparam Err The final result type of the error message
  * @since 3.0.0
  */
trait ErrorBuilder[Err] {
    private [errors] final type _Err = Err

    /*
      * This is the top level function, which finally compiles all the formatted
      * sub-parts into a finished value of type `Err`.
      *
      * @param pos This is the representation of the position of the error in the
      *            input (see the `[[pos]]` method)
      * @param source This is the representation of the filename (if it exists)
      *               (see the `[[source]]` method)
      * @param ctxs This is the representation of any addition contextual information
      *             in the error (see the `[[nestedContexts]]` method)
      * @param lines This is the main body of the error message (see `[[vanillaError]]`
      *              or `[[specialisedError]]` methods)
      * @return The final assembled error message
      * @since 3.0.0
      */
    //def format(pos: Position, source: Source, ctxs: NestedContexts, lines: ErrorInfoLines): Err

    /**
      * This is the top level function, which finally compiles all the formatted
      * sub-parts into a finished value of type `Err`.
      *
      * @param pos This is the representation of the position of the error in the
      *            input (see the `[[pos]]` method)
      * @param source This is the representation of the filename (if it exists)
      *               (see the `[[source]]` method)
      * @param lines This is the main body of the error message (see `[[vanillaError]]`
      *              or `[[specialisedError]]` methods)
      * @return The final assembled error message
      * @since 3.0.0
      */
    def format(pos: Position, source: Source, lines: ErrorInfoLines): Err

    /**
      * The representation type of position information within the generated message
      * @since 3.0.0
      */
    type Position
    /**
      * The representation of the file information
      * @since 3.0.0
      */
    type Source
    /*
      * The representation of contextual information, including the file and additional
      * context
      * @since ???
      */
    //type Context
    /**
      * Formats a position into the representation type given by `Position`.
      *
      * @param line The line the error occurred at
      * @param col The column the error occurred at
      * @return A representation of the position
      * @since 3.0.0
      */
    def pos(line: Int, col: Int): Position
    /**
      * Formats the name of the file if it exists into the type give by `Source`
      *
      * @param sourceName The source name of the file, if any
      * @since 3.0.0
      */
    def source(sourceName: Option[String]): Source
    /*
      * Formats any additional contextual information from the parser. This might,
      * for instance, include function or class names.
      *
      * @param context The context information produced by the parser
      * @return A representation of the context
      * @since ???
      */
    //def contexualScope(context: String): Context

    /*
      * The representation of collapsed nested contextual information.
      * @since ???
      */
    //type NestedContexts
    /*
      * Contextual information produced by `[[contextualScope]]` is combined by this
      * method into a single piece of information. This does not include information
      * about the source file.
      *
      * @param contexts The nested contexts to be collapsed, most general first
      *                 (produced by `[[contextualScope]]`)
      * @since ???
      */
    //def nestContexts(contexts: List[Context]): NestedContexts

    /**
      * The representation type of the main body within the error message
      * @since 3.0.0
      */
    type ErrorInfoLines
    /**
      * Vanilla errors are those produced such that they have information about
      * both `expected` and `unexpected` tokens. These are usually the default,
      * and are not produced by `fail` (or any derivative) combinators.
      *
      * @param unexpected Information about which token(s) caused the error
      *                   (see the `[[unexpected]]` method)
      * @param expected Information about which token(s) would have avoided
      *                 the error (see the `[[expected]]` method)
      * @param reasons Additional information about why the error occured
      *                (see the `[[combineMessages]]` method)
      * @param line Representation of the line of input that this error occured
      *             on (see the `[[lineInfo]]` method)
      * @since 3.0.0
      */
    def vanillaError(unexpected: UnexpectedLine, expected: ExpectedLine, reasons: Messages, line: LineInfo): ErrorInfoLines
    /**
      * Specialised errors are triggered by `fail` and any combinators that are
      * implemented in terms of `fail`. These errors take precedence over
      * the vanilla errors, and contain less, more specialised, information
      *
      * @param msgs Information detailing the error (see the `[[combineMessages]]` method)
      * @param line Representation of the line of input that this error occured
      *             on (see the `[[lineInfo]]` method)
      * @since 3.0.0
      */
    def specialisedError(msgs: Messages, line: LineInfo): ErrorInfoLines

    /**
      * The representation of all the different possible tokens that could
      * have prevented an error.
      */
    type ExpectedItems
    /**
      * The representation of the combined reasons or failure messages from
      * the parser.
      */
    type Messages
    /**
      * Details how to combine the various expected items into a single
      * representation.
      *
      * @param alts The possible items that fix the error
      * @since 3.0.0
      */
    def combineExpectedItems(alts: Set[Item]): ExpectedItems
    /**
      * Details how to combine any reasons or messages generated within a
      * single error. Reasons are used by `vanilla` messages and messages
      * are used by `specialised` messages.
      *
      * @param alts The messages to combine (see the `[[message]]` or `[[reason]]`
      *             methods)
      * @since 3.0.0
      */
    def combineMessages(alts: Seq[Message]): Messages

    /**
      * The representation of the information regarding the problematic token.
      * @since 3.0.0
      */
    type UnexpectedLine
    /**
      * The representation of the information regarding the solving tokens.
      * @since 3.0.0
      */
    type ExpectedLine
    /**
      * The representation of a reason or a message generated by the parser.
      * @since 3.0.0
      */
    type Message
    /**
      * The representation of the line of input where the error occurred.
      * @since 3.0.0
      */
    type LineInfo
    /**
      * Describes how to handle the (potentially missing) information
      * about what token(s) caused the error.
      *
      * @param item The `Item` that caused this error
      * @since 3.0.0
      */
    def unexpected(item: Option[Item]): UnexpectedLine
    /**
      * Describes how to handle the information about the tokens that
      * could have avoided the error.
      *
      * @param alts The tokens that could have prevented the error
      *             (see the `[[combineExpectedItems]]` method)
      * @since 3.0.0
      */
    def expected(alts: ExpectedItems): ExpectedLine
    /**
      * Describes how to represent the reasons behind a parser fail.
      * These reasons originate from the `explain` combinator.
      *
      * @param reason The reason produced by the parser
      * @since 3.0.0
      */
    def reason(reason: String): Message
    /**
      * Describes how to represent the messages produced by the
      * `fail` combinator (or any that are implemented using it).
      *
      * @param msg The message produced by the parser
      * @since 3.0.0
      */
    def message(msg: String): Message
    /**
      * Describes how to format the information about the line that
      * the error occured on.
      *
      * @param line The full line of input that produced this error
      *             message
      * @param linesBefore The lines of input just before the one that
      *                    produced this message (up to `[[numLinesBefore]]`)
      * @param linesAfter The lines of input just after the one that
      *                   produced this message (up to `[[numLinesAfter]]`)
      * @param errorPointsAt The offset into the line that the error
      *                      points at
      * @since 3.1.0
      */
    def lineInfo(line: String, linesBefore: Seq[String], linesAfter: Seq[String], errorPointsAt: Int): LineInfo

    /**
      * The number of lines of input to request before an error occured
      * @since 3.1.0
      */
    val numLinesBefore: Int
    /**
      * The number of lines of input to request after an error occured
      * @since 3.1.0
      */
    val numLinesAfter: Int

    /**
      * The base type of `Raw`, `Named` and `EndOfInput` that
      * represents the individual items within the error.
      * @since 3.0.0
      */
    type Item
    /**
      * This represents "raw" tokens, where are those without
      * labels: i.e. they come direct from the input, or the
      * characters that the parser is trying to read.
      * @since 3.0.0
      */
    type Raw <: Item
    /**
      * This represents "named" tokens, which have been provided
      * with a label.
      * @since 3.0.0
      */
    type Named <: Item
    /**
      * Represents the end of the input.
      * @since 3.0.0
      */
    type EndOfInput <: Item
    /**
      * Formats a raw item generated by either the input string or
      * a input reading combinator without a label.
      *
      * @param item The raw, unprocessed input
      * @since 3.0.0
      */
    def raw(item: String): Raw
    /**
      * Formats a named item generated by a label.
      *
      * @param item The name given to the label
      * @since 3.0.0
      */
    def named(item: String): Named
    /**
      * Value that represents the end of the input
      * in the error message.
      * @since 3.0.0
      */
    val endOfInput: EndOfInput
}

object ErrorBuilder {
    // $COVERAGE-OFF$
    /**
      * The default error builder used by Parsley, which produces
      * an error as a String. An instance of `DefaultErrorBuilder`.
      */
    implicit val stringError: ErrorBuilder[String] = new DefaultErrorBuilder
    // $COVERAGE-ON$
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy