Jancy Grammar

Below you can check the full Jancy grammar for reference. This listing is auto-generated from *.llk files by Graco parser generator, and is basically the actual Jancy grammar as it is used by the Jancy compiler but with all the actions, rule attributes and rule arguments removed for readability.

lookahead = 2;

start
nullable
compilation_unit
    :   global_declaration*
    ;

global_declaration
    :   import_declaration
    |   namespace_declaration
    |   extension_declaration
    |   using_declaration
    |   friend_declaration
    |   access_declaration
    |   alignment_declaration
    |   normal_item_declaration
    |   named_type_specifier
    |   ';'
    ;

import_declaration
    :   TokenKind_Import TokenKind_Literal
    ;

namespace_declaration
    :   TokenKind_Namespace qualified_name '{' global_declaration* '}'
    ;

extension_declaration
    :   TokenKind_Extension TokenKind_Identifier ':' type_name '{' named_type_block_declaration* '}'
    ;

using_declaration
    :   TokenKind_Using using_namespace_kind qualified_name_list ';'
    ;

friend_declaration
    :   TokenKind_Friend qualified_name_list ';'
    ;

access_declaration
    :   access_specifier ':'
    ;

alignment_declaration
    :   TokenKind_Alignment '='? alignment_value ';'
    |   TokenKind_Alignment '(' alignment_value ')'
    ;

start
normal_item_declaration
    :   item_declaration_w_specifier
    |   item_declaration_wo_specifier
    ;

named_type_specifier
    :   enum_specifier
    |   struct_specifier
    |   union_specifier
    |   class_specifier
    |   library_specifier
    ;

named_type_block_declaration
    :   friend_declaration
    |   access_declaration
    |   alignment_declaration
    |   setas_declaration
    |   normal_item_declaration
    |   named_type_specifier
    |   ';'
    ;

setas_declaration
    :   TokenKind_SetAs '='? type_name ';'
    |   TokenKind_SetAs '(' type_name ')'
    ;

local_declaration
    :   statement
    |   using_declaration
    |   alignment_declaration
    |   local_item_declaration
    |   named_type_specifier
    |   catch_label
    |   finally_label
    ;

statement
    :   compound_stmt
    |   expression_stmt
    |   if_stmt
    |   switch_stmt
    |   while_stmt
    |   do_stmt
    |   for_stmt
    |   break_stmt
    |   continue_stmt
    |   return_stmt
    |   once_stmt
    |   try_stmt
    |   unsafe_stmt
    |   assert_stmt
    |   ';'
    ;

local_item_declaration
    :   item_declaration_w_specifier
    |   item_declaration_wo_specifier
    ;

catch_label
    :   TokenKind_Catch ':'
    ;

finally_label
    :   TokenKind_Finally ':'
    ;

qualified_name
    :   qualified_name_impl
    ;

type_name
    :   type_name_impl
    ;

using_namespace_kind
    :   TokenKind_Namespace
    |   TokenKind_Extension
    ;

qualified_name_list
    :   qualified_name (',' qualified_name)*
    ;

access_specifier
    :   TokenKind_Public
    |   TokenKind_Protected
    ;

alignment_value
    :   TokenKind_Integer
    |   TokenKind_Default
    ;

setas_value
    :   type_name
    |   TokenKind_Default
    ;

qualified_name_impl
    :   TokenKind_Identifier ('.' TokenKind_Identifier)*
    ;

item_declaration_w_specifier
    :   declaration_specifier_list declarator_list? declaration_terminator
    ;

item_declaration_wo_specifier_rslv
    :   declarator_name '('
    ;

item_declaration_wo_specifier
    :   declarator_prefix* declarator_name function_suffix declarator_suffix* declaration_terminator
    ;

declaration_specifier_list
    :   declaration_specifier+
    ;

declarator_list
    :   full_declarator (',' full_declarator)*
    ;

declaration_terminator
    :   ';'
    |   declaration_body_pass1
    ;

declarator_prefix
    :   '*' type_modifier*
    ;

declarator_name
    :   declarator_qualifier ('.' declarator_qualifier)*
    ;

function_suffix
    :   '(' function_formal_argument_list? ')' function_modifier*
    ;

declarator_suffix
    :   array_suffix
    |   function_suffix
    |   bitfield_suffix
    ;

