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
- Grouped
- Alphabetic
- By Inheritance
- Operators
- AnyRef
- Any
- Hide All
- Show All
- Public
- All
Type Members
-
sealed
trait
Associativity extends AnyRef
Associativity of an operator.
-
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
operator
s of that level and an associativity. -
implicit
class
LevelDecorator[Op] extends AnyRef
Implicitly decorates an
operator
syntax to add anis
method that indicates the associativity of the operator.Implicitly decorates an
operator
syntax to add anis
method that indicates the associativity of the operator.Example
val level = div | times is LeftAssociative
Value Members
-
final
def
!=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
final
def
##(): Int
- Definition Classes
- AnyRef → Any
-
final
def
==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
final
def
asInstanceOf[T0]: T0
- Definition Classes
- Any
-
def
clone(): AnyRef
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @native() @throws( ... )
-
final
def
eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
def
equals(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
def
finalize(): Unit
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( classOf[java.lang.Throwable] )
-
final
def
getClass(): Class[_]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
-
def
hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
-
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-associativeop
.Syntax that represents repetitions of
elem
separated by left-associativeop
. 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.
-
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-associativeop
.Syntax that represents repetitions of
elem
separated by right-associativeop
. 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. *
-
final
def
isInstanceOf[T0]: Boolean
- Definition Classes
- Any
-
final
def
ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
final
def
notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
final
def
notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
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.
-
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 ofop
.Syntax that represents
elem
postfixed by any number ofop
.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.
-
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 ofop
.Syntax that represents
elem
prefixed by any number ofop
.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.
-
final
def
synchronized[T0](arg0: ⇒ T0): T0
- Definition Classes
- AnyRef
-
def
toString(): String
- Definition Classes
- AnyRef → Any
-
final
def
wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @throws( ... )
-
object
LeftAssociative extends (Operators.this)#Associativity with Product with Serializable
Left-associativity.
-
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.
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.