module Identifiers {
	//ALSO not ready for formatting, investigate

	
	group module_parameters{
		//module parameters - done
		//TREE => ModuleDef->ModuleParDef->ModulePar->Type
		//											->ModuleParList->Identifier | ConstExpression
		//								 ->MultitypedModuleParList->ModulePar*
		//				   				 
		modulepar u_1 mp_1, mp_2;
		modulepar integer mp_3, mp_4, mp_5 := 1, mp_6;
		modulepar {
			u_1 mp_7 :=1, mp_8;
			integer mp_9;
		}
		modulepar{
		}
	}

	
	//=======================================//
	
	group signatures{
		//signature definitions - done
		//TREE => ModuleDef->SignatureDef->Identifier
		signature s_1 ();
	}	

	group templates{
		//template definitions - done ?
		//TREE => ModuleDef->TemplateDef->TemplateRestriction ?
		//								->BaseTemplate->Type | Signature
		//											  ->Identifier
		template integer pt_1 := 1;

		template u_1 ut_1 := {
			field1 := pt_1 
		} 

		template u_1 ut_2 modifies ut_1 := {
			field1 :=2
		} 

		template u_1 put_1 (integer p_1) := {
			field1 := p_1 
		} 

		template u_1 put_1 (u_1 p_1) := { //repeated identifier
			field1 := p_1 
		} 
	
		template (omit) u_1 oput_1 (u_1 p_1) := {
			field1 := p_1 
		} 
		
//		template (value)
		
//		template (present)
	
	
	}

	
	group types{
		//type definitions
			
		group structured{
			//structured - done
			//ports - done
			//TREE => ModuleDef->TypeDef->StructuredTypeDef->PortDef->Identifier
			type port p_1 message{
				inout subtype_1
			}
		
			//components - done - identical to ports
			//TREE => ModuleDef->TypeDef->StructuredTypeDef->ComponentDef->Identifier
			type component comp_1 {
				var subtype_1 localDef_1;
				//...
			}
			type component comp_2 extends comp_1 {
				var subtype_1 localDef_2;
				//...
			}
		
			//enum - done
			//TREE => ModuleDef->TypeDef->StructuredTypeDef->EnumDef->Identifier | address
			
			type enumerated address {A,B};
			
			type enumerated subtype_1 {X, y, Z};
		
		
			//unions - done - similar to sets and records
			//TREE => ModuleDef->TypeDef->StructuredTypeDef->UnionDef->UnionDefBody->Identifier | address
			type union address {subtype_1 field_1}
			
			type union u_1{
				subtype_1 field_1	
			}	
	
			group sets_and_records{	
				//records - done
				//TREE => ModuleDef->TypeDef->StructuredTypeDef->RecordDef->StructDefBody->Identifier | address
				type record address {}
				
				type record r_1{
					subtype_1 field_1	
				}	
			
				//sets - done - identical to records
				//TREE => ModuleDef->TypeDef->StructuredTypeDef->SetDef->StructDefBody->Identifier | address
				type set address {}
				
				type set s_1{
					subtype_1 field_1	
				}	
				
				//record of - done
				//TREE => ModuleDef->TypeDef->StructuredTypeDef->RecordOfDef->StringLength ?
				//															->StructOfDefBody->(Type | NestedTypeDef)->Identifier | address
				type record of subtype_1 address (a,b) //=> this should be legit generates errors though 
				type record of subtype_1 ro_1
			
				type record length(2) of subtype_1 address (a,b) 
				type record length(2..4) of subtype_1 ro_2
				
				//with nested types
				type record of record{subtype_1 field_1} address (a,b) 
				type record of record{subtype_1 field_1} ron_1
			
				type record length(2) of record{subtype_1 field_1}  address (a,b) 
				type record length(2..4) of record{subtype_1 field_1}  ro_2
				
				
				//set of - done - identical to record of 
				//TREE => ModuleDef->TypeDef->StructuredTypeDef->SetOfDef->StringLength ?
				//  													 ->StructOfDefBody->(Type | NestedTypeDef)->Identifier | address
				type set of subtype_1 address (a,b) 
				type set of subtype_1 ro_1
			
				type set length(2) of subtype_1 address (a,b) 
				type set length(2..4) of subtype_1 ro_2
				
				//with nested types
				type set of set{subtype_1 field_1} address (a,b) 
				type set of record{subtype_1 field_1} ron_1
			
				type set length(2) of record{subtype_1 field_1}  address (a,b) 
				type set length(2..4) of set{subtype_1 field_1}  ro_2
				
			}
		}
		group subtyped{
			//subtyped - done
			//TREE => ModuleDef->TypeDef->SubTypeDef->Type
			//										->Identifier | address
			
			type integer subtype_a;
			
			type subtype_a subtype_b;
				
			type integer subtype_1 (1..10);
			
			type subtype_1 subtype_2 (4..8);
			
			type integer address (A .. D);
			
			type subtype_1 address (X, y, Z);
			
			type integer subtype_3[3] (1..10);
			
			type subtype_1 subtype_4[4] (4..8);
			
			type integer address[2] (A .. D);
			
			type subtype_1 address[2] (X, y, Z);
	
		}
	}
	
	group constants{
		//constant definitions - done
		//TREE => ModuleDefinition->ConstDef->Type
		//								    ->SingleConstDef->Identifier
		const subtype_1 c_1 := x;
		const subtype_2 c_2 := y,c_3 := z;
	}
	
	group functions{	
		//function definitions - done
		//TREE => ModuleDefinition->FunctionDef->Identifier
	
		function f_1 () runs on comp_1 {
			var subtype_1 localDef_1;
			//...
		}
	
		function f_2 (subtype_1 fp_1, subtype_2 fp_2) runs on comp_1 {
			var subtype_1 localDef_1;
			//...
		}
	}
	
	group testcases{
		//testcase definitions - done
		//TREE => ModuleDefinition->TestcaseDef->Identifier
	
		testcase tc_1 () runs on comp_1 system sys_1 {
			var subtype_1 localDef_1;
			//...
		}
	
		testcase tc_2 (subtype_1 fp_1, subtype_2 fp_2) runs on comp_1 system sys_1 {
			var subtype_1 localDef_1;
			//...
		}
	}
	
	group altsteps{
		//altstep definitions - done
		//TREE => ModuleDefinition->AltstepDef->Identifier
		
		altstep as_1 () runs on comp_1{
		 	var subtype_1 localDef_1;
		 	//...
		}
	
		altstep as_2 (type_1 fp_1, type_2 fp_2) runs on comp_1{
		 	var subtype_1 localDef_1;
		 	//...
		}
	}
		
	//=======================================//

	//group definitions - done
	////TREE => ModuleDefinition->GroupDef->Identifier
	group g_1 {
		group g_2{
		
		}
	}
	
	//=======================================//

	group externals{
		//external constant definitions - done
		//TREE => ModuleDefinition->ExtConstDef->Type
		//									   ->Identifier+
		external const subtype_1 cx_1;
		external const type_2 cx_2, cx_3;
	
		//external function definitions - done
		//TREE => ModuleDefinition->ExtFunctionDef->Identifier
		external function fx_1 ();
		external function fx_2 (type_1 fp_1, type_2 fp_2) return type_3;
	}
}