declaration_body_pass1
    :   compound_stmt_pass1
    ;

compound_stmt_pass1
    :   '{' statement_pass1* '}'
    ;

statement_pass1
    :   compound_stmt_pass1
    |   TokenKind_Catch
    |   TokenKind_Finally
    |   any
    ;

type_name_impl
    :   type_specifier_modifier_list declarator_prefix* declarator_suffix*
    ;

type_specifier_modifier_list
    :   type_specifier_modifier+
    ;

type_name_list
    :   type_name (',' type_name)*
    ;

attribute_block
    :   '[' attribute_declarator_list ']'
    ;

nullable
attribute_declarator_list
    :   attribute_declarator (',' attribute_declarator)*
    ;

nullable
attribute_declarator
    :   TokenKind_Identifier ('=' expression_pass1)?
    |   epsilon
    ;

expression_pass1
    :   primary_expr_pass1+
    ;

primary_expr_pass1
    :   '{' primary_expr_pass1* '}'
    |   '[' primary_expr_pass1* ']'
    |   '(' primary_expr_pass1* ')'
    |   any
    ;

arg_list_pass1
    :   '(' arg_pass1* ')'
    ;

arg_pass1
    :   '(' arg_pass1* ')'
    |   any
    ;

start
expression_save_value
    :   expression
    ;

start
expression
    :   conditional_expr
    ;

start
nullable
expression_or_empty_list_save_list
    :   expression_or_empty_list
    ;

nullable
expression_or_empty_list
    :   expression (',' expression_or_empty)*
    |   ',' expression_or_empty (',' expression_or_empty)*
    |   epsilon
    ;

conditional_expr
    :   logical_or_expr ('?' conditional_expr ':' conditional_expr)?
    ;

nullable
expression_or_empty
    :   conditional_expr
    |   epsilon
    ;

expression_list
    :   expression (',' expression)*
    ;

start
constant_expr
    :   conditional_expr
    ;

start
constant_integer_expr
    :   expression
    ;

logical_or_expr
    :   logical_and_expr (TokenKind_LogOr logical_and_expr)*
    ;

logical_and_expr
    :   inclusive_or_expr (TokenKind_LogAnd inclusive_or_expr)*
    ;

inclusive_or_expr
    :   exclusive_or_expr ('|' exclusive_or_expr)*
    ;

exclusive_or_expr
    :   and_expr ('^' and_expr)*
    ;

and_expr
    :   equality_expr ('&' equality_expr)*
    ;

equality_expr
    :   relational_expr (equality_operator relational_expr)*
    ;

relational_expr
    :   shift_expr (relational_operator shift_expr)*
    ;

equality_operator
    :   TokenKind_Eq
    |   TokenKind_Ne
    ;

shift_expr
    :   additive_expr (shift_operator additive_expr)*
    ;

relational_operator
    :   '<'
    |   '>'
    |   TokenKind_Le
    |   TokenKind_Ge
    ;

additive_expr
    :   multiplicative_expr (additive_operator multiplicative_expr)*
    ;

shift_operator
    :   TokenKind_Shl
    |   TokenKind_Shr
    ;

multiplicative_expr
    :   at_expr (multiplicative_operator at_expr)*
    ;

additive_operator
    :   '+'
    |   '-'
    ;

at_expr
    :   assignment_expr ('@' assignment_expr)*
    ;

multiplicative_operator
    :   '*'
    |   '/'
    |   '%'
    ;

assignment_expr
    :   unary_expr assignment_operator_expr?
    ;

unary_expr
    :   postfix_expr
    |   unary_operator_expr
    ;

assignment_operator_expr
    :   assignment_operator conditional_expr
    |   '=' curly_initializer
    ;

assignment_operator
    :   '='
    |   TokenKind_RefAssign
    |   TokenKind_AddAssign
    |   TokenKind_SubAssign
    |   TokenKind_MulAssign
    |   TokenKind_DivAssign
    |   TokenKind_ModAssign
    |   TokenKind_ShlAssign
    |   TokenKind_ShrAssign
    |   TokenKind_AndAssign
    |   TokenKind_XorAssign
    |   TokenKind_OrAssign
    ;

start
curly_initializer
    :   '{' curly_initializer_item (',' curly_initializer_item)* '}'
    ;

postfix_expr
    :   primary_expr postfix_operator*
    ;

