1: // Reference ETL Parser for Java
     2: // Copyright (c) 2000-2006 Constantine A Plotnikov
     3: //
     4: // Permission is hereby granted, free of charge, to any person 
     5: // obtaining a copy of this software and associated documentation 
     6: // files (the "Software"), to deal in the Software without restriction,
     7: // including without limitation the rights to use, copy, modify, merge, 
     8: // publish, distribute, sublicense, and/or sell copies of the Software, 
     9: // and to permit persons to whom the Software is furnished to do so, 
    10: // subject to the following conditions:
    11: //
    12: // The above copyright notice and this permission notice shall be 
    13: // included in all copies or substantial portions of the Software.
    14: // 
    15: // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
    16: // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
    17: // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
    18: // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
    19: // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
    20: // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
    21: // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
    22: // SOFTWARE. 
    23: doctype public "-//IDN etl.sf.net//ETL//Grammar 0.2";
    24: 
    25: /// This is a definition for the grammar language itself.
    26: /// This grammar is actually used for parsing other grammars. 
    27: /// The text of this specific grammar itself is parsed using bootstrap 
    28: /// parser, then the grammar is compiled using normal grammar compilation 
    29: /// path.
    30: ///
    31: /// The pasing model is AST bulding. The parser tries to match syntax 
    32: /// constructs and creates AST according to specified AST constructs. 
    33: /// AST assumes to contains objects and properties. So AST is directly 
    34: /// mappable to object models like JavaBeans, EMOF, MOF 1.2, and EMF.
    35: /// 
    36: /// Properties are identified by name and objects are identfied by 
    37: /// namespace URI and name. The object identification idea is borrowed from XMI
    38: /// and it is even possible to generate XMI-file without prior knowlege of 
    39: /// metamodel.
    40: ///
    41: /// There are two kinds of syntax constructs: expressions and statements.
    42: ///
    43: /// Expression model is borrowed from prolog. Operator has been borrowed from
    44: /// Prolog almost as is. Each operator has priority and associativity. 
    45: /// Associativity has format "AfA" where A can be "x" or "y", "y" matches 
    46: /// expression of the same priority and "x" matches expression of lesser 
    47: /// priority. For example yfx operator is "+" and "-" from C, x+y-z is parsed 
    48: /// as (x+y)-y. Example of  xfy operator is assingment operator from C. a=b=c 
    49: /// is parsed as a=(b=c).
    50: ///
    51: /// Note that yfy are not supported yet. You have to choose between yfx or xfy,
    52: ///
    53: /// Also "f" operators have special semantics, they appear on level 0 and 
    54: /// are primary operators. They can have neither left nor right part.
    55: ///
    56: /// Operators can be simple or composite. Simple operators have just a token 
    57: /// specified. See definition of "|" and "?" operators in this this grammar.
    58: /// Composite operators allow more complex syntax constructs. Composite 
    59: /// operators are used define primiary level of the grammar. However they can
    60: /// be used to specify non primary operators too. Java method invocation and
    61: /// array access operators are examples of this. Composite operator can use
    62: /// all syntax expressions used in statements.
    63: ///
    64: /// Statement defines content of segment returned from term paser. The statement
    65: /// is defined using generic constructs like sections, lists, and choice, and 
    66: /// and tokens.
    67: /// 
    68: /// <author>const</author>
    69: grammar net.sf.etl.grammars.Grammar {
    70: 	namespace g = "http://etl.sf.net/etl/grammar/0.2";
    71: 	
    72: 	/// This abstract context contains definition used across this grammar. 
    73: 	context abstract Base {
    74: 		
    75: 		/// String token definition
    76: 		def String {
    77: 			string(quote="\"") | string(quote='\'');
    78: 		};
    79: 
    80: 		/// Documentation mapping definition. This mapping is used 
    81: 		/// by all statements in the grammar.
    82: 		documentation Documentation {
    83: 			let documentation += doclines wrapper g:DocumentationLine.text;
    84: 		};		
    85: 
    86: 		/// Definition of object name expression. This reusable fragment
    87: 		/// is used in placess where obejct name is required.
    88: 		def ObjectNameDef {
    89: 			object g:ObjectName {
    90: 				let prefix = identifier;
    91: 				section : {
    92: 					let name = identifier;
    93: 				};
    94: 			};
    95: 		};
    96: 
    97: 		/// Definition for wrapper section fragment. 
    98: 		def WrapperDef {
    99: 			section wrapper {
   100: 				ref(WrapperObject);
   101: 			};
   102: 		};
   103: 
   104: 		/// Definition for wrapper specification fragment. Whrapper is
   105: 		/// is usually attached to tokens. When token matches, its value
   106: 		/// wrapped into specified object and property.
   107: 		def WrapperObject {
   108: 			object g:Wrapper {
   109: 				let object = ref(ObjectNameDef);
   110: 				section . {
   111: 					let property = identifier;
   112: 				};
   113: 			};
   114: 		};
   115: 	};
   116: 
   117: 
   118: 	
   119: 	/// This is base mapping syntax context. Mapping context might
   120: 	/// contain blank statements and let statements.
   121: 	context abstract BaseMappingSyntax {
   122: 		include Base;
   123: 
   124: 		/// Let statement. It is used to define mapping from syntax 
   125: 		/// to property of the object. The stamenet matches expression
   126: 		/// after "=" or "+=". All objects or values that are encountered
   127: 		/// in the property are assigned to property of top object specified 
   128: 		/// by name property.
   129: 		///
   130: 		/// The "+=" version assumes list property, the "=" version assumes 
   131: 		/// property with upper mulitplicity equal to 1.
   132: 		statement Let {
   133: 			object g:Let {
   134: 				section let {
   135: 					let name = identifier;
   136: 					let operator = token(+=) | token(=);
   137: 					let expression = expression;
   138: 				};
   139: 			};
   140: 		};
   141: 		
   142: 		/// This is blank statement. It is used to attach attributes 
   143: 		/// and documentation comments. This is may be used for example
   144: 		/// for attaching annotations after last statement.
   145: 		statement BlankStatement {
   146: 			object g:BlankSyntaxStatement {
   147: 			};
   148: 		};
   149: 	};
   150: 
   151: 	/// This is base syntax context. This context might contain object
   152: 	/// specification in additiont to let statement.
   153: 	context abstract BaseSyntax {
   154: 		include BaseMappingSyntax;
   155: 
   156: 		/// Utility definition used in different parts of the syntax
   157: 		def SequenceDef  {
   158: 			object g:Sequence {
   159: 				let syntax += block;
   160: 			};
   161: 		};
   162: 
   163: 		/// Object expression. It is used to specify context of parsing. 
   164: 		/// 
   165: 		/// The expression matches its content, and creates an context object
   166: 		/// all properties that are directly or indirectly specified in the 
   167: 		/// content will be assumed to be specified in context of this object
   168: 		/// unless new object derective is enountered.
   169: 		///
   170: 		/// It is an error to specify value or object generators inside object
   171: 		/// whithout property layer.
   172: 		composite Object(f) {
   173: 			object g:ObjectOp {
   174: 				section object {
   175: 					let name = ref(ObjectNameDef);
   176: 					let syntax = ref(SequenceDef);
   177: 				};
   178: 			};
   179: 		};
   180: 	};
   181: 
   182: 
   183: 	/// This is base syntax context. 
   184: 	context abstract BaseCompositeSyntax {
   185: 		include BaseSyntax;
   186: 		
   187: 		/// Expression statement. This statement is a container for expression.
   188: 		/// The statement has the same sematics as expression contained in it.
   189: 		statement Expression {
   190: 			object g:ExpressionStatement {
   191: 				let syntax = expression;
   192: 			};
   193: 		};
   194: 		
   195: 		
   196: 	};
   197: 
   198: 
   199: 	/// This syntax is used inside documentation statement. 
   200: 	context DocumentationSyntax {
   201: 		include BaseMappingSyntax;
   202: 		/// This is doclines expression. It matches sequence of documntation lines.
   203: 		/// <example>
   204: 		/// 	let documentation += doclines wrapper xj:DocumentationLine.text;
   205: 		/// </example>
   206: 		composite Doclines(f) {
   207: 			object g:DocLines {
   208: 				section doclines {
   209: 					let wrapper = ref(WrapperDef)?;
   210: 				};
   211: 			};
   212: 		};
   213: 	};	
   214: 
   215: 	/// This context specifies syntax for simple operations
   216: 	context SimpleOpSyntax {
   217: 		include BaseCompositeSyntax;
   218: 		
   219: 		/// This experession matches left operand in expression. It is used
   220: 		/// in let expression to specify property to which left operand 
   221: 		/// of operator should be assigned.
   222: 		composite Left(f) {
   223: 			object g:Operand {
   224: 				let position = token(left);
   225: 			};
   226: 		};
   227: 		
   228: 		/// This expersion matches right operand in expression. It is used
   229: 		/// in let expression to specify property to which right operand 
   230: 		/// of operator should be assigned.
   231: 		composite Right(f) {
   232: 			object g:Operand {
   233: 				let position = token(right);
   234: 			};
   235: 		};
   236: 	};
   237: 	
   238: 	/// This context contains definition of primitive syntax operators
   239: 	context abstract CompositeOperatorsSyntax {
   240: 		include BaseCompositeSyntax;
   241: 		
   242: 		/// Choice operator. It matches one of two alternatives.
   243: 		simple ChoiceOp(yfx,200,|) {
   244: 			object g:ChoiceOp { let options += left; let options += right; };
   245: 		};
   246: 
   247: 		/// This operaor matches empty sequence of tokens or its operand.
   248: 		simple OptionalOp(yf,100,?) {
   249: 			object g:OptionalOp { let syntax = left; };
   250: 		};
   251: 		
   252: 		/// This operaiton matches non empty sequence of specified operand.
   253: 		simple OneOrMoreOp(yf,100,+) {
   254: 			object g:OneOrMoreOp { let syntax = left; };
   255: 		};
   256: 
   257: 		/// This operation is composition of optional and one of more operators.
   258: 		/// Basicaly it is the composition of + and ? operators.
   259: 		simple ZeroOrMoreOp(yf,100,*) {
   260: 			object g:ZeroOrMoreOp { let syntax = left; };
   261: 		};
   262: 	};
   263: 	
   264: 	/// This context defines expressions that might happen in context 
   265: 	/// of modifiers expressions.
   266: 	context ModifiersSyntax {
   267: 		include BaseMappingSyntax;
   268: 
   269: 		/// This is modifier specification. It can contain optinal wrapper.
   270: 		composite Modifier(f) {
   271: 			object g:ModifierOp {
   272: 				 section modifier {
   273: 					let value = token;
   274: 					let wrapper = ref(WrapperDef)?; 
   275: 				};
   276: 			};
   277: 		};
   278: 	};
   279: 	
   280: 	// Free form composite syntax
   281: 	context CompositeSyntax {
   282: 		include CompositeOperatorsSyntax;
   283: 		import ModifiersSyntax = ModifiersSyntax;
   284: 		
   285: 
   286: 		/// Sequence statement is a simple block. Elements in this blocks are 
   287: 		/// matched sequentially. It is used to group syntax elements together.
   288: 		composite Sequence(f) {
   289: 			ref(SequenceDef);
   290: 		};
   291: 		
   292: 		/// This is a section. The section matches token specified as its name
   293: 		/// and then an expression specified as its body. The section prefix is 
   294: 		/// intended to be unique in the context where section occurs. The section
   295: 		/// token is not reported as value to parser.
   296: 		composite Section(f) {
   297: 			object g:Section {
   298: 				section section {
   299: 					let name = token;
   300: 					let syntax = ref(SequenceDef);
   301: 				};
   302: 			};
   303: 		};
   304: 
   305: 		/// Reference to definition in this context or in included context.
   306: 		/// The expression is replaced with content of original definition.
   307: 		/// Recurision is not allowed to be created using references.
   308: 		composite Ref(f) {
   309: 			object g:Ref {
   310: 				section ref {
   311: 					brackets () {
   312: 						let name = identifier;
   313: 					};
   314: 				};
   315: 			};
   316: 		};
   317: 
   318: 		/// Block reference. The statement matches block that that contains
   319: 		/// statements of the sepcified context. If no context is specified,
   320: 		/// reference to current context is assumed. Block procudes possibly
   321: 		/// empty sequence of objects. And it should happen in context of 
   322: 		/// of list property.
   323: 		composite BlockRef(f) {
   324: 			object g:BlockRef {
   325: 				 section block {
   326: 					brackets () {
   327: 						let context = identifier;
   328: 					}?;
   329: 				};
   330: 			};
   331: 		};
   332: 		
   333: 		/// This is reusable fragment used to specify expression priority
   334: 		def ExpressionPriorityDef {
   335: 			section priority {
   336: 				section = {
   337: 					let priority = integer;
   338: 				};
   339: 			};
   340: 		};
   341: 		/// Expression reference. This reference matches expression from 
   342: 		/// specified context and of specified priority. If context is ommited,
   343: 		/// current context is assumed. The expression production always 
   344: 		/// produces a single object as result if parsing is successul.
   345: 		composite ExpressionRef(f) {
   346: 			object g:ExpressionRef {
   347: 				 section expression {
   348: 					brackets () {
   349: 						{
   350: 							ref(ExpressionPriorityDef);
   351: 						} | {	
   352: 							let context = identifier;
   353: 							section , {
   354: 								ref(ExpressionPriorityDef);
   355: 							}?;
   356: 						};	
   357: 					}?;
   358: 				};
   359: 			};
   360: 		};
   361: 
   362: 
   363: 		/// This construct matches sequence sepated by the specified 
   364: 		/// separator. This construct is just a useful shorthand. The separator 
   365: 		/// can be any specific token. The expression 
   366: 		///
   367: 		/// list , { 
   368: 		///   <content>;
   369: 		/// } 
   370: 		///
   371: 		/// is equivalent to 
   372: 		///
   373: 		/// {
   374: 		///    <content>; 
   375: 		///    section , {
   376: 		///       <content>; 
   377: 		///    }*;
   378: 		/// }
   379: 		composite List(f) {
   380: 			object g:List {
   381: 				 section list {
   382: 					let separator = token;
   383: 					let syntax = ref(SequenceDef);
   384: 				};
   385: 			};
   386: 		};
   387: 
   388: 		/// this construct matches brackets and syntax enclosed in brackes.
   389: 		/// This construct is just a useful shorthand. The separator 
   390: 		/// can be any specific token. For example, the expression 
   391: 		/// brackets ( ) { 
   392: 		///   <content>;
   393: 		/// } 
   394: 		///
   395: 		/// is equivalent to 
   396: 		///
   397: 		/// section ( {
   398: 		///    <content>;
   399: 		///    section ) {};
   400: 		/// };
   401: 		composite Brackets(f) {
   402: 			object g:Brackets {
   403: 				 section brackets {
   404: 					let open = token;
   405: 					let close = token;
   406: 					let syntax = ref(SequenceDef);
   407: 				};
   408: 			};
   409: 		};
   410: 		
   411: 		/// This construct matches set of modifiers. This construct
   412: 		/// matches any number or modifiers in any order. Each modifier
   413: 		/// if matches produces its text as a value. Wrapper specified 
   414: 		/// for modifiers construct applies to all modifiers inside it
   415: 		/// unless overridden by modifier.
   416: 		composite Modifiers(f) {
   417: 			object g:Modifiers {
   418: 				 section modifiers {
   419: 					let wrapper = ref(WrapperDef)?; 
   420: 					let modifiers += block(ModifiersSyntax);
   421: 				};
   422: 			};
   423: 		};
   424: 		
   425: 		/// This contstruct matches any token or token specified in brackets.
   426: 		/// It produces a value of its text. If no token is specified, 
   427: 		/// the construct matches any significant token with exception of 
   428: 		/// documentation comment. See this grammar for numerous examples of its
   429: 		/// usage (including this definition).
   430: 		///
   431: 		/// Optional wrapper causes wrapping value produced by this expression
   432: 		/// into specified wrapper.
   433: 		composite Token(f) {
   434: 			object g:TokenOp {
   435: 				 section token {
   436: 					brackets ( ) {
   437: 						let value = token;
   438: 					}?;
   439: 				};
   440: 				let wrapper = ref(WrapperDef)?; 
   441: 			};
   442: 		};
   443: 		
   444: 		/// This operator matches string with specified quote kind.
   445: 		/// The quote must be specified. The operator produces matched text
   446: 		/// as a value.
   447: 		///
   448: 		/// Optional wrapper causes wrapping value produced by this expression
   449: 		/// into specified wrapper.
   450: 		composite StringOp(f) {
   451: 			object g:StringOp {
   452: 				 section string {
   453: 					brackets () {
   454: 						section quote {
   455: 							section = {
   456: 								let quote = ref(String);
   457: 							};
   458: 						};
   459: 					};
   460: 				};
   461: 				let wrapper = ref(WrapperDef)?; 
   462: 			};
   463: 		};
   464: 		
   465: 		/// This operator matches any identifier. The operator produces matched text
   466: 		/// as a value.
   467: 		///
   468: 		/// Optional wrapper causes wrapping value produced by this expression
   469: 		/// into specified wrapper.
   470: 		composite Identifier(f) {
   471: 			object g:IdentifierOp {
   472: 				section identifier {
   473: 				};
   474: 				let wrapper = ref(WrapperDef)?; 
   475: 			};
   476: 		};
   477: 
   478: 
   479: 		/// This operator matches integer without suffix or with specified suffix
   480: 		/// The operator produces matched text as a value.
   481: 		///
   482: 		/// Optional wrapper causes wrapping value produced by this expression
   483: 		/// into specified wrapper.
   484: 		composite Integer(f) {
   485: 			object g:IntegerOp {
   486: 				  section integer {
   487: 					brackets () {
   488: 						section suffix {
   489: 							section = {;
   490: 								let suffix = ref(String);
   491: 							};
   492: 						}?;
   493: 					}?;
   494: 					let wrapper = ref(WrapperDef)?; 
   495: 				};
   496: 			};
   497: 		};
   498: 
   499: 
   500: 		/// This operator matches float without suffix or with specified suffix.
   501: 		/// The operator produces matched text as a value.
   502: 		///
   503: 		/// Optional wrapper causes wrapping value produced by this expression
   504: 		/// into specified wrapper.
   505: 		composite Float(f) {
   506: 			object g:FloatOp {
   507: 				section float {
   508: 					brackets () {
   509: 						section suffix {
   510: 							section = {;
   511: 								let suffix = ref(String);
   512: 							};
   513: 						}?;
   514: 					}?;
   515: 				};
   516: 				let wrapper = ref(WrapperDef)?; 
   517: 			};
   518: 		};
   519: 
   520: 
   521: 		/// This operator matches any graphics token.
   522: 		/// The operator produces matched text as a value.
   523: 		///
   524: 		/// Optional wrapper causes wrapping value produced by this expression
   525: 		/// into specified wrapper.
   526: 		composite Graphics(f) {
   527: 			object g:GraphicsOp {
   528: 				section graphics {
   529: 				};
   530: 				let wrapper = ref(WrapperDef)?; 
   531: 			};
   532: 		};
   533: 
   534: 	};
   535: 	
   536: 	/// Composite operator syntax. 
   537: 	/// Note that this definition is oversimplifed. There are additional 
   538: 	/// constraint that "left" and "right" exprssion might happen only on top 
   539: 	/// level. The construct will be possibly adjusted later. 
   540: 	context CompositeOpSyntax {
   541: 		include SimpleOpSyntax;
   542: 		include CompositeSyntax;
   543: 	};
   544: 	
   545: 	/// This context defines content of context statement. So it defines itself.
   546: 	context ContextContent {
   547: 		include Base;
   548: 		import compositeOpSyntax = CompositeOpSyntax;
   549: 		import simpleOpSyntax = SimpleOpSyntax;
   550: 		import compositeSyntax = CompositeSyntax;
   551: 		import documentationSyntax = DocumentationSyntax;
   552: 
   553: 		/// This is blank statement. It is used to attach attributes 
   554: 		/// and documentation comments.
   555: 		statement BlankStatement {
   556: 			object g:BlankContextMember {
   557: 			};
   558: 		};
   559: 
   560: 
   561: 		/// Operator associativity defintiion. It matches any valid associativity.
   562: 		def OpAssociativity {
   563: 			token(f) | token(xf) | token(yf) |token(xfy) |
   564: 			token(xfx) |token(yfx) |token(fx) |token(fy);
   565: 		};
   566: 
   567: 		/// Simple operator. See grammar comment for details.
   568: 		statement SimpleOp {
   569: 			object g:SimpleOp {
   570: 				section simple {
   571: 					let name = identifier;
   572: 					brackets () {
   573: 						let associativity = ref(OpAssociativity); 
   574: 						section , {
   575: 							let priority = integer;
   576: 						};
   577: 						section , {
   578: 							let text = token;
   579: 						};
   580: 					};
   581: 					let syntax += block(simpleOpSyntax);
   582: 				};
   583: 			};
   584: 		};
   585: 
   586: 		/// Composite operator. See grammar comment for details.
   587: 		statement CompositeOp {
   588: 			object g:CompositeOp {
   589: 				section composite {
   590: 					let name = identifier;
   591: 					brackets () {
   592: 						let associativity = ref(OpAssociativity); 
   593: 						section , {
   594: 							let priority = integer;
   595: 						}?;
   596: 					};
   597: 					let syntax += block(compositeOpSyntax);
   598: 				};
   599: 			};
   600: 		};
   601: 
   602: 
   603: 		/// Attributes definition. Attributes can be applied only to
   604: 		/// statements. To apply them to expressions, define an composite
   605: 		/// operator that uses the same syntax. Such operator and attributes
   606: 		/// declaration can share syntax through def statement.
   607: 		statement Attributes {
   608: 			object g:Attributes {
   609: 				section attributes {
   610: 					let name = identifier;
   611: 					let syntax += block(compositeSyntax);
   612: 				};
   613: 			};
   614: 		};
   615: 		
   616: 		/// Statement definition. Statement attempt to match entire segment.
   617: 		/// If statement matches part of segment and there are some 
   618: 		/// unmatched significant tokens left, it is a syntax error.
   619: 		statement Statement {
   620: 			object g:Statement {
   621: 				section statement {
   622: 					let name = identifier;
   623: 					let syntax += block(compositeSyntax);
   624: 				};
   625: 			};
   626: 		};
   627: 
   628: 		/// Documentation syntax. It matches documentation comments before
   629: 		/// start of grammar. The definition is used to specify property
   630: 		/// where documentation is put.
   631: 		statement DocumentationSyntax {
   632: 			object g:DocumentationSyntax {
   633: 				section documentation {
   634: 					let name = identifier;
   635: 					let syntax += block(documentationSyntax);
   636: 					
   637: 				};
   638: 			};
   639: 		};
   640: 
   641: 		/// A fragment definition. It is used to define reusable parts of the 
   642: 		/// syntax. References to definitions are replaced with content of the 
   643: 		/// definition, so it is an error for definition to refer to itself 
   644: 		/// throgh ref construct.
   645: 		statement Def {
   646: 			object g:Def {
   647: 				section def {
   648: 					let name = identifier;
   649: 					let syntax += block(compositeSyntax);
   650: 				};
   651: 			};
   652: 		};
   653: 		
   654: 		/// Include operation cause all definitions except redefined 
   655: 		/// to be included in this context. It is an error if two definitions 
   656: 		/// are available using different paths. If wrapper chain is specified
   657: 		/// The statements will be wrapped into the specified chain.
   658: 		statement ContextInclude {
   659: 			object g:ContextInclude {
   660: 				section include {
   661: 					let contextName = identifier;
   662: 					let wrappers += section wrapper {
   663: 						list / {
   664: 							ref(WrapperObject);
   665: 						};
   666: 					}?;
   667: 				};
   668: 			};
   669: 		};
   670: 
   671: 		/// Import operation makes context referencable from this context or 
   672: 		/// allows redefinition of context reference.
   673: 		statement ContextImport {
   674: 			object g:ContextImport {
   675: 				section import {
   676: 					let localName = identifier;
   677: 					section = {
   678: 						let contextName = identifier;
   679: 						section from {
   680: 							let grammarName = identifier;
   681: 						}?;
   682: 					};
   683: 				};
   684: 			};
   685: 		};
   686: 	};
   687: 	
   688: 	/// This context defines grammar content.
   689: 	context GrammarContent {
   690: 		include Base;
   691: 		import contextContent = ContextContent;
   692: 		
   693: 		/// This definition provides way of referencing other grammars.
   694: 		def GrammarRef {
   695: 			{
   696: 				let systemId = ref(String);
   697: 				section public {
   698: 					let publicId = ref(String);
   699: 				}?;
   700: 			} | {
   701: 				section public {
   702: 					let publicId = ref(String);
   703: 				};
   704: 			};				
   705: 		};
   706: 
   707: 		/// This is blank statement. It is used to attach attributes 
   708: 		/// and documentation comments.
   709: 		statement BlankStatement {
   710: 			object g:BlankGrammarMember {
   711: 			};
   712: 		};
   713: 
   714: 		
   715: 		/// This is an include statement. Include causes all context from 
   716: 		/// included grammar to be added to current grammar. The definitions
   717: 		/// from grammar include are added only if current grammar does not 
   718: 		/// have definitions with the same name.
   719: 		///
   720: 		/// Grammar imports and context imports also follow this inclusion rule.
   721: 		/// It is an error to include two different non-shadowed definitions by
   722: 		/// different include paths.
   723: 		statement Include {
   724: 			object g:GrammarInclude {
   725: 				section include {
   726: 					ref(GrammarRef);
   727: 				};
   728: 			};
   729: 		};
   730: 
   731: 		/// This is grammar import statement. A statement allows contexts of this
   732: 		/// gramamr  to import context from specified grammar.
   733: 		statement Import {
   734: 			object g:GrammarImport {
   735: 				section import {
   736: 					let name = identifier;
   737: 					section = {
   738: 						ref(GrammarRef);
   739: 					};	
   740: 				};
   741: 			};
   742: 		};
   743: 
   744: 
   745: 		/// Namespace declaration is used to declare namespace prefix. The 
   746: 		/// prefix declaration is local to grammar.
   747: 		statement Namespace {
   748: 			object g:Namespace {
   749: 				section namespace {
   750: 					let prefix = identifier;
   751: 					section = {
   752: 						let uri = ref(String);
   753: 					};	
   754: 				};
   755: 			};
   756: 		};
   757: 
   758: 		/// Context definition. This deifnition is used to define context.
   759: 		/// Context may be default and abstract. Abstract contexts 
   760: 		/// cannot be used for parsing and are used only in context include.
   761: 		/// Abstract contexts may be imported only by abstract contexts.
   762: 		///
   763: 		/// Default context is a context that used to parse source when
   764: 		/// no context is specified in doctype. 
   765: 		statement Context {
   766: 			object g:Context {
   767: 				section context {
   768: 					modifiers wrapper g:Modifier.value {
   769: 						let abstractModifier = modifier abstract;
   770: 						let defaultModifier = modifier default;
   771: 					};
   772: 					let name = identifier;
   773: 					let content += block(contextContent);
   774: 				};
   775: 			};
   776: 		};
   777: 	};
   778: 	
   779: 	/// This context contains definition of grammar construct itself
   780: 	context default GrammarSource {
   781: 		include Base;
   782: 		import grammarContent = GrammarContent;
   783: 
   784: 		/// This is blank statement. It is used to attach attributes 
   785: 		/// and documentation comments. It is ignored during grammar
   786: 		/// compilation.
   787: 		statement BlankStatement {
   788: 			object g:BlankTopLevel {
   789: 			};
   790: 		};
   791: 
   792: 		/// Grammar statement. It defines grammar. Grammar name is purely 
   793: 		/// informative and is used in reported events to identify grammar
   794: 		/// by logical name rather by URI that happens to be current grammar
   795: 		/// location.
   796: 		///
   797: 		/// Grammar can be abstract, in that case it cannot be instantiated
   798: 		/// and referenced from doctype. It can be only included into other 
   799: 		/// grammars.
   800: 		statement Grammar {
   801: 			object g:Grammar {
   802: 				section grammar {
   803: 					modifiers wrapper g:Modifier.value {
   804: 						let abstractModifier = modifier abstract;
   805: 					};
   806: 					let name += list . {identifier;};
   807: 					let content += block(grammarContent);
   808: 				};
   809: 			};
   810: 		};
   811: 	};
   812: };