2020-03-08 02:21:55 +03:00
|
|
|
(*
|
|
|
|
This file is part of the Lawspec compiler, a specification language for tax and social benefits
|
|
|
|
computation rules.
|
|
|
|
Copyright (C) 2019 Inria, contributor: Denis Merigoux <denis.merigoux@inria.fr>
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*)
|
|
|
|
|
|
|
|
%{
|
2020-03-08 03:52:31 +03:00
|
|
|
open Ast
|
2020-04-10 13:14:16 +03:00
|
|
|
open Parse_utils
|
2020-03-08 02:21:55 +03:00
|
|
|
%}
|
|
|
|
|
|
|
|
%token EOF
|
2020-03-08 03:52:31 +03:00
|
|
|
%token<string> LAW_ARTICLE
|
|
|
|
%token<string> LAW_CODE
|
|
|
|
%token<string> LAW_TEXT
|
2020-03-08 06:28:45 +03:00
|
|
|
%token<string> CONSTRUCTOR IDENT
|
|
|
|
%token<string> END_CODE
|
2020-03-08 07:27:46 +03:00
|
|
|
%token<int> INT_LITERAL
|
2020-04-11 19:16:15 +03:00
|
|
|
%token<int * int> DECIMAL_LITERAL
|
2020-04-03 23:58:34 +03:00
|
|
|
%token BEGIN_CODE
|
|
|
|
%token COLON ALT DATA
|
|
|
|
%token OF INTEGER COLLECTION
|
|
|
|
%token RULE CONDITION DEFINED_AS
|
2020-03-08 07:12:12 +03:00
|
|
|
%token EXISTS IN SUCH THAT NOW LESSER GREATER
|
2020-04-03 23:34:11 +03:00
|
|
|
%token DOT AND OR LPAREN RPAREN OPTIONAL EQUAL
|
2020-03-08 07:27:46 +03:00
|
|
|
%token COMMA CARDINAL LESSER_EQUAL GREATER_EQUAL
|
2020-04-03 23:58:34 +03:00
|
|
|
%token ASSERTION FIXED BY YEAR
|
2020-03-08 08:06:32 +03:00
|
|
|
%token PLUS MINUS MULT DIV MATCH WITH VARIES_WITH
|
2020-04-11 19:16:15 +03:00
|
|
|
%token FOR ALL WE_HAVE INCREASING DECREASING
|
2020-04-11 22:23:52 +03:00
|
|
|
%token NOT BOOLEAN PERCENT
|
2020-04-03 23:34:11 +03:00
|
|
|
%token FIELD FILLED IFF EURO NOT_EQUAL DEFINITION
|
2020-04-03 23:58:34 +03:00
|
|
|
%token STRUCT CONTENT IF THEN DEPENDS DECLARATION
|
2020-04-11 19:16:15 +03:00
|
|
|
%token CONTEXT INCLUDES ENUM ELSE DATE SUM
|
|
|
|
%token BEGIN_METADATA END_METADATA MONEY DECIMAL
|
2020-04-03 23:34:11 +03:00
|
|
|
|
2020-03-08 02:21:55 +03:00
|
|
|
%type <Ast.source_file> source_file
|
|
|
|
|
|
|
|
%start source_file
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
2020-04-03 23:58:34 +03:00
|
|
|
typ_base:
|
2020-04-14 12:46:48 +03:00
|
|
|
| INTEGER { (Integer, mk_position $sloc) }
|
|
|
|
| BOOLEAN { (Boolean, mk_position $sloc) }
|
|
|
|
| MONEY { (Money, mk_position $sloc) }
|
|
|
|
| DECIMAL { (Decimal, mk_position $sloc) }
|
|
|
|
| DATE { (Date, mk_position $sloc) }
|
|
|
|
| c = constructor {
|
|
|
|
let (s, _) = c in
|
|
|
|
(Named s, mk_position $sloc)
|
|
|
|
}
|
|
|
|
|
|
|
|
collection_marked:
|
|
|
|
| COLLECTION { mk_position $sloc }
|
|
|
|
|
|
|
|
optional_marked:
|
|
|
|
| OPTIONAL { mk_position $sloc }
|
2020-03-08 07:01:26 +03:00
|
|
|
|
2020-04-03 23:58:34 +03:00
|
|
|
typ:
|
2020-04-14 12:46:48 +03:00
|
|
|
| collection = option(collection_marked) t = typ_base optional = option(optional_marked) {
|
|
|
|
(Data {
|
|
|
|
typ_data_collection = collection;
|
|
|
|
typ_data_optional = optional;
|
|
|
|
typ_data_base = t;
|
|
|
|
}, mk_position $sloc)
|
|
|
|
}
|
2020-03-08 07:01:26 +03:00
|
|
|
|
2020-04-10 19:46:06 +03:00
|
|
|
qident_late:
|
2020-04-14 12:46:48 +03:00
|
|
|
| ident {}
|
|
|
|
| constructor {}
|
|
|
|
| ident DOT qident_late {}
|
|
|
|
| constructor DOT qident_late {}
|
2020-04-10 19:46:06 +03:00
|
|
|
|
2020-03-08 07:01:26 +03:00
|
|
|
qident:
|
2020-04-14 12:46:48 +03:00
|
|
|
| ident {}
|
|
|
|
| ident DOT qident_late {}
|
|
|
|
| constructor DOT qident_late {}
|
2020-03-08 07:01:26 +03:00
|
|
|
|
|
|
|
primitive_expression:
|
|
|
|
| NOW {}
|
2020-04-03 23:34:11 +03:00
|
|
|
| qident {}
|
2020-04-10 19:46:06 +03:00
|
|
|
| LPAREN expression RPAREN {}
|
2020-03-08 07:01:26 +03:00
|
|
|
|
2020-03-08 08:06:32 +03:00
|
|
|
date_qualifier:
|
|
|
|
| YEAR {}
|
|
|
|
|
2020-03-08 08:30:05 +03:00
|
|
|
constructor_payload:
|
|
|
|
| OF base_expression {}
|
|
|
|
|
2020-04-11 19:16:15 +03:00
|
|
|
num_literal:
|
2020-03-08 07:27:46 +03:00
|
|
|
| INT_LITERAL {}
|
2020-04-11 19:16:15 +03:00
|
|
|
| DECIMAL_LITERAL {}
|
|
|
|
|
|
|
|
literal:
|
|
|
|
| num_literal {}
|
2020-04-11 22:23:52 +03:00
|
|
|
| num_literal PERCENT {}
|
2020-04-11 19:16:15 +03:00
|
|
|
| num_literal EURO {}
|
2020-03-08 08:06:32 +03:00
|
|
|
| INT_LITERAL date_qualifier {}
|
2020-04-14 12:46:48 +03:00
|
|
|
| constructor option(constructor_payload) {}
|
2020-03-08 07:27:46 +03:00
|
|
|
|
2020-03-08 07:01:26 +03:00
|
|
|
compare_op:
|
|
|
|
| LESSER {}
|
2020-03-08 07:27:46 +03:00
|
|
|
| LESSER_EQUAL {}
|
2020-03-08 07:12:12 +03:00
|
|
|
| GREATER {}
|
2020-03-08 07:27:46 +03:00
|
|
|
| GREATER_EQUAL {}
|
|
|
|
| EQUAL {}
|
2020-04-03 23:34:11 +03:00
|
|
|
| NOT_EQUAL {}
|
2020-03-08 07:27:46 +03:00
|
|
|
|
|
|
|
func:
|
|
|
|
| CARDINAL {}
|
2020-04-03 23:34:11 +03:00
|
|
|
| qident {}
|
2020-03-08 07:01:26 +03:00
|
|
|
|
2020-04-11 23:55:43 +03:00
|
|
|
aggregate_func:
|
|
|
|
| SUM {}
|
|
|
|
| CARDINAL {}
|
|
|
|
|
|
|
|
aggregate:
|
2020-04-14 12:46:48 +03:00
|
|
|
| aggregate_func FOR ident IN primitive_expression OF base_expression {}
|
2020-04-11 23:55:43 +03:00
|
|
|
|
2020-03-08 07:12:12 +03:00
|
|
|
base_expression:
|
2020-03-08 07:01:26 +03:00
|
|
|
| primitive_expression {}
|
2020-04-10 19:46:06 +03:00
|
|
|
| qident IN qident {}
|
2020-03-08 07:27:46 +03:00
|
|
|
| literal {}
|
2020-04-11 23:55:43 +03:00
|
|
|
| aggregate {}
|
2020-04-03 23:34:11 +03:00
|
|
|
| func OF separated_nonempty_list(COMMA, primitive_expression) {}
|
2020-04-14 12:46:48 +03:00
|
|
|
| qident WITH constructor {}
|
2020-03-08 07:12:12 +03:00
|
|
|
|
2020-03-08 08:06:32 +03:00
|
|
|
mult_op:
|
|
|
|
| MULT {}
|
|
|
|
| DIV {}
|
|
|
|
|
|
|
|
mult_expression:
|
2020-03-08 07:12:12 +03:00
|
|
|
| base_expression {}
|
2020-04-03 23:34:11 +03:00
|
|
|
| base_expression mult_op mult_expression {}
|
2020-03-08 08:06:32 +03:00
|
|
|
|
|
|
|
sum_op:
|
|
|
|
| PLUS {}
|
|
|
|
| MINUS {}
|
|
|
|
|
|
|
|
sum_expression:
|
|
|
|
| mult_expression {}
|
2020-04-03 23:34:11 +03:00
|
|
|
| mult_expression sum_op sum_expression {}
|
2020-03-08 07:12:12 +03:00
|
|
|
|
|
|
|
logical_op:
|
|
|
|
| AND {}
|
|
|
|
| OR {}
|
2020-04-03 23:34:11 +03:00
|
|
|
| IFF {}
|
2020-03-08 07:01:26 +03:00
|
|
|
|
2020-03-08 08:49:29 +03:00
|
|
|
logical_unop:
|
|
|
|
| NOT {}
|
|
|
|
|
2020-03-08 07:01:26 +03:00
|
|
|
compare_expression:
|
2020-03-08 07:12:12 +03:00
|
|
|
| sum_expression {}
|
2020-04-03 23:34:11 +03:00
|
|
|
| sum_expression compare_op compare_expression {}
|
2020-03-08 07:01:26 +03:00
|
|
|
|
2020-03-08 07:12:12 +03:00
|
|
|
logical_expression:
|
|
|
|
| compare_expression {}
|
2020-03-08 08:49:29 +03:00
|
|
|
| logical_unop compare_expression {}
|
2020-04-03 23:34:11 +03:00
|
|
|
| compare_expression logical_op logical_expression {}
|
2020-03-08 07:01:26 +03:00
|
|
|
|
2020-03-08 08:06:32 +03:00
|
|
|
optional_binding:
|
|
|
|
| {}
|
2020-04-14 12:46:48 +03:00
|
|
|
| OF ident {}
|
2020-03-08 08:49:29 +03:00
|
|
|
| OF LPAREN constructor_binding RPAREN {}
|
|
|
|
|
|
|
|
constructor_binding:
|
2020-04-14 12:46:48 +03:00
|
|
|
| constructor optional_binding {}
|
2020-03-08 08:06:32 +03:00
|
|
|
|
|
|
|
match_arm:
|
2020-03-08 08:49:29 +03:00
|
|
|
| constructor_binding COLON logical_expression {}
|
2020-03-08 08:06:32 +03:00
|
|
|
|
|
|
|
match_arms:
|
|
|
|
| ALT match_arm match_arms {}
|
|
|
|
| {}
|
|
|
|
|
2020-03-08 08:30:05 +03:00
|
|
|
forall_prefix:
|
2020-04-14 12:46:48 +03:00
|
|
|
| FOR ALL separated_nonempty_list(COMMA,ident) IN separated_nonempty_list(COMMA,qident) WE_HAVE {}
|
2020-03-08 08:30:05 +03:00
|
|
|
|
|
|
|
exists_prefix:
|
2020-04-14 12:46:48 +03:00
|
|
|
| EXISTS ident IN qident SUCH THAT {}
|
2020-03-08 08:30:05 +03:00
|
|
|
|
2020-03-08 07:01:26 +03:00
|
|
|
expression:
|
2020-03-08 08:30:05 +03:00
|
|
|
| exists_prefix expression {}
|
|
|
|
| forall_prefix expression {}
|
2020-04-10 19:46:06 +03:00
|
|
|
| MATCH primitive_expression WITH match_arms {}
|
|
|
|
| IF expression THEN expression ELSE base_expression {}
|
2020-03-08 07:12:12 +03:00
|
|
|
| logical_expression {}
|
2020-03-08 07:01:26 +03:00
|
|
|
|
|
|
|
condition:
|
2020-04-07 14:59:52 +03:00
|
|
|
| IF expression {}
|
2020-03-08 07:01:26 +03:00
|
|
|
|
2020-04-07 14:59:52 +03:00
|
|
|
condition_consequence:
|
|
|
|
| condition THEN {}
|
2020-03-08 08:30:05 +03:00
|
|
|
|
2020-04-10 13:55:18 +03:00
|
|
|
rule_parameters:
|
|
|
|
| DEPENDS definition_parameters {}
|
|
|
|
|
2020-04-03 23:34:11 +03:00
|
|
|
rule:
|
2020-04-10 19:46:06 +03:00
|
|
|
| option(rule_parameters) option(condition_consequence) option(forall_prefix) base_expression FILLED {}
|
2020-03-08 08:49:29 +03:00
|
|
|
|
2020-04-03 23:34:11 +03:00
|
|
|
definition_parameters:
|
2020-04-14 12:46:48 +03:00
|
|
|
| OF separated_nonempty_list(COMMA, ident) {}
|
2020-03-08 08:30:05 +03:00
|
|
|
|
2020-04-03 23:34:11 +03:00
|
|
|
definition:
|
2020-04-07 14:59:52 +03:00
|
|
|
| option(forall_prefix) qident option(definition_parameters) option(condition_consequence) DEFINED_AS expression {}
|
2020-03-08 06:28:45 +03:00
|
|
|
|
2020-03-08 08:06:32 +03:00
|
|
|
variation_type:
|
|
|
|
| INCREASING {}
|
|
|
|
| DECREASING {}
|
|
|
|
|
2020-04-10 19:46:06 +03:00
|
|
|
assertion_base:
|
2020-03-08 08:06:32 +03:00
|
|
|
| logical_expression {}
|
2020-04-14 12:46:48 +03:00
|
|
|
| qident FIXED BY ident {}
|
2020-04-03 23:34:11 +03:00
|
|
|
| qident VARIES_WITH base_expression option(variation_type) {}
|
2020-04-10 19:46:06 +03:00
|
|
|
|
|
|
|
assertion:
|
|
|
|
| option(condition_consequence) assertion_base {}
|
2020-03-08 08:30:05 +03:00
|
|
|
| exists_prefix assertion {}
|
|
|
|
| forall_prefix assertion {}
|
2020-03-08 08:06:32 +03:00
|
|
|
|
2020-04-03 23:34:11 +03:00
|
|
|
application_field_item:
|
2020-03-08 07:27:46 +03:00
|
|
|
| RULE option(OPTIONAL) rule {}
|
2020-04-03 23:34:11 +03:00
|
|
|
| DEFINITION option(OPTIONAL) definition {}
|
2020-04-10 19:46:06 +03:00
|
|
|
| ASSERTION assertion {}
|
2020-04-07 14:59:52 +03:00
|
|
|
| field_decl_includes {}
|
2020-03-08 06:28:45 +03:00
|
|
|
|
2020-04-14 12:46:48 +03:00
|
|
|
ident:
|
|
|
|
| i = IDENT { (i, mk_position $sloc) }
|
|
|
|
|
|
|
|
condition_pos:
|
|
|
|
| CONDITION { mk_position $sloc }
|
|
|
|
|
2020-04-03 23:58:34 +03:00
|
|
|
struct_field_base:
|
2020-04-14 12:46:48 +03:00
|
|
|
| DATA i= ident CONTENT t = typ {
|
|
|
|
(i, t)
|
|
|
|
}
|
|
|
|
| pos = condition_pos i = ident {
|
|
|
|
(i, (Condition, pos))
|
|
|
|
}
|
2020-04-03 23:58:34 +03:00
|
|
|
|
|
|
|
struct_field_func:
|
|
|
|
| DEPENDS OF typ {}
|
|
|
|
|
|
|
|
struct_field:
|
2020-04-14 12:46:48 +03:00
|
|
|
| name_and_typ = struct_field_base option(struct_field_func) {
|
|
|
|
let (name, typ) = name_and_typ in
|
|
|
|
({
|
|
|
|
struct_decl_field_name = name;
|
|
|
|
struct_decl_field_typ = typ;
|
|
|
|
}, mk_position $sloc)
|
|
|
|
}
|
2020-04-03 23:58:34 +03:00
|
|
|
|
|
|
|
field_decl_item:
|
2020-04-14 12:46:48 +03:00
|
|
|
| CONTEXT ident STRUCT constructor {}
|
2020-04-03 23:58:34 +03:00
|
|
|
|
|
|
|
field_decl_include:
|
2020-04-14 12:46:48 +03:00
|
|
|
| constructor DOT ident EQUAL constructor DOT ident option(condition) {}
|
2020-04-07 14:59:52 +03:00
|
|
|
|
|
|
|
field_decl_includes_context:
|
|
|
|
| CONTEXT nonempty_list(field_decl_include) {}
|
2020-04-03 23:58:34 +03:00
|
|
|
|
|
|
|
field_decl_includes:
|
2020-04-14 12:46:48 +03:00
|
|
|
| INCLUDES FIELD constructor option(field_decl_includes_context) {}
|
2020-04-03 23:58:34 +03:00
|
|
|
|
2020-04-10 13:55:18 +03:00
|
|
|
enum_decl_line_payload:
|
2020-04-10 19:46:06 +03:00
|
|
|
| CONTENT typ {}
|
2020-04-10 13:55:18 +03:00
|
|
|
|
|
|
|
enum_decl_line:
|
2020-04-14 12:46:48 +03:00
|
|
|
| ALT constructor option(enum_decl_line_payload) {}
|
|
|
|
|
|
|
|
constructor:
|
|
|
|
| c = CONSTRUCTOR { (c, mk_position $sloc) }
|
2020-04-10 13:55:18 +03:00
|
|
|
|
2020-03-08 06:28:45 +03:00
|
|
|
code_item:
|
2020-04-14 12:46:48 +03:00
|
|
|
| FIELD constructor COLON nonempty_list(application_field_item) {
|
|
|
|
(FieldUse (), mk_position $sloc)
|
|
|
|
}
|
|
|
|
| DECLARATION STRUCT c = constructor COLON fields = list(struct_field) {
|
|
|
|
(StructDecl {
|
|
|
|
struct_decl_name = c;
|
|
|
|
struct_decl_fields = fields;
|
|
|
|
}, mk_position $sloc)
|
|
|
|
}
|
|
|
|
| DECLARATION FIELD constructor COLON nonempty_list(field_decl_item) list(field_decl_includes) {
|
|
|
|
(FieldDecl (), mk_position $sloc)
|
|
|
|
}
|
|
|
|
| DECLARATION ENUM constructor COLON nonempty_list(enum_decl_line) {
|
|
|
|
(EnumDecl (), mk_position $sloc)
|
2020-04-14 12:01:31 +03:00
|
|
|
}
|
2020-03-08 06:28:45 +03:00
|
|
|
|
|
|
|
code:
|
2020-04-14 12:01:31 +03:00
|
|
|
| code = list(code_item) { (code, mk_position $sloc) }
|
2020-03-08 06:28:45 +03:00
|
|
|
|
2020-04-10 13:02:05 +03:00
|
|
|
metadata_block:
|
2020-04-14 12:01:31 +03:00
|
|
|
| BEGIN_CODE code_and_pos = code text = END_CODE END_METADATA {
|
|
|
|
let (code, pos) = code_and_pos in
|
|
|
|
(code, (text, pos))
|
|
|
|
}
|
2020-04-10 13:02:05 +03:00
|
|
|
|
2020-03-08 02:21:55 +03:00
|
|
|
source_file_item:
|
2020-03-08 03:52:31 +03:00
|
|
|
| title = LAW_ARTICLE { LawArticle title }
|
|
|
|
| code = LAW_CODE { LawCode code }
|
|
|
|
| text = LAW_TEXT { LawText text }
|
2020-04-14 12:01:31 +03:00
|
|
|
| BEGIN_METADATA code = metadata_block {
|
|
|
|
let (code, source_repr) = code in
|
|
|
|
MetadataBlock (code, source_repr)
|
|
|
|
}
|
|
|
|
| BEGIN_CODE code_and_pos = code text = END_CODE {
|
|
|
|
let (code, pos) = code_and_pos in
|
|
|
|
CodeBlock (code, (text, pos))
|
|
|
|
}
|
2020-03-08 02:21:55 +03:00
|
|
|
|
|
|
|
source_file:
|
2020-03-08 03:52:31 +03:00
|
|
|
| i = source_file_item f = source_file { i::f }
|
|
|
|
| EOF { [] }
|