unary_operator_expr
    :   '+' unary_expr
    |   '-' unary_expr
    |   '~' unary_expr
    |   '&' unary_expr
    |   '*' unary_expr
    |   '!' unary_expr
    |   TokenKind_Inc unary_expr
    |   TokenKind_Dec unary_expr
    |   TokenKind_Try unary_expr
    |   TokenKind_Dynamic? '(' type_name ')' unary_expr
    |   TokenKind_New new_operator_type new_operator_curly_initializer?
    |   TokenKind_Delete unary_expr
    ;

cast_operator_rslv
    :   TokenKind_Dynamic? '(' type_specifier_modifier
    ;

new_operator_type
    :   type_name_impl
    |   qualified_type_name TokenKind_Construct? '(' expression_or_empty_list ')'
    ;

new_operator_curly_initializer
    :   curly_initializer
    ;

type_name_w_constructor_rslv
    :   qualified_name TokenKind_Construct? '('
    ;

qualified_type_name
    :   basetype_qualified_name
    ;

type_specifier_modifier
    :   type_specifier
    |   type_modifier
    ;

primary_expr
    :   '(' conditional_expr ')'
    |   literal
    |   TokenKind_BaseType
    |   TokenKind_Identifier
    |   TokenKind_This
    |   TokenKind_Integer
    |   TokenKind_Fp
    |   TokenKind_True
    |   TokenKind_False
    |   TokenKind_Null
    |   TokenKind_Dynamic? TokenKind_SizeOf '(' type_name_or_expr ')'
    |   TokenKind_Dynamic? TokenKind_CountOf '(' type_name_or_expr ')'
    |   TokenKind_Dynamic? TokenKind_TypeOf '(' type_name_or_expr ')'
    |   TokenKind_OffsetOf '(' expression_0 ')'
    |   TokenKind_BindingOf '(' conditional_expr ')'
    ;

postfix_operator
    :   '(' expression_or_empty_list ')'
    |   '~' '(' expression_or_empty_list ')'
    |   '[' expression_or_empty ']'
    |   TokenKind_Inc
    |   TokenKind_Dec
    |   '.' TokenKind_Weak? member_operator
    |   TokenKind_Ptr member_operator
    ;

member_operator
    :   TokenKind_Identifier
    |   TokenKind_Get
    |   TokenKind_Set
    ;

literal
    :   literal_atom+
    ;

type_name_or_expr
    :   type_name
    |   expression
    ;

start
expression_0
    :   conditional_expr_0
    ;

literal_atom
    :   TokenKind_Literal
    |   TokenKind_HexLiteral
    |   TokenKind_FmtLiteral expression TokenKind_FmtSpecifier?
    ;

nullable
curly_initializer_item
    :   TokenKind_Identifier '=' (curly_initializer | expression)
    |   expression
    |   curly_initializer
    |   epsilon
    ;

start
expression_save_value_0
    :   expression_0
    ;

conditional_expr_0
    :   logical_or_expr_0 ('?' conditional_expr_0 ':' conditional_expr_0)?
    ;

nullable
expression_or_empty_0
    :   conditional_expr_0
    |   epsilon
    ;

expression_list_0
    :   expression_0 (',' expression_0)*
    ;

nullable
expression_or_empty_list_0
    :   expression_0 (',' expression_or_empty_0)*
    |   ',' expression_or_empty_0 (',' expression_or_empty_0)*
    |   epsilon
    ;

logical_or_expr_0
    :   logical_and_expr_0 (TokenKind_LogOr logical_and_expr_0)*
    ;

logical_and_expr_0
    :   inclusive_or_expr_0 (TokenKind_LogAnd inclusive_or_expr_0)*
    ;

inclusive_or_expr_0
    :   exclusive_or_expr_0 ('|' exclusive_or_expr_0)*
    ;

exclusive_or_expr_0
    :   and_expr_0 ('^' and_expr_0)*
    ;

and_expr_0
    :   equality_expr_0 ('&' equality_expr_0)*
    ;

equality_expr_0
    :   relational_expr_0 (equality_operator relational_expr_0)*
    ;

relational_expr_0
    :   shift_expr_0 (relational_operator shift_expr_0)*
    ;

shift_expr_0
    :   additive_expr_0 (shift_operator additive_expr_0)*
    ;

