scala.util.parsing.combinator.syntactical

trait BindingParsers

[source: scala/util/parsing/combinator/syntactical/BindingParsers.scala]

trait BindingParsers
extends Parsers with Binders

This component augments the generic parsers with support for variable binding.

Use bind to decorate a parser that parses a binder (e.g., the name of a local variable or an argument name in a list of formal arguments): besides the parser, it requires a fresh Binder object, which serves as a container for one or more binders with the same scope. The result of the parser is added to the binder's elements. Note that semantic equality (equals) is used to link a binder to its bound occurrences (along with its scope, of course).

For example, here's how you'd write a parser (p) for a let construct (assuming b: Binder[Name]):

   "val" ~! bind(name, b) ~ ":" ~ typeP ~ "=" ~ term ~ "in" ~ in(term, b),

This can be read as ``The parser that matches val (and then does not back-track anymore), a name -- which represents a binder we'll call b -- a colon, a type, an equals sign, a term, the keyword in and finally a term where `b' is in scope.''

The result of this parser is a nested tuple of depth 3, containing a Type, a Term and an UnderBinder[Name, Term]. Note that the binder itself is discarded (the UnderBinder keeps track of it).

newScope makes an empty scope so that you can use into to pass it to a function that makes a parser whose bound variables end up in this scope: In our example, it would be used like this (with b free in p):

    newScope[Name] into { b => p }

Finally, bound(p) constructs a parser that checks that the result of p is bound by some binder b (i.e., b has an element which equals the result of p) in the current scope (as delineated by in(scopeP, b), where p is called during `scopeP'). If scoping is indeed respected, bound(p) wraps the result of p in a BoundElement.

Author
Adriaan Moors
Method Summary
def bind [bt <: NameElement](binderParser : Parser[bt], scope : Scope[bt]) : UnitParser
Generate a UnitParser that parses a binder The result of `binderParser' (a binder) will be added to the binder container `binder', so that `b' can later be used to refer to the binder parsed by `binderParser' (e.g., in the `in' combinator)
def bound [bt <: NameElement](boundElementParser : Parser[bt]) : Parser[BoundElement[NameElement]]
A parser that checks that there are no unbound variables. `bound(p)' succeeds if the element parsed by p is bound by an active binder (see `in')
protected def findScope [bt <: NameElement](x : bt) : Option[Scope[bt]]
def in [scopeT, bt <: NameElement](scopeParser : Parser[scopeT], scope : Scope[bt])(implicit view$1 : (scopeT) => Mappable[scopeT]) : Parser[UnderBinder[bt, scopeT]]

Parse something that is in the scope of the given binders.

During the execution of scopeParser, the binders in binder are active: see bound for more information. The result of the decorated parser is wrapped in an UnderBinder.

protected def inScope [bt <: NameElement, res](scope : Scope[bt])(block : => res) : res
def nested [T <: NameElement](s : Scope[T]) : Parser[Scope[T]]
def newScope [T <: NameElement] : Parser[Scope[T]]
A shortcut for `success(new Scope[t])' Typically used in combination with the `into' combiner as follows:
newScope[Name] into { b => 
      "val" ~! bind(name, b) ~ ":" ~ typeP ~ "=" ~ term ~ "in" ~ in(term, b)}
Methods inherited from Binders
UserNameElementIsMappable (abstract), UnderBinderIsMappable, ScopeIsMappable, NameElementIsMappable, sequence, unsequence, return_
Methods inherited from Mappable
StringIsMappable, ListIsMappable, OptionIsMappable
Methods inherited from Parsers
commit, commit, not, elem, elem, accept, accept, accept, failure, fail, success, success, discard, log, log, rep, rep, repsep, rep1, rep1, repN, rep1, repN, rep1sep, rep1sep, chainl1, chainl1, chainr1, opt, opt, positioned, positioned
Methods inherited from AnyRef
getClass, hashCode, equals, clone, toString, notify, notifyAll, wait, wait, wait, finalize, ==, !=, eq, ne, synchronized
Methods inherited from Any
==, !=, isInstanceOf, asInstanceOf
Method Details
def newScope[T <: NameElement] : Parser[Scope[T]]
A shortcut for `success(new Scope[t])' Typically used in combination with the `into' combiner as follows:
newScope[Name] into { b => 
      "val" ~! bind(name, b) ~ ":" ~ typeP ~ "=" ~ term ~ "in" ~ in(term, b)}

def nested[T <: NameElement](s : Scope[T]) : Parser[Scope[T]]

def bind[bt <: NameElement](binderParser : Parser[bt], scope : Scope[bt]) : UnitParser
Generate a UnitParser that parses a binder The result of `binderParser' (a binder) will be added to the binder container `binder', so that `b' can later be used to refer to the binder parsed by `binderParser' (e.g., in the `in' combinator)
Parameters
binderParser - a parser that parses a binder (e.g., a variable name)
scope - a scope that will contain the parsed binder
Returns
a parser with the same behaviour as `binderParser', except that its result will be added to `scope' and not returned.

def in[scopeT, bt <: NameElement](scopeParser : Parser[scopeT], scope : Scope[bt])(implicit view$1 : (scopeT) => Mappable[scopeT]) : Parser[UnderBinder[bt, scopeT]]

Parse something that is in the scope of the given binders.

During the execution of scopeParser, the binders in binder are active: see bound for more information. The result of the decorated parser is wrapped in an UnderBinder.

Parameters
scopeParser - the parser that parses something that is in the scope of `binder'
binder - a container of binders, typically populated by `bind'
Returns
a parser that has the same behaviour as `scopeParser', but whose result is wrapped in an `UnderBinder'

def bound[bt <: NameElement](boundElementParser : Parser[bt]) : Parser[BoundElement[NameElement]]
A parser that checks that there are no unbound variables. `bound(p)' succeeds if the element parsed by p is bound by an active binder (see `in')
Parameters
boundElementParser - a parser that parses an element that must be bound
Returns
a parser that succeeds if the element parsed by `boundElementParser' was bound, wrapping its result in a `BoundElement'

protected def inScope[bt <: NameElement, res](scope : Scope[bt])(block : => res) : res

protected def findScope[bt <: NameElement](x : bt) : Option[Scope[bt]]