# B Content Markup Validation Grammar

Overview: Mathematical Markup Language (MathML) Version 2.0 (Second Edition)
Previous: A Parsing MathML
Next: C Content Element Definitions
B Content Markup Validation Grammar

This presents an informal EBNF grammar that can be used to validate the structure of Content Markup.

J

- It defines the valid expression trees in content markup. It does not define the rules for attribute validation. That must be done separately.
- The non-terminal Presentation_tags is a placeholder for a valid presentation element start tag or end tag.
- The string `#PCDATA` denotes XML parsed character data.
- Symbols beginning with '_' (for example _mmlarg) are internal symbols. A recursive grammar is usually required for their recognition.
- Symbols which are all in lowercase symbols (for example 'ci') are terminal symbols representing MathML content elements.
- Symbols beginning with Uppercase letters are terminals representating other tokens.

J

##### whitespace definitions including Presentation_tags

[1] | `Presentation_tags` | ::= | `"presentation"` | /* placeholder */
[2] | `Space` | ::= | `#x09 | #x0A | #x0D | #x20` | /* tab, lf, cr, space characters */
[3] | `S` | ::= | `(Space | Presentation_tags")*` | /* treat presentation as space */

##### Characters, only for content validation characters

[4] | `Char` | ::= | `#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]` | /* valid XML chars */

- 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 and end tag functions

[5] | `_start(\%x)` | ::= | `"<\%x" (Char - '>')* ">"` | /* returns a valid start tag for the element \%x */
[6] | `_end(\%x)` | ::= | `"<\%x" Space* ">"` | /* returns a valid end tag for the element \%x */
[7] | `_empty(\%x)` | ::= | `"<\%x" (Char - '>')* "/>"` | /* returns a valid empty tag for the element \%x */
[8] | `_sg(\%x)` | ::= | `S _start(\%x)` | /* start tag preceded by optional whitespace */
[9] | `_eg(\%x)` | ::= | `_end(\%x) S` | /* end tag followed by optional whitespace */
[10] | `_ey(\%x)` | ::= | `S _empty(\%x) S` | /* empty tag preceded and followed by optional whitespace */

##### semantics, annotation, etc.

[11] | `semantics` | ::= | `_sg(semantics) _mmlarg _annot* _eg(semantics)`
|  |  | `_sg(semantics) _mmlarg _annot* _eg(semantics)`
[12] | `annotation` | ::= | `_sg(annotation) #PCDATA _eg(annotation)`
[13] | `annotation-xml` | ::= | `_sg(annotation-xml) _ANY _eg(annotation-xml)`
[14] | `_ANY` | ::= | `"AnyXML"` | /* placeholder for wellformed XML Fragment (not Mixed Content) */
[15] | `_annot` | ::= | `annotation | annotation-xml`

J

##### mathml content constructs

[15a] | `_mmlall` | ::= | `_container | _relation | _operator | _qualifier | _other`
[16] | `_mmlarg` | ::= | `_container`
|  |  | `_container | _token | _operator | _relation`
[17] | `_container` | ::= | `_token | _special | _constructor`
|  |  | `_special | _constructor`
[18] | `_token` | ::= | `ci | cn | csymbol | _constantsym`
[19] | `_special` | ::= | `apply | lambda | reln | fn | semantics`
[20] | `_constructor` | ::= | `interval | list | matrix | matrixrow | set | vector | piecewise | piece | otherwise`
[20a] | `_other` | ::= | `condition | declare | sep`
[21] | `_qualifier` | ::= | `lowlimit | uplimit | bvar | degree | logbase | domainofapplication | momentabout`
|  |  | `lowlimit | uplimit | degree | logbase | domainofapplication | momentabout | condition` | /* interval is both a qualifier and a constructor */
[22] | `_constantsym` | ::= | `integers | rationals | reals | naturalnumbers | complexes | primes | exponentiale | imaginaryi | notanumber | true | false | pi | eulergamma | infinity`

##### relations

[23] | `_relation` | ::= | `_genrel | _setrel | _seqrel2ary`
[24] | `_genrel` | ::= | `_genrel2ary | _genrelnary`
[25] | `_genrel2ary` | ::= | `ne`
[26] | `_genrelnary` | ::= | `eq | leq | lt | geq | gt`
[27] | `_setrel` | ::= | `_seqrel2ary | _setrelnary`
[28] | `_setrel2ary` | ::= | `in | notin | notsubset | notprsubset`
[29] | `_setrelnary` | ::= | `subset | prsubset`
[30] | `_seqrel2ary` | ::= | `tendsto`

##### operators

[31] | `_operator` | ::= | `_funcop | _arithop | _calcop | _vcalcop | _seqop | _trigop | _classop | _statop | _lalgop | _logicop | _setop`

##### functional operators

[32] | `_funcop` | ::= | `_funcop1ary | _funcopnary`
[33] | `_funcop1ary` | ::= | `inverse | ident | domain | codomain | image`
[34] | `_funcopnary` | ::= | `fn| compose` | /* general user-defined function is n-ary */

(note `minus` is both 1ary and 2ary)

##### arithmetic operators

