Appendix

BNF Syntax

This is the full grammar of the LSP language.

identifier
    : simple_identifier
    | contextual_keyword

contextual_keyword
    : 'pragma'
    | 'as'
    | 'from'
    | 'extends'
    ;

expression
    : ternary_expression
    | lambda_expression
    | table_expression
    ;

expression_no_range
    : ternary_expression_no_range
    | lambda_expression
    | table_expression
    ;

ternary_expression_no_range
    : or_expression_no_range
    | or_expression_no_range
        '?'ternary_expression_no_range
        ':'ternary_expression_no_range
    ;

or_expression_no_range
    : and_expression_no_range
    | or_expression_no_range '||' and_expression_no_range
    ;

and_expression_no_range
    : equality_expression_no_range
    | and_expression_no_range '&&' equality_expression_no_range
    ;

equality_expression_no_range
    : relational_expression_no_range
    | equality_expression_no_range '==' relational_expression_no_range
    | equality_expression_no_range '!=' relational_expression_no_range
    ;

relational_expression_no_range
    : additive_expression
    | relational_expression_no_range 'is' additive_expression
    | relational_expression_no_range 'is' 'nil'
    | relational_expression_no_range 'is' 'bool'
    | relational_expression_no_range 'is' 'int'
    | relational_expression_no_range 'is' 'double'
    | relational_expression_no_range '<' additive_expression
    | relational_expression_no_range '>' additive_expression
    | relational_expression_no_range '<=' additive_expression
    | relational_expression_no_range '>=' additive_expression
    ;

ternary_expression
    : or_expression
    | or_expression
        '?' ternary_expression
        ':' ternary_expression
    ;

or_expression
    : and_expression
    | or_expression '||' and_expression
    ;

and_expression
    : equality_expression
    | and_expression '&&' equality_expression
    ;

equality_expression
    : relational_expression
    | equality_expression '==' relational_expression
    | equality_expression '!=' relational_expression
    ;

relational_expression
    : range_expression
    | relational_expression 'is' range_expression
    | relational_expression 'is' 'nil'
    | relational_expression 'is' 'bool'
    | relational_expression 'is' 'int'
    | relational_expression 'is' 'double'
    | relational_expression '<' range_expression
    | relational_expression '>' range_expression
    | relational_expression '<=' range_expression
    | relational_expression '>=' range_expression
    ;

range_expression
    : additive_expression
    | additive_expression '..' additive_expression
    | additive_expression '...' additive_expression
    ;

additive_expression
    : multiplicative_expression
    | additive_expression '+' multiplicative_expression
    | additive_expression '-' multiplicative_expression
    ;

multiplicative_expression
    : unary_expression
    | multiplicative_expression '*' unary_expression
    | multiplicative_expression '/' unary_expression
    | multiplicative_expression '%' unary_expression
    ;

unary_expression
    : function_call_expression
    | new_expression
    | '+' unary_expression
    | '-' unary_expression
    | '!' unary_expression
    | 'typeof' unary_expression
    ;

new_expression
    : 'new' member_array_expression arguments
    ;

function_call_expression
    : primary_expression
    | super_expression
    | function_call_expression '[' expression ']'
    | function_call_expression '.' identifier
    | function_call
    ;

member_array_expression
    : primary_expression
    | super_expression
    | member_array_expression '[' expression ']'
    | member_array_expression '.' identifier
    ;

super_expression
    : 'super' '.' identifier
    ;

primary_expression
    : assignment_identifier
    | 'true'
    | 'false'
    | 'nan'
    | 'inf'
    | 'nil'
    | string
    | integer
    | double
    | '(' expression ')'
    ;

lambda_expression
    : identifier '=>' block_statement
    | function_arguments_declaration '=>' block_statement
    |  identifier '=>' lambda_body_expression
    | function_arguments_declaration '=>' lambda_body_expression
    | 'function' function_arguments_declaration block_statement
    ;

lambda_body_expression
    : ternary_expression
    | lambda_expression
    ;

table_expression
    : '{' '}'
    | '{' table_list '}'
    ;

table_list
    : expression
    | table_key '=' expression
    | table_key ':' expression
    | table_list ',' expression
    | table_list ',' table_key '=' expression
    | table_list ',' table_key ':' expression
    ;

table_key
    : string
    | identifier
    | integer
    | '-' integer
    ;

function_call
    : function_call_expression arguments
    | function_call_expression variadic_arguments
    ;

arguments
    : '(' ')'
    | '(' function_argument_list ')'
    ;

variadic_arguments
    : variadic_compositor_list '(' function_variadic_list ')'
    ;

function_argument_list
    : expression
    | function_argument_list ',' expression
    ;

function_variadic_list
    : expression
    | function_variadic_list ',' expression
    ;

variadic_compositor_list
    : '[' filter_iterator ']'
    | variadic_compositor_list '[' filter_iterator ']'
    ;

filter_iterator
    : identifier 'in' expression ':' expression
    | identifier ',' identifier 'in' expression ':' expression
    | identifier 'in' expression
    | identifier ',' identifier 'in' expression
    ;

range_iterator
    : additive_expression '..' additive_expression
    | additive_expression '...' additive_expression
    ;

