halotukozak.alpaca

Members list

Packages

Type members

Classlikes

object CtxScope

Attributes

Source
scopes.scala
Supertypes
class Object
trait Matchable
class Any
Self type
CtxScope.type
object ErrorHandling

Attributes

Source
ErrorHandling.scala
Supertypes
class Object
trait Matchable
class Any
Self type
final class IgnoredToken[+Ctx <: LexerCtx] extends Token[ValidName, Ctx, Nothing]

What Token.Ignored returns inside a lexer block: its matches are consumed but produce no lexeme. Use it for whitespace, comments and anything else the parser should not see.

What Token.Ignored returns inside a lexer block: its matches are consumed but produce no lexeme. Use it for whitespace, comments and anything else the parser should not see.

Type parameters

Ctx

the lexer context type

Attributes

Source
lexer.scala
Supertypes
class Token[ValidName, Ctx, Nothing]
class Object
trait Matchable
class Any
object LexerCtx

Attributes

Companion
trait
Source
lexer.scala
Supertypes
class Object
trait Matchable
class Any
Self type
LexerCtx.type
trait LexerCtx extends Product, Selectable

The base of every lexer context: the state a lexer carries from one token to the next, read and assigned as ctx in rule bodies, and snapshotted into every lexeme and LexerError.

The base of every lexer context: the state a lexer carries from one token to the next, read and assigned as ctx in rule bodies, and snapshotted into every lexeme and LexerError.

A context must be a case class whose fields all have default values, since the lexer macro builds the initial context from those defaults:

case class BrainLexContext(squareBrackets: Int = 0, line: Line = Line.Start) extends LexerCtx

A field whose type has a given Tracking, like Line or Column, is updated after every match.

Attributes

Companion
object
Source
lexer.scala
Supertypes
trait Selectable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all
Known subtypes
class Default
class Empty
object LexerError

Attributes

Companion
class
Source
lexer.scala
Supertypes
class Object
trait Matchable
class Any
Self type
LexerError.type
final class LexerError extends Selectable

Input that did not match any token, as reported by tokenize in a Result.Failure.

Input that did not match any token, as reported by tokenize in a Result.Failure.

Like a Lexeme, it carries the lexer context's fields as they were where the input starts, read by name (error.line when the context has a line field) on the errors tokenize returns.

Value parameters

unexpected

the input that was not matched: one character, or with ErrorHandling.Strategy.SkipToNextMatch everything skipped up to the next match

Attributes

Companion
object
Source
lexer.scala
Supertypes
trait Selectable
class Object
trait Matchable
class Any
final class LexerException extends RuntimeException

Thrown by getOrThrow on a lexer Result when some input did not match a token.

Thrown by getOrThrow on a lexer Result when some input did not match a token.

Value parameters

errors

the errors the lexer reported, in input order

Attributes

Source
lexer.scala
Supertypes
class RuntimeException
class Exception
class Throwable
trait Serializable
class Object
trait Matchable
class Any
Show all
object LexerScope

Attributes

Source
scopes.scala
Supertypes
class Object
trait Matchable
class Any
Self type
LexerScope.type
trait ParserCtx extends Product, Selectable

The base of every parser context: state carried through a parse, such as a symbol table, read and assigned as ctx in the actions and returned in the Result.

The base of every parser context: state carried through a parse, such as a symbol table, read and assigned as ctx in the actions and returned in the Result.

A context must be a case class whose fields all have default values, since the parser builds the initial context from those defaults:

case class BrainParserCtx(functions: Set[String] = Set.empty) extends ParserCtx

Assigning a field in an action (ctx.functions += name) is rewritten into a copy, so the fields can stay vals, as in a lexer context.

Attributes

Companion
object
Source
parser.scala
Supertypes
trait Selectable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all
Known subtypes
class Empty
object ParserCtx

Attributes

Companion
trait
Source
parser.scala
Supertypes
class Object
trait Matchable
class Any
Self type
ParserCtx.type
object ParserError

Attributes

Companion
class
Source
parser.scala
Supertypes
class Object
trait Matchable
class Any
Self type
sealed abstract class ParserError

Why the input does not match the grammar, as reported by parse in a Result.Failure.

Why the input does not match the grammar, as reported by parse in a Result.Failure.

The type member Fields is the lexer context's fields, which the lexemes carry. parse returns errors with the fields of the lexemes it was given, so positions are the lexer context's fields, e.g. error.unexpected.map(_.line), or error.last.map(_.line) at the end of the input. In a signature, write that type as MyLexer.ParserError; plain ParserError is an error over any lexemes, without their fields.

