Packages

  • package root

    Scallion is a library for easily writing LL(1) parsers in Scala, with support for pretty printing.

    Overview

    Scallion is a library for easily writing LL(1) parsers in Scala, with support for pretty printing. See the package scallion for more information.

    Definition Classes
    root
  • package scallion

    This package is used to describe syntax for LL(1) languages.

    This package is used to describe syntax for LL(1) languages.

    To use the package, mix-in the scallion.Parsers trait.

    object MyParser extends Parsers {
    
      // Type of tokens.
      type Token = MyToken
    
      // Type of token kinds.
      type Kind = MyKind
    
      // Define the token kind of tokens.
      override def getKind(token: Token): Kind = ...
    
      // Then define your syntax using combinators.
      lazy val mySyntax = ...
    }
    Definition Classes
    root
  • package util
    Definition Classes
    scallion
  • package visualization
    Definition Classes
    scallion
  • Debug
  • Enumeration
  • Operators
  • PairDecorator
  • Parsers
  • Parsing
  • PrettyPrinting
  • Syntaxes
  • ~
t

scallion

Operators

trait Operators extends AnyRef

Contains utilities to write syntaxes with infix, prefix and postfix operators. Expected to be mixed-in to Syntaxes.

Example

The following example shows how to build a syntax for a language with unary operators and infix operators of different priority levels.

// Syntax for basic expressions, which are our operands.
lazy val basic: Syntax[Expr] = number | open.skip ~ value ~ close.skip

// Syntax for postfix application of an operator.
lazy val postfixed: Syntax[Expr] = postfixes(basic, fac)({
  // Indicates how to apply the operator.
  case (e, op) => UnaryExpr(op, e)
}, {
  // Optionally, indicates how to unapply an operator.
  // This is only used for pretty printing.
  case UnaryExpr(op, e) => (e, op)
})

// Syntax for infix application of various operators.
lazy val value: Syntax[Expr] = recursive {

  // In this case, our operands are postfixed basic expressions.
  operators(postfixed)(
    // Indicates the various operators and their associativity.
    // First level in multiplication and division, which are
    // left associative and bind the strongest.
    times | div is LeftAssociative,

    // On the next priority level are addition and subtraction,
    // which are also left associative.
    plus | minus is LeftAssociative
  )({
    // Indicates how to apply a binary operator.
    case (l, op, r) => BinaryExpr(op, l, r)
  }, {
    // Optionally, indicates how to unapply a binary operator.
    // This is only used for pretty printing.
    case BinaryExpr(op, l, r) => (l, op, r)
  })
}
Self Type
Operators with Syntaxes
Source
Operators.scala
Linear Supertypes
AnyRef, Any
Known Subclasses
Ordering
  1. Grouped
  2. Alphabetic
  3. By Inheritance