statement
    : block_statement
    | assignment_statement
    | local_assignment_statement
    | local_statement
    | if_else_statement
    | for_statement
    | while_statement
    | dowhile_statement
    | continue_statement
    | break_statement
    | modifier_statement
    | throw_statement
    | trycatch_statement
    | with_statement
    | function_call_statement
    | new_statement
    | return_statement
    | super_constructor_statement
    | ';'
    ;

block_statement
    : '{' '}'
    | '{' statement_list '}'
    ;

statement_list
    : statement
    | statement_list statement
    ;

assignment_statement
    : identifier assignment_operator expression ';'
    | assignment_identifier assignment_compositor_list assignment_operator expression ';'
    ;

assignment_identifier
    : identifier
    | 'this'
    ;

assignment_operator
    : '='
    | '<-'
    | '+='
    | '-='
    | '/='
    | '*='
    | '%='
    ;

assignment_compositor_list
    : assignment_compositor
    | assignment_compositor_list assignment_compositor
    ;

assignment_compositor
    : '[' filter_iterator ']'
    | '[' range_iterator ']'
    | '[' expression_no_range ']'
    | '.' identifier
    ;

local_assignment_statement
    : 'local' identifier local_assignment_operator expression ';'
    | 'local' assignment_identifier assignment_compositor_list local_assignment_operator expression ';'
    ;

local_assignment_operator
    : '='
    | '<-'
    ;

local_statement
    : 'local' identifier ';'
    ;

if_else_statement
    : if_condition statement
    | if_condition statement statement
    ;

if_condition
    : 'if' '(' expression ')'
    ;

for_statement
    : 'for' for_compositor_list statement
    ;

for_compositor_list
    : '[' filter_iterator ']'
    | for_compositor_list '[' filter_iterator ']'
    ;

while_statement
    : 'while' '(' expression ')' statement
    ;

dowhile_statement
    : 'do' statement 'while' '(' expression ')' ';'
    ;

continue_statement
    : 'continue' ';'
    ;

break_statement
    : 'break' ';'
    ;

modifier_statement
    : modifier expression ';'
    ;

modifier
    : 'minimize'
    | 'maximize'
    | 'constraint'
    ;

throw_statement
    : 'throw' expression ';'
    | 'throw' ';'
    ;

trycatch_statement
    : 'try' statement 'catch' '(' identifier ')' statement
    ;

with_statement
    : 'with' '(' with_resource ')' statement
    ;

with_resource
    : identifier
    | identifier '=' expression

function_call_statement
    : function_call ';'
    ;

new_statement
    : new_expression ';'

return_statement
    : 'return' ';'
    | 'return' expression ';'
    ;

super_constructor_statement
    : 'super' arguments ';'
    ;

declaration_list
    : function_declaration
    | class_declaration
    | declaration_list function_declaration
    | declaration_list class_declaration
    ;

function_declaration
    : 'function' identifier function_arguments_declaration block_statement
    ;

function_arguments_declaration
    : '(' ')'
    | '(' function_identifier_list ')'
    ;

function_identifier_list
    : identifier
    | function_identifier_list ',' identifier
    ;

class_declaration
    : class_header '{' '}'
    | class_header '{' class_member_list '}'
    ;

class_header
    : 'class' identifier
    | 'class' identifier 'extends compound_name
    | 'final' 'class' identifier
    | 'final' 'class' identifier 'extends compound_name
    ;

class_member_list
    : class_member_list class_member
    | class_member
    ;

class_member
    : class_constructor
    | class_method
    | class_field
    | class_static_function
    | class_static_field
    ;

class_constructor
    : 'constructor' function_arguments_declaration block_statement
    ;

class_method
    : 'override' identifier function_arguments_declaration block_statement
    | identifier function_arguments_declaration block_statement
    ;

class_field
    : identifier';'
    | identifier '=' expression ';'
    ;

class_static_function
    : 'static' identifier function_arguments_declaration block_statement
    ;

class_static_field
    : 'static' identifier';'
    | 'static' identifier '=' expression ';'
    ;

pragma_list
    : pragma_statement
    | pragma_list pragma_statement
    ;

pragma_statement
    : 'pragma' simple_identifier ';'
    | 'pragma' simple_identifier simple_identifier ';'
    | 'pragma' simple_identifier integer ';'
    | 'pragma' simple_identifier double ';'
    ;

use_list
    : use_statement
    | use_list use_statement
    ;

use_statement
    : TOKEN_USE simple_identifier ';'
    | TOKEN_USE compound_name 'as' simple_identifier ';'
    | TOKEN_USE import_list 'from' compound_name ';'
    ;

import_list
    : simple_identifier
    | simple_identifier 'as' simple_identifier
    | import_list ',' simple_identifier
    | import_list ',' simple_identifier 'as' simple_identifier
    ;

compound_name
    : compound_name_part

compound_name_part
    : simple_identifier
    | compound_name_part '.' simple_identifier
    ;

header_section
    : pragma_list
    | pragma_list use_list
    | use_list
    ;

program
    : <EOF>
    | declaration_list <EOF>
    | header_section <EOF>
    | header_section declaration_list <EOF>
    ;