Attributes

Companion
object
Source
parser.scala
Supertypes
class Object
trait Matchable
class Any
final class ParserException extends RuntimeException

Thrown by getOrThrow on a parse Result when parsing failed.

Thrown by getOrThrow on a parse Result when parsing failed.

Value parameters

errors

the errors the parser reported, in input order

Attributes

Source
parser.scala
Supertypes
class RuntimeException
class Exception
class Throwable
trait Serializable
class Object
trait Matchable
class Any
Show all
object ParserScope

Attributes

Source
scopes.scala
Supertypes
class Object
trait Matchable
class Any
Self type
object Production

Attributes

Source
Production.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Production.type

Attributes

Source
scopes.scala
Supertypes
class Object
trait Matchable
class Any
Self type
sealed trait ProductionSelector extends Selectable

What production returns: the parser's named productions as members, each a Production, so production.plus is the production named "plus".

What production returns: the parser's named productions as members, each a Production, so production.plus is the production named "plus".

Attributes

Note

This is a compile-time only feature and can be used only inside resolutions(...).

Source
ProductionSelector.scala
Supertypes
trait Selectable
class Object
trait Matchable
class Any

Attributes

Source
scopes.scala
Supertypes
class Object
trait Matchable
class Any
Self type
enum Result[+Ctx, +Value, +Err]

The outcome of tokenizing or parsing: the value, or the errors met on the way.

The outcome of tokenizing or parsing: the value, or the errors met on the way.

Both cases carry the context (lexer or parser) as it was when the run ended. A Result.Failure may still hold a value in recovered, when an error-handling strategy skipped past the errors and the run went on to the end; otherwise recovered is None.

MyParser.parse(lexemes) match
 case Result.Success(ctx, value) => println(value)
 case Result.Failure(ctx, recovered, errors) => errors.foreach(e => println(e.message))

For Alpaca's own error types, getOrThrow returns the value or throws the errors as an exception (LexerException for LexerErrors, ParserException for ParserErrors).

Type parameters

Ctx

the lexer or parser context type

Err

the error type: LexerError for tokenize, ParserError for parse

Value

the value: the lexemes for tokenize, the root rule's result for parse

Attributes

Source
Result.scala
Supertypes
trait Enum
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all
sealed trait Rule[Value]

Represents a grammar rule in the parser.

Represents a grammar rule in the parser.

A rule defines how a non-terminal symbol can be parsed by specifying one or more productions. Each production maps a pattern of symbols to a result value.

Rules are created using the rule function and can be used in pattern matching within parser productions.

Type parameters

Value

the type of value produced when this rule is matched

Attributes

Source
parser.scala
Supertypes
class Object
trait Matchable
class Any
sealed class Token[+Name <: ValidName, +Ctx <: LexerCtx, +Value]

What Token["NAME"] and Token["NAME"](value) return inside a lexer block: a marker the lexer macro reads to define a token. It exists only at compile time and cannot be created or extended outside the library.

What Token["NAME"] and Token["NAME"](value) return inside a lexer block: a marker the lexer macro reads to define a token. It exists only at compile time and cannot be created or extended outside the library.

The token a lexer defines is read as MyLexer.NAME, and its type is named the same way: val t: MyLexer.NAME = MyLexer.NAME. In a parser, MyLexer.NAME(lexeme) matches one; as a type, a token can be a SeparatedBy separator, and in resolutions(...) it can be ordered against productions.

Type parameters

Ctx

the lexer context type

Name

the token's name

Value

the type of the value its lexemes carry

Attributes

Companion
object
Source
lexer.scala
Supertypes
class Object
trait Matchable
class Any
Known subtypes
class IgnoredToken[Ctx]
object Token

Factory methods for creating token definitions in the lexer DSL.

Factory methods for creating token definitions in the lexer DSL.

Attributes

Companion
class
Source
lexer.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Token.type

Types

A lexer or a parser context, LexerCtx or ParserCtx: a case class whose fields all have default values, read and assigned as ctx in lexer rules, parser actions and the handlers built by ErrorHandling.forLexer and ErrorHandling.forParser.

A lexer or a parser context, LexerCtx or ParserCtx: a case class whose fields all have default values, read and assigned as ctx in lexer rules, parser actions and the handlers built by ErrorHandling.forLexer and ErrorHandling.forParser.

There ctx.count += 1 is rewritten into a copy, so the fields can stay vals: ctx has a setter for each one, which resolves through Selectable to applyDynamic and is rewritten away before it is ever called.

Attributes

Source
AlpacaCtx.scala

Type representing conflict resolution rules for the parser.

