stored_definition:
	[ within [ name ] ";" ]
	{ [ final ] class_definition ";" }

class_definition :
	[ encapsulated ]
	[ partial ]
	( class | model | record | block | connector | type | package | function ) class_specifier

class_specifier :
IDENT string_comment composition end IDENT
| IDENT "=" base_prefix name [ array_subscripts ]
[ class_modification ] comment
| IDENT "=" enumeration "(" ( [enum_list] | ":" ) ")" comment
| extends IDENT [ class_modification ] string_comment composition
end IDENT

base_prefix : type_prefix

enum_list : enumeration_literal { "," enumeration_literal}

enumeration_literal : IDENT comment

composition :
element_list
{ public element_list |
protected element_list |
equation_clause |
algorithm_clause
}
[ external [ language_specification ]
[ external_function_call ] [ annotation ";" ]
[ annotation ";" ] ]

language_specification : STRING

external_function_call :
[ component_reference "=" ]
IDENT "(" [ expression { "," expression } ] ")"

element_list :
{ element ";" | annotation ";" }
element :
import_clause |
extends_clause |
[ redeclare ]
[ final ]
[ inner | outer ]
( ( class_definition | component_clause) |
replaceable ( class_definition | component_clause)
[constraining_clause comment])

import_clause :
import ( IDENT "=" name | name ["." "*"] ) comment

extends_clause :
extends name [ class_modification ] [annotation]

constraining_clause :
extends name [ class_modification ]

component_clause:
type_prefix type_specifier [ array_subscripts ] component_list

type_prefix :
[ flow ]
[ discrete | parameter | constant ] [ input | output ]

type_specifier :
name

component_list :
component_declaration { "," component_declaration }

component_declaration :
declaration comment

declaration :
IDENT [ array_subscripts ] [ modification ]

modification :
class_modification [ "=" expression ]
| "=" expression
| ":=" expression

class_modification :
"(" [ argument_list ] ")"

argument_list :
argument { "," argument }

argument :
element_modification
| element_redeclaration

element_modification :
[ each ] [ final ] component_reference [ modification ] string_comment
element_redeclaration :
redeclare [ each ] [ final ]
( ( class_definition | component_clause1) |
replaceable ( class_definition | component_clause1)
[constraining_clause])

component_clause1 :
type_prefix type_specifier component_declaration

equation_clause :
[ initial ] equation { equation ";" | annotation ";" }

algorithm_clause :
[ initial ] algorithm { algorithm ";" | annotation ";" }

equation :
( simple_expression "=" expression
| conditional_equation_e
| for_clause_e
| connect_clause
| when_clause_e
| IDENT function_call )
comment

algorithm :
( component_reference ( ":=" expression | function_call )
| "(" output_expression_list ")" ":=" component_reference function_call
| break
| return
| conditional_equation_a
| for_clause_a
| while_clause
| when_clause_a )
comment

conditional_equation_e :
if expression then
{ equation ";" }
{ elseif expression then
{ equation ";" }
}
[ else
{ equation ";" }
]
end if

conditional_equation_a :
if expression then
{ algorithm ";" }
{ elseif expression then
{ algorithm ";" }
}
[ else
{ algorithm ";" }
]
end if

for_clause_e :
for for_indices loop
{ equation ";" }
end for

for_clause_a :
for for_indices loop
{ algorithm ";" }
end for

for_indices :
for_index {"," for_index}

for_index:
IDENT [ in expression ]

while_clause :
while expression loop
{ algorithm ";" }
end while

when_clause_e :
when expression then
{ equation ";" }
{ elsewhen expression then
{ equation ";" } }
end when

when_clause_a :
when expression then
{ algorithm ";" }
{ elsewhen expression then
{ algorithm ";" } }
end when

connect_clause :
connect "(" component_reference "," component_reference ")"

expression :
simple_expression
| if expression then expression { elseif expression then expression } else
expression

simple_expression :
logical_expression [ ":" logical_expression [ ":" logical_expression ] ]

logical_expression :
logical_term { or logical_term }

logical_term :
logical_factor { and logical_factor }

logical_factor :
[ not ] relation

relation :
arithmetic_expression [ rel_op arithmetic_expression ]

rel_op :
"<" | "<=" | ">" | ">=" | "==" | "<>"

arithmetic_expression :
[ add_op ] term { add_op term }

add_op :
"+" | "-"

term :
factor { mul_op factor }

mul_op :
"*" | "/"

factor :
primary [ "^" primary ]

primary :
UNSIGNED_NUMBER
| STRING
| false
| true
| component_reference [ function_call ]
| "(" output_expression_list ")"
| "[" expression_list { ";" expression_list } "]"
| "{" function_arguments "}"
| end

name :
IDENT [ "." name ]

component_reference :
IDENT [ array_subscripts ] [ "." component_reference ]

function_call :
"(" [ function_arguments ] ")"

function_arguments :
expression [ "," function_arguments | for for_indices ]
| named_arguments

named_arguments: named_argument [ "," named_arguments ]

named_argument: IDENT "=" expression

output_expression_list:
[ expression ] { "," [ expression ] }

expression_list :
expression { "," expression }

array_subscripts :
"[" subscript { "," subscript } "]"

subscript :
":" | expression

comment :
string_comment [ annotation ]

string_comment :
[ STRING { "+" STRING } ]

annotation :
annotation class_modification