additive_expr_0
    :   multiplicative_expr_0 (additive_operator multiplicative_expr_0)*
    ;

multiplicative_expr_0
    :   at_expr_0 (multiplicative_operator at_expr_0)*
    ;

at_expr_0
    :   assignment_expr_0 ('@' assignment_expr_0)*
    ;

assignment_expr_0
    :   unary_expr_0 (assignment_operator conditional_expr_0)?
    ;

unary_expr_0
    :   postfix_expr_0
    |   unary_operator_expr_0
    ;

postfix_expr_0
    :   primary_expr_0 postfix_operator_0*
    ;

unary_operator_expr_0
    :   '+' unary_expr_0
    |   '-' unary_expr_0
    |   '~' unary_expr_0
    |   '&' unary_expr_0
    |   '*' unary_expr_0
    |   '!' unary_expr_0
    |   TokenKind_Inc unary_expr_0
    |   TokenKind_Dec unary_expr_0
    |   TokenKind_Try unary_expr_0
    |   '(' type_name ')' unary_expr_0
    |   storage_specifier? TokenKind_New new_operator_sype_0
    |   TokenKind_Delete unary_expr_0
    ;

storage_specifier
    :   TokenKind_Typedef
    |   TokenKind_Alias
    |   TokenKind_Static
    |   TokenKind_Thread
    |   TokenKind_Stack
    |   TokenKind_Heap
    |   TokenKind_Abstract
    |   TokenKind_Virtual
    |   TokenKind_Override
    |   TokenKind_Mutable
    ;

new_operator_sype_0
    :   type_name
    |   qualified_type_name TokenKind_Construct? '(' expression_or_empty_list_0 ')'
    ;

primary_expr_0
    :   '(' conditional_expr_0 ')'
    |   literal_0
    |   TokenKind_BaseType
    |   TokenKind_Identifier
    |   TokenKind_This
    |   TokenKind_Integer
    |   TokenKind_Fp
    |   TokenKind_True
    |   TokenKind_False
    |   TokenKind_Null
    |   TokenKind_Dynamic? TokenKind_SizeOf '(' type_name_or_expr_0 ')'
    |   TokenKind_Dynamic? TokenKind_CountOf '(' type_name_or_expr_0 ')'
    |   TokenKind_Dynamic? TokenKind_TypeOf '(' type_name_or_expr_0 ')'
    |   TokenKind_OffsetOf '(' expression_0 ')'
    |   TokenKind_BindingOf '(' conditional_expr_0 ')'
    ;

postfix_operator_0
    :   '(' expression_or_empty_list_0 ')'
    |   '~' '(' expression_or_empty_list_0 ')'
    |   '[' expression_or_empty_0 ']'
    |   TokenKind_Inc
    |   TokenKind_Dec
    |   '.' TokenKind_Weak? member_operator_0
    |   TokenKind_Ptr member_operator_0
    ;

member_operator_0
    :   TokenKind_Identifier
    |   TokenKind_Get
    |   TokenKind_Set
    ;

literal_0
    :   literal_atom_0+
    ;

type_name_or_expr_0
    :   type_name
    |   expression_0
    ;

literal_atom_0
    :   TokenKind_Literal
    |   TokenKind_HexLiteral
    |   TokenKind_FmtLiteral expression_0 TokenKind_FmtSpecifier?
    ;

start
compound_stmt
    :   '{' local_declaration* '}'
    ;

start
automaton_compound_stmt
    :   '{' automaton_declaration* '}'
    ;

automaton_declaration
    :   TokenKind_RegExpLiteral
    |   local_declaration local_declaration*
    ;

start
constructor_compound_stmt
    :   '{' btm_construct_stmt* local_declaration* '}'
    ;

btm_construct_stmt
    :   btm_construct_name '(' expression_or_empty_list ')'
    |   TokenKind_BaseType '.' TokenKind_Construct '(' expression_or_empty_list ')'
    |   ';'
    ;

btm_construct_stmt_rslv
    :   TokenKind_Identifier '.' (TokenKind_Identifier '.')* TokenKind_Construct
    ;

btm_construct_name
    :   TokenKind_Identifier '.' (TokenKind_Identifier '.')* TokenKind_Construct
    ;

expression_stmt
    :   expression ';'
    ;

