Table Of Contents

Previous topic

Introduction

Next topic

syntax

This Page

fbrelation

fbrelation
by Alex Forsythe <awforsythe@gmail.com> <http://awforsythe.com>

Defines an interpreter for a small declarative language used to define MotionBuilder relation constraints. In this language, a program consists of a series of relation constraint declarations, each of which contains a series of box and connection declarations, each on its own line.

Loading a relation constraint program takes place in three phases: parsing, compilation, and execution.

  1. The parsing phase constructs abstract syntax objects from input text, using the static parse() method of the various classes in the syntax submodule. These methods may throw a ParsingError if they encounter malformed syntax.
  2. The compilation phase turns abstract syntax objects into semantically validated declaration objects, using the compile() method of the individual syntax objects. These methods perform some static checking to ensure that the program is relatively sound. If any of these checks fail, a CompilationError will be thrown.
  3. Finally, the execution phase constructs and configures new FBConstraintRelation objects from the compiled declarations. The execute() methods of the declaration objects handle the instantiation and configuration of MotionBuilder objects, and they will throw an ExecutionError if they encounter problems at runtime.
loads(string)[source]

Parses, compiles, and executes a program from its provided source text.

Returns:a dictionary mapping constraint declaration names to their corresponding FBConstraintRelation objects.
Raises :a RelationException if a program is invalid or unsupported.
load(fp)[source]

Parses, compiles, and executes a program from the provided open file.

Note :Returns and raises identically to loads.

Running a program

The implementation of loads() shows in very clear terms what happens when an fbrelation program is run:

def loads(string):
    syntax = ProgramSyntax.parse(string)
    declaration = syntax.compile()
    constraints = declaration.execute()
    return constraints

First, a new ProgramSyntax object is constructed from the input text. We can then use that object to compile a new ProgramDeclaration. We then execute the declaration in MotionBuilder, giving us a dictionary that contains the newly created relation constraints, indexed by name.

Elements of a program

A collection of syntax classes model the abstract syntax of an fbrelation program. The syntax and structure of a program is defined recursively: a program is made up of relations, which are made up of node and connection declarations. The following table summarizes these composition relationships:

element composed of syntax class
program n relations ProgramSyntax
relation 1 name, n boxes, m connections RelationSyntax
box 1 name, 1 attributelist BoxSyntax
attributelist n names, n values AttributeListSyntax
connection 2 nodes ConnectionSyntax
node 1 box name, 0 or 1 node names NodeSyntax

Once the program and its constituent elements are compiled, the program’s semantics are represented by various declaration classes. The syntax objects employ an abstract factory pattern, with their compile methods creating a declaration object of the appropriate subclass based on the details specified in the program. The base classes for each of these elements are as follows:

element declaration class
program ProgramDeclaration
relation RelationDeclaration
box BoxDeclaration
connection ConnectionDeclaration
node NodeDeclaration

Program, relation, and connection declarations do not themselves exhibit any polymorphism, as they serve mostly as containers. The different box and node declaration subclasses are documented in more detail in the corresponding modules.