Top-down template grammars and bottom-up template grammars can contain symbol class expressions. A symbol class expression defines a named terminal symbol class or named nonterminal symbol class. See Classes, for how to specify named terminal symbol classes as part of inclusive terminal symbol classes or exclusive terminal symbol classes.
Note: only bottom-up template grammars support nonterminal symbol classes. See Nonterminal Symbol Classes, for more information.
A symbol class expression has the format
:NAME: = EXPRESSION ;
where NAME is the name of a symbol class to define, and EXPRESSION specifies the content of the symbol class. NAME is a sequence of English letters, digits, and the characters ‘_’ starting with an English letter or ‘_’.
For terminal symbol classes, EXPRESSION can be:
:all: = . ;
:single: = [ "zero" ] ; :multiple: = [ "one" "two" "three" $$ ] ; :vnont: = [ :c0: :c1: :c2: "_ER" ] ;
:vterm: = [^ :vnont: ] ;
:any: = :all: ;
For nonterminal symbol classes, EXPRESSION can be:
:Level1: = [ L1_0 L1_1 L1_2 L1_3 :W: ] ;
:LevelLast: = :Level3: ;
EXPRESSION can be a set theory operation on symbol classes, where ‘(’ … ‘)’ enclose subexpressions:
Example 1
:selected_a: = [ "aa" "bb" "cc" "dd" ] ; :selected_b: = [ "ff" "ee" "dd" "cc" ] ; :selected_c: = [ "cc" "ee" "dd" ] ; :common: = :selected_a: & :selected_b: & :selected_c: ;The terminal symbol class
:common:is[ "cc" "dd" ].Example 2
AA: ... ; BB: ... ; CC: ... ; DD: ... ; EE: ... ; FF: ... ; :SelectedA: = [ AA BB CC DD ] ; :SelectedB: = [ FF EE DD CC ] ; :SelectedC: = [ CC EE DD ] ; :Common: = :SelectedA: & :SelectedB: & :SelectedC: ;The nonterminal symbol class
:Common:is[ CC DD ].
:expected: = ( :selected_a: | :selected_b: ) & :allowed: ;
This notation is equivalent to:
:expected: = [ :selected_a: :selected_b: ] & :allowed: ;
Example
:all_vterm: = [ $$ "aa" "bb" "cc" ] ; :no_eos: = :all_vterm: - [ $$ ] ;The terminal symbol class
:no_eos:is[ "aa" "bb" "cc" ].
Example
:left: = [ "aa" "bb" "cc" ] ; :right: = [ "ab" "cc" "aa" "dd" ] ; :unique: = :left: ^ :right: ;The terminal symbol class
:unique:is[ "ab" "bb" "dd" ].
For terminal symbol classes, EXPRESSION can contain the operator ‘~’ denoting a complement:
:other: = ~( :selected_a: | :selected_b: ) ;
This notation is equivalent to:
:other: = [^ :selected_a: :selected_b: ] ;
If EXPRESSION references named symbol classes, a grammar must contain their definitions earlier in its text. If EXPRESSION references nonterminal symbols (in nonterminal symbol classes), a grammar can contain their definitions anywhere in its text.
To define a named nonterminal symbol class as a deep copy of a nonterminal symbol class expression, use the operator ‘=*=’ instead of ‘=’:
:NonterminalSymbolClassName: =*= NonterminalSymbolClassExpression ;
The operator ‘=*=’ creates a deep copy of each nonterminal symbol of a nonterminal symbol class specified by NonterminalSymbolClassExpression. See Cloning Nonterminal Symbols, for details on the deep copying process. New nonterminal symbols have unique names to distinguish them from source nonterminal symbols. A named nonterminal symbol class NonterminalSymbolClassName consists of the new nonterminal symbols.