[35] | `_arithop` | ::= | `_arithop1ary | _arithop2ary | _arithopnary | root`
[36] | `_arithop1ary` | ::= | `abs | conjugate | factorial | minus | arg | real | imaginary | floor | ceiling`
[37] | `_arithop2ary` | ::= | `quotient | divide | minus | power | rem`
[38] | `_arithopnary` | ::= | `plus | times | max | min | gcd | lcm`

##### calculus and vector calculus

[39] | `_calcop` | ::= | `int | diff | partialdiff`
[40] | `_vcalcop` | ::= | `divergence | grad | curl | laplacian`

##### sequences and series

[41] | `_seqop` | ::= | `sum | product | limit`

##### elementary classical functions and trigonometry

[42] | `_classop` | ::= | `exp | ln | log`
[43] | `_trigop` | ::= | `sin | cos | tan | sec | csc | cot | sinh | cosh | tanh | sech | csch | coth | arcsin | arccos | arctan`

##### statistics operators

[44] | `_statop` | ::= | `_statopnary | moment`
[45] | `_statopnary` | ::= | `mean | sdev | variance | median | mode`

##### linear algebra operators

[46] | `_lalgop` | ::= | `_lalgop1ary |_lalgop2ary | _lalgopnary`
[47] | `_lalgop1ary` | ::= | `determinant | transpose`
[48] | `_lalgop2ary` | ::= | `vectorproduct | scalarproduct | outerproduct`
[49] | `_lalgopnary` | ::= | `selector`

##### logical operators

[50] | `_logicop` | ::= | `_logicop1ary | _logicopnary | _logicop2ary | _logicopquant`
[51] | `_logicop1ary` | ::= | `not`
[52] | `_logicop2ary` | ::= | `implies | equivalent | approx | factorof`
[53] | `_logicopnary` | ::= | `and | or | xor`
[54] | `_logicopquant` | ::= | `forall | exists`

##### set theoretic operators

[55] | `_setop` | ::= | `_setop1ary |_setop2ary | _setopnary`
[56] | `_setop1ary` | ::= | `card`
[57] | `_setop2ary` | ::= | `setdiff`
[58] | `_setopnary` | ::= | `union | intersect | cartesianproduct`

##### operator groups

[59] | `_unaryop` | ::= | `_funcop1ary | _arithop1ary | _trigop | _classop | _calcop | _vcalcop | _logicop1ary | _lalgop1ary | _setop1ary`
[60] | `_binaryop` | ::= | `_arithop2ary | _setop2ary | _logicop2ary | _lalgop2ary`
[61] | `_naryop` | ::= | `_arithopnary | _statopnary | _logicopnary | _lalgopnary | _setopnary | _funcopnary`
[62] | `_specialop` | ::= | `_special | ci | csymbol`
[63] | `_ispop` | ::= | `int | sum | product`
[64] | `_diffop` | ::= | `diff | partialdiff`
[65] | `_binaryrel` | ::= | `_genrel2ary | _setrel2ary | _seqrel2ary`
[66] | `_naryrel` | ::= | `_genrelnary | _setrelnary`

##### separator

[67] | `sep` | ::= | `_ey(sep)`

##### leaf tokens and data content of leaf elements

[68] | `_mdatai` | ::= | `(#PCDATA | Presentation_tags)*` | /* note _mdata includes Presentation constructs here. */
[69] | `_mdatan` | ::= | `(#PCDATA | sep | Presentation_tags)*` | /* note _mdata includes Presentation constructs here. */
[70] | `ci` | ::= | `_sg(ci) _mdatai _eg(ci)`
[71] | `cn` | ::= | `_sg(cn) _mdatan _eg(cn)`
[72] | `csymbol` | ::= | `_sg(csymbol) _mdatai _eg(csymbol)`