if_stmt
    :   TokenKind_If '(' expression ')' statement (TokenKind_Else statement)?
    ;

switch_stmt
    :   TokenKind_Switch '(' expression ')' '{' switch_block_stmt* '}'
    ;

while_stmt
    :   TokenKind_While '(' expression ')' statement
    ;

do_stmt
    :   TokenKind_Do statement TokenKind_While '(' expression ')' ';'
    ;

for_stmt
    :   TokenKind_For '(' (local_item_declaration | expression_or_empty_list ';') for_stmt_condition ';' expression_list? ')' statement
    ;

break_stmt
    :   TokenKind_Break ';'
    ;

continue_stmt
    :   TokenKind_Continue ';'
    ;

return_stmt
    :   TokenKind_Return expression? ';'
    ;

once_stmt
    :   storage_specifier? TokenKind_Once statement
    ;

try_stmt
    :   TokenKind_Try '{' local_declaration* '}'
    ;

unsafe_stmt
    :   TokenKind_Unsafe '{' local_declaration* '}'
    ;

assert_stmt
    :   TokenKind_Assert '(' expression_pass1 (',' expression)? ')'
    ;

switch_block_stmt
    :   TokenKind_Case constant_integer_expr ':'
    |   TokenKind_Default ':'
    |   local_declaration
    ;

nullable
for_stmt_condition
    :   expression
    |   epsilon
    ;

start
reactor_body
    :   '{' reactor_stmt reactor_stmt* '}'
    ;

reactor_stmt
    :   reactor_expression_stmt
    |   reactor_onevent_stmt
    |   ';'
    ;

reactor_expression_stmt
    :   expression_pass1 ';'
    ;

reactor_onevent_stmt
    :   TokenKind_OnEvent reactor_event_name function_suffix compound_stmt
    ;

reactor_event_name
    :   '(' expression_list ')'
    |   TokenKind_BindingOf '(' expression ')'
    |   any+
    ;

start
reactor_body_0
    :   '{' reactor_stmt_0 reactor_stmt_0* '}'
    ;

reactor_stmt_0
    :   reactor_expression_stmt_0
    |   reactor_onevent_stmt_0
    |   ';'
    ;

reactor_expression_stmt_0
    :   expression_0 ';'
    ;

reactor_onevent_stmt_0
    :   TokenKind_OnEvent reactor_event_name_0 function_suffix reactor_compound_stmt_0
    ;

reactor_event_name_0
    :   '(' expression_list_0 ')'
    |   TokenKind_BindingOf '(' expression_0 ')'
    |   any+
    ;

reactor_compound_stmt_0
    :   '{' (reactor_compound_stmt_0 | any)* '}'
    ;

declaration_specifier
    :   attribute_block
    |   storage_specifier
    |   access_specifier
    |   type_specifier
    |   type_modifier
    ;

type_specifier
    :   TokenKind_Void
    |   TokenKind_Variant
    |   TokenKind_Class
    |   TokenKind_Bool
    |   TokenKind_Int8
    |   TokenKind_Int16
    |   TokenKind_Int32
    |   TokenKind_Int64
    |   TokenKind_Int
    |   TokenKind_IntPtr
    |   TokenKind_Char
    |   TokenKind_Float
    |   TokenKind_Double
    |   TokenKind_Auto
    |   property_template_specifier
    |   qualified_type_name
    ;

type_modifier
    :   TokenKind_Unsigned
    |   TokenKind_BigEndian
    |   TokenKind_Const
    |   TokenKind_ReadOnly
    |   TokenKind_Volatile
    |   TokenKind_Weak
    |   TokenKind_Thin
    |   TokenKind_Safe
    |   TokenKind_Unsafe
    |   TokenKind_Cdecl
    |   TokenKind_Stdcall
    |   TokenKind_Thiscall
    |   TokenKind_Jnccall
    |   TokenKind_Array
    |   TokenKind_Function
    |   TokenKind_Property
    |   TokenKind_Bindable
    |   TokenKind_AutoGet
    |   TokenKind_Indexed
    |   TokenKind_Multicast
    |   TokenKind_Event
    |   TokenKind_Reactor
    |   TokenKind_Automaton
    ;

property_template_specifier
    :   TokenKind_Property named_type_block_impl
    ;

qualified_type_name_rslv
    :   basetype_qualified_name '('?
    ;

