Appendix

BNF Syntax

This is the full grammar of the LSP language. For sake of simplicity, operator priorities do not figure in this document as well as the techniques used to solve the remaining ambiguities (dandling else, ...).

expression
    : arithm_expression
    | table_expression
    | range_expression
    ;

arithm_expression
    : primary_expression
    | lambda_expression
    | arithm_expression '||' arithm_expression
    | arithm_expression '&&' arithm_expression
    | arithm_expression '==' arithm_expression
    | arithm_expression '!=' arithm_expression
    | arithm_expression 'is' arithm_expression
    | arithm_expression 'is' 'nil'
    | arithm_expression 'is' 'int'
    | arithm_expression 'is' 'double'
    | arithm_expression '<' arithm_expression
    | arithm_expression '>' arithm_expression
    | arithm_expression '<=' arithm_expression
    | arithm_expression '>=' arithm_expression
    | arithm_expression '+' arithm_expression
    | arithm_expression '-' arithm_expression
    | arithm_expression '*' arithm_expression
    | arithm_expression '/' arithm_expression
    | arithm_expression '%' arithm_expression
    | arithm_expression '?' arithm_expression ':' arithm_expression
    | '+' arithm_expression
    | '-' arithm_expression
    | '!' arithm_expression
    | 'typeof' arithm_expression
    ;

primary_expression
    : identifier
    | 'true'
    | 'false'
    | 'nan'
    | 'inf'
    | 'nil'
    | string
    | integer
    | double
    | primary_expression '[' expression ']'
    | primary_expression '.' identifier
    | function_call
    | '(' expression ')'
    ;

lambda_expression
    : identifier '=>' block_statement
    | '(' function_identifier_list ')' '=>' block_statement
    | '(' ')' '=>' block_statement
    |  identifier '=>' arithm_expression
    | '(' function_identifier_list ')' '=>' arithm_expression
    | '(' ')' '=>' arithm_expression
    | 'function' '(' function_identifier_list ')' block_statement
    | 'function' '(' ')' block_statement
    ;

range_expression
    : arithm_expression '..' arithm_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
    : primary_expression '(' ')'
    | primary_expression '(' function_argument_list ')'
    | primary_expression variadic_compositor_list '(' function_argument_list ')'
    ;

function_argument_list
    : expression
    | function_argument_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
    ;

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
    | function_call_statement
    | return_statement
    | ';'
    ;

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

statement_list
    : statement
    | statement_list statement
    ;

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

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

assignment_compositor_list
    : assignment_compositor
    | assignment_compositor_list assignment_compositor
    ;

assignment_compositor
    : '[' filter_iterator ']'
    | '[' arithm_expression ']'
    | '[' range_expression ']'
    | '.' identifier
    ;

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

local_assignment_operator
    : '='
    | '<-'
    ;

local_statement
    : 'local' identifier ';'
    ;

if_else_statement
    : 'if' '(' expression ')'
    | 'if' '(' expression ')' 'else' statement
    ;

for_statement
    : 'for' for_compositor_list statement
    ;

for_compositor_list
    : for_compositor
    | for_compositor_list for_compositor
    ;

for_compositor
    : '[' filter_iterator ']'
    | '[' range_expression ']'
    ;

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
    ;

function_call_statement
    : function_call ';'
    ;

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

function_list
    : function
    | function_list function
    ;

function
    : 'function' identifier '(' function_identifier_list ')' block_statement
    | 'function' identifier '(' ')' block_statement
    ;

function_identifier_list
    : identifier
    | function_identifier_list ',' identifier
    ;

use_section
    : use_statement
    | use_section use_statement
    ;

use_statement
    :  identifier ';'
    ;

start
    : TOKEN_END
    | function_list TOKEN_END
    | use_section TOKEN_END
    | use_section function_list TOKEN_END
    ;