Inherited
  1. Operators
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Type Members

  1. sealed trait Associativity extends AnyRef

    Associativity of an operator.

  2. case class Level[Op](operator: (Operators.this)#Syntax[Op], associativity: (Operators.this)#Associativity) extends Product with Serializable

    Represents a precedence level with a syntax for the various operators of that level and an associativity.

  3. implicit class LevelDecorator[Op] extends AnyRef

    Implicitly decorates an operator syntax to add an is method that indicates the associativity of the operator.

    Implicitly decorates an operator syntax to add an is method that indicates the associativity of the operator.

    Example

    val level = div | times is LeftAssociative

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  5. def clone(): AnyRef
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @native() @throws( ... )
  6. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  7. def equals(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  8. def finalize(): Unit
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  9. final def getClass(): Class[_]
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  10. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  11. def infixLeft[Op, A](elem: (Operators.this)#Syntax[A], op: (Operators.this)#Syntax[Op])(function: (A, Op, A) ⇒ A, inverse: PartialFunction[A, (A, Op, A)] = PartialFunction.empty): (Operators.this)#Syntax[A]

    Syntax that represents repetitions of elem separated by left-associative op.

    Syntax that represents repetitions of elem separated by left-associative op. The value returned is reduced left-to-right.

    Example

    val binaryOp: Syntax[Operator] = ...
    val operand: Syntax[Expr] = ...
    
    val operationExpr = infixLeft(operand, binaryOp) {
      // Describes how to turn two values and an operator into a value.
      case (lhs, op, rhs) => BinaryExpr(op, lhs, rhs)
    }

    With inverse function, for pretty printing support:

    val binaryOp: Syntax[Operator] = ...
    val operand: Syntax[Expr] = ...
    
    val operationExpr = infixLeft(operand, binaryOp)({
      // Describes how to turn two values and an operator into a value.
      case (lhs, op, rhs) => BinaryExpr(op, lhs, rhs)
    }, {
      // Describes how to turn a `BinaryExpr` back to its components.
      case BinaryExpr(op, lhs, rhs) => (lhs, op, rhs)
    })
    elem

    Syntax for the operands.

    op

    Syntax for the operators.

    function

    Function to apply an operation.

    inverse

    Function to reverse an operation.

  12. def infixRight[Op, A](elem: (Operators.this)#Syntax[A], op: (Operators.this)#Syntax[Op])(function: (A, Op, A) ⇒ A, inverse: PartialFunction[A, (A, Op, A)] = PartialFunction.empty): (Operators.this)#Syntax[A]

    Syntax that represents repetitions of elem separated by right-associative op.

    Syntax that represents repetitions of elem separated by right-associative op. The value returned is reduced right-to-left.

    Example

    val binaryOp: Syntax[Operator] = ...
    val operand: Syntax[Expr] = ...
    
    val operationExpr = infixRight(operand, binaryOp) {
      // Describes how to turn two values and an operator into a value.
      case (lhs, op, rhs) => BinaryExpr(op, lhs, rhs)
    }

    With inverse function, for pretty printing support:

    val binaryOp: Syntax[Operator] = ...
    val operand: Syntax[Expr] = ...
    
    val operationExpr = infixRight(operand, binaryOp)({
      // Describes how to turn two values and an operator into a value.
      case (lhs, op, rhs) => BinaryExpr(op, lhs, rhs)
    }, {
      // Describes how to turn a `BinaryExpr` back to its components.
      case BinaryExpr(op, lhs, rhs) => (lhs, op, rhs)
    })
    elem

    Syntax for the operands.

    op

    Syntax for the operators.

    function

    Function to apply an operation.

    inverse

    Function to reverse an operation. *

  13. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  14. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  15. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  16. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  17. def operators[Op, A](elem: (Operators.this)#Syntax[A])(levels: (Operators.this)#Level[Op]*)(function: (A, Op, A) ⇒ A, inverse: PartialFunction[A, (A, Op, A)] = PartialFunction.empty): (Operators.this)#Syntax[A]

    Syntax that represents repetitions of elem separated by infix operators.

    Syntax that represents repetitions of elem separated by infix operators.

    The operators in earlier levels are considered to bind tighter than those in later levels.

    Example

    val andOp: Syntax[Operator]
    val orOp: Syntax[Operator]
    val implyOr: Syntax[Operator]
    
    val operand: Syntax[Expr]
    
    val operationExpr = operators(operand)(
      // The "and" operation binds the strongest.
      andOp is LeftAssociative,
    
      // Then, the "or" operation.
      orOp is LeftAssociative,
    
      // Finally, the "imply" operation, which is right associative.
      implyOr is RightAssociative
    )({
      // Defines how to turn two values and an operator into a value.
      case (lhs, op, rhs) => BinaryExpr(op, lhs, rhs)
    }, {
      // Optionally, defines how to turn a value back into its components.
      // This part is only needed if you want to support pretty printing.
      case BinaryExpr(op, lhs, rhs) => (lhs, op, rhs)
    })

    If multiple operators share the same priority level, you can simply combine them using | before specifying the associativity:

    val operationExpr = operators(operand)(
      // First, multiplication and division, at the same priority level.
      timesOp | divOp is LeftAssociative,
    
      // Then, addition and substraction, at the next priority level.
      plusOp | minusOp is LeftAssociative
    )({
      case (lhs, op, rhs) => BinaryExpr(op, lhs, rhs)
    }, {
      case BinaryExpr(op, lhs, rhs) => (lhs, op, rhs)
    })
    elem

    Syntax for the operands.

    levels

    Operators (with associativity), in decreasing priority.

    function

    Function to apply an operation.

    inverse

    Function to reverse an operation.

  18. def postfixes[Op, A](elem: (Operators.this)#Syntax[A], op: (Operators.this)#Syntax[Op])(function: (A, Op) ⇒ A, inverse: PartialFunction[A, (A, Op)] = PartialFunction.empty): (Operators.this)#Syntax[A]

    Syntax that represents elem postfixed by any number of op.

    Syntax that represents elem postfixed by any number of op.

    Operators are applied left-to-right.

    Example

    val simpleExpr: Syntax[Expr] = ...
    val unaryOps: Syntax[Operator] = ...
    
    val postfixedExpr = postfixes(simpleExpr, unaryOps) {
      // Defines how to convert an `expr` and an `op` into a `Unary` expression.
      case (expr, op) => Unary(op, expr)
    }

    With inverse function, for pretty printing support:

    val simpleExpr: Syntax[Expr] = ...
    val unaryOps: Syntax[Operator] = ...
    
    val postfixedExpr = postfixes(simpleExpr, unaryOps)({
      // Defines how to convert an `expr` and an `op` into a `Unary` expression.
      case (expr, op) => Unary(op, expr)
    }, {
      // Defines how to convert a `Unary` expression into its components.
      case Unary(op, expr) => (expr, op)
    })
    elem

    Syntax for the operands.

    op

    Syntax for the operators.

    function

    Function to apply an operation.

    inverse

    Function to reverse an operation.

  19. def prefixes[Op, A](op: (Operators.this)#Syntax[Op], elem: (Operators.this)#Syntax[A])(function: (Op, A) ⇒ A, inverse: PartialFunction[A, (Op, A)] = PartialFunction.empty): (Operators.this)#Syntax[A]

    Syntax that represents elem prefixed by any number of op.

    Syntax that represents elem prefixed by any number of op.

    Operators are applied right-to-left.

    Example

    val simpleExpr: Syntax[Expr] = ...
    val unaryOps: Syntax[Operator] = ...
    
    val prefixedExpr = prefixes(unaryOps, simpleExpr) {
      // Defines how to convert an `op` and an `expr` into an `expr`.
      case (op, expr) => Unary(op, expr)
    }

    With inverse function, for pretty printing support:

    val simpleExpr: Syntax[Expr] = ...
    val unaryOps: Syntax[Operator] = ...
    
    val prefixedExpr = prefixes(unaryOps, simpleExpr)({
      // Defines how to convert an `op` and an `expr` into a `Unary` expression.
      case (op, expr) => Unary(op, expr)
    }, {
      // Defines how to convert a `Unary` expression into its components.
      case Unary(op, expr) => (op, expr)
    })
    op

    Syntax for the operators.

    elem

    Syntax for the operands.

    function

    Function to apply an operation.

    inverse

    Function to reverse an operation.

  20. final def synchronized[T0](arg0: ⇒ T0): T0
    Definition Classes
    AnyRef
  21. def toString(): String
    Definition Classes
    AnyRef → Any
  22. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  23. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  24. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @throws( ... )
  25. object LeftAssociative extends (Operators.this)#Associativity with Product with Serializable

    Left-associativity.

  26. object RightAssociative extends (Operators.this)#Associativity with Product with Serializable

    Right-associativity.

Inherited from AnyRef

Inherited from Any

Combinators

Priority Levels

Priority levels for the operators combinator.

Associativity

Associativity for priority levels.

Ungrouped