Type representing conflict resolution rules for the parser.

Conflict resolutions are used to resolve shift/reduce and reduce/reduce conflicts in the parsing table by specifying precedence relationships between productions and tokens.

Attributes

Source
parser.scala
opaque type CtxScope

Evidence that code runs where ctx is available: a lexer rule, a parser action, or an ErrorHandling.forLexer or ErrorHandling.forParser handler. Its Ctx member is the context type.

Evidence that code runs where ctx is available: a lexer rule, a parser action, or an ErrorHandling.forLexer or ErrorHandling.forParser handler. Its Ctx member is the context type.

Attributes

Source
scopes.scala
opaque type ErrorHandling[Ctx <: AlpacaCtx]

How tokenizing or parsing goes on after input that is not accepted.

How tokenizing or parsing goes on after input that is not accepted.

Whatever the strategy, the error is reported in the Result.Failure that tokenize or parse returns; the strategy only decides whether the run stops there or skips past the input and goes on. It is given the error, and reads and changes the context as ctx, so it can decide per error.

The lexer and the parser look for an ErrorHandling for their context, which defaults to ErrorHandling.Strategy.Stop. Define a given for your context type, built with ErrorHandling.forLexer or ErrorHandling.forParser, to change that:

given ErrorHandling[MyLexerCtx] = ErrorHandling.forLexer: error =>
 ctx.skipped += 1
 ErrorHandling.Strategy.SkipOne
given ErrorHandling[MyParserCtx] = ErrorHandling.forParser(_ => ErrorHandling.Strategy.SkipToNextMatch)

Type parameters

Ctx

the lexer or parser context this applies to

Attributes

Source
ErrorHandling.scala
type LexerDefinition[Ctx <: LexerCtx] = PartialFunction[String, Token[ValidName, Ctx, Any]]

Type alias for lexer rule definitions.

Type alias for lexer rule definitions.

A lexer definition is a partial function that maps string patterns (as regex literals) to token definitions.

Type parameters

Ctx

the global context type

Attributes

Source
lexer.scala
opaque type LexerScope

Evidence that code runs inside a lexer rule, where ctx and Token[...] are available. Only the lexer macro creates one; its Ctx member is the lexer context type.

Evidence that code runs inside a lexer rule, where ctx and Token[...] are available. Only the lexer macro creates one; its Ctx member is the lexer context type.

Attributes

Source
scopes.scala
type Parser[Ctx <: ParserCtx] = Parser[Ctx]

The base of a parser: extend it with an object whose rules are vals built with rule, one of them root. extends Parser uses the empty ParserCtx.Empty context; extends Parser[MyCtx] carries MyCtx through the actions, as ctx.

The base of a parser: extend it with an object whose rules are vals built with rule, one of them root. extends Parser uses the empty ParserCtx.Empty context; extends Parser[MyCtx] carries MyCtx through the actions, as ctx.

Type parameters

Ctx

the parser context type

Attributes

Source
parser.scala
opaque type ParserScope

Evidence that code runs inside a parser definition, where rule and named productions are available. Every Parser provides one; its Ctx member is the parser context type, which the productions of a rule bind as their ProductionScope.

Evidence that code runs inside a parser definition, where rule and named productions are available. Every Parser provides one; its Ctx member is the parser context type, which the productions of a rule bind as their ProductionScope.

Attributes

Source
scopes.scala
opaque type Production

A reference to one of the parser's productions inside resolutions, taken from production. or Production(symbols*) and passed to before/after. It exists only at compile time, so it has no members and no other way to create one.

A reference to one of the parser's productions inside resolutions, taken from production. or Production(symbols*) and passed to before/after. It exists only at compile time, so it has no members and no other way to create one.

Attributes

Source
Production.scala
type ProductionDefinition[Value] = PartialFunction[Tuple | Lexeme[_, _], Value]

Defines a single production in a grammar rule.

Defines a single production in a grammar rule.

A production definition is a partial function that matches a specific pattern of symbols (as a tuple of terminals and non-terminals, or a single lexeme) and produces a result value of type Value. Productions are the building blocks of grammar rules, specifying how input sequences are recognized and transformed.

Production definitions are typically passed to the rule function to define the possible ways a non-terminal can be parsed.

See the documentation for rule for more details.

Type parameters

Value

the result type produced by this production

Attributes

Source
parser.scala
opaque type ProductionScope

Evidence that code runs inside a production of a parser's rule, where ctx and the token and rule extractors (MyLexer.NUM(n), Expr(e), Expr.List(es)) are available. Only rule binds one; its Ctx member is the parser context type.

