-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhl7validation.lark
110 lines (81 loc) · 3.36 KB
/
hl7validation.lark
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// import "pkg://package.name/path/to/resource"
// MSH
// PID 1
// PV1 1..n
//
// "MSH.9.1.1" must be "OML"
// "MSH.9.1.2" must be "O21"
// "MSH.3.1.1" must be not empty
// "MSH.3.1.1" may be "Lab system"
// "MSH.3.1.1" may be string
// "MSH.3.1.1" may be one of "Lab1", "Lab2", "Lab3"
// "MSH.3.2" cannot be int
// "MSH.3.3" must be be int
// "MSH.3.3" must be int if "MSH.4" is empty
start: structure
structure: import_rules segments ruleset // first structure then field rules
import_rules: (import_rule+)?
import_rule: "import" ESCAPED_STRING -> import_rule
segments: (structure_segment+)? -> create_segment
ruleset: (rule+)?
rule: test_rule -> create_rule
| base_rule -> create_rule
base_rule: selector_field predicate
test_rule: base_rule "if" check_rule
check_rule: selector_field test
_selector_segment_a: /([A-Z]{3})/
_selector_segment_b: /([A-Z]{2}[0-9]{1})/
// MSH, PID, PV1
selector_segment: _selector_segment_a | _selector_segment_b
// ABC.1
// ABC.1.2
// ABC.1.2.3
selector_field : "\"" + /([A-Z]{3}|[A-Z]{2}[0-9]{1})\.\d+(\.\d+)*/ + "\"" -> selector_field
// selector: selector_field | selector_segment
optional_selector_segment: "[" selector_segment "]" -> optional_segment
segment_cardinality: SEGMENT_NONE | SEGMENT_ONE | SEGMENT_AT_LEAST_ONE | SEGMENT_MANY | SEGMENT_AT_MOST_ONE
// MSH 1
// PID 1
// [PV1] 0..n
// [OBX] 0..n
// ORC 1..n
// OBR 1..n
// OBX 0..n
// NTE 0..n
structure_segment: /(\s+)/(optional_selector_segment|selector_segment (segment_cardinality)?) -> structure_segment
predicate: "must be" CHECK_VALUES -> must_be_value // must be "a", "b", 1, r"2022010102"
| "must match" REGEXP -> must_be_value // must be r"[a-z]+"
| "must be" CHECK_TYPES -> must_be_type // must be int, string
| "may be" CHECK_TYPES -> may_be_type
| "may be" CHECK_VALUES -> may_be_value
| "may be one of" list_of_values -> may_be_one_of
| "must be one of" list_of_values -> must_be_one_of
| "cannot be one of" list_of_values -> cannot_be_one_of
| "cannot be" CHECK_VALUES -> cannot_be_value
| "cannot be" CHECK_TYPES -> cannot_be_type
| "must be not empty" -> must_be_not_empty
| "must be empty" -> must_be_empty
test: "is of value" CHECK_VALUES -> test_is_value
| "matches" REGEXP -> test_is_value
| "is empty" -> test_is_empty
| "is one of" list_of_values -> test_list_of_values
| "is not empty" -> test_is_not_empty
| "is of type" CHECK_TYPES -> test_is_type
CHECK_TYPES: "int" | "string"
%import common (NUMBER, INT, ESCAPED_STRING, WS)
%ignore WS
%ignore COMMENT
ESCAPED_STRINGS: ESCAPED_STRING+
// r"regexp contents"
REGEXP: /r".*?"/
_NL: /(\r?\n)+\s*/
CHECK_VALUES: NUMBER | INT | ESCAPED_STRING | ESCAPED_STRINGS
list_of_values: CHECK_VALUES ["," CHECK_VALUES]*
PREDICATE_VALUE: CHECK_TYPES | CHECK_VALUES
predicate_values: PREDICATE_VALUE | list_of_values
COMMENT: /\s*/ "//" /[^\n]/*
SEGMENT_NONE: "0"
SEGMENT_ONE: "1"
SEGMENT_AT_MOST_ONE: "0..1"
SEGMENT_AT_LEAST_ONE: "1..n"
SEGMENT_MANY: "0..n"