`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

[73] | `condition` | ::= | `_sg(condition) reln | apply | set _eg(condition)`

##### domains for integral, sum , product, and specials

[73a] | `_ispdomain` | ::= | `(lowlimit uplimit?) | uplimit | interval | condition`
[74] | `_domainofapp` | ::= | `domainofapplication | _domainabbrev`
[75] | `_domainabbrev` | ::= | `(lowlimit uplimit?) | uplimit | interval | condition`

Note that `apply` is used in place of the deprecated `reln` in MathML2.0 for relational operators as well as arithmetic, algebraic etc.

##### apply construct

[76] | `apply` | ::= | `_sg(apply) _applybody | _relnbody _eg(apply)`
[77] | `_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 */
|  |  | `| (_naryop bvar* _domainofapp? _mmlarg)` | /* n-ary ops, over domain of application */
|  |  | `| (_specialop _mmlarg*)` | /* special ops can be applied to anything */
|  |  | `| (_specialop bvar* _domainofapp? _mmlarg)` | /* special ops, over domain of application */
|  |  | `| (_ispop bvar? _ispdomain? _mmlarg)` | /* integral, sum, product */
|  |  | `| (_ispop domainofapplication? _mmlarg)` | /* integral, sum, product */
|  |  | `| (_ispop bvar* _domainofapp? _mmlarg)` | /* integral, sum, product */
|  |  | `| (_diffop bvar* _mmlarg)` | /* differential ops */
|  |  | `| (log logbase? _mmlarg)` | /* logs */
|  |  | `| (moment degree? momentabout? _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 */
|  |  | `| (_logicopquant bvar* _domainofapp? _mmlarg)` | /* quantifier with explicit bound variables */

Equations and relations - `reln` uses lisp-like syntax (like `apply`) the `bvar` and `condition` elements are used to construct a "such that" or "where" constraint on the relation. Note that `reln` is deprecated but still valid in MathML2.0.

J

##### equations and relations

[78] | `reln` | ::= | `_sg(reln) _relnbody _eg(reln)`
[79] | `_relnbody` | ::= | `( _binaryrel bvar* condition? _mmlarg _mmlarg ) | ( _naryrel bvar* condition? _mmlarg* )`

##### fn construct Note that fn is deprecated but still valid in MathML2.0

[80] | `fn` | ::= | `_sg(fn) _fnbody _eg(fn)`
[81] | `_fnbody` | ::= | `Presentation_tags | _container`
|  |  | `Presentation_tags | _mmlarg`

##### `lambda` construct - note at least 1 bvar must be presentJ

[82] | `lambda` | ::= | `_sg(lambda) _lambdabody _eg(lambda)`
[83] | `_lambdabody` | ::= | `bvar+ _container`
|  |  | `bvar* _domainofapp? _mmlarg` | /* multivariate lambda calculus */

##### `declare` construct

[84] | `declare` | ::= | `_sg(declare) _declarebody _eg(declare)`
[85] | `_declarebody` | ::= | `ci (fn | constructor)?`

##### constructors

[86] | `interval` | ::= | `_sg(interval) _mmlarg _mmlarg _eg(interval)` | /* start, end define interval */
[87] | `set` | ::= | `_sg(set) _lsbody _eg(set)`
[88] | `list` | ::= | `_sg(list) _lsbody _eg(list)`
[89] | `_lsbody` | ::= | `_mmlarg*` | /* enumerated arguments */
|  |  | `| (bvar* condition _mmlarg)` | /* enumerated arguments */
|  |  | `| (bvar* _domainofapp _mmlarg)` | /* generated arguments */
[90] | `matrix` | ::= | `_sg(matrix) matrixrow* _eg(matrix)`
|  |  | `| _sg(matrix) bvar* _domainofapp? _mmlarg _eg(matrix)` | /* vectors over domain of application */
[91] | `matrixrow` | ::= | `_sg(matrixrow) _mmlarg* _eg(matrixrow)` | /* allows matrix of operators */
[92] | `vector` | ::= | `_sg(vector) _mmlarg* _eg(vector)`
|  |  | `| _sg(vector) bvar* _domainofapp? _mmlarg _eg(vector)` | /* vectors over domain of application */
[93] | `piecewise` | ::= | `_sg(piecewise) piece+ otherwise? _eg(piecewise)`
|  |  | `_sg(piecewise) piece* otherwise? _eg(piecewise)`
[94] | `piece` | ::= | `_sg(piece) _mmlall _mmlall _eg(piece)`
|  |  | `_sg(piece) _mmlarg _mmlarg _eg(piece)` | /* used by piecewise */
[95] | `otherwise` | ::= | `_sg(otherwise) _mmlarg _eg(otherwise)` | /* used by piecewise */

##### bound variables

[96] | `_cisemantics` | ::= | `_sg(semantics) _citoken _annot* _eg(semantics)`
[97] | `_citoken` | ::= | `ci | _cisemantics`
[98] | `bvar` | ::= | `_sg(bvar) _citoken degree? _eg(bvar)`
[99] | `degree` | ::= | `_sg(degree) _mmlarg _eg(degree)`

##### other qualifiers - note the contained _mmlarg could be a `reln`

[100] | `lowlimit` | ::= | `_sg(lowlimit) _mmlarg _eg(lowlimit)`
[101] | `uplimit` | ::= | `_sg(uplimit) _mmlarg _eg(uplimit)`
[102] | `logbase` | ::= | `_sg(logbase) _mmlarg _eg(logbase)`
[103] | `domainofapplication` | ::= | `_sg(domainofapplication) _mmlarg _eg(domainofapplication)`
[104] | `momentabout` | ::= | `_sg(momentabout) _mmlarg _eg(momentabout)`

##### relations and operators and constant symbols (one declaration for each operator and relation element)

[104a] | `_relation` | ::= | `_ey(\%relation2)` | /* for example <eq/> <lt/> */
[104b] | `_operator` | ::= | `_ey(\%operator)` | /* for example <exp/> <times/> */
[104c] | `_const-symbol` | ::= | `_ey(\%const-symbol)` | /* for example <integers/> <false/> */

J

The top level `math` element. Allow `declare` only at the head of a `math` element.

##### math

[105] | `math` | ::= | `_sg(math) declare* _mmlarg* _eg(math)`

Overview: Mathematical Markup Language (MathML) Version 2.0 (Second Edition)
Previous: A Parsing MathML
Next: C Content Element Definitions