//hide all:
TinyBNF ::=	#ignore(JAVA) [classDeclaration]* #empty
	=> { traceLine("this file has been parsed successfully"); };
classDeclaration ::=
	IDENT:"class"
	IDENT:sName
	=> insert project.listOfClasses[sName].name = sName;
	[
		':'
		IDENT:sParent
		=> {
			if !findElement(sParent, project.listOfClasses)
				error("class '" + sParent + "' should have been declared before");
			ref project.listOfClasses[sName].parent = project.listOfClasses[sParent];
		}
	]?
	classBody(project.listOfClasses[sName]);
//show:
classBody(myClass : node) ::=
	'{' [attributeDeclaration(myClass)]* '}';
attributeDeclaration(myClass : node) ::=
//note: the name of the class for the association is assigned to the local variable \samp{sName},
	IDENT:sClass
//note: we'll need a local variable to point to the attribute's node for commodity,
	=> local myAttribute;
	=> {
//note: the local variable \samp{myAttribute} hasn't been declared here, because it disappears
//note: at the end of the scope (the trailing brace); a new node is added to the list of
//note: attributes,
		pushItem myClass.listOfAttributes;
//note: the local variable \samp{myAttribute} points to the last item of the list,
		ref myAttribute = myClass.listOfAttributes#back;
//note: the class specifier of the association must have been declared,
		if !findElement(sClass, project.listOfClasses)
			error("class '" + sClass + "' should have been declared before");
//note: we populate the parse tree as done by hand,
		ref myAttribute.class = project.listOfClasses[sClass];
	}
//note: this attribute \textit{isArray} is added only if the type of the association is an array,
	['[' ']' => insert myAttribute.isArray = true;]?
//note: we complete the attribute description by assigning its name,
	IDENT:sName => {insert myAttribute.name = sName;};

IDENT ::= #!ignore ['a'..'z'|'A'..'Z']+;
