DMNTK | Decision Model and Notation Toolkit
dmntk-feel-grammar
FEEL grammar and parsing tables generator:
- Definition of the grammar for
FEEL
language in the format acceptable byBison
parser generator. - LALR parsing tables generator for
Rust
language.
Overview
Excerpt from Decision Model and Notation™ specification, ver. 1.3, pp. 105-179:
"DMN 1.3 defines the friendly enough expression language (FEEL) for the purpose of giving standard executable semantics to many kinds of expressions in decision model. [...] FEEL syntax is defined as a grammar here [...]".
dmntk-feel-grammar crate defines the Bison
version of the full FEEL
grammar
as defined in clause 10.3 of cited above Decision Model and Notation™ specification.
In addition, dmntk-feel-grammar crate provides functionality of generating LALR parsing tables
and reduce actions, right to be used by LALR
parser written in Rust.
Such parser that uses the output from dmntk-feel-grammar crate
is implemented here: dmntk-feel-parser.
To Do List
- Verify if all rules are implemented
- Prepare overview diagram (input->box->output)
- Add example with usage in build.rs
- Implement a feature to install and run this crate as a binary
- Add example with usage as a binary.
- Describe the concept how the parsing tables are generated and extracted, and why this way
- Describe the alternative approach how to achieve the same and why we have chosen this way
- Add
Bison
installation instruction - Are there any other requirements to run this crate?
Grammar rules
The following grammar rules are taken from Decision Model and Notation™ ver. 1.3
-
expression =
- a. boxed_expression |
- b. textual_expression ;
-
textual_expression =
- a. for_expression | if_expression | quantified_expression |
- b. disjunction |
- c. conjunction |
- d. comparison |
- e. arithmetic_expression |
- f. instance_of |
- g. path_expression | filter_expression | function_invocation |
- h. literal | simple_positive_unary_test | name |
(
, expression ,)
;
-
textual_expressions = textual expression , {
,
, textual_expression } ; -
arithmetic_expression =
- a. addition | subtraction |
- b. multiplication | division |
- c. exponentiation |
- d. arithmetic_negation ;
-
simple_expression = arithmetic_expression | simple_value ;
-
simple_expressions = simple_expression , {
,
, simple_expression } ; -
simple_positive_unary_test =
- a. [
<
|<=
|>
|>=
] , endpoint | - b. interval ;
- a. [
-
interval = ( open_interval_start | closed_interval_start ) , endpoint ,
..
, endpoint , ( open_interval_end | closed_interval_end ) ; -
open_interval_start =
(
|]
; -
closed_interval_start =
[
; -
open_interval_end =
)
|[
; -
closed_interval_end =
]
; -
positive_unary_test = expression ;
-
positive_unary_tests = positive_unary_test , {
,
, positive_unary_test } ; -
unary_tests =
- a. positive_unary_tests |
- b.
not
,(
, positive_unary_tests,)
| - c.
-
;
-
endpoint = simple_value ;
-
simple_value = qualified_name | simple_literal ;
-
qualified_name = name , {
.
, name } ; -
addition = expression ,
+
, expression ; -
subtraction = expression ,
-
, expression ; -
multiplication = expression ,
*
, expression ; -
division = expression ,
/
, expression ; -
exponentiation = expression,
**
, expression ; -
arithmetic_negation =
-
, expression ; -
name = name_start , { name_part | additional_name_symbols } ;
-
name_start = name_start_char, { name_part_char } ;
-
name_part = name_part_char , { name_part_char } ;
-
name_start_char =
?
|[A-Z]
|_
|[a-z]
|[\uC0-\uD6]
|[\uD8-\uF6]
|[\uF8-\u2FF]
|[\u370-\u37D]
|[\u37F-\u1FFF]
|[\u200C-\u200D]
|[\u2070-\u218F]
|[\u2C00-\u2FEF]
|[\u3001-\uD7FF]
|[\uF900-\uFDCF]
|[\uFDF0-\uFFFD]
|[\u10000-\uEFFFF]
; -
name_part_char = name_start_char | digit |
\uB7
|[\u0300-\u036F]
|[\u203F-\u2040]
; -
additional_name_symbols =
.
|/
|-
|’
|+
|*
; -
literal = simple_literal |
null
; -
simple_literal = numeric_literal | string_literal | boolean_literal | date_time_literal ;
-
string_literal =
"
, { character – ("
| vertical_space) | string_escape_sequence},"
; -
boolean_literal =
true
|false
; -
numeric_literal = [
-
] , ( digits , [.
, digits ] |.
, digits ) ; -
digit = [0-9] ;
-
digits = digit , { digit } ;
-
function_invocation = expression , parameters ;
-
parameters =
(
, ( named_parameters | positional_parameters ) ,)
; -
named_parameters = parameter_name ,
:
, expression , {,
, parameter name ,:
, expression } ; -
parameter_name = name ;
-
positional_parameters = [ expression , {
,
, expression } ] ; -
path_expression = expression ,
.
, name ; -
for_expression =
for
, name ,in
, iteration context {,
, name ,in
, iteration context } ,return
, expression ; -
if_expression =
if
, expression ,then
, expression ,else
expression ; -
quantified_expression = (
some
|every
) , name ,in
, expression , {,
, name ,in
, expression } ,satisfies
, expression ; -
disjunction = expression ,
or
, expression ; -
conjunction = expression ,
and
, expression ; -
comparison =
- a. expression , (
=
|!=
|<
|<=
|>
|>=
) , expression | - b. expression ,
between
, expression ,and
, expression | - c. expression ,
in
, positive_unary_test | - d. expression ,
in
,(
, positive unary tests,)
;
- a. expression , (
-
filter_expression = expression ,
[
, expression ,]
; -
instance_of = expression ,
instance
,of
, type ; -
type =
- a. qualified_name |
- b.
list
<
type>
| - c.
context
<
name:
type {,
name:
type }>
| - d.
function
<
[ type {,
type } ]>
->
type ;
-
boxed_expression = list | function_definition | context ;
-
list =
[
, [ expression , {,
, expression } ] ,]
; -
function_definition =
function
,(
, [ formal_parameter {,
, formal parameter } ] ,)
, [external
] , expression ; -
formal_parameter = parameter_name [
:
type ] ; -
context =
{
, [context_entry , {,
, context_entry } ] ,}
; -
context_entry = key ,
:
, expression ; -
key = name | string_literal ;
-
date_time_literal = at_literal | function_invocation ;
-
white_space = vertical_space |
\u0009
|\u0020
|\u0085
|\u00A0
|\u1680
|\u180E
|[\u2000-\u200B]
|\u2028
|\u2029
|\u202F
|\u205F
|\u3000
|\uFEFF
; -
vertical_space =
[\u000A-\u000D]
; -
iteration_context = expression, [
..
, expression ] ; -
string_escape_sequence =
\'
|\"
|\\
|\n
|\r
|\t
| code_point; -
at_literal =
@
, string_literal
License
dmntk-feel-grammar is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
See LICENSE-APACHE and LICENSE-MIT for details.