Content Markup Validation Grammar
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 '_' eg. _mmlarg are internal symbols
// (recursive grammar usually required for recognition)
//
// all-lowercase symbols eg. '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 | var | median | mode
// linear algebra operators
_lalgop ::= _lalgop1ary | _lalgopnary
_lalgop1ary ::= determinant | transpose
_lalgopnary ::= select
// 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) //eg. <eq/> <lt/>
_operator ::= _ey(%operator) //eg. <exp/> <times/>
//the top level math element
math ::= _sg(math) mmlall* _eg(math)
Up: Table of Contents