Evidence that code runs inside a production of a parser's rule, where ctx and the token and rule extractors (MyLexer.NUM(n), Expr(e), Expr.List(es)) are available. Only rule binds one; its Ctx member is the parser context type.

Attributes

Source
scopes.scala
opaque type ResolutionScope[ParserType <: Parser[_]]

Evidence that code runs inside resolutions, where production, Production(...) and before/after are available. Gives production the parser it refers to.

Evidence that code runs inside resolutions, where production, Production(...) and before/after are available. Gives production the parser it refers to.

Type parameters

ParserType

the parser's singleton type

Attributes

Source
scopes.scala
opaque type Resolutions[ParserType <: Parser[_]]

How the parser ParserType resolves the conflicts in its grammar. Provide one as a given next to the parser object (before or after it) or as the object's last member, built with resolutions:

How the parser ParserType resolves the conflicts in its grammar. Provide one as a given next to the parser object (before or after it) or as the object's last member, built with resolutions:

given Resolutions[CalcParser.type] = resolutions(
 production.plus.before(CalcLexer.PLUS), // + is left-associative
)

Type parameters

ParserType

the parser's singleton type

Attributes

Source
parser.scala
type SepValue[Separator] = Separator match { case Token[name, _$3, value] => Lexeme[name, value] case Rule[result] => result }

The runtime value type of a separator symbol used by .SeparatedBy.

The runtime value type of a separator symbol used by .SeparatedBy.

The parser places Lexeme values on the stack for terminals, so when the separator is a token named name whose value has type value (e.g. MyLexer.COMMA), its runtime value is Lexeme[name, value]. For a rule separator Rule[result] (typically passed as a singleton type like Sep.type), the runtime value is result — whatever that rule produces.

Type parameters

Separator

