catala/src/lawspec/parsing/parser.mly

328 lines
7.2 KiB
OCaml
Raw Normal View History

(*
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
open Parse_utils
%}
%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
%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 {}
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 {}
| {}
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 {}
exists_prefix:
2020-04-14 12:46:48 +03:00
| EXISTS ident IN qident SUCH THAT {}
2020-03-08 07:01:26 +03:00
expression:
| 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-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-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 {}
| 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
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))
}
source_file:
2020-03-08 03:52:31 +03:00
| i = source_file_item f = source_file { i::f }
| EOF { [] }