LocalSolver logo
is now
Hexaly logo

We're excited to share that we are moving forward. We're leaving behind the LocalSolver brand and transitioning to our new identity: Hexaly. This represents a leap forward in our mission to enable every organization to make better decisions faster when faced with operational and strategic challenges.


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>
    ;