the separator symbol type (a token type or a rule's .type)

Attributes

Source
parser.scala

Value members

Concrete methods

transparent inline def ctx[Ctx <: AlpacaCtx](using scope: Of[Ctx]): Ctx

The context inside a lexer rule body or an ErrorHandling.forLexer handler: read its fields, or assign them (ctx.count += 1) to change the context for the tokens that follow. The assignment is rewritten into a copy, so the fields can stay vals.

The context inside a lexer rule body or an ErrorHandling.forLexer handler: read its fields, or assign them (ctx.count += 1) to change the context for the tokens that follow. The assignment is rewritten into a copy, so the fields can stay vals.

In a parser action or an ErrorHandling.forParser handler it is the parser context, the same way.

Attributes

Source
lexer.scala
transparent inline def lexer[Ctx <: LexerCtx](using withDefault[Ctx, Default])(inline rules: Of[Ctx] ?=> LexerDefinition[Ctx])(using errorHandling: ErrorHandling[Ctx]): Lexer[Ctx]

Creates a lexer from a DSL-based definition.

Creates a lexer from a DSL-based definition.

This is the main entry point for defining a lexer. It uses a macro to compile the lexer definition into efficient tokenization code.

Example:

val myLexer = lexer {
 case "\\d+" => Token["number"]
 case "[a-zA-Z]+" => Token["identifier"]
 case "\\s+" => Token.Ignored
}

Type parameters

Ctx

the global context type, defaults to LexerCtx.Default

Value parameters

errorHandling

implicit ErrorHandling for custom error recovery

rules

the lexer rules as a partial function

Attributes

Returns

a Lexer that can tokenize input strings

Source
lexer.scala
transparent inline def production[ParserType <: Parser[_] : ResolutionScope]: ProductionSelector

Selects one of the parser's named productions by its name: production.plus is the production named "plus". Names that are not Scala identifiers go in backticks (production.`if then`).

Selects one of the parser's named productions by its name: production.plus is the production named "plus". Names that are not Scala identifiers go in backticks (production.`if then`).

This is compile-time only and can be used only inside resolutions.

Attributes

Source
parser.scala
def resolutions[ParserType <: Parser[_]](elements: ResolutionScope[ParserType] ?=> ConflictResolution*): Resolutions[ParserType]

Collects the conflict resolutions for the parser ParserType, each written with before or after (see Resolutions).

Collects the conflict resolutions for the parser ParserType, each written with before or after (see Resolutions).

Value parameters

elements

the resolutions; inside them, production. refers to ParserType's named productions

Attributes

Source
parser.scala
inline def rule(using scope: ParserScope)[Value](inline productions: Of[scope.Ctx] ?=> ProductionDefinition[Value]*): Rule[Value]

Creates a grammar rule from one or more productions.

Creates a grammar rule from one or more productions.

This is the main way to define grammar rules in the parser DSL. Each production is a partial function that matches a pattern of symbols (terminals and non-terminals) and produces a result value.

This is compile-time only and should only be used inside parser class definitions.

Example:

val Expr: Rule[Int] = rule(
 { case (Expr(a), CalcLexer.PLUS(_), CalcLexer.NUMBER(b)) => a + b.value },
 { case CalcLexer.NUMBER(n) => n.value },
)

Type parameters

Value

the result type produced by this rule

Value parameters

productions

one or more productions that define this rule

Attributes

Returns

a Rule instance

Source
parser.scala

Extensions

Extensions

extension (inline first: Production | Token[_, _, _])
infix inline def after[ParserType <: Parser[_] : ResolutionScope](inline others: Production | Token[_, _, _]*): ConflictResolution

Resolves the conflicts between this production or token and each of others in favour of others: the reverse of before. production.plus.after(CalcLexer.TIMES) shifts * instead of reducing plus, so * binds tighter than +.

Resolves the conflicts between this production or token and each of others in favour of others: the reverse of before. production.plus.after(CalcLexer.TIMES) shifts * instead of reducing plus, so * binds tighter than +.

This is compile-time only and can be used only inside resolutions.

Value parameters

others

the productions and tokens that win over this one

Attributes

Returns

a conflict resolution rule

Source
parser.scala
infix inline def before[ParserType <: Parser[_] : ResolutionScope](inline others: Production | Token[_, _, _]*): ConflictResolution

Resolves the conflicts between this production or token and each of others in favour of this one: a production is reduced rather than shifting a token of others or reducing a production of others; a token is shifted rather than reducing a production of others. production.plus.before(CalcLexer.PLUS) reduces 1 + 2 before shifting the next +, so + is left-associative.

Resolves the conflicts between this production or token and each of others in favour of this one: a production is reduced rather than shifting a token of others or reducing a production of others; a token is shifted rather than reducing a production of others. production.plus.before(CalcLexer.PLUS) reduces 1 + 2 before shifting the next +, so + is left-associative.

This is compile-time only and can be used only inside resolutions.

Value parameters

others

the productions and tokens this one wins over

Attributes

Returns

a conflict resolution rule

Source
parser.scala
extension (name: String)
inline def apply[Value](production: ProductionDefinition[Value])(using ParserScope): production.type

Defines a named production for use in grammar rules and conflict resolution.

Defines a named production for use in grammar rules and conflict resolution.

This extension method allows you to assign a name to a specific production within a rule. Named productions can be referenced in conflict resolution rules as production., enabling fine-grained control over precedence and associativity.

Usage:

val Expr: Rule[Int] = rule(
 "plus" { case (Expr(a), CalcLexer.PLUS(_), Expr(b)) => a + b },
 { case CalcLexer.NUMBER(n) => n.value },
)

// In conflict resolution:
given Resolutions[CalcParser.type] = resolutions(
 production.plus.before(CalcLexer.PLUS),
)

Type parameters

Value

the result type produced by this production

Value parameters

production

the production to name

Attributes

Returns

the original production, annotated with the given name

Source
parser.scala
extension [Ctx <: ParserCtx](parser: Parser[Ctx])
inline def parse[LexemeFields <: AnyNamedTuple](lexemes: List[withFields[Lexeme[_, _], LexemeFields]]): Result[Ctx, parser.root.type match { case Rule[result] => result }, withFields[ParserError, LexemeFields]]

Parses a list of lexemes using the defined grammar.

Parses a list of lexemes using the defined grammar.

The result type is inferred from the root rule. Input that does not match the grammar is not thrown as an exception: it comes back as a Result.Failure listing the ParserErrors.

Type parameters

LexemeFields

the lexer context's fields, which the lexemes carry; the errors carry them too, so error.unexpected.map(_.line) compiles when they have a line

Value parameters

lexemes

the list of lexemes to parse

Attributes

Returns

the value the root rule produced, or the errors that stopped the parser, with the context either way

Source
parser.scala

Exports

Defined exports

final val Column: Column
Exported from Column$package

Attributes

Source
lexer.scala
final val LazyReader: LazyReader
Exported from lexer

Attributes

Source
lexer.scala
final val Lexeme: Lexeme
Exported from lexer

Attributes

Source
lexer.scala
final type Lexer = [Ctx <: LexerCtx] =>> Lexer[Ctx]
Exported from lexer

Attributes

Source
lexer.scala
final val Line: Line
Exported from Line$package

Attributes

Source
lexer.scala
final val Tracking: Tracking
Exported from lexer

Attributes

Source
lexer.scala