Up: Table of Contents | REC-MathML-19980407

# 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