BMF / BMA / BMO — the three-tech split
The applied paper bml-search-algorithms.txt names the three-tech split that holds the system together. Each technology owns one altitude:
Keeps this page in sync as the body changes. Pause it any time for a quieter view.
Path /people/bmf-grammar
Last refresh never
Work · 2000 · Parser layer
BNF augmented with execution. When a rule matches, code fires. Expressions are tagged and placed on a structured stack each rule transforms into the target language's object model. The grammar file BMF-grammar.bml is itself written in BML — banner reads Digi4Fun (R) BMF 1.0 Alpha 1.
companion/source-samples/BMF-grammar.bml in the archive)bml-search-algorithms.txtWhat BMF actually is
Parser is the first noun. Executable grammar is the second. BMF rules don't describe a parse tree — they build one as they go, with code firing on every successful match and a stack standing ready to undo every side effect on failure. The grammar is alive at parse time.
The applied paper bml-search-algorithms.txt names the three-tech split that holds the system together. Each technology owns one altitude:
Source · BMF.bml header
Here is the actual top of BMF-grammar.bml from the 2000 archive — the file that defines the BMF grammar in BML:
{`// Name: BMF.bml
// Author: Urs C. Muff
// Date: 11-Apr-2000
// Platform: BML Virtual Machine
// Compiler: JBMF (R) Compiler
package BMF;
import BMF.primitive.*;
class BMF [public] : Application {
const String DefaultBMFSyntax = "BMF.library.BMF";
section [class, public] {
String m_strDefaultConfigFile = "BMF.cfg";
String m_strConfigFile = m_strDefaultConfigFile;
}
section [class, public] {
bool m_bDebug = true;
}
section [public] {
void Main( String[] hArgs ) { HandleArgs( hArgs ); }
}
}`}
class BMF [public]: Application — BMF is a class in BML, inheriting from Application. section [class, public] is Smalltalk-style category-pane visibility expressed as BML syntax. The compiler that compiled this file is named in the header: JBMF (R) — the Java port. The system was already self-bootstrapped at the moment this comment was typed.
Sample · BML grammar in BMF
BMF is BNF augmented with execution. The notation reads like EBNF with a few specific moves that matter:
::= rule definition · | branch (OR-list, tried in order, backtracked){... } zero-or-more · [... ] optional · < 'a'..'z' > character classitem \\ separator separator-list (same as item { separator item })$tag:Element tag a sub-element so action code can lift it by nameRule( arg1, arg2 )::=... template rule — arguments bound at call-site, resolved at parse-timeWith those moves, here is a fragment of BML's own grammar written in BMF — the same notation the parser is reading while parsing it. These rules are pulled directly from the 2000 thesis ( backtracking-model-languages.txt ):
{`// BML grammar fragment, written in BMF
// (Backtracking Model Form — the same form parsing this file)
Number ::= < '0'..'9' > [ '.' < '0'..'9' > ];
Identifier ::= < 'a'..'z' | 'A'..'Z' | '_' >
{ < 'a'..'z' | 'A'..'Z' | '_' | '0'..'9' > };
Expression ::= Term { ( "-" | "+" ) Term };
Term ::= "(" Expression ")" | Number | Identifier;
// template rule — argument-passing, anticipating ANTLR
List( item, separator ) ::= item { separator item };
Other ::= List( Identifier, "," );
// BML's own control flow, in BMF
If ::= "if" "(" Expression ")" $then:Statement
[ "else" $else:Statement ];
Select ::= LabelDecl "select" "(" Expression ")" SwitchBlock;
SwitchBlock ::= "{"
{ ( "case" CaseExpr \\\\ "," ":" | "default" ":" )
Statement }
"}";
CaseExpr ::= Expression [ ".." Expression ];
For ::= LabelDecl "for" "(" [ Expression ] ";"
[ Expression ] ";"
[ Expression ] ")" Statement;
// the backtracking statement — BMF's own discipline,
// expressed in the language it parses
Choice ::= "choice" CodeBlock \\\\ ",";
// binary types — read raw bytes with the same grammar machine
BinaryType ::= "binary" Identifier "["
"size" "=" int ","
"mapping" "=" ( "signed" | "unsigned"
| "float" | "double" | "no" )
"]";`}
Read If closely: the two Statement occurrences carry tags $then and $else. When the rule matches, the action code attached to If can ask the parse stack for the entry tagged $then and get the then-branch's already-built object — no positional indexing, no second pass over the tree. The parse tree decorates itself as it grows.
Read Choice closely: BML's backtracking statement is "choice" CodeBlock \\ "," — a comma-separated list of code blocks. The grammar of the language carries the same backtracking discipline as the grammar engine that parses it. The parser, the assembly ( BMCPU ), and the language all unwind the same way.
The full self-description lives at companion/source-samples/BMF-grammar.bml — the BMF compiler driver, written in BML, compiled by JBMF, parsing files described by grammars written in BMF. Three layers of self-bootstrap, all visible in one file.
BMF rules are not pure recognizers. Each rule's right-hand side carries action code that fires on a match. Expressions on the parse stack are tagged so an action can lift the value of any subexpression by name. When a rule fails mid-way through — say, the third alternative of a choose block doesn't match — the runtime walks back through every tagged stack entry and undoes the side effects each action introduced, then tries the next alternative.
The same shape recurs three times in the system. At the parser level it's grammar backtracking. At the BMA ( BMCPU ) level it's the DO/ UNDO mode flag — every assembly instruction has a forward and a reverse semantics. At the language level ( BML ) it's choose / Cut / Fail / MultiMatch. The unwinding pattern threads through every layer.
Naming the BNF play
The acronym is a deliberate pun. BMF reads publicly as Backtracking Model Form; reads privately, in the team, as Bjorg-Muff Form, with the same cadence as BNF (Backus-Naur Form). Backus and Naur described grammars that machines could parse; Bjorg and Muff described grammars that machines could parse and execute and undo. Same prefix, one octave up.