basetype_qualified_name
    :   TokenKind_BaseType
    |   TokenKind_BaseType '.' qualified_name_impl
    |   qualified_name_impl
    ;

start
named_type_block_impl
    :   '{' named_type_block_declaration* '}'
    ;

full_declarator
    :   declarator (TokenKind_Construct? arg_list_pass1)? ('=' expression_pass1)?
    ;

declarator
    :   declarator_prefix* declarator_name declarator_suffix*
    ;

declarator_qualifier
    :   TokenKind_Identifier
    |   TokenKind_Get
    |   TokenKind_Set
    |   TokenKind_Preconstruct
    |   TokenKind_Construct
    |   TokenKind_Destruct
    |   TokenKind_Static TokenKind_Construct
    |   TokenKind_Static TokenKind_Destruct
    |   TokenKind_Operator declarator_operator_qualifier
    ;

declarator_operator_qualifier
    :   '(' ')'
    |   type_name
    |   operator_name
    |   TokenKind_New
    |   TokenKind_Ellipsis
    |   TokenKind_Cdecl TokenKind_Ellipsis
    ;

operator_name
    :   '~'
    |   '!'
    |   TokenKind_Inc
    |   TokenKind_Dec
    |   TokenKind_Postfix TokenKind_Inc
    |   TokenKind_Postfix TokenKind_Dec
    |   TokenKind_Postfix? TokenKind_Ptr
    |   '+'
    |   '-'
    |   '*'
    |   '/'
    |   '%'
    |   TokenKind_Shl
    |   TokenKind_Shr
    |   '&'
    |   '^'
    |   '|'
    |   TokenKind_Eq
    |   TokenKind_Ne
    |   '<'
    |   TokenKind_Le
    |   '>'
    |   TokenKind_Ge
    |   '='
    |   TokenKind_RefAssign
    |   TokenKind_AddAssign
    |   TokenKind_SubAssign
    |   TokenKind_MulAssign
    |   TokenKind_DivAssign
    |   TokenKind_ModAssign
    |   TokenKind_ShlAssign
    |   TokenKind_ShrAssign
    |   TokenKind_AndAssign
    |   TokenKind_XorAssign
    |   TokenKind_OrAssign
    |   TokenKind_AtAssign
    |   TokenKind_LogAnd
    |   TokenKind_LogOr
    |   '[' ']'
    |   '@'
    ;

array_suffix
    :   '[' expression_pass1 ']'
    |   '[' TokenKind_Integer ']'
    |   '[' ']'
    ;

function_suffix_rslv
    :   '(' ')'
    |   '(' TokenKind_Ellipsis ')'
    |   '(' (type_specifier | type_modifier)
    ;

bitfield_suffix
    :   ':' TokenKind_Integer
    ;

function_formal_argument_list
    :   function_formal_argument (',' function_formal_argument)*
    ;

function_modifier
    :   TokenKind_Throws
    |   TokenKind_Const
    ;

function_formal_argument
    :   declaration_specifier_list declarator_prefix* declarator_name? declarator_suffix* ('=' expression_pass1)?
    |   TokenKind_Ellipsis
    ;

enum_specifier
    :   enum_modifier* TokenKind_Enum TokenKind_Identifier? (':' type_name)? enum_block
    ;

struct_specifier
    :   TokenKind_Struct TokenKind_Identifier? (':' type_name_list)? named_type_block
    ;

union_specifier
    :   TokenKind_Union TokenKind_Identifier? named_type_block
    ;

class_specifier
    :   TokenKind_Opaque? TokenKind_Class TokenKind_Identifier (':' type_name_list)? named_type_block
    ;

library_specifier
    :   TokenKind_Library TokenKind_Identifier '{' named_type_block_declaration* '}'
    ;

start
named_type_specifier_save_type
    :   named_type_specifier
    ;

enum_modifier
    :   TokenKind_Exposed
    |   TokenKind_BitFlag
    ;

enum_block
    :   '{' enum_member_list '}'
    ;

nullable
enum_member_list
    :   enum_member (',' enum_member)*
    ;

nullable
enum_member
    :   TokenKind_Identifier ('=' expression_pass1)?
    |   epsilon
    ;

named_type_block
    :   named_type_block_impl
    ;

Controllers

DS110x Family

Boards

EM1001