C. Content Markup Validation Grammar

Mathematical Markup Language (MathML) Version 2.0
B Operator Dictionary
C Content Markup Validation Grammar
D Content Element Definitions

Informal EBNF grammar for Content Markup structure validation
=============================================================
// Notes
//
// This defines the valid expression trees in content markup
//
// ** it does not define attribute validation -
// ** this has to be done on top
//
// Presentation_tags is a placeholder for a valid
// presentation element start tag or end tag
//
// #PCDATA is the XML parsed character data
//
// symbols beginning with '_' for example _mmlarg are internal symbols
// (recursive grammar usually required for recognition)
//
// all-lowercase symbols for example 'ci' are terminal symbols
// representing MathML content elements
//
// symbols beginning with Uppercase are terminals
// representating other tokens
//
// revised sb 3.nov.97, 16.nov.97 and 22.dec.1997
// revised sb 6.jan.98, 6.Feb.1998 and 4.april.1998
// whitespace  definitions  including presentation_tags
Presentation_tags ::= "presentation"        //placeholder
Space    ::= #x09 | #xoA | #xoD | #x20      //tab, lf, cr, space characters
S        ::= (Space | Presentation_tags)*   //treat presentation as space
// only for content validation
// characters
Char     ::= Space | [#x21 - #xFFFD] 
             | [#x00010000 - #x7FFFFFFFF]   //valid XML chars
// start and end tag functions
// start(\%x) returns a valid start tag for the element \%x
// end(\%x) returns a valid end tag for the element \%x
// empty(\%x) returns a valid empty tag for the element \%x
//
// start(ci)    ::= "<ci>"
// end(cn)              ::= "</cn>"
// empty(plus)  ::= "<plus/>"
//
// The reason for doing this is to avoid writing a grammar
// for all the attributes. The model below is not complete
// for all possible attribute values.
_start(\%x)      ::= "<\%x" (Char - '>')* ">"
// returns a valid start tag for the element \%x
_end(\%x)        ::= "<\%x" Space* ">"
// returns a valid end tag for the element \%x
_empty(\%x)      ::= "<\%x" (Char - '>')* "/>"
// returns a valid empty tag for the element \%x
_sg(\%x)         ::= S _start(\%x)
// start tag preceded by optional whitespace
_eg(\%x)         ::= _end(\%x) S
// end tag followed by optional whitespace
_ey(\%x)         ::= S _empty(\%x) S
// empty tag preceded and followed by optional whitespace
// mathml content constructs
// allow declare within generic argument type so we can insert it anywhere
_mmlall         ::= _container | _relation | _operator | _qualifier | _other
_mmlarg         ::= declare* _container declare*
_container      ::= _token | _special | _constructor
_token          ::= ci | cn
_special        ::= apply | lambda | reln
_constructor    ::= interval | list | matrix | matrixrow | set | vector
_other          ::= condition |  declare | sep
_qualifier      ::= lowlimit | uplimit | bvar | degree | logbase
// relations
_relation       ::= _genrel | _setrel | _seqrel2ary
_genrel         ::= _genrel2ary | _genrelnary
_genrel2ary     ::= ne
_genrelnary     ::= eq | leq | lt | geq | gt
_setrel         ::=  _seqrel2ary | _setrelnary
_setrel2ary     ::=  in | notin | notsubset | notprsubset
_setrelnary     ::= subset | prsubset
_seqrel2ary     ::= tendsto
//operators
_operator       ::= _funcop | _sepop | _arithop | _calcop
                | _seqop | _trigop | _statop | _lalgop
                | _logicop | _setop
_funcop         ::= _funcop1ary | _funcopnary
_funcop1ary     ::= inverse     | ident
_funcopnary     ::= fn| compose   // general user-defined function is n-ary
// arithmetic operators
// (note minus is both 1ary and 2ary)
_arithop        ::= _arithop1ary | _arithop2ary | _arithopnary  | root
_arithop1ary    ::= abs | conjugate | exp | factorial | minus
_arithop2ary    ::= quotient | divide | minus | power | rem
_arithopnary    ::= plus | times | max | min | gcd
// calculus
_calcop         ::= _calcop1ary | log | int | diff | partialdiff
_calcop1ary     ::= ln 
// sequences and series
_seqop          ::= sum | product | limit
// trigonometry
_trigop         ::= sin | cos | tan | sec | csc | cot | sinh 
                    | cosh | tanh | sech | csch | coth 
                    | arcsin | arccos | arctan
// statistics operators
_statop         ::= _statopnary | moment
_statopnary     ::= mean | sdev | variance | median | mode
// linear algebra operators
_lalgop         ::= _lalgop1ary | _lalgopnary
_lalgop1ary     ::= determinant | transpose
_lalgopnary     ::= selector
// logical operators
_logicop        ::= _logicop1ary | _logicopnary | _logicop2ary | _logicopquant
_logicop1ary    ::= not
_logicop2ary    ::= implies
_logicopnary    ::= and | or | xor
_logicopquant   ::= forall | exists
// set theoretic operators
_setop          ::= _setop2ary | _setopnary
_setop2ary      ::= setdiff
_setopnary      ::= union | intersect
// operator groups
_unaryop        ::=  _func1ary | _arithop1ary | _trigop | _lalgop1ary 
                     | _calcop1ary | _logicop1ary
_binaryop       ::=  _arithop2ary | _setop2ary | _logicop2ary
_naryop         ::=  _arithopnary | _statopnary  | _logicopnary 
                     | _lalgopnary | _setopnary | _funcopnary
_ispop          ::= int | sum | product
_diffop         ::= diff | partialdiff
_binaryrel      ::= _genrel2ary | _setrel2ary |  _seqrel2ary
_naryrel        ::= _genrelnary | _setrelnary
//separator
sep             ::=  _ey(sep)
// leaf tokens  and data content of leaf elements
// note _mdata includes Presentation constructs here.
_mdatai         ::= (#PCDATA | Presentation_tags)*
_mdatan         ::= (#PCDATA | sep | Presentation_tags)*
ci              ::=  _sg(ci) _mdatai _eg(ci)
cn              ::=  _sg(cn) _mdatan _eg(cn)
// condition -  constraints constraints. contains either
// a single reln (relation), or
// an apply holding a logical combination of relations, or
// a set (over which the operator should be applied)
condition       ::= _sg(condition)  reln | apply | set  _eg(condition)
// domains for integral, sum , product
_ispdomain      ::= (lowlimit  uplimit?)
                | uplimit
                | interval
                | condition
// apply construct
apply           ::= _sg(apply) _applybody _eg(apply)
_applybody      ::= ( _unaryop _mmlarg  )
//1-ary ops
                                | (_binaryop _mmlarg _mmlarg)
//2-ary ops
                                | (_naryop _mmlarg*)
//n-ary ops, enumerated arguments
                                | (_naryop bvar* condition _mmlarg)
//n-ary ops, condition defines argument list
                                | (_ispop  bvar? _ispdomain? _mmlarg)
//integral, sum, product
                                | (_diffop bvar* _mmlarg)
//differential ops
                                | (log logbase? _mmlarg)
//logs
                                | (moment degree? _mmlarg*)
//statistical moment
                                | (root degree? _mmlarg)
//radicals - default is square-root
                                | (limit bvar* lowlimit? condition? _mmlarg)
//limits
                                | (_logicopquant bvar+ condition? (reln | apply))
//quantifier with explicit bound variables
// equations and relations - reln uses lisp-like syntax (like apply)
// the bvar and condition are used to construct a "such that" or
// "where" constraint on the relation
reln            ::= _sg(reln) _relnbody _eg(reln)
_relnbody       ::= ( _binaryrel bvar* condition? _mmlarg _mmlarg )
                    | ( _naryrel bvar* condition? _mmlarg*  )
// fn construct
fn                      ::= _sg(fn) _fnbody _eg(fn)
_fnbody         ::=  Presentation_tags | container 
// lambda construct     - note at least 1 bvar must be present
lambda          ::=  _sg(lambda) _lambdabody _eg(lambda)
_lambdabody     ::=  bvar+ _container  //multivariate lambda calculus
//declare construct
declare         ::= _sg(declare) _declarebody _eg(declare)
_declarebody    ::= ci (fn | constructor)?
// constructors
interval        ::=  _sg(interval) _mmlarg _mmlarg _eg(interval)
//start, end define interval
set         ::=  _sg(set) _lsbody _eg(set)
list        ::=  _sg(list) _lsbody _eg(list)
_lsbody         ::=  _mmlarg*                  //enumerated arguments
                 | (bvar* condition _mmlarg)   //condition constructs arguments
matrix          ::= _sg(matrix) matrixrow* _eg(matrix)
matrixrow       ::= _sg(matrixrow) _mmlall* _eg(matrixrow)
//allows matrix of operators
vector          ::= _sg(vector) _mmlarg* _eg(vector)
//qualifiers - note the contained _mmlarg could be a reln
lowlimit        ::= _sg(lowlimit) _mmlarg  _eg(lowlimit)
uplimit         ::= _sg(uplimit) _mmlarg _eg(uplimit)
bvar            ::= _sg(bvar) ci degree? _eg(bvar)
degree          ::= _sg(degree) _mmlarg _eg(degree)
logbase         ::= _sg(logbase) _mmlarg _eg(logbase)
//relations and operators
// (one declaration for each operator and relation element)
_relation       ::= _ey(\%relation)         //for example <eq/>  <lt/>
_operator       ::= _ey(\%operator)         //for example <exp/> <times/>
//the top level math element
math            ::= _sg(math) mmlall* _eg(math)