/*
* DMNTK - Decision Model and Notation Toolkit
*
* FEEL grammar.
* Copyright 2018-2021 Dariusz Depta Engos Software <dariusz.depta@engos.software>
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
%define api.token.prefix {TOKEN_}
%define api.symbol.prefix {SYMBOL_}
%start feel
%token START_BOXED_EXPRESSION
%token START_CONTEXT
%token START_NAME
%token START_TEXTUAL_EXPRESSION
%token START_TEXTUAL_EXPRESSIONS
%token START_UNARY_TESTS
%token AT
%token NOT
%token COLON
%token COMMA
%token EVERY
%token FOR
%token LEFT_BRACE
%token NULL
%token RIGHT_ARROW
%token OF
%token LIST
%token RANGE
%token CONTEXT
%token THEN
%token FUNCTION
%token EXTERNAL
%token IF
%token RIGHT_BRACE
%token RIGHT_BRACKET
%token RIGHT_PAREN
%token RETURN
%token ELLIPSIS
%token SOME
%token NUMERIC
%token STRING
%token BOOLEAN
%precedence RETURN EXTERNAL SATISFIES
%precedence ELSE
%left OR
%left AND
%nonassoc EQ NQ LT LE GT GE
%precedence BETWEEN
%precedence BETWEEN_AND
%right IN
%left MINUS PLUS
%left MUL DIV
%precedence PREC_NEG
%left EXP
%precedence INSTANCE
%precedence NAME NAME_DATE_TIME
%precedence LEFT_PAREN LEFT_BRACKET
%precedence DOT
%precedence PREC_EXTERNAL
%%
feel:
START_BOXED_EXPRESSION boxed_expression
| START_CONTEXT context
| START_NAME NAME {/* name */}
| START_TEXTUAL_EXPRESSION textual_expression
| START_TEXTUAL_EXPRESSIONS textual_expressions
| START_UNARY_TESTS {/* unary_tests_begin */} unary_tests
;
expression:
boxed_expression
| textual_expression
;
boxed_expression:
list
| function_definition
| context
;
textual_expression:
FOR iteration_contexts RETURN expression {/* for */}
| IF expression THEN expression ELSE expression {/* if */}
| SOME quantified_expressions SATISFIES expression {/* some */}
| EVERY quantified_expressions SATISFIES expression {/* every */}
| expression BETWEEN {/* between_begin */} expression BETWEEN_AND expression {/* between */}
| expression OR expression {/* disjunction */}
| expression AND expression {/* conjunction */}
| expression EQ expression {/* comparison_eq */}
| expression NQ expression {/* comparison_nq */}
| expression LT expression {/* comparison_lt */}
| expression LE expression {/* comparison_le */}
| expression GT expression {/* comparison_gt */}
| expression GE expression {/* comparison_ge */}
| expression IN LEFT_PAREN comparison_in {/* comparison_in */}
| expression IN expression {/* comparison_in */}
| expression PLUS expression {/* addition */}
| expression MINUS expression {/* subtraction */}
| expression MUL expression {/* multiplication */}
| expression DIV expression {/* division */}
| expression EXP expression {/* exponentiation */}
| MINUS expression %prec PREC_NEG {/* negation */}
| expression INSTANCE OF type {/* instance_of */}
| expression DOT NAME {/* path */}
| expression LEFT_BRACKET expression RIGHT_BRACKET {/* filter */}
| expression LEFT_PAREN parameters
| literal
| simple_positive_unary_test
| NAME {/* name */}
| NAME_DATE_TIME {/* name_date_time */}
| LEFT_PAREN expression RIGHT_PAREN
;
textual_expressions:
textual_expression
| textual_expression COMMA textual_expressions
;
unary_tests:
MINUS {/* unary_tests_irrelevant */}
| NOT LEFT_PAREN positive_unary_tests RIGHT_PAREN {/* unary_tests_negated */}
| positive_unary_tests
;
positive_unary_tests:
expression COMMA positive_unary_tests {/* expression_list_tail */}
| expression {/* expression_list_tail */}
;
comparison_in:
expression COMMA positive_unary_tests RIGHT_PAREN {/* expression_list_tail */}
;
simple_positive_unary_test:
LT endpoint {/* comparison_unary_lt */}
| LE endpoint {/* comparison_unary_le */}
| GT endpoint {/* comparison_unary_gt */}
| GE endpoint {/* comparison_unary_ge */}
| interval
;
interval:
interval_start interval_end {/* interval */}
;
interval_start:
LEFT_PAREN endpoint ELLIPSIS {/* interval_start */}
| RIGHT_BRACKET endpoint ELLIPSIS {/* interval_start */}
| LEFT_BRACKET endpoint ELLIPSIS {/* interval_start */}
;
interval_end:
endpoint RIGHT_PAREN {/* interval_end */}
| endpoint LEFT_BRACKET {/* interval_end */}
| endpoint RIGHT_BRACKET {/* interval_end */}
;
endpoint:
simple_value
;
simple_value:
qualified_name
| simple_literal
;
literal:
simple_literal
| NULL {/* literal_null */}
;
simple_literal:
NUMERIC {/* literal_numeric */}
| STRING {/* literal_string */}
| BOOLEAN {/* literal_boolean */}
| AT STRING {/* literal_at */}
| NAME_DATE_TIME LEFT_PAREN {/* literal_date_time */} parameters
;
context:
LEFT_BRACE {/* context_begin */} context_entries {/* context_end */}
;
context_entries:
RIGHT_BRACE {/* empty_context */}
| context_entry context_entry_tail {/* context_entry_tail */}
;
context_entry:
key COLON expression {/* context_entry */}
;
context_entry_tail:
RIGHT_BRACE
| COMMA context_entry context_entry_tail {/* context_entry_tail */}
;
key:
NAME {/* key_name */}
| STRING {/* key_string */}
;
list:
LEFT_BRACKET list_items {/* list */}
;
list_items:
RIGHT_BRACKET {/* list_empty */}
| expression list_tail {/* list_tail */}
;
list_tail:
RIGHT_BRACKET
| COMMA expression list_tail {/* list_tail */}
;
parameters:
RIGHT_PAREN {/* function_invocation_no_parameters */}
| named_parameters {/* function_invocation */}
| positional_parameters {/* function_invocation */}
;
named_parameters:
named_parameter named_parameters_tail {/* named_parameters_tail */}
;
named_parameter:
NAME COLON expression {/* named_parameter */}
;
named_parameters_tail:
RIGHT_PAREN
| COMMA named_parameter named_parameters_tail {/* named_parameters_tail */}
;
positional_parameters:
expression positional_parameters_tail {/* positional_parameters_tail */}
;
positional_parameters_tail:
RIGHT_PAREN
| COMMA expression positional_parameters_tail {/* positional_parameters_tail */}
;
qualified_name:
NAME {/* name */}
| NAME DOT qualified_name
;
type:
qualified_name
| LIST {/* type_name */} LT type GT {/* list_type */}
| RANGE {/* type_name */} LT type GT {/* range_type */}
| CONTEXT LT context_type_entries
| FUNCTION {/* type_name */} LT function_type_parameters {/* type_name */} RIGHT_ARROW type {/* function_type */}
;
context_type_entries:
context_type_entry context_type_entry_tail {/* context_type_entry_tail */}
;
context_type_entry:
NAME COLON type {/* context_type_entry */}
;
context_type_entry_tail:
GT
| COMMA context_type_entry context_type_entry_tail {/* context_type_entry_tail */}
;
function_type_parameters:
GT {/* function_type_parameters_empty */}
| type function_type_parameters_tail {/* function_type_parameters_tail */}
;
function_type_parameters_tail:
GT
| {/* type_name */} COMMA type function_type_parameters_tail {/* function_type_parameters_tail */}
;
iteration_contexts:
NAME IN iteration_context
| COMMA iteration_contexts
;
iteration_context:
expression
| expression ELLIPSIS expression
;
quantified_expressions:
NAME IN expression
| COMMA NAME IN quantified_expressions
;
function_definition:
FUNCTION LEFT_PAREN formal_parameters external {/* function_definition */}
;
formal_parameters:
RIGHT_PAREN {/* function_formal_parameters_empty */}
| formal_parameter formal_parameters_tail {/* function_formal_parameters_tail */}
;
formal_parameters_tail:
RIGHT_PAREN
| COMMA formal_parameter formal_parameters_tail {/* function_formal_parameters_tail */}
;
formal_parameter:
NAME {/* type_name */} COLON type {/* function_formal_parameter_with_type */}
| NAME {/* function_formal_parameter_no_type */}
;
external:
expression %prec PREC_EXTERNAL {/* function_body */}
| EXTERNAL expression {/* function_body_external */}
;
%%