Appendix B : VTML Grammar
%terminal{
SPECIAL_CHAR:CharacterToken DATA:DataToken STRING:StringToken
USER_KEYWORD:StringToken INTEGER:IntegerToken
# Operation keywords
VTML ATTLIST INS DEL EXTINS EXTDEL USROP
ADEL ADELEND
# Sets of attribute names:
POS LEN ITEMS ATT INCLUDES EXCLUDES
OWNER TIMESTAMP COMMENT BASE %}
# We've got, basically, external changes and internal changes. A USROP
# can be both, in theory. We require external changes first,
# specially delimited.
doc ::= '(' header ')'
(%epsilon% |
('(' ins_contents ')' ('(' ins_contents ')' )*));
header ::= VTML STRING:id
(doc_att:att '=' STRING:value)* ')' external*;
internal ::= '(' tag_contents;
tag_contents ::= ins_contents ')'
| del_contents ')'
| adel_contents ')'
| adelend_contents ')';
ins_contents ::= INS STRING:id change_attlist ')' element+ ;
del_contents ::= DEL STRING:id change_attlist ')' element+ ;
adel_contents ::= ADEL STRING:id change_attlist ')' ;
adelend_contents ::= ADELEND STRING:id ')' ;
element ::= (data | internal);
data ::= DATA:data
change_attlist ::= (change_att:att '=' STRING:value )*;
%terminal{
SPECIAL_CHAR:CharacterToken DATA:DataToken STRING:StringToken
USER_KEYWORD:StringToken INTEGER:IntegerToken
# Operation keywords
VTML ATTLIST INS DEL EXTINS EXTDEL USROP
ADEL ADELEND
# Sets of attribute names:
POS LEN ITEMS ATT INCLUDES EXCLUDES
OWNER TIMESTAMP COMMENT BASE %}
# We've got, basically, external changes and internal changes. A USROP
# can be both, in theory. We require external changes first,
# specially delimited.
doc ::= '(' header ')'
(%epsilon% |
('(' ins_contents ')' ('(' ins_contents ')' )*));
header ::= VTML STRING:id
(doc_att:att '=' STRING:value)* ')' external*;
internal ::= '(' tag_contents;
tag_contents ::= ins_contents ')'
| del_contents ')'
| adel_contents ')'
| adelend_contents ')';
ins_contents ::= INS STRING:id change_attlist ')' element+ ;
del_contents ::= DEL STRING:id change_attlist ')' element+ ;
adel_contents ::= ADEL STRING:id change_attlist ')' ;
adelend_contents ::= ADELEND STRING:id ')' ;
element ::= (data | internal);
data ::= DATA:data
change_attlist ::= (change_att:att